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