1# 2# SPDX-License-Identifier: BSD-3-Clause 3# 4# Copyright © 2019-2021 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# 35project('picolibc', 'c', 36 default_options: [ 37 'buildtype=minsize', 38 'debug=true', 39 'c_std=c18', 40 'b_staticpic=false', 41 'warning_level=2', 42 ], 43 license : 'BSD', 44 meson_version : '>= 0.53', 45 version: '1.8.6' 46 ) 47 48targets = [] 49 50fs = import('fs') 51 52cc = meson.get_compiler('c') 53 54# Find the compiler installation directory by parsing the output of 55# cc -print-search-dirs 56 57cc_install_dir = '' 58foreach _line : run_command(cc.cmd_array() + ['-print-search-dirs'], check : false).stdout().split('\n') 59 if _line.startswith('install: ') 60 if meson.version().version_compare('>=0.56') 61 # trim off the leading 'install: ' 62 cc_install_dir = _line.substring(9) 63 else 64 cc_install_dir = run_command(['expr', _line, ':', 'install: *\(.*\)'], check : false).stdout().split('\n')[0] 65 endif 66 endif 67endforeach 68 69# these options are required for all C compiler operations, including 70# detecting many C compiler features, as we cannot expect there 71# to be a working C library on the system. 72 73core_c_args = [] 74if not get_option('use-stdlib') 75 core_c_args += cc.get_supported_arguments(['-nostdlib']) 76endif 77 78# Find the picolibc name for the host cpu. Provide 79# for some common aliases 80 81cpu_family_aliases = { 82 # aarch64 83 'arm64' : 'aarch64', 84 # arc 85 'arc64' : 'arc', 86 # cris 87 'crisv32' : 'cris', 88 # m68hc11 89 'm6811' : 'm68hc11', 90 'm6812' : 'm68hc11', 91 'm68hc12' : 'm68hc11', 92 # m68k 93 'fido' : 'm68k', 94 # m88k 95 'm88110' : 'm88k', 96 # Microblaze 97 'microblazeel' : 'microblaze', 98 # or1k 99 'or1knd': 'or1k', 100 # powerpc 101 'powerpc64' : 'powerpc', 102 'ppc64' : 'powerpc', 103 'ppc64le' : 'powerpc', 104 # riscv 105 'riscv32' : 'riscv', 106 'riscv64' : 'riscv', 107 # sparc 108 'sparc64' : 'sparc', 109 # x86 110 'amd64' : 'x86', 111 'i486' : 'x86', 112 'i586' : 'x86', 113 'i686' : 'x86', 114 'x86_64' : 'x86', 115 } 116 117# Check for an alias, default to provided name 118host_cpu_family = cpu_family_aliases.get(host_machine.cpu_family(), host_machine.cpu_family()) 119 120# Make sure we have meson build support for the machine-specific files 121if not fs.is_file('newlib/libc/machine' / host_cpu_family / 'meson.build') 122 message = ''' 123 124Unsupported architecture: "@0@" 125 126 Read the Supported Architectures section in README.md 127 to learn how to add a new architecture. 128''' 129 error(message.format(host_cpu_family)) 130endif 131 132# Find out about float types 133 134long_double_code = ''' 135#include <float.h> 136#ifndef __LDBL_MANT_DIG__ 137#error No long double support in float.h 138#endif 139long double test(void) 140{ 141 long double ld = 0.0L; 142 return ld; 143} 144''' 145 146have_long_double = cc.compiles(long_double_code, name : 'long double check', args: core_c_args) 147 148enable_multilib = get_option('multilib') 149multilib_list = get_option('multilib-list') 150multilib_exclude = get_option('multilib-exclude') 151enable_picolib = get_option('picolib') 152enable_picocrt = get_option('picocrt') 153enable_picocrt_lib = get_option('picocrt-lib') 154enable_semihost = get_option('semihost') 155enable_tests = get_option('tests') 156enable_native_tests = get_option('native-tests') 157tests_enable_stack_protector = get_option('tests-enable-stack-protector') 158tests_enable_full_malloc_stress = get_option('tests-enable-full-malloc-stress') 159tests_enable_posix_io = get_option('tests-enable-posix-io') 160have_alias_attribute_option = get_option('have-alias-attribute') 161have_format_attribute_option = get_option('have-format-attribute') 162have_weak_attribute_option = get_option('have-weak-attribute') 163 164newlib_iconv_encodings = get_option('newlib-iconv-encodings') 165newlib_iconv_encodings_exclude = get_option('newlib-iconv-encodings-exclude') 166newlib_iconv_from_encodings = get_option('newlib-iconv-from-encodings') 167newlib_iconv_to_encodings = get_option('newlib-iconv-to-encodings') 168newlib_iconv_external_ccs = get_option('newlib-iconv-external-ccs') 169 170newlib_atexit_dynamic_alloc = get_option('newlib-atexit-dynamic-alloc') 171newlib_nano_malloc = get_option('newlib-nano-malloc') 172lite_exit = get_option('lite-exit') 173 174newlib_elix_level = get_option('newlib-elix-level') 175c_args = ['-include', '@0@/@1@'.format(meson.current_build_dir(), 'picolibc.h')] + core_c_args 176native_c_args = ['-DNO_NEWLIB'] 177 178if get_option('profile') 179 c_args += ['-pg', '-no-pie'] 180endif 181 182if get_option('freestanding') 183 c_args += ['-ffreestanding'] 184endif 185 186# Disable ssp and fortify source while building picolibc (it's enabled 187# by default by the ubuntu native compiler) 188c_flags = cc.get_supported_arguments(['-fno-common', '-frounding-math', '-fsignaling-nans', 189 '-Wno-unsupported-floating-point-opt', '-fno-stack-protector', 190 '-fno-builtin-copysignl']) 191 192c_sanitize_bounds_flags = cc.get_supported_arguments(['-fsanitize=bounds']) 193c_sanitize_trap_flags = cc.get_supported_arguments(['-fsanitize-undefined-trap-on-error']) 194c_sanitize_no_trap_flags = cc.get_supported_arguments(['-fno-sanitize-undefined-trap-on-error', '-static-libubsan']) 195have_ubsan = c_sanitize_bounds_flags != [] 196c_args += c_flags 197native_c_args += c_flags 198 199sanitize_bounds = get_option('sanitize-bounds') 200sanitize_trap_on_error = get_option('sanitize-trap-on-error') 201 202if sanitize_bounds 203 if not have_ubsan 204 error('sanitize-bounds option selected but -fsanitize=bounds is not supported') 205 endif 206 c_args += c_sanitize_bounds_flags 207 native_c_args += c_sanitize_bounds_flags 208 if sanitize_trap_on_error 209 c_args += c_sanitize_trap_flags 210 else 211 c_args += c_sanitize_no_trap_flags 212 endif 213endif 214 215if cc.symbols_have_underscore_prefix() 216 global_prefix = '_' 217else 218 global_prefix = '' 219endif 220fast_strcmp = get_option('fast-strcmp') 221 222newlib_mb = get_option('newlib-mb') 223newlib_locale_info = get_option('newlib-locale-info') 224 225newlib_obsolete_math = get_option('newlib-obsolete-math') 226newlib_obsolete_math_float = get_option('newlib-obsolete-math-float') 227newlib_obsolete_math_double = get_option('newlib-obsolete-math-double') 228 229sysroot_install = get_option('sysroot-install') 230system_libc = get_option('system-libc') 231prefix = get_option('prefix') 232 233nm = find_program('nm', required : false) 234 235check_duplicate_names = nm.found() 236 237if nm.found() 238 duplicate_names = find_program('scripts/duplicate-names', required : true) 239endif 240 241# Select exit code 242picoexit = get_option('picoexit') 243 244# Shared stdio options 245io_long_long = get_option('io-long-long') 246newlib_io_long_long = get_option('newlib-io-long-long') 247if newlib_io_long_long != 'auto' 248 io_long_long = newlib_io_long_long == 'true' 249endif 250 251io_c99_formats = get_option('io-c99-formats') 252newlib_io_c99_formats = get_option('newlib-io-c99-formats') 253if newlib_io_c99_formats != 'auto' 254 io_c99_formats = newlib_io_c99_formats == 'true' 255endif 256 257io_pos_args = get_option('io-pos-args') 258newlib_io_pos_args = get_option('newlib-io-pos-args') 259if newlib_io_pos_args != 'auto' 260 io_pos_args = newlib_io_pos_args == 'true' 261endif 262 263# Select stdio implementation 264tinystdio = get_option('tinystdio') 265 266has_link_defsym = meson.get_cross_property('has_link_defsym', 267 cc.has_link_argument('-Wl,--defsym=' + 'start=0') or 268 cc.has_link_argument('-Wl,--defsym=' + '_start=0') or 269 cc.has_link_argument('-Wl,--defsym=' + '__start=0') or 270 cc.has_link_argument('-Wl,--defsym=' + '___start=0') ) 271has_link_alias = meson.get_cross_property('has_link_alias', cc.has_link_argument('-Wl,-alias,' + global_prefix + 'main,testalias')) 272lib_gcc = meson.get_cross_property('libgcc', '-lgcc') 273 274# tinystdio options 275posix_console = tinystdio and get_option('posix-console') 276posix_io = tinystdio and (get_option('posix-io') or posix_console) 277io_float_exact = not tinystdio or get_option('io-float-exact') 278atomic_ungetc = tinystdio and get_option('atomic-ungetc') 279format_default = get_option('format-default') 280printf_aliases = get_option('printf-aliases') 281io_percent_b = tinystdio and get_option('io-percent-b') 282io_long_double = get_option('io-long-double') or get_option('newlib-io-long-double') 283printf_small_ultoa = tinystdio and get_option('printf-small-ultoa') 284minimal_io_long_long = tinystdio and get_option('minimal-io-long-long') 285fast_bufio = tinystdio and get_option('fast-bufio') 286 287if printf_aliases 288 double_printf_compile_args=['-DPICOLIBC_DOUBLE_PRINTF_SCANF'] 289 float_printf_compile_args=['-DPICOLIBC_FLOAT_PRINTF_SCANF'] 290 llong_printf_compile_args=['-DPICOLIBC_LONG_LONG_PRINTF_SCANF'] 291 int_printf_compile_args=['-DPICOLIBC_INTEGER_PRINTF_SCANF'] 292 min_printf_compile_args=['-DPICOLIBC_MINIMAL_PRINTF_SCANF'] 293else 294 double_printf_compile_args=[] 295 float_printf_compile_args=[] 296 llong_printf_compile_args=[] 297 int_printf_compile_args=[] 298 min_printf_compile_args=[] 299endif 300double_printf_link_args=double_printf_compile_args 301float_printf_link_args=float_printf_compile_args 302llong_printf_link_args=llong_printf_compile_args 303int_printf_link_args=int_printf_compile_args 304min_printf_link_args=min_printf_compile_args 305 306if tinystdio and printf_aliases 307 vfprintf_symbol = global_prefix + 'vfprintf' 308 __d_vfprintf_symbol = global_prefix + '__d_vfprintf' 309 __f_vfprintf_symbol = global_prefix + '__f_vfprintf' 310 __l_vfprintf_symbol = global_prefix + '__l_vfprintf' 311 __i_vfprintf_symbol = global_prefix + '__i_vfprintf' 312 __m_vfprintf_symbol = global_prefix + '__m_vfprintf' 313 vfscanf_symbol = global_prefix + 'vfscanf' 314 __d_vfscanf_symbol = global_prefix + '__d_vfscanf' 315 __f_vfscanf_symbol = global_prefix + '__f_vfscanf' 316 __l_vfscanf_symbol = global_prefix + '__l_vfscanf' 317 __i_vfscanf_symbol = global_prefix + '__i_vfscanf' 318 __m_vfscanf_symbol = global_prefix + '__m_vfscanf' 319 320 if has_link_defsym 321 if format_default != 'double' 322 double_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __d_vfprintf_symbol 323 double_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __d_vfscanf_symbol 324 endif 325 if format_default != 'float' 326 float_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __f_vfprintf_symbol 327 float_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __f_vfscanf_symbol 328 endif 329 if format_default != 'long-long' 330 llong_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __l_vfprintf_symbol 331 llong_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __l_vfscanf_symbol 332 endif 333 if format_default != 'integer' 334 int_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __i_vfprintf_symbol 335 int_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __i_vfscanf_symbol 336 endif 337 if format_default != 'minimal' 338 min_printf_link_args += '-Wl,--defsym=' + vfprintf_symbol + '=' + __m_vfprintf_symbol 339 min_printf_link_args += '-Wl,--defsym=' + vfscanf_symbol + '=' + __m_vfscanf_symbol 340 endif 341 elif has_link_alias 342 if format_default == 'double' 343 float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol 344 float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol 345 llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol 346 llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol 347 int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol 348 int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol 349 min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __d_vfprintf_symbol 350 min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __d_vfscanf_symbol 351 endif 352 if format_default == 'float' 353 double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol 354 double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol 355 llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol 356 llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol 357 int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol 358 int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol 359 min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __f_vfprintf_symbol 360 min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __f_vfscanf_symbol 361 endif 362 if format_default == 'long-long' 363 double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol 364 double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol 365 float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol 366 float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol 367 int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol 368 int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol 369 min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __l_vfprintf_symbol 370 min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __l_vfscanf_symbol 371 endif 372 if format_default == 'integer' 373 double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol 374 double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol 375 float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol 376 float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol 377 llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol 378 llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol 379 min_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __i_vfprintf_symbol 380 min_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __i_vfscanf_symbol 381 endif 382 if format_default == 'minimal' 383 double_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol 384 double_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol 385 float_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol 386 float_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol 387 llong_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol 388 llong_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol 389 int_printf_link_args += '-Wl,-alias,' + vfprintf_symbol + ',' + __m_vfprintf_symbol 390 int_printf_link_args += '-Wl,-alias,' + vfscanf_symbol + ',' + __m_vfscanf_symbol 391 endif 392 if format_default != 'double' 393 double_printf_link_args += '-Wl,-alias,' + __d_vfprintf_symbol + ',' + vfprintf_symbol 394 double_printf_link_args += '-Wl,-alias,' + __d_vfscanf_symbol + ',' + vfscanf_symbol 395 endif 396 if format_default != 'float' 397 float_printf_link_args += '-Wl,-alias,' + __f_vfprintf_symbol + ',' + vfprintf_symbol 398 float_printf_link_args += '-Wl,-alias,' + __f_vfscanf_symbol + ',' + vfscanf_symbol 399 endif 400 if format_default != 'long-long' 401 llong_printf_link_args += '-Wl,-alias,' + __l_vfprintf_symbol + ',' + vfprintf_symbol 402 llong_printf_link_args += '-Wl,-alias,' + __l_vfscanf_symbol + ',' + vfscanf_symbol 403 endif 404 if format_default != 'integer' 405 int_printf_link_args += '-Wl,-alias,' + __i_vfprintf_symbol + ',' + vfprintf_symbol 406 int_printf_link_args += '-Wl,-alias,' + __i_vfscanf_symbol + ',' + vfscanf_symbol 407 endif 408 if format_default != 'minimal' 409 min_printf_link_args += '-Wl,-alias,' + __m_vfprintf_symbol + ',' + vfprintf_symbol 410 min_printf_link_args += '-Wl,-alias,' + __m_vfscanf_symbol + ',' + vfscanf_symbol 411 endif 412 else 413 if enable_tests 414 # If the alias flag is not supported and we are building tests, emit an 415 # error here to avoid surprising test failures. 416 error('Symbol alias linker flag not supported - printf tests will fail!') 417 endif 418 endif 419endif 420 421# A bunch of newlib-stdio only options 422newlib_global_stdio_streams = get_option('newlib-global-stdio-streams') 423newlib_fvwrite_in_streamio = get_option('newlib-fvwrite-in-streamio') 424newlib_fseek_optimization = get_option('newlib-fseek-optimization') 425newlib_nano_formatted_io = get_option('newlib-nano-formatted-io') 426newlib_io_float = get_option('newlib-io-float') 427newlib_stdio64 = get_option('newlib-stdio64') 428newlib_wide_orient = get_option('newlib-wide-orient') 429newlib_have_fcntl = get_option('newlib-have-fcntl') 430 431# Check for a bunch of newlib-stdio only options and complain 432# if they are selected while using tinystdio 433 434if tinystdio 435 if newlib_io_float 436 error('tinystdio uses a run-time mechanism to select floating point io (newlib-io-float)') 437 endif 438 if newlib_global_stdio_streams 439 error('tinystdio always has (reentrant) global stdio streams (newlib-global-stdio-streams)') 440 endif 441 if newlib_fvwrite_in_streamio 442 error('tinystdio has no fvwrite support (newlib-fvwrite-in-streamio)') 443 endif 444 if newlib_fseek_optimization 445 error('tinystdio has no fseek support (newlib-fseek-optimization)') 446 endif 447 if newlib_nano_formatted_io 448 error('tinystdio uses a run-time mechanism to select smaller printf code (newlib-nano-formatted-io)') 449 endif 450 if newlib_wide_orient 451 error('tinystdio does not support the wide-orient option (newlib-wide-orient)') 452 endif 453else 454 if posix_console 455 error('newlib stdio does not support the posix-console option (posix-console)') 456 endif 457 if io_pos_args 458 error('newlib stdio has bugs with positional arguments (io-pos-args)') 459 endif 460endif 461 462if host_cpu_family == '' 463 host_cc_machine=run_command(cc.cmd_array() + ['-dumpmachine'], check : true).stdout().strip().split('-') 464 host_cpu_family=host_cc_machine[0] 465 message('Computed host_cpu_family as ' + host_cpu_family) 466endif 467 468if have_alias_attribute_option == 'auto' 469 have_alias_attribute = cc.has_function_attribute('alias') 470else 471 have_alias_attribute = have_alias_attribute_option == 'true' 472endif 473 474if have_format_attribute_option == 'auto' 475 have_format_attribute = cc.has_function_attribute('format') 476else 477 have_format_attribute = have_format_attribute_option == 'true' 478endif 479 480if have_weak_attribute_option == 'auto' 481 have_weak_attribute = cc.has_function_attribute('weak') 482else 483 have_weak_attribute = have_weak_attribute_option == 'true' 484endif 485 486tls_model_spec = '' 487thread_local_storage = false 488thread_local_storage_option = get_option('thread-local-storage') 489have_picolibc_tls_api = fs.is_file('newlib/libc/picolib/machine' / host_cpu_family / 'tls.c') 490if thread_local_storage_option == 'auto' or thread_local_storage_option == 'picolibc' 491 # We assume that _set_tls() is defined in the arch specific tls.c 492 if thread_local_storage_option == 'auto' or have_picolibc_tls_api 493 thread_local_storage = not cc.has_function('__emutls_get_address', args: core_c_args + [lib_gcc]) 494 endif 495else 496 thread_local_storage = get_option('thread-local-storage') == 'true' 497endif 498if thread_local_storage 499 tls_model_spec = '%{!ftls-model:-ftls-model=' + get_option('tls-model') + '}' 500endif 501 502if sysroot_install 503 sysroot = run_command(cc.cmd_array() + ['-print-sysroot'], check : true).stdout().split('\n')[0] 504 if sysroot != '' 505 specs_prefix_format = '%R/@0@' 506 else 507 sysroot = cc_install_dir + '../../../..' 508 specs_prefix_format = '%:getenv(GCC_EXEC_PREFIX ../../@0@)' 509 endif 510 if not get_option('sysroot-install-skip-checks') 511 if sysroot == '' 512 error('sysroot install requested, but compiler has no sysroot') 513 endif 514 if not fs.is_samepath(sysroot, prefix) 515 error('sysroot install requires --prefix=' + sysroot) 516 endif 517 endif 518else 519 specs_prefix_format = prefix + '/@0@' 520endif 521 522build_type_subdir = get_option('build-type-subdir') 523 524lib_dir = prefix / get_option('libdir') / build_type_subdir 525 526include_dir = prefix / get_option('includedir') / build_type_subdir 527 528newlib_iconv_dir = get_option('newlib-iconv-dir') 529if newlib_iconv_dir == '' 530 newlib_iconv_dir = join_paths(lib_dir, 'locale') 531endif 532 533newlib_iconv_runtime_dir = get_option('newlib-iconv-runtime-dir') 534if newlib_iconv_runtime_dir == '' 535 newlib_iconv_runtime_dir = newlib_iconv_dir 536endif 537 538specs_dir_option = get_option('specsdir') 539if build_type_subdir != '' 540 specs_dir = '' 541 specs_install = false 542elif specs_dir_option == '' 543 specs_dir = cc_install_dir 544 specs_install = specs_dir != '' 545elif specs_dir_option == 'none' 546 specs_dir = '' 547 specs_install = false 548else 549 specs_dir = join_paths(prefix, specs_dir_option) 550 specs_install = true 551endif 552 553# Let targets add more support libraries 554additional_libs_list = meson.get_cross_property('additional_libs', []) 555 556compiler_id = cc.get_id() 557if compiler_id == 'ccomp' 558 # When passing the specs file to CompCert, the libcompcert needs to be included there as well 559 additional_libs_list += '-lcompcert' 560endif 561 562additional_libs = ' '.join(additional_libs_list) 563 564if compiler_id == 'gcc' and target_machine.cpu_family() == 'msp430' 565 # Extract -mhwmult-selection-snippet from GCC. 566 dumped_specs = run_command(cc.cmd_array() + '-dumpspecs').stdout() 567 hwmult_start = dumped_specs.split('%{mhwmult=auto')[1] 568 hwmult_snippet = '%{mhwmult=auto' + hwmult_start.split('-lc')[0] 569 additional_libs += hwmult_snippet 570endif 571 572specs_extra = '' 573specs_extra_list = meson.get_cross_property('specs_extra', []) 574if specs_extra_list != [] 575 specs_extra = '\n' + '\n'.join(specs_extra_list) 576endif 577 578specs_printf = '' 579if tinystdio and printf_aliases 580 specs_printf=('%{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfprintf=' + __d_vfprintf_symbol + '}' + 581 ' %{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfscanf=' + __d_vfscanf_symbol + '}' + 582 ' %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfprintf=' + __f_vfprintf_symbol + '}' + 583 ' %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfscanf=' + __f_vfscanf_symbol + '}' + 584 ' %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfprintf=' + __l_vfprintf_symbol + '}' + 585 ' %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfscanf=' + __l_vfscanf_symbol + '}' + 586 ' %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfprintf=' + __i_vfprintf_symbol + '}' + 587 ' %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfscanf=' + __i_vfscanf_symbol + '}' + 588 ' %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfprintf=' + __m_vfprintf_symbol + '}' + 589 ' %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfscanf=' + __m_vfscanf_symbol + '}') 590endif 591 592crt0_expr = '%{-crt0=*:crt0-%*%O%s; :crt0%O%s}' 593 594if system_libc 595 specs_isystem = '' 596 specs_libpath = '' 597 specs_startfile = crt0_expr 598else 599 600# 601# Construct path values for specs file 602# 603# Each of these needs to handle --picolibc-prefix and 604# --picolibc-buildtype options, system-root vs absolute paths and 605# multilib stuff. That makes this all unreasonably complicated. 606# 607# Each option is computed in three parts, the 'prefix' value 608# (corresponding to --picolibc-prefix), the 'buildtype' value 609# (corresponding to --picolibc-buildtype) and the 'gen' value (for 610# when neither of these options is specifed). 611# 612# Because 'getenv' appends a space afterwards in GCC spec files, the 613# entire final path elements must be specified inside the parens; 614# e.g. %:getenv(FOO a/b/c) instead of %:getenv(FOO)/a/b/c. That means 615# we use the specs_prefix_format value computed above to build paths 616# instead of simple concatenation 617# 618 619# 620# How to format each of the three option-selected 621# values 622# 623picolibc_prefix_format = '-picolibc-prefix=*:@0@' 624picolibc_buildtype_format = '-picolibc-buildtype=*:@0@' 625gen_format = '@0@' 626 627# 628# How to glue the three options together 629# 630specs_option_format = '%{@0@; @1@; :@2@}' 631 632# 633# Build the -isystem value 634# 635 636prefix_include_dir = '%*/@0@/'.format(get_option('includedir')) 637isystem_prefix = picolibc_prefix_format.format(prefix_include_dir) 638 639buildtype_include_dir = specs_prefix_format.format(get_option('includedir') / '%*') 640isystem_buildtype = picolibc_buildtype_format.format(buildtype_include_dir) 641 642gen_include_dir = specs_prefix_format.format(get_option('includedir')) 643isystem_gen = gen_format.format(gen_include_dir) 644 645specs_isystem = '-isystem ' + specs_option_format.format(isystem_prefix, isystem_buildtype, isystem_gen) 646 647# 648# Build the non-multilib -L value 649# 650 651prefix_lib_dir = '%*/@0@'.format(get_option('libdir')) 652lib_prefix = picolibc_prefix_format.format(prefix_lib_dir) 653 654buildtype_lib_dir = specs_prefix_format.format(get_option('libdir') / '%*') 655lib_buildtype = picolibc_buildtype_format.format(buildtype_lib_dir) 656 657gen_lib_dir = specs_prefix_format.format(get_option('libdir')) 658lib_gen = gen_format.format(gen_lib_dir) 659 660specs_libpath = '-L' + specs_option_format.format(lib_prefix, lib_buildtype, lib_gen) 661 662# 663# Build the non-multilib *startfile options 664# 665 666prefix_crt0_path = '%*/@0@'.format(get_option('libdir')) / crt0_expr 667crt0_prefix = picolibc_prefix_format.format(prefix_crt0_path) 668 669buildtype_crt0_path = specs_prefix_format.format(get_option('libdir') / '%*' / crt0_expr) 670crt0_buildtype = picolibc_buildtype_format.format(buildtype_crt0_path) 671 672gen_crt0_path = specs_prefix_format.format(get_option('libdir') / crt0_expr) 673crt0_gen = gen_format.format(gen_crt0_path) 674 675# 676# Now build multilib versions of the -L and *startfile values 677# 678if enable_multilib 679 680 # 681 # Build the multilib -L value 682 # 683 prefix_multilib_dir = '%*/@0@'.format(get_option('libdir') / '%M') 684 multilib_prefix = picolibc_prefix_format.format(prefix_multilib_dir) 685 686 buildtype_multilib_dir = specs_prefix_format.format(get_option('libdir') / '%*/%M') 687 multilib_buildtype = picolibc_buildtype_format.format(buildtype_multilib_dir) 688 689 gen_multilib_dir = specs_prefix_format.format(get_option('libdir') / '%M') 690 multilib_gen = gen_format.format(gen_multilib_dir) 691 692 specs_multilibpath = '-L' + specs_option_format.format(multilib_prefix, multilib_buildtype, multilib_gen) 693 694 # 695 # Prepend the multilib -L option to the non-multilib option 696 # 697 specs_libpath = specs_multilibpath + ' ' + specs_libpath 698 699 # 700 # Build the multilib *startfile options 701 # 702 prefix_multilib_crt0_path = '%*/@0@'.format(get_option('libdir')) / '%M' / crt0_expr 703 crt0_prefix = picolibc_prefix_format.format(prefix_multilib_crt0_path) 704 705 buildtype_multilib_crt0_path = specs_prefix_format.format(get_option('libdir') / '%*/%M' / crt0_expr) 706 crt0_buildtype = picolibc_buildtype_format.format(buildtype_multilib_crt0_path) 707 708 gen_multilib_crt0_path = specs_prefix_format.format(get_option('libdir') / '%M' / crt0_expr) 709 crt0_gen = gen_format.format(gen_multilib_crt0_path) 710endif 711 712# 713# Construct the *startfile value from the options computed 714# above. As there's only one value, it's either the 715# multilib path or the non-multilib path 716# 717specs_startfile = specs_option_format.format(crt0_prefix, crt0_buildtype, crt0_gen) 718endif 719 720specs_data = configuration_data() 721specs_data.set('SPECS_ISYSTEM', specs_isystem) 722specs_data.set('SPECS_LIBPATH', specs_libpath) 723specs_data.set('SPECS_STARTFILE', specs_startfile) 724specs_data.set('TLSMODEL', tls_model_spec) 725specs_data.set('LINK_SPEC', meson.get_cross_property('link_spec', '')) 726specs_data.set('CC1_SPEC', meson.get_cross_property('cc1_spec', '')) 727specs_data.set('CC1PLUS_SPEC', meson.get_cross_property('cc1plus_spec', '')) 728specs_data.set('ADDITIONAL_LIBS', additional_libs) 729specs_data.set('SPECS_EXTRA', specs_extra) 730specs_data.set('SPECS_PRINTF', specs_printf) 731 732# Create C and C++ specific specs data, 733# that includes setting the correct linker script 734# and adding the C++ startup/shutdown files 735 736specs_c_data = specs_data 737 738specs_c_data.set('PICOLIBC_LD', 'picolibc.ld') 739specs_c_data.set('CRTBEGIN', '') 740specs_c_data.set('CRTEND', '') 741 742specs_cpp_data = specs_data 743 744specs_cpp_data.set('PICOLIBC_LD', 'picolibcpp.ld') 745specs_cpp_data.set('CRTBEGIN', 'crtbegin%O%s') 746specs_cpp_data.set('CRTEND', 'crtend%O%s') 747 748picolibc_specs = configure_file(input: 'picolibc.specs.in', 749 output: 'picolibc.specs', 750 configuration: specs_c_data, 751 install_dir: specs_dir, 752 install: specs_install) 753 754picolibc_specs_name = 'picolibc.specs' 755 756picolibcpp_specs = configure_file(input: 'picolibc.specs.in', 757 output: 'picolibcpp.specs', 758 configuration: specs_cpp_data, 759 install_dir: specs_dir, 760 install: specs_install) 761 762# Not all compilers necessarily support all warnings; only use these which are: 763c_warnings = [ 764 '-Werror=implicit-function-declaration', 765 '-Werror=vla', 766 '-Warray-bounds', 767 '-Wold-style-definition', 768 '-Werror=double-promotion', 769] 770if get_option('analyzer') 771 c_warnings += [ 772 '-fanalyzer', 773 ] 774endif 775disabled_warnings = [ 776 '-Wno-missing-braces', 777 '-Wno-implicit-int', 778 '-Wno-return-type', 779 '-Wno-unused-command-line-argument', 780] 781c_flags = cc.get_supported_arguments(c_warnings, disabled_warnings) 782c_args += c_flags 783native_c_args += c_flags 784 785# Make sure _LIBC is not defined when building tests 786test_c_args = c_args 787c_args += ['-D_LIBC', '-U_FORTIFY_SOURCE'] 788 789# Select a fortify source option 790fortify_source = get_option('fortify-source') 791if fortify_source == 'none' 792 test_c_args += '-U_FORTIFY_SOURCE' 793else 794 test_c_args += '-D_FORTIFY_SOURCE=' + fortify_source 795endif 796 797# CompCert does not support bitfields in packed structs, so avoid using this optimization 798bitfields_in_packed_structs_code = ''' 799struct test { int part: 24; } __attribute__((packed)); 800unsigned int foobar (const struct test *p) { return p->part; } 801''' 802have_bitfields_in_packed_structs = cc.compiles(bitfields_in_packed_structs_code, name : 'packed structs may contain bitfields', args: core_c_args) 803 804# CompCert does not have __builtin_mul_overflow 805builtin_mul_overflow_code = ''' 806#include <stddef.h> 807int overflows (size_t a, size_t b) { size_t x; return __builtin_mul_overflow(a, b, &x); } 808volatile size_t aa = 42; 809int main (void) { return overflows(aa, aa); } 810''' 811have_builtin_mul_overflow = cc.links(builtin_mul_overflow_code, name : 'has __builtin_mul_overflow', args: core_c_args) 812 813# CompCert does not have __builtin_add_overflow 814builtin_add_overflow_code = ''' 815#include <stddef.h> 816int overflows (size_t a, size_t b) { size_t x; return __builtin_add_overflow(a, b, &x); } 817volatile size_t aa = 42; 818int main (void) { return overflows(aa, aa); } 819''' 820have_builtin_add_overflow = cc.links(builtin_add_overflow_code, name : 'has __builtin_add_overflow', args: core_c_args) 821 822# CompCert does not support _Complex 823complex_code = ''' 824float _Complex test(float _Complex z) { return z; } 825''' 826have_complex = cc.compiles(complex_code, name : 'supports _Complex', args: core_c_args) 827 828builtin_complex_code = ''' 829#include <stddef.h> 830double _Complex test(double r, double i) { return __builtin_complex(r, i); } 831''' 832 833have_builtin_complex = have_complex and cc.compiles(builtin_complex_code, name : 'supports __builtin_complex', args: core_c_args) 834 835# CompCert does not have __builtin_expect 836builtin_expect_code = ''' 837volatile int a = 42; 838int main (void) { 839 return __builtin_expect(a, 1); 840} 841''' 842have_builtin_expect = cc.links(builtin_expect_code, name : 'has __builtin_expect', args: core_c_args) 843 844werror_c_args = core_c_args + cc.get_supported_arguments('-Werror') 845 846# CompCert uses the GCC preprocessor, which causes to 847# > #if __has_attribute(__alloc_size__) 848# produce a wrong result. So test if the compiler has that attribute 849alloc_size_code = ''' 850void *foobar(int) __attribute__((__alloc_size__(1))); 851void *foobar2(int, int) __attribute__((__alloc_size__(1, 2))); 852''' 853have_alloc_size = cc.compiles(alloc_size_code, name : 'attribute __alloc_size__', args : werror_c_args) 854 855# attributes constructor/destructor are a GNU extension - if the compiler doesn't have them, don't test them. 856attr_ctor_dtor_code = ''' 857void __attribute__((constructor(101))) ctor (void) {} 858void __attribute__((destructor(101))) dtor (void) {} 859''' 860have_attr_ctor_dtor = cc.compiles(attr_ctor_dtor_code, name : 'attributes constructor/destructor', args : werror_c_args) 861 862if enable_multilib 863 used_libs = [] 864 865 # Ask the compiler for the set of available multilib configurations, 866 # set up the build system to compile for all desired ones 867 868 target_list = run_command(cc.cmd_array() + get_option('c_args') + ['--print-multi-lib'], check : true).stdout().strip().split('\n') 869 870 has_mcmodel = false 871 foreach target : target_list 872 if target.contains('mcmodel=') 873 has_mcmodel = true 874 endif 875 endforeach 876 877 foreach target : target_list 878 message('target ' + target) 879 tmp = target.split(';') 880 matches_exclude = false 881 foreach exclude : multilib_exclude 882 if tmp[0].contains(exclude) 883 matches_exclude = true 884 message('skipping target ' + tmp[0]) 885 break 886 endif 887 endforeach 888 if matches_exclude 889 continue 890 endif 891 flags = [] 892 893 # Let the user specify a subset of the possible multilib 894 # configurations to build for 895 if multilib_list == [] or tmp[0] in multilib_list 896 used_libs += tmp[0] 897 if tmp.length() > 1 898 foreach flag : tmp[1].strip('@').split('@') 899 if flag != '' 900 if host_cpu_family == 'nios2' 901 # Hacks for NIOS II to get rid of -fsingle-precision-constant 902 # mode (which breaks libm). We don't need fph2 as that 903 # doesn't set the single precision constant flag 904 if flag == 'mcustom-fpu-cfg=60-1' 905 flags += ['-mcustom-fmuls=252', '-mcustom-fadds=253', 906 '-mcustom-fsubs=254'] 907 elif flag == 'mcustom-fpu-cfg=60-2' 908 flags += ['-mcustom-fmuls=252', '-mcustom-fadds=253', 909 '-mcustom-fsubs=254', '-mcustom-fdivs=255'] 910 elif flag == 'mcustom-fpu-cfg=72-3' 911 flags += ['-mcustom-floatus=243', '-mcustom-fixsi=244', 912 '-mcustom-floatis=245','-mcustom-fcmpgts=246', 913 '-mcustom-fcmples=249', '-mcustom-fcmpeqs=250', 914 '-mcustom-fcmpnes=251', '-mcustom-fmuls=252', 915 '-mcustom-fadds=253', '-mcustom-fsubs=254', 916 '-mcustom-fdivs=255'] 917 else 918 flags += '-' + flag 919 endif 920 else 921 flags += '-' + flag 922 endif 923 endif 924 endforeach 925 if tmp[0] == '.' 926 name = '' 927 else 928 name = tmp[0].underscorify() 929 endif 930 else 931 name = '' 932 endif 933 targets += name 934 935 # rv64 needs to use a non-default mcmodel so that variables can 936 # live in a broader range of memory addresses 937 if not has_mcmodel and name.startswith('rv64') 938 flags += [ '-mcmodel=medany' ] 939 endif 940 941 # Add any extra flags for this target from the cross file 942 flags += meson.get_cross_property('c_args_' + name, []) 943 944 value = [tmp[0], flags] 945 set_variable('target_' + name, value) 946 endif 947 endforeach 948 949 # Make sure all requested multilib configurations 950 # are actually available 951 if multilib_list != [] 952 foreach lib : multilib_list 953 if lib not in used_libs 954 error('Unavailable multilib: ' + lib) 955 endif 956 endforeach 957 endif 958else 959 targets = [''] 960 target_ = ['.', []] 961endif 962 963foreach target : ['default-target'] + targets 964 965 message('generate linker script target ' + target) 966 967 custom_mem_config = meson.get_cross_property('custom_mem_config_' + target, '') 968 969 if target == 'default-target' or custom_mem_config != '' 970 971 picolibc_linker_type_data = configuration_data() 972 # We need to use different alignment flags for .tdata/.tbss for ld.bfd 973 # (ALIGN_WITH_INPUT, which is not supported by ld.lld) and ld.lld 974 # (ALIGN(__tls_align), which is rejected as non-constant by ld.bfd), so we use 975 # the {BFD,LLD}_{START,END} templates to comment out the incompatible flag. 976 if cc.get_linker_id() == 'ld.lld' 977 picolibc_linker_type_data.set('BFD_START', '/* For ld.bfd: ') 978 picolibc_linker_type_data.set('BFD_END', '*/') 979 picolibc_linker_type_data.set('LLD_START', '') 980 picolibc_linker_type_data.set('LLD_END', '') 981 if host_cpu_family == 'riscv' 982 # ld.lld before version 15 did not support linker relaxations, disable 983 # them if we are using an older version. 984 # There is no `cc.get_linker_version()` function, so we detect ld.lld 985 # version 15 by checking for a newly added linker flag. 986 if not cc.has_link_argument('--package-metadata=1') 987 message('Linking for RISCV with ld.lld < 15, forcing -mno-relax') 988 c_args += ['-mno-relax'] 989 endif 990 endif 991 else 992 picolibc_linker_type_data.set('BFD_START', '') 993 picolibc_linker_type_data.set('BFD_END', '') 994 picolibc_linker_type_data.set('LLD_START', '/* For ld.lld: ') 995 picolibc_linker_type_data.set('LLD_END', '*/') 996 endif 997 998 init_memory_template = ''' 999 @0@ (rx!w) : 1000 ORIGIN = DEFINED(__@0@) ? __@0@ : @1@, 1001 LENGTH = DEFINED(__@0@_size) ? __@0@_size : @2@''' 1002 init_phdr_template = ''' 1003 text_@0@ PT_LOAD;''' 1004 init_section_template = ''' 1005 .@0@ : {@1@ 1006 } >@2@ AT>@2@ :@3@ 1007''' 1008 default_init_section_template = init_section_template.format('@0@', ''' 1009 KEEP (*(.text.init.enter)) 1010 KEEP (*(.data.init.enter)) 1011 KEEP (*(SORT_BY_NAME(.init) SORT_BY_NAME(.init.*)))''', 1012 '@1@', 1013 '@2@') 1014 1015 additional_sections = [] 1016 1017 fallback_flash_addr = '0x10000000' 1018 fallback_flash_size = '0x00010000' 1019 1020 if meson.get_cross_property('separate_boot_flash_' + custom_mem_config, 1021 meson.get_cross_property('separate_boot_flash', false)) 1022 boot_flash_addr = meson.get_cross_property( 1023 'default_boot_flash_addr_' + custom_mem_config, 1024 meson.get_cross_property( 1025 'default_boot_flash_addr', 1026 '0x10000000')) 1027 boot_flash_size = meson.get_cross_property( 1028 'default_boot_flash_size_' + custom_mem_config, 1029 meson.get_cross_property( 1030 'default_boot_flash_size', 1031 '0x00000400')) 1032 additional_sections = [ 1033 { 1034 'name' : 'boot_flash', 1035 'addr' : boot_flash_addr, 1036 'size' : boot_flash_size, 1037 'contents' : default_init_section_template.format('boot_flash', 'boot_flash', 'text_boot_flash') 1038 }] 1039 fallback_flash_addr = '0x10000400' 1040 fallback_flash_size = '0x0000fc00' 1041 else 1042 additional_section_names = meson.get_cross_property('additional_sections_' + custom_mem_config, 1043 meson.get_cross_property('additional_sections', [])) 1044 if additional_section_names != [] 1045 foreach section_name : additional_section_names 1046 default_content_list = ['*.(.' + section_name + ')', '*.(.' + section_name + '.*)'] 1047 content_list = meson.get_cross_property('default_' + section_name + '_contents', default_content_list) 1048 contents = '' 1049 foreach content : content_list 1050 contents += ''' 1051 @0@'''.format(content) 1052 endforeach 1053 additional_sections += [ 1054 { 1055 'name' : section_name, 1056 'addr' : meson.get_cross_property('default_' + section_name + '_addr'), 1057 'size' : meson.get_cross_property('default_' + section_name + '_size'), 1058 'contents' : init_section_template.format(section_name, contents, section_name, 'text_' + section_name) 1059 }] 1060 endforeach 1061 endif 1062 endif 1063 1064 init_memory = '' 1065 init_phdrs = '' 1066 init_sections = '' 1067 1068 if additional_sections != [] 1069 foreach section : additional_sections 1070 section_name = section['name'] 1071 init_memory += init_memory_template.format(section_name, section['addr'], section['size']) 1072 init_phdrs += init_phdr_template.format(section_name) 1073 init_sections += section['contents'] 1074 endforeach 1075 else 1076 init_memory = '' 1077 init_sections = default_init_section_template.format('init', 'flash', 'text') 1078 endif 1079 1080 picolibc_linker_type_data.set('INIT_MEMORY', init_memory) 1081 picolibc_linker_type_data.set('INIT_PHDRS', init_phdrs) 1082 picolibc_linker_type_data.set('INIT_SECTIONS', init_sections) 1083 1084 picolibc_linker_type_data.set( 1085 'DEFAULT_FLASH_ADDR', meson.get_cross_property( 1086 'default_flash_addr_' + custom_mem_config, 1087 meson.get_cross_property( 1088 'default_flash_addr', 1089 fallback_flash_addr))) 1090 1091 picolibc_linker_type_data.set( 1092 'DEFAULT_FLASH_SIZE', meson.get_cross_property( 1093 'default_flash_size_' + custom_mem_config, 1094 meson.get_cross_property( 1095 'default_flash_size', 1096 fallback_flash_size))) 1097 1098 picolibc_linker_type_data.set( 1099 'DEFAULT_RAM_ADDR', 1100 meson.get_cross_property('default_ram_addr_' + custom_mem_config, 1101 meson.get_cross_property('default_ram_addr', 1102 '0x20000000'))) 1103 1104 picolibc_linker_type_data.set( 1105 'DEFAULT_RAM_SIZE', 1106 meson.get_cross_property('default_ram_size_' + custom_mem_config, 1107 meson.get_cross_property('default_ram_size', 1108 '0x00008000'))) 1109 1110 picolibc_linker_type_data.set( 1111 'DEFAULT_STACK_SIZE', 1112 meson.get_cross_property('default_stack_size_' + custom_mem_config, 1113 meson.get_cross_property('default_stack_size', 1114 '0x00001000'))) 1115 1116 picolibc_linker_type_data.set( 1117 'DEFAULT_ALIGNMENT', 1118 meson.get_cross_property('default_alignment_' + custom_mem_config, 1119 meson.get_cross_property('default_alignment', 1120 '8'))) 1121 1122 picolibc_ld_data = configuration_data() 1123 picolibc_ld_data.merge_from(picolibc_linker_type_data) 1124 picolibc_ld_data.set('CPP_START', '/*') 1125 picolibc_ld_data.set('CPP_END', '*/') 1126 picolibc_ld_data.set('C_START', '') 1127 picolibc_ld_data.set('C_END', '') 1128 picolibc_ld_data.set('PREFIX', global_prefix) 1129 1130 if target == 'default-target' 1131 picolibc_ld_file = 'picolibc.ld' 1132 picolibc_ld_variable = 'picolibc_ld' 1133 picolibc_ld_config_variable = 'picolibc_ld_config' 1134 picolibcpp_ld_file = 'picolibcpp.ld' 1135 picolibcpp_ld_variable = 'picolibcpp_ld' 1136 picolibcpp_ld_config_variable = 'picolibcpp_ld_config' 1137 picolibc_ld_install = true 1138 else 1139 picolibc_ld_file = 'picolibc_' + custom_mem_config + '.ld' 1140 picolibc_ld_variable = 'picolibc_' + target + '_ld' 1141 picolibc_ld_config_variable = 'picolibc_' + target + 'ld_config' 1142 picolibcpp_ld_file = 'picolibcpp_' + custom_mem_config + '.ld' 1143 picolibcpp_ld_variable = 'picolibcpp_' + target + '_ld' 1144 picolibcpp_ld_config_variable = 'picolibcpp_' + target + 'ld_config' 1145 picolibc_ld_install = false 1146 endif 1147 1148 if not is_variable(picolibc_ld_config_variable) 1149 set_variable(picolibc_ld_config_variable, 1150 configure_file(input: 'picolibc.ld.in', 1151 output: picolibc_ld_file, 1152 configuration: picolibc_ld_data, 1153 install: picolibc_ld_install, 1154 install_dir: lib_dir)) 1155 endif 1156 1157 set_variable(picolibc_ld_variable, get_variable(picolibc_ld_config_variable)) 1158 1159 picolibcpp_ld_data = configuration_data() 1160 picolibcpp_ld_data.merge_from(picolibc_linker_type_data) 1161 picolibcpp_ld_data.set('CPP_START', '') 1162 picolibcpp_ld_data.set('CPP_END', '') 1163 picolibcpp_ld_data.set('C_START', '/*') 1164 picolibcpp_ld_data.set('C_END', '*/') 1165 picolibcpp_ld_data.set('PREFIX', global_prefix) 1166 1167 if not is_variable(picolibcpp_ld_config_variable) 1168 set_variable(picolibcpp_ld_config_variable, 1169 configure_file(input: 'picolibc.ld.in', 1170 output: picolibcpp_ld_file, 1171 configuration: picolibcpp_ld_data, 1172 install: picolibc_ld_install, 1173 install_dir: lib_dir)) 1174 endif 1175 1176 set_variable(picolibcpp_ld_variable, get_variable(picolibcpp_ld_config_variable)) 1177 1178 endif 1179endforeach 1180 1181conf_data = configuration_data() 1182 1183# The supported builtins vary depending on compiler and target. 1184# If you want to check for a given builtin, add an array 1185# ['some_builtin_name', '__call_to_builtin(1,2,3);'] 1186# The below loop will then add the define HAVE_SOME_BUILTIN_NAME if the code snippet 1187# > int main (void) { __call_to_builtin(1,2,3); return 0; } 1188# can be compiled + linked. 1189# The name should match the builtin, but technically it's not necessary 1190builtins = [ 1191 ['builtin_alloca', '__builtin_alloca(1)', 'void *'], 1192 ['builtin_ffs', '__builtin_ffs(42)', 'int'], 1193 ['builtin_ffsl', '__builtin_ffsl((long)42)', 'long'], 1194 ['builtin_ffsll', '__builtin_ffsll((long long)42)', 'long long'], 1195 ['builtin_ctz', '__builtin_ctz((unsigned int)42)', 'int'], 1196 ['builtin_ctzl', '__builtin_ctzl((unsigned long)42)', 'int'], 1197 ['builtin_ctzll', '__builtin_ctzll((unsigned long long)42)', 'int'], 1198 ['builtin_copysignl', '__builtin_copysignl((long double)42, (long double) 42)', 'long double'], 1199 ['builtin_copysign', '__builtin_copysign(42, 42)', 'double'], 1200 ['builtin_isinfl', '__builtin_isinfl((long double)42)', 'int'], 1201 ['builtin_isinf', '__builtin_isinf((long double)42)', 'int'], 1202 ['builtin_isnanl', '__builtin_isnanl((long double)42)', 'int'], 1203 ['builtin_isnan', '__builtin_isnan((long double)42)', 'int'], 1204 ['builtin_finitel', '__builtin_finitel((long double)42)', 'int'], 1205 ['builtin_isfinite', '__builtin_isfinite((long double)42)', 'int'], 1206 ['builtin_issignalingl', '__builtin_issignalingl((long double)42)', 'int'], 1207] 1208foreach builtin : builtins 1209 builtin_template=''' 1210static int foo(@1@ i __attribute__((unused))) { return 0; } 1211int main(void) { return foo(@0@); } 1212''' 1213 builtin_code = builtin_template.format(builtin[1], builtin[2]) 1214 have_current_builtin = cc.links(builtin_code, name : 'test for __' + builtin[0], args: core_c_args) 1215 conf_data.set('_HAVE_' + builtin[0].to_upper(), have_current_builtin, description: 'The compiler supports __' + builtin[0]) 1216endforeach 1217 1218NEWLIB_VERSION='4.1.0' 1219NEWLIB_MAJOR_VERSION=4 1220NEWLIB_MINOR_VERSION=1 1221NEWLIB_PATCHLEVEL_VERSION=0 1222 1223if get_option('newlib-retargetable-locking') != get_option('newlib-multithread') 1224 error('newlib-retargetable-locking and newlib-multithread must be set to the same value') 1225endif 1226 1227conf_data.set('_HAVE_CC_INHIBIT_LOOP_TO_LIBCALL', 1228 cc.has_argument('-fno-tree-loop-distribute-patterns'), 1229 description: 'Compiler flag to prevent detecting memcpy/memset patterns') 1230 1231conf_data.set('_HAVE_NO_BUILTIN_ATTRIBUTE', 1232 cc.compiles('int __attribute__((no_builtin)) foo(int x) { return x + 1; }', 1233 name : 'no_builtin attribute', 1234 args : werror_c_args), 1235 description: 'Compiler attribute to prevent the optimizer from adding new builtin calls') 1236 1237conf_data.set('_HAVE_LONG_DOUBLE', have_long_double, 1238 description: 'Compiler has long double type') 1239conf_data.set('_HAVE_ALIAS_ATTRIBUTE', have_alias_attribute) 1240conf_data.set('_HAVE_FORMAT_ATTRIBUTE', have_format_attribute) 1241conf_data.set('_HAVE_WEAK_ATTRIBUTE', have_weak_attribute) 1242conf_data.set('_WANT_REGISTER_FINI', get_option('newlib-register-fini')) 1243conf_data.set('_WANT_IO_LONG_LONG', io_long_long) 1244conf_data.set('_WANT_MINIMAL_IO_LONG_LONG', minimal_io_long_long) 1245conf_data.set('_WANT_FAST_BUFIO', fast_bufio) 1246conf_data.set('_WANT_IO_POS_ARGS', io_pos_args) 1247conf_data.set('_WANT_IO_C99_FORMATS', io_c99_formats) 1248conf_data.set('_IO_FLOAT_EXACT', io_float_exact) 1249conf_data.set('_WANT_IO_PERCENT_B', io_percent_b) 1250conf_data.set('_WANT_IO_LONG_DOUBLE', io_long_double) 1251conf_data.set('_ASSERT_VERBOSE', get_option('assert-verbose')) 1252 1253if not tinystdio 1254 conf_data.set('NO_FLOATING_POINT', not newlib_io_float) 1255 conf_data.set('FLOATING_POINT', newlib_io_float) 1256 conf_data.set('_WANT_REENT_GLOBAL_STDIO_STREAMS', newlib_global_stdio_streams) 1257 conf_data.set('__LARGE64_FILES', newlib_stdio64) 1258endif 1259conf_data.set('_WANT_REENT_SMALL', get_option('newlib-reent-small')) 1260conf_data.set('_MB_CAPABLE', newlib_mb) 1261conf_data.set('_MB_LEN_MAX', newlib_mb ? '8' : '1') 1262conf_data.set('__SINGLE_THREAD__', get_option('newlib-multithread') == false) 1263conf_data.set('_ICONV_ENABLE_EXTERNAL_CCS', newlib_iconv_external_ccs) 1264conf_data.set('_ELIX_LEVEL', newlib_elix_level) 1265if newlib_iconv_external_ccs 1266 conf_data.set_quoted('ICONV_DEFAULT_NLSPATH', newlib_iconv_runtime_dir) 1267endif 1268conf_data.set('_ATEXIT_DYNAMIC_ALLOC', newlib_atexit_dynamic_alloc) 1269conf_data.set('_REENT_GLOBAL_ATEXIT', get_option('newlib-global-atexit')) 1270conf_data.set('_FVWRITE_IN_STREAMIO', newlib_fvwrite_in_streamio) 1271conf_data.set('_FSEEK_OPTIMIZATION', newlib_fseek_optimization) 1272conf_data.set('_WIDE_ORIENT', newlib_wide_orient) 1273conf_data.set('_HAVE_FCNTL', newlib_have_fcntl) 1274conf_data.set('_NANO_MALLOC', newlib_nano_malloc) 1275conf_data.set('_UNBUF_STREAM_OPT', get_option('newlib-unbuf-stream-opt')) 1276conf_data.set('_LITE_EXIT', lite_exit) 1277conf_data.set('_PICO_EXIT', picoexit) 1278conf_data.set('_NANO_FORMATTED_IO', newlib_nano_formatted_io) 1279conf_data.set('_RETARGETABLE_LOCKING', get_option('newlib-retargetable-locking')) 1280conf_data.set('TINY_STDIO', tinystdio, description: 'Use tiny stdio from gcc avr') 1281conf_data.set('_IEEE_LIBM', not get_option('want-math-errno'), description: 'math library does not set errno (offering only ieee semantics)') 1282conf_data.set('_WANT_MATH_ERRNO', get_option('want-math-errno'), description: 'math library sets errno') 1283conf_data.set('PREFER_SIZE_OVER_SPEED', get_option('optimization') == 's', description: 'Optimize for space over speed') 1284conf_data.set('FAST_STRCMP', fast_strcmp, description: 'Always optimize strcmp for performance') 1285conf_data.set('__HAVE_LOCALE_INFO__', newlib_locale_info, description: 'locale support') 1286conf_data.set('__HAVE_LOCALE_INFO_EXTENDED__', get_option('newlib-locale-info-extended'), description: 'extended locale support') 1287conf_data.set('NEWLIB_GLOBAL_ERRNO', get_option('newlib-global-errno'), description: 'use global errno variable') 1288conf_data.set('_HAVE_INITFINI_ARRAY', get_option('newlib-initfini-array'), description: 'compiler supports INIT_ARRAY sections') 1289conf_data.set('_HAVE_INIT_FINI', get_option('newlib-initfini'), description: 'Support _init() and _fini() functions') 1290conf_data.set('NEWLIB_TLS', thread_local_storage, description: 'use thread local storage') 1291conf_data.set('PICOLIBC_TLS', thread_local_storage, description: 'use thread local storage') 1292conf_data.set('_HAVE_PICOLIBC_TLS_API', thread_local_storage and have_picolibc_tls_api, description: '_set_tls and _init_tls functions available') 1293conf_data.set('POSIX_IO', posix_io, description: 'Use open/close/read/write in tinystdio') 1294conf_data.set('_PRINTF_SMALL_ULTOA', printf_small_ultoa, description: 'avoid software division in decimal conversion') 1295conf_data.set('ATOMIC_UNGETC', atomic_ungetc, description: 'Use atomics for fgetc/ungetc for re-entrancy') 1296conf_data.set('_PICOLIBC_ATOMIC_SIGNAL', get_option('atomic-signal'), description: 'Use atomics for signal/raise for re-entrancy') 1297conf_data.set('_HAVE_BITFIELDS_IN_PACKED_STRUCTS', have_bitfields_in_packed_structs, description: 'Use bitfields in packed structs') 1298conf_data.set('_HAVE_BUILTIN_MUL_OVERFLOW', have_builtin_mul_overflow, description: 'Compiler has __builtin_mul_overflow') 1299conf_data.set('_HAVE_BUILTIN_ADD_OVERFLOW', have_builtin_add_overflow, description: 'Compiler has __builtin_add_overflow') 1300conf_data.set('_HAVE_COMPLEX', have_complex, description: 'Compiler supports _Complex') 1301conf_data.set('_HAVE_BUILTIN_COMPLEX', have_builtin_complex, description: 'Compiler has __builtin_complex') 1302conf_data.set('_HAVE_BUILTIN_EXPECT', have_builtin_expect, description: 'Compiler has __builtin_expect') 1303conf_data.set('_HAVE_ALLOC_SIZE', have_alloc_size, description: 'The compiler REALLY has the attribute __alloc_size__') 1304conf_data.set('_HAVE_ATTRIBUTE_ALWAYS_INLINE', 1305 cc.has_function_attribute('always_inline'), 1306 description: 'The compiler supports the always_inline function attribute') 1307conf_data.set('_HAVE_ATTRIBUTE_GNU_INLINE', 1308 cc.has_function_attribute('gnu_inline'), 1309 description: 'The compiler supports the gnu_inline function attribute') 1310conf_data.set('__PICOLIBC_CRT_RUNTIME_SIZE', 1311 get_option('crt-runtime-size'), 1312 description: 'Compute static memory area sizes at runtime instead of link time') 1313if tinystdio 1314 conf_data.set('_FORMAT_DEFAULT_DOUBLE', 1315 format_default == 'double', 1316 description: 'The default printf functions is the double variant') 1317 conf_data.set('_FORMAT_DEFAULT_FLOAT', 1318 format_default == 'float', 1319 description: 'The default printf functions is the float variant') 1320 conf_data.set('_FORMAT_DEFAULT_INTEGER', 1321 format_default == 'integer', 1322 description: 'The default printf functions is the integer variant') 1323 conf_data.set('_FORMAT_DEFAULT_MINIMAL', 1324 format_default == 'minimal', 1325 description: 'The default printf functions is the minimal variant') 1326endif 1327errno_function=get_option('errno-function') 1328if errno_function == 'auto' 1329 errno_function = 'false' 1330 # these symbols are from the glibc and os x system C libraries, 1331 # it's useful to access them when doing testing 1332 foreach e : ['__errno_location', '__error'] 1333 code = '''extern int @0@(); 1334int main(void) { 1335 return @0@(); 1336} 1337'''.format(e) 1338 if cc.links(code, name : 'detect errno function') 1339 errno_function = e 1340 break 1341 endif 1342 endforeach 1343elif errno_function == 'zephyr' 1344 if thread_local_storage 1345 errno_function = 'false' 1346 else 1347 errno_function = 'z_errno_wrap' 1348 endif 1349endif 1350 1351if errno_function != 'false' 1352 conf_data.set('__PICOLIBC_ERRNO_FUNCTION', errno_function) 1353endif 1354 1355# Obsolete newlib options 1356conf_data.set('_WANT_USE_LONG_TIME_T', get_option('newlib-long-time_t'), description: 'Obsoleted. Define time_t to long instead of using a 64-bit type') 1357conf_data.set('REENTRANT_SYSCALLS_PROVIDED', get_option('newlib-reentrant-syscalls-provided'), description: 'Obsoleted. Reentrant syscalls provided for us') 1358conf_data.set('MISSING_SYSCALL_NAMES', get_option('newlib-missing-syscall-names'), description: 'Obsoleted. Use regular syscalls') 1359 1360if newlib_obsolete_math == 'auto' 1361 obsolete_math_value = false 1362elif newlib_obsolete_math == 'true' 1363 obsolete_math_value = 1 1364elif newlib_obsolete_math == 'false' 1365 obsolete_math_value = 0 1366endif 1367 1368if newlib_obsolete_math_float == 'auto' 1369 obsolete_math_float_value = false 1370elif newlib_obsolete_math_float == 'true' 1371 obsolete_math_float_value = 1 1372elif newlib_obsolete_math_float == 'false' 1373 obsolete_math_float_value = 0 1374endif 1375 1376if newlib_obsolete_math_double == 'auto' 1377 obsolete_math_double_value = false 1378elif newlib_obsolete_math_double == 'true' 1379 obsolete_math_double_value = 1 1380elif newlib_obsolete_math_double == 'false' 1381 obsolete_math_double_value = 0 1382endif 1383 1384conf_data.set('__OBSOLETE_MATH', obsolete_math_value, description: 'Use old math code (undef auto, 0 no, 1 yes)') 1385conf_data.set('__OBSOLETE_MATH_FLOAT', obsolete_math_float_value, description: 'Use old math code for float funcs (undef auto, 0 no, 1 yes)') 1386conf_data.set('__OBSOLETE_MATH_DOUBLE', obsolete_math_double_value, description: 'Use old math code for double funcs (undef auto, 0 no, 1 yes)') 1387 1388# Check if compiler has -fno-builtin 1389 1390arg_fnobuiltin = [] 1391if cc.has_argument('-fno-builtin') 1392 arg_fnobuiltin = ['-fno-builtin'] 1393endif 1394 1395# Compute iconv encodings to support in the library 1396 1397# Dig out the list of available encodings from the encoding.aliases file. Only 1398# accept the first entry from each line 1399 1400available_encodings = [] 1401# fs.read was added in meson version 0.57.0. The sed invocation can be 1402# removed once picolibc requires a version of meson newer than that. 1403if meson.version().version_compare('>=0.57') 1404 foreach line : fs.read('newlib/libc/iconv/encoding.aliases').split('\n') 1405 if line != '' and not line.startswith('#') 1406 available_encodings += [line.split()[0]] 1407 endif 1408 endforeach 1409else 1410 _available_encodings = run_command(['sed', '-e', '/^#/d', '-e', '/^$/d', '-e', 's/ .*$//', files('newlib/libc/iconv/encoding.aliases')[0]], check : true).stdout().split('\n') 1411 foreach _encoding : _available_encodings 1412 if _encoding != '' 1413 available_encodings += _encoding 1414 endif 1415 endforeach 1416endif 1417 1418# Include all available encodings if none were specified on the command line 1419 1420if newlib_iconv_encodings.length() == 0 1421 newlib_iconv_encodings = available_encodings 1422elif newlib_iconv_encodings.length() == 1 and newlib_iconv_encodings[0] == 'none' 1423 newlib_iconv_encodings = [] 1424endif 1425 1426# Use newlib_iconv_encodings for from/to by default 1427 1428if newlib_iconv_from_encodings.length() == 0 1429 newlib_iconv_from_encodings = newlib_iconv_encodings 1430endif 1431if newlib_iconv_to_encodings.length() == 0 1432 newlib_iconv_to_encodings = newlib_iconv_encodings 1433endif 1434 1435# Set config variables for each requested 'from' encoding 1436 1437foreach from : newlib_iconv_from_encodings 1438 message('from ' + from) 1439 if not available_encodings.contains(from) 1440 error('Requested from encoding ' + from + ' is not available. Look in newlib/libc/iconv/encoding.aliases') 1441 endif 1442 encoding_include = true 1443 if from not in newlib_iconv_encodings_exclude 1444 conf_data.set('_ICONV_FROM_ENCODING_' + from.to_upper(), true) 1445 endif 1446endforeach 1447 1448# Set config variables for each requested 'to' encoding 1449 1450foreach to : newlib_iconv_to_encodings 1451 if not available_encodings.contains(to) 1452 error('Requested to encoding ' + to + ' is not available. Look in newlib/libc/iconv/encoding.aliases') 1453 endif 1454 if to not in newlib_iconv_encodings_exclude 1455 conf_data.set('_ICONV_TO_ENCODING_' + to.to_upper(), true) 1456 endif 1457endforeach 1458 1459version_array = meson.project_version().split('.') 1460 1461if version_array.length() > 2 1462 picolibc_patch_level = version_array[2] 1463else 1464 picolibc_patch_level = 0 1465endif 1466 1467conf_data.set('__PICOLIBC_VERSION__', '"@0@"'.format(meson.project_version()), description: 'The Picolibc version in string format.') 1468conf_data.set('__PICOLIBC__', version_array[0], description: 'The Picolibc major version number.') 1469conf_data.set('__PICOLIBC_MINOR__', version_array[1], description: 'The Picolibc minor version number.') 1470conf_data.set('__PICOLIBC_PATCHLEVEL__', picolibc_patch_level, description: 'The Picolibc patch level.') 1471 1472# Old version macros. These have just a single leading underscore, 1473# which isn't consistent with the newlib macros; they were created 1474# by mistake. 1475conf_data.set('_PICOLIBC_VERSION', '"@0@"'.format(meson.project_version()), description: 'The Picolibc version in string format.') 1476conf_data.set('_PICOLIBC__', version_array[0], description: 'The Picolibc major version number.') 1477conf_data.set('_PICOLIBC_MINOR__', version_array[1], description: 'The Picolibc minor version number.') 1478 1479conf_data.set('_NEWLIB_VERSION', '"@0@"'.format(NEWLIB_VERSION), description: 'The newlib version in string format.') 1480conf_data.set('__NEWLIB__', NEWLIB_MAJOR_VERSION, description: 'The newlib major version number.') 1481conf_data.set('__NEWLIB_MINOR__', NEWLIB_MINOR_VERSION, description: 'The newlib minor version number.') 1482conf_data.set('__NEWLIB_PATCHLEVEL__', NEWLIB_PATCHLEVEL_VERSION, description: 'The newlib patch level.') 1483 1484if tinystdio 1485 stdio_inc_dir = 'newlib/libc/tinystdio' 1486else 1487 stdio_inc_dir = 'newlib/libc/stdio' 1488endif 1489 1490inc_dirs = [stdio_inc_dir, '.', 'newlib/libc/include'] 1491 1492inc = include_directories(inc_dirs) 1493 1494# We don't need '-fdata-sections' currently as there aren't any 1495# files with data used in separate code paths. This works around 1496# versions of gcc for RISC-V which have a bug that mis-names 1497# initialized read-only data segments when -fdata-sections 1498# is defined 1499arguments = [] 1500if cc.has_argument('-ffunction-sections') 1501 arguments += ['-ffunction-sections'] 1502endif 1503 1504if thread_local_storage 1505 tls_arg = '-ftls-model=' + get_option('tls-model') 1506 assert(cc.has_argument(tls_arg), 'Compiler does not support \'-ftls-model\'!') 1507 arguments += [tls_arg] 1508endif 1509 1510add_project_arguments(arguments, language: 'c') 1511 1512# libc will adjust this if supported 1513has_ieeefp_funcs = false 1514 1515# semihost will adjust these if supported 1516 1517# any kind of semihosting support, enough to run general 1518has_semihost = false 1519 1520# arm compatible semihosting, enough to run arm semihost tests 1521has_arm_semihost = false 1522 1523# some semihost needs bios to run the tests with qemu 1524bios_bin = [] 1525 1526# make sure to include semihost BEFORE picocrt! 1527if enable_semihost 1528 subdir('semihost') 1529endif 1530if tinystdio 1531 subdir('dummyhost') 1532endif 1533 1534conf_data.set('_HAVE_SEMIHOST', has_semihost, description: 'Semihost APIs supported') 1535 1536# By default, tests don't require any special arguments 1537 1538# disable compiler built-ins so we don't use native equivalents 1539native_c_args += arg_fnobuiltin 1540if tests_enable_stack_protector 1541 if cc.has_argument('-fstack-protector-all') and cc.has_argument('-fstack-protector-strong') 1542 test_c_args += ['-fstack-protector-all', '-fstack-protector-strong', '-DTESTS_ENABLE_STACK_PROTECTOR'] 1543 else 1544 tests_enable_stack_protector = false 1545 endif 1546endif 1547 1548if have_long_double and get_option('test-long-double') 1549 test_c_args += ['-D_TEST_LONG_DOUBLE'] 1550 native_c_args += ['-D_TEST_LONG_DOUBLE'] 1551endif 1552 1553# Meson version 0.53.2 doesn't check for the skip_sanity_check value 1554# before attempting to run test fragments during configuration. That 1555# means the exe_wrapper value needs to handle being run at that 1556# point. To support this, the exe_wrapper becomes a script which 1557# checks for a environment variable (PICOLIBC_TEST) and exits 1558# indicating success if that is not present. 1559# 1560# This was fixed in meson version 0.54.2, so this can be removed from 1561# here and the sample cross scripts once picolibc requires a version 1562# of meson newer than that. 1563 1564test_env = environment({'PICOLIBC_TEST' : '1'}) 1565test_env.prepend('PATH', meson.current_source_dir() / 'scripts') 1566 1567# CompCert needs the '-WUl,' prefix to correctly pass the --spec parameters to the linker 1568specs_prefix = '' 1569if cc.get_id() == 'ccomp' 1570 specs_prefix = '-WUl,' 1571endif 1572 1573if has_semihost 1574 specs = picolibc_specs 1575 specs_name = picolibc_specs_name 1576else 1577 specs = configure_file(input: 'test.specs.in', 1578 output: '@BASENAME@', 1579 configuration: specs_data, 1580 install: false) 1581 specs_name = 'test.specs' 1582endif 1583 1584# Clang does not support spec files 1585specs_line = [] 1586if cc.get_id() != 'clang' 1587 specs_line += [specs_prefix + '--specs', specs_prefix + meson.current_build_dir() / specs_name] 1588endif 1589test_c_args += specs_line 1590 1591if has_semihost 1592 foreach target : ['default-target'] + targets 1593 if target == 'default-target' 1594 test_link_args_variable = 'test_link_args' 1595 test_linker_files_variable = 'test_linker_files' 1596 test_link_depends_variable = 'test_link_depends' 1597 picolibc_ld_value = picolibc_ld 1598 else 1599 test_link_args_variable = 'test_link_args_' + target 1600 test_linker_files_variable = 'test_linker_files_' + target 1601 test_link_depends_variable = 'test_link_depends_' + target 1602 picolibc_ld_value = get_variable('picolibc_' + target + '_ld', picolibc_ld) 1603 endif 1604 1605 if meson.version().version_compare('>=1.4.0') 1606 picolibc_ld_string = picolibc_ld_value.full_path() 1607 else 1608 picolibc_ld_string = '@0@'.format(picolibc_ld_value) 1609 endif 1610 1611 set_variable(test_link_args_variable, 1612 ['-nostartfiles', '-T', picolibc_ld_string, 1613 lib_gcc] + additional_libs_list + specs_line) 1614 1615 set_variable(test_linker_files_variable, [picolibc_ld_value]) 1616 1617 # Make sure all of the tests get re-linked if the linker scripts change. 1618 set_variable(test_link_depends_variable, [picolibc_ld_value, specs]) 1619 endforeach 1620else 1621 test_link_args = specs_line 1622 test_linker_files = [specs] 1623 test_link_depends = [specs] 1624endif 1625 1626# make sure to include semihost BEFORE picocrt! 1627if enable_picocrt 1628 subdir('picocrt') 1629endif 1630subdir('newlib') 1631 1632if enable_tests 1633 subdir('test') 1634endif 1635 1636conf_data.set('_HAVE_IEEEFP_FUNCS', has_ieeefp_funcs, description: 'IEEE fp funcs available') 1637 1638configure_file(output : 'picolibc.h', 1639 configuration: conf_data, 1640 install_dir: include_dir) 1641 1642# Usage as an embedded subproject: 1643# If picolibc is embedded into the source as a subproject, 1644# provide a dependency to be used by the main project: 1645# dependency('libc', fallback: ['picolibc', 'libc_dep']) 1646if not enable_multilib and meson.is_subproject() 1647 picolibc_dep = declare_dependency(include_directories: inc, link_with: [lib_c]) 1648endif 1649