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