Skip to content

Latest commit

 

History

History
195 lines (165 loc) · 11 KB

build.md

File metadata and controls

195 lines (165 loc) · 11 KB

Building Picolibc

Picolibc is designed to be cross-compiled for embedded systems on a Linux host using GCC. Picolibc uses the meson build system, which is a slightly quirky build system designed to replace autotools with a single language.

Selecting build options

Use -D= on the meson command line to change from the default value. Many of these options set configuration values for the newlib code base and should match that configuration system. The defaults should be reasonable for small embedded systems.

Option Default Description
fast-strcmp true Always optimize strcmp for performance (to make Dhrystone happy)
multilib true Build every multilib configuration supported by the compiler
picolib true Include picolib bits for tls and sbrk support
thread-local-storage true Use TLS for global variables
tls-model local-exec Select TLS model (global-dynamic, local-dynamic, initial-exec or local-exec)
newlib-global-errno false Use single global errno even when thread-local-storage=true
newlib-initfini-array true Use .init_array and .fini_array sections in picocrt
newlib-initfini true Support _init() and _fini() functions in picocrt
hw-fp false Turn on hardware floating point math
have-alias-attribute true Compiler supports alias attribute
tests false Enable tests
newlib-tinystdio true Use tiny stdio from avr libc
specsdir auto Where to install the .specs file (default is in the GCC directory)
newlib-mb false Enable multibyte support
newlib-iconv-encodings false Enable specific comma-separated list of bidirectional iconv encodings to be built-in
newlib-iconv-from-encodings false Enable specific comma-separated list of "from" iconv encodings to be built-in
newlib-iconv-to-encodings false Enable specific comma-separated list of "to" iconv encodings to be built-in
newlib-iconv-external-ccs false Enable capabilities to load external CCS files for iconv
newlib-register-fini false Enable finalization function registration using atexit
newlib-atexit-dynamic-alloc false Enable dynamic allocation of atexit entries
newlib-global-atexit false Enable atexit data structure as global
newlib_wide_orient false Turn off wide orientation in streamio
newlib-nano-malloc true Use small-footprint nano-malloc implementation
lite-exit true Enable light weight exit
newlib-retargetable-locking false Allow locking routines to be retargeted at link time
newlib-long-time_t false Define time_t to long
newlib-multithread false Enable support for multiple threads
newlib-iconv false Enable iconv library support
newlib-locale-info false Enable locale support
newlib-locale-info-extended false Enable even more locale support

Options when using legacy stdio bits

Normally, Picolibc is built with the small stdio library adapted from avrlibc (newlib-tinystdio=true). It still has the original newlib stdio bits and those might still work (newlib-tinystdio=false). These options are relevant only in that configuration

Option Default Description
newlib-reent-small false Enable small reentrant struct support
newlib-io-pos-args false Enable printf-family positional arg support
newlib-io-c99-formats false Enable C99 support in IO functions like printf/scanf
newlib-io-long-long false Enable long long type support in IO functions like printf/scanf
newlib-io-long-double false Enable long double type support in IO functions printf/scanf
newlib-global-stdio-streams false Enable global stdio streams
newlib-fvwrite-in-streamio false Disable iov in streamio
newlib-fseek-optimization false Disable fseek optimization
newlib-unbuf-stream-opt false Enable unbuffered stream optimization in streamio
newlib_nano_formatted_io false Use nano version formatted IO
newlib-io-float false Enable printf/scanf family float support
newlib-supplied-syscalls false Enable newlib supplied syscalls

Building for embedded RISC-V and ARM systems

Meson sticks all of the cross-compilation build configuration bits in a separate configuration file. There are a bunch of things you need to set, which the build system really shouldn't care about. Example configuration settings for RISC-V processors are in cross-riscv64-unknown-elf.txt:

[binaries]
c = 'riscv64-unknown-elf-gcc'
ar = 'riscv64-unknown-elf-ar'
as = 'riscv64-unknown-elf-as'
ld = 'riscv64-unknown-elf-ld'
strip = 'riscv64-unknown-elf-strip'

[host_machine]
system = 'unknown'
cpu_family = 'riscv'
cpu = 'riscv'
endian = 'little'

Settings for ARM processors are in cross-arm-none-eabi.txt:

[binaries]
c = 'arm-none-eabi-gcc'
ar = 'arm-none-eabi-ar'
as = 'arm-none-eabi-as'
ld = 'arm-none-eabi-ld'
strip = 'arm-none-eabi-strip'

