1# Building Picolibc 2 3Picolibc is designed to be cross-compiled for embedded systems on a 4Linux host using GCC. There is some support for Clang, but that 5doesn't include the built-in multilib support. Picolibc uses the meson 6build system, which is a slightly quirky build system designed to 7replace autotools with a single language. 8 9Picolibc requires meson version 0.50 or newer. If your operating 10system provides an older version, you can get the latest using 11pip. For example, on a Debian or Ubuntu system, you would do: 12 13 $ sudo apt install pip 14 $ pip install meson 15 16On POSIX systems, meson uses the low-level 'ninja' build tool and 17currently requires at least ninja version 1.5. If your operating 18system doesn't provide at least this version, head over to 19[ninja-build.org](https://ninja-build.org) to find out how to 20download and install the latest bits. 21 22## Selecting build options 23 24Use -D<option-name>=<value> on the meson command line to change from 25the default value. Many of these options set configuration values for 26the newlib code base and should match that configuration system. The 27defaults should be reasonable for small embedded systems. 28 29### General build options 30 31These options control some general build configuration values. 32 33| Option | Default | Description | 34| ------ | ------- | ----------- | 35| fast-strcmp | true | Always optimize strcmp for performance (to make Dhrystone happy) | 36| have-alias-attribute | auto | Compiler supports __alias__ attribute (default autodetected) | 37| have-format-attribute | auto | Compiler supports __format__ attribute (default autodetected) | 38| multilib | true | Build every multilib configuration supported by the compiler | 39| multilib-list | <empty> | If non-empty, the set of multilib configurations to compile for | 40| native-tests | false | Build tests against native libc (used to validate tests) | 41| picolib | true | Include picolib bits for tls and sbrk support | 42| picocrt | true | Build crt0.o (C startup function) | 43| picocrt-lib | true | Also wrap crt0.o into a library -lcrt0, which is easier to find via the library path | 44| semihost | true | Build the semihost library (libsemihost.a) | 45| fake-semihost | false | Create a fake semihost library to allow tests to link | 46| specsdir | auto | Where to install the .specs file (default is in the GCC directory). <br> If set to `none`, then picolibc.specs will not be installed at all.| 47| sysroot-install | false | Install in GCC sysroot location (requires sysroot in GCC) | 48| tests | false | Enable tests | 49| tinystdio | true | Use tiny stdio from avr libc | 50 51### Options applying to both legacy stdio and tinystdio 52 53These options extend support in printf and scanf for additional 54types and formats. 55 56| Option | Default | Description | 57| ------ | ------- | ----------- | 58| io-c99-formats | true | Enable C99 support in IO functions like printf/scanf | 59| io-long-long | false | Enable long long type support in IO functions like printf/scanf. For tiny-stdio, this only affects the integer-only versions, the full version always includes long long support. | 60| io-pos-args | false | Enable printf-family positional arg support. For tiny-stdio, this only affects the integer-only versions, the full version always includes positional argument support. | 61| io-long-double | false | Enable long double support in printf/scanf. | 62 63 64`long long` support is always enabled for the tinystdio full 65printf/scanf modes, the `io-long-long` option adds them to the limited 66(float and integer) versions, as well as to the original newlib stdio 67bits. 68 69### Options when using tinystdio bits 70 71These options apply when tinystdio is enabled, which is the 72default. For stdin/stdout/stderr, the application will need to provide 73`stdin`, `stdout` and `stderr`, which are three pointers to FILE 74structures (which can all reference a single shared FILE structure, 75and which can be aliases to the same underlying global pointer). 76 77Note that while posix-io support is enabled by default, using it will 78require that the underlying system offer the required functions. POSIX 79console support offers built-in `stdin`, `stdout` and `stderr` 80definitions which use the same POSIX I/O functions. 81 82| Option | Default | Description | 83| ------ | ------- | ----------- | 84| atomic-ungetc | true | Make getc/ungetc re-entrant using atomic operations | 85| io-float-exact | true | Provide round-trip support in float/string conversions | 86| posix-io | true | Provide fopen/fdopen using POSIX I/O (requires open, close, read, write, lseek) | 87| posix-console | false | Use POSIX I/O for stdin/stdout/stderr | 88| format-default | double | Sets the default printf/scanf style ('double', 'float' or 'integer') | 89| printf-aliases | true | Support link-time printf aliases to set the default printf/scanf variant | 90| io-percent-b | false | Support the %b as proposed in the upcoming C standard | 91| printf-small-ultoa | false | Avoid soft division routine during integer binary to decimal conversion in printf | 92| minimal-io-long-long | false | Support long long integers in the minimal printf and scanf variants | 93| fast-bufio | false | Improve performance of some I/O operations when using bufio | 94 95 96### Options when using legacy stdio bits 97 98Normally, Picolibc is built with the small stdio library adapted from 99avrlibc (tinystdio=true). It still has the original newlib 100stdio bits and those still work (tinystdio=false), but depend 101on POSIX I/O functions from the underlying system, and perform many 102malloc calls at runtime. These options are relevant only in that 103configuration 104 105| Option | Default | Description | 106| ------ | ------- | ----------- | 107| newlib-elix-level | 0 | Extends stdio API based on level | 108| newlib-fseek-optimization | false | Enable fseek optimization | 109| newlib-fvwrite-in-streamio | false | Enable iov in streamio | 110| newlib-global-stdio-streams | false | Enable global stdio streams | 111| newlib-have-fcntl | false | System has fcntl function available | 112| newlib-io-float | false | Enable printf/scanf family float support | 113| newlib-io-long-double | false | Enable long double type support in IO functions printf/scanf | 114| newlib-nano-formatted-io | false | Use nano version formatted IO | 115| newlib-reent-small | false | Enable small reentrant struct support | 116| newlib-stdio64 | true | Include 64-bit APIs | 117| newlib-unbuf-stream-opt | false | Enable unbuffered stream optimization in streamio | 118| newlib-wide-orient | false | Turn off wide orientation in streamio | 119 120### Internationalization options 121 122These options control which character sets are supported by iconv. 123 124| Option | Default | Description | 125| ------ | ------- | ----------- | 126| newlib-iconv-encodings | <empty> | Comma-separated list of iconv encodings to be built-in (default all supported). <br> Set to `none` to disable all encodings. | 127| newlib-iconv-from-encodings | <empty> | Comma-separated list of "from" iconv encodings to be built-in (default iconv-encodings) | 128| newlib-iconv-to-encodings | <empty> | Comma-separated list of "to" iconv encodings to be built-in (default iconv-encodings) | 129| newlib-iconv-external-ccs | false | Use file system to store iconv tables. Requires fopen. (default built-in to memory) | 130| newlib-iconv-dir | libdir/locale | Directory to install external CCS files. Only used with newlib-iconv-external-ccs=true | 131| newlib-iconv-runtime-dir | newlib-iconv-dir | Directory to read external CCS files from at runtime. | 132 133These options control how much Locale support is included in the 134library. By default, picolibc only supports the 'C' locale. 135 136| Option | Default | Description | 137| ------ | ------- | ----------- | 138| newlib-locale-info | false | Enable locale support | 139| newlib-locale-info-extended | false | Enable even more locale support | 140| newlib-mb | false | Enable multibyte support | 141 142### Startup/shutdown options 143 144These control how much support picolibc includes for calling functions 145at startup and shutdown times. 146 147| Option | Default | Description | 148| ------ | ------- | ----------- | 149| lite-exit | true | Enable lightweight exit | 150| newlib-atexit-dynamic-alloc | false | Enable dynamic allocation of atexit entries | 151| newlib-global-atexit | false | Enable atexit data structure as global, instead of in TLS. <br> If `thread-local-storage` == false, then the atexit data structure is always global. | 152| newlib-initfini | true | Support _init() and _fini() functions in picocrt | 153| newlib-initfini-array | true | Use .init_array and .fini_array sections in picocrt | 154| newlib-register-fini | false | Enable finalization function registration using atexit | 155| crt-runtime-size | false | Compute .data/.bss sizes at runtime rather than linktime. <br> This option exists for targets where the linker can't handle a symbol that is the difference between two other symbols, e.g. m68k.| 156 157### Thread local storage support 158 159By default, Picolibc can uses native TLS support as provided by the 160compiler, this allows re-entrancy into the library if the run-time 161environment supports that. A TLS model is specified only when TLS is 162enabled. The default TLS model is local-exec. 163 164As a separate option, you can make `errno` not use TLS if necessary. 165 166| Option | Default | Description | 167| ------ | ------- | ----------- | 168| thread-local-storage | auto | Use TLS for global variables. Default is automatic based on compiler support | 169| tls-model | local-exec | Select TLS model (global-dynamic, local-dynamic, initial-exec or local-exec) | 170| newlib-global-errno | false | Use single global errno even when thread-local-storage=true | 171| errno-function | <empty> | If set, names a function which returns the address of errno. 'auto' will try to auto-detect. | 172 173### Malloc option 174 175Picolibc offers two malloc implementations, the larger version offers 176better performance on large memory systems and for applications doing 177a lot of variable-sized allocations and deallocations. The smaller, 178default, implementation works best when applications perform few, 179persistent allocations. 180 181| Option | Default | Description | 182| ------ | ------- | ----------- | 183| newlib-nano-malloc | true | Use small-footprint nano-malloc implementation | 184 185### Locking support 186 187There are some functions in picolibc that use global data that needs 188protecting when accessed by multiple threads. The largest set of these 189are the legacy stdio code, but there are other functions that can use 190locking, e.g. when newlib-global-atexit is enabled, calls to atexit 191need to lock the shared global data structure if they may be called 192from multiple threads at the same time. By default, these are enabled 193and use the retargetable API defined in [locking.md](locking.md). 194 195| Option | Default | Description | 196| ------ | ------- | ----------- | 197| newlib-retargetable-locking | true | Allow locking routines to be retargeted at link time | 198| newlib-multithread | true | Enable support for multiple threads | 199 200 201### Legacy newlib options 202 203These either have no effect or should not be enabled in normal use of 204picolibc, they're left in the library to help users porting from 205newlib environments. 206 207| Option | Default | Description | 208| ------ | ------- | ----------- | 209| newlib-long-time_t | false | Define time_t to long instead of using a 64-bit type | 210| newlib-supplied-syscalls | false | Enable newlib supplied syscalls (obsolete) | 211| newlib-reentrant-syscalls-provided| false| Underlying system provides reentrant syscall API | 212| newlib-missing-syscall-names| false | Underlying system provides syscall names without leading underscore | 213 214### Math library options 215 216There are two versions of many libm functions, old ones from SunPro 217and new ones from ARM. The new ones are generally faster for targets 218with hardware double support, except that the new float-valued 219functions use double-precision computations. On sytems without 220hardware double support, that's going to pull in soft double 221code. Measurements show the old routines are generally more accurate, 222which is why they are enabled by default. 223 224POSIX requires many of the math functions to set errno when exceptions 225occur; disabling that makes them only support fenv() exception 226reporting, which is what IEEE floating point and ANSI C standards 227require. 228 229| Option | Default | Description | 230| ------ | ------- | ----------- | 231| newlib-obsolete-math | true | Use old code for both float and double valued functions | 232| newlib-obsolete-math-float | auto | Use old code for float-valued functions | 233| newlib-obsolete-math-double | auto | Use old code for double-valued functions | 234| want-math-errno | false | Set errno when exceptions occur | 235 236newlib-obsolete-math provides the default value for the 237newlib-obsolete-math-float and newlib-obsolete-math-double parameters; 238those control the compilation of the individual fucntions. 239 240## Building for embedded RISC-V and ARM systems 241 242Meson sticks all of the cross-compilation build configuration bits in 243a separate configuration file. There are a bunch of things you need to 244set, which the build system really shouldn't care about. Example 245configuration settings for RISC-V processors are in 246cross-riscv64-unknown-elf.txt: 247 248 [binaries] 249 c = 'riscv64-unknown-elf-gcc' 250 ar = 'riscv64-unknown-elf-ar' 251 as = 'riscv64-unknown-elf-as' 252 ld = 'riscv64-unknown-elf-ld' 253 strip = 'riscv64-unknown-elf-strip' 254 255 [host_machine] 256 system = 'unknown' 257 cpu_family = 'riscv' 258 cpu = 'riscv' 259 endian = 'little' 260 261 [properties] 262 c_args = [ '-nostdlib', '-msave-restore', '-fno-common' ] 263 # default multilib is 64 bit 264 c_args_ = [ '-mcmodel=medany' ] 265 needs_exe_wrapper = true 266 skip_sanity_check = true 267 268Settings for ARM processors are in cross-arm-none-eabi.txt: 269 270 [binaries] 271 c = 'arm-none-eabi-gcc' 272 ar = 'arm-none-eabi-ar' 273 as = 'arm-none-eabi-as' 274 ld = 'arm-none-eabi-ld' 275 strip = 'arm-none-eabi-strip' 276 277 [host_machine] 278 system = 'none' 279 cpu_family = 'arm' 280 cpu = 'arm' 281 endian = 'little' 282 283 [properties] 284 c_args = [ '-nostdlib', '-fno-common' ] 285 needs_exe_wrapper = true 286 skip_sanity_check = true 287 288If those programs aren't in your path, you can edit the file to point 289wherever they may be. 290 291### Auto-detecting the compiler multi-lib configurations 292 293The PicoLibc configuration detects the processor configurations 294supported by the compiler using the `--print-multi-lib` command-line option: 295 296 $ riscv64-unknown-elf-gcc --print-multi-lib 297 .; 298 rv32e/ilp32e;@march=rv32e@mabi=ilp32e 299 rv32ea/ilp32e;@march=rv32ea@mabi=ilp32e 300 rv32em/ilp32e;@march=rv32em@mabi=ilp32e 301 rv32eac/ilp32e;@march=rv32eac@mabi=ilp32e 302 rv32emac/ilp32e;@march=rv32emac@mabi=ilp32e 303 rv32i/ilp32;@march=rv32i@mabi=ilp32 304 rv32if/ilp32f;@march=rv32if@mabi=ilp32f 305 rv32ifd/ilp32d;@march=rv32ifd@mabi=ilp32d 306 rv32ia/ilp32;@march=rv32ia@mabi=ilp32 307 rv32iaf/ilp32f;@march=rv32iaf@mabi=ilp32f 308 rv32imaf/ilp32f;@march=rv32imaf@mabi=ilp32f 309 rv32iafd/ilp32d;@march=rv32iafd@mabi=ilp32d 310 rv32im/ilp32;@march=rv32im@mabi=ilp32 311 rv32imf/ilp32f;@march=rv32imf@mabi=ilp32f 312 rv32imfc/ilp32f;@march=rv32imfc@mabi=ilp32f 313 rv32imfd/ilp32d;@march=rv32imfd@mabi=ilp32d 314 rv32iac/ilp32;@march=rv32iac@mabi=ilp32 315 rv32imac/ilp32;@march=rv32imac@mabi=ilp32 316 rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f 317 rv32imafdc/ilp32d;@march=rv32imafdc@mabi=ilp32d 318 rv64i/lp64;@march=rv64i@mabi=lp64 319 rv64if/lp64f;@march=rv64if@mabi=lp64f 320 rv64ifd/lp64d;@march=rv64ifd@mabi=lp64d 321 rv64ia/lp64;@march=rv64ia@mabi=lp64 322 rv64iaf/lp64f;@march=rv64iaf@mabi=lp64f 323 rv64imaf/lp64f;@march=rv64imaf@mabi=lp64f 324 rv64iafd/lp64d;@march=rv64iafd@mabi=lp64d 325 rv64im/lp64;@march=rv64im@mabi=lp64 326 rv64imf/lp64f;@march=rv64imf@mabi=lp64f 327 rv64imfc/lp64f;@march=rv64imfc@mabi=lp64f 328 rv64imfd/lp64d;@march=rv64imfd@mabi=lp64d 329 rv64iac/lp64;@march=rv64iac@mabi=lp64 330 rv64imac/lp64;@march=rv64imac@mabi=lp64 331 rv64imafc/lp64f;@march=rv64imafc@mabi=lp64f 332 rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d 333 334 $ arm-none-eabi-gcc --print-multi-lib 335 .; 336 thumb;@mthumb 337 hard;@mfloat-abi=hard 338 thumb/v6-m;@mthumb@march=armv6s-m 339 thumb/v7-m;@mthumb@march=armv7-m 340 thumb/v7e-m;@mthumb@march=armv7e-m 341 thumb/v7-ar;@mthumb@march=armv7 342 thumb/v8-m.base;@mthumb@march=armv8-m.base 343 thumb/v8-m.main;@mthumb@march=armv8-m.main 344 thumb/v7e-m/fpv4-sp/softfp;@mthumb@march=armv7e-m@mfpu=fpv4-sp-d16@mfloat-abi=softfp 345 thumb/v7e-m/fpv4-sp/hard;@mthumb@march=armv7e-m@mfpu=fpv4-sp-d16@mfloat-abi=hard 346 thumb/v7e-m/fpv5/softfp;@mthumb@march=armv7e-m@mfpu=fpv5-d16@mfloat-abi=softfp 347 thumb/v7e-m/fpv5/hard;@mthumb@march=armv7e-m@mfpu=fpv5-d16@mfloat-abi=hard 348 thumb/v7-ar/fpv3/softfp;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=softfp 349 thumb/v7-ar/fpv3/hard;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=hard 350 thumb/v7-ar/fpv3/hard/be;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=hard@mbig-endian 351 thumb/v8-m.main/fpv5-sp/softfp;@mthumb@march=armv8-m.main@mfpu=fpv5-sp-d16@mfloat-abi=softfp 352 thumb/v8-m.main/fpv5-sp/hard;@mthumb@march=armv8-m.main@mfpu=fpv5-sp-d16@mfloat-abi=hard 353 thumb/v8-m.main/fpv5/softfp;@mthumb@march=armv8-m.main@mfpu=fpv5-d16@mfloat-abi=softfp 354 thumb/v8-m.main/fpv5/hard;@mthumb@march=armv8-m.main@mfpu=fpv5-d16@mfloat-abi=hard 355 356On RISC-V, PicoLibc is compiled 36 times, while on ARM, the library is 357compiled 20 times with the specified compiler options (replace the 358'@'s with '-' to see what they will be). 359 360### Running meson 361 362Because Picolibc targets smaller systems like the SiFive FE310 or ARM 363Cortex-M0 parts with only a few kB of RAM and flash, the default 364values for all of the configuration options are designed to minimize 365the library code size. Here's the 366[do-riscv-configure](../scripts/do-riscv-configure) script from the repository 367that configures the library for small RISC-V systems: 368 369 #!/bin/sh 370 ARCH=riscv64-unknown-elf 371 DIR=`dirname $0` 372 meson "$DIR" \ 373 -Dincludedir=picolibc/$ARCH/include \ 374 -Dlibdir=picolibc/$ARCH/lib \ 375 --cross-file "$DIR"/cross-$ARCH.txt \ 376 "$@" 377 378This script is designed to be run from a build directory, so you'd do: 379 380 $ mkdir build-riscv64-unknown-elf 381 $ cd build-riscv64-unknown-elf 382 $ ../scripts/do-riscv-configure 383 384You can select the installation directory by passing it to the meson script: 385 386 $ ../scripts/do-riscv-configure -Dprefix=/path/to/install/dir/ 387 388### Compiling 389 390Once configured, you can compile the libraries with 391 392 $ ninja 393 ... 394 $ ninja install 395 ... 396 $ 397