1#
2# SPDX-License-Identifier: BSD-3-Clause
3#
4# Copyright © 2019 Keith Packard
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12#
13# 2. Redistributions in binary form must reproduce the above
14#    copyright notice, this list of conditions and the following
15#    disclaimer in the documentation and/or other materials provided
16#    with the distribution.
17#
18# 3. Neither the name of the copyright holder nor the names of its
19#    contributors may be used to endorse or promote products derived
20#    from this software without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33# OF THE POSSIBILITY OF SUCH DAMAGE.
34#
35
36src_picocrt = []
37src_picocrt_none = files('crt0-none.c')
38
39machine_dir = 'machine' / host_cpu_family
40picocrt_march_add=''
41if fs.is_dir(machine_dir)
42  subdir(machine_dir)
43else
44  src_picocrt = files('shared/crt0.c')
45endif
46
47foreach target : targets
48  value = get_variable('target_' + target)
49
50  instdir = join_paths(lib_dir, value[0])
51
52  if picocrt_march_add != ''
53    new_cflags = []
54    foreach cflag : value[1]
55      if cflag.startswith('-march') and not cflag.contains(picocrt_march_add)
56	cflag = cflag + picocrt_march_add
57      endif
58      new_cflags += cflag
59    endforeach
60    value = [value[0], new_cflags]
61  endif
62
63  if target == ''
64    crt_name = 'crt0.o'
65    crt_hosted_name = 'crt0-hosted.o'
66    crt_minimal_name = 'crt0-minimal.o'
67    crt_semihost_name = 'crt0-semihost.o'
68    crt_none_name = 'crt0-none.o'
69    libcrt_name = 'crt0'
70    libcrt_hosted_name = 'crt0-hosted'
71    libcrt_minimal_name = 'crt0-minimal'
72    libcrt_semihost_name = 'crt0-semihost'
73    libcrt_none_name = 'crt0-none'
74  else
75    crt_name = join_paths(target, 'crt0.o')
76    crt_hosted_name = join_paths(target, 'crt0-hosted.o')
77    crt_minimal_name = join_paths(target, 'crt0-minimal.o')
78    crt_semihost_name = join_paths(target, 'crt0-semihost.o')
79    crt_none_name = join_paths(target, 'crt0-none.o')
80    libcrt_name = join_paths(target, 'libcrt0')
81    libcrt_hosted_name = join_paths(target, 'libcrt0-hosted')
82    libcrt_minimal_name = join_paths(target, 'libcrt0-minimal')
83    libcrt_semihost_name = join_paths(target, 'libcrt0-semihost')
84    libcrt_none_name = join_paths(target, 'libcrt0-none')
85  endif
86
87  crt0_name = 'crt0' + target
88  crt0_hosted_name = 'crt0_hosted' + target
89  crt0_minimal_name = 'crt0_minimal' + target
90  crt0_semihost_name = 'crt0_semihost' + target
91  crt0_none_name = 'crt0_none' + target
92
93  _c_args = value[1] + arg_fnobuiltin + ['-ffreestanding']
94  _link_args = value[1] + ['-r', '-ffreestanding']
95
96  # The normal variant does not call 'exit' after return from main (c lingo: freestanding execution environment)
97  _crt = executable(crt_name,
98		    src_picocrt,
99		    include_directories : inc,
100		    install : true,
101		    install_dir : instdir,
102		    c_args : _c_args,
103		    link_args : _link_args)
104
105  set_variable(crt0_name,
106	       _crt.extract_objects(src_picocrt)
107	      )
108
109  if enable_picocrt_lib
110    static_library(libcrt_name,
111                   [],
112		   include_directories : inc,
113                   install : true,
114                   install_dir : instdir,
115		   c_args : _c_args,
116                   objects: get_variable(crt0_name),
117                   pic: false)
118  endif
119
120  # The 'hosted' variant calls 'exit' after return from main (c lingo: hosted execution environment)
121  _crt = executable(crt_hosted_name,
122		    src_picocrt,
123		    include_directories : inc,
124		    install : true,
125		    install_dir : instdir,
126		    c_args : _c_args + ['-DCRT0_EXIT'],
127		    link_args : _link_args)
128
129  set_variable(crt0_hosted_name,
130	       _crt.extract_objects(src_picocrt)
131	      )
132
133  if enable_picocrt_lib
134    static_library(libcrt_hosted_name,
135                   [],
136		   include_directories : inc,
137                   install : true,
138                   install_dir : instdir,
139                   pic: false,
140                   objects: get_variable(crt0_hosted_name),
141		   c_args : value[1] + ['-DCRT0_EXIT'])
142  endif
143
144  # The 'minimal' variant doesn't call exit, nor does it invoke any constructors
145  _crt = executable(crt_minimal_name,
146		    src_picocrt,
147		    include_directories : inc,
148		    install : true,
149		    install_dir : instdir,
150		    c_args : _c_args + ['-DCONSTRUCTORS=0'],
151		    link_args : _link_args)
152
153  set_variable(crt0_minimal_name,
154	       _crt.extract_objects(src_picocrt)
155	      )
156
157  if enable_picocrt_lib
158    static_library(libcrt_minimal_name,
159                   [],
160		   include_directories : inc,
161                   install : true,
162                   install_dir : instdir,
163                   pic: false,
164                   objects: get_variable(crt0_minimal_name),
165		   c_args : _c_args + ['-DCONSTRUCTORS=0'])
166  endif
167
168  if has_arm_semihost
169    # The 'semihost' variant calls sys_semihost_get_cmdline to build argv
170    # and calls exit when main returns
171    _crt = executable(crt_semihost_name,
172		      src_picocrt,
173		      include_directories : inc,
174		      install : true,
175		      install_dir : instdir,
176		      c_args : _c_args + ['-DCRT0_EXIT', '-DCRT0_SEMIHOST'],
177		      link_args : _link_args)
178
179    set_variable(crt0_semihost_name,
180		 _crt.extract_objects(src_picocrt)
181		)
182
183    if enable_picocrt_lib
184      static_library(libcrt_semihost_name,
185                     [],
186		     include_directories : inc,
187                     install : true,
188                     install_dir : instdir,
189                     pic: false,
190                     objects: get_variable(crt0_semihost_name),
191		     c_args : value[1] + ['-DCRT0_EXIT', '-DCRT0_SEMIHOST'])
192    endif
193  endif
194
195  # The 'none' variant is completely empty
196  _crt = executable(crt_none_name,
197		    src_picocrt_none,
198		    include_directories : inc,
199		    install : true,
200		    install_dir : instdir,
201		    c_args : _c_args,
202		    link_args : _link_args)
203
204  set_variable(crt0_none_name,
205	       _crt.extract_objects(src_picocrt_none)
206	      )
207
208
209endforeach
210