[host_machine]
system = 'none'
cpu_family = 'arm'
cpu = 'arm'
endian = 'little'

If those programs aren't in your path, you can edit the file to point wherever they may be.

Auto-detecting the compiler configurations

The PicoLibc configuration detects the processor configurations supported by the compiler using the --print-multi-lib command-line option:

$ riscv64-unknown-elf-gcc --print-multi-lib
.;
rv32e/ilp32e;@march=rv32e@mabi=ilp32e
rv32em/ilp32e;@march=rv32em@mabi=ilp32e
rv32eac/ilp32e;@march=rv32eac@mabi=ilp32e
rv32emac/ilp32e;@march=rv32emac@mabi=ilp32e
rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32imf/ilp32f;@march=rv32imf@mabi=ilp32f
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv32imafdc/ilp32d;@march=rv32imafdc@mabi=ilp32d
rv64i/lp64;@march=rv64i@mabi=lp64
rv64im/lp64;@march=rv64im@mabi=lp64
rv64imf/lp64f;@march=rv64imf@mabi=lp64f
rv64iac/lp64;@march=rv64iac@mabi=lp64
rv64imac/lp64;@march=rv64imac@mabi=lp64
rv64imafc/lp64f;@march=rv64imafc@mabi=lp64f
rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d


$ arm-none-eabi-gcc --print-multi-lib
.;
thumb;@mthumb
hard;@mfloat-abi=hard
thumb/v6-m;@mthumb@march=armv6s-m
thumb/v7-m;@mthumb@march=armv7-m
thumb/v7e-m;@mthumb@march=armv7e-m
thumb/v7-ar;@mthumb@march=armv7
thumb/v8-m.base;@mthumb@march=armv8-m.base
thumb/v8-m.main;@mthumb@march=armv8-m.main
thumb/v7e-m/fpv4-sp/softfp;@mthumb@march=armv7e-m@mfpu=fpv4-sp-d16@mfloat-abi=softfp
thumb/v7e-m/fpv4-sp/hard;@mthumb@march=armv7e-m@mfpu=fpv4-sp-d16@mfloat-abi=hard
thumb/v7e-m/fpv5/softfp;@mthumb@march=armv7e-m@mfpu=fpv5-d16@mfloat-abi=softfp
thumb/v7e-m/fpv5/hard;@mthumb@march=armv7e-m@mfpu=fpv5-d16@mfloat-abi=hard
thumb/v7-ar/fpv3/softfp;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=softfp
thumb/v7-ar/fpv3/hard;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=hard
thumb/v7-ar/fpv3/hard/be;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=hard@mbig-endian
thumb/v8-m.main/fpv5-sp/softfp;@mthumb@march=armv8-m.main@mfpu=fpv5-sp-d16@mfloat-abi=softfp
thumb/v8-m.main/fpv5-sp/hard;@mthumb@march=armv8-m.main@mfpu=fpv5-sp-d16@mfloat-abi=hard
thumb/v8-m.main/fpv5/softfp;@mthumb@march=armv8-m.main@mfpu=fpv5-d16@mfloat-abi=softfp
thumb/v8-m.main/fpv5/hard;@mthumb@march=armv8-m.main@mfpu=fpv5-d16@mfloat-abi=hard

On RISC-V, PicoLibc is compiled 19 times, while on ARM, the library is compiled 20 times with the specified compiler options (replace the '@'s with '-' to see what they will be).

Running meson

Because Picolibc targets smaller systems like the SiFive FE310 or ARM Cortex-M0 parts with only a few kB of RAM and flash, the default values for all of the configuration options are designed to minimize the library code size. Here's the do-riscv-configure script from the repository that configures the library for small RISC-V systems:

#!/bin/sh
ARCH=riscv64-unknown-elf
DIR=`dirname $0`
meson "$DIR" \
    -Dincludedir=picolibc/$ARCH/include \
    -Dlibdir=picolibc/$ARCH/lib \
    --cross-file "$DIR"/cross-$ARCH.txt \
    "$@"

This script is designed to be run from a build directory, so you'd do:

$ mkdir build-riscv64-unknown-elf
$ cd build-riscv64-unknown-elf
$ ../do-riscv-configure

Compiling

Once configured, you can compile the libraries with

$ ninja
...
$ ninja install
...
$