PicoLibC is a Lightweight C library for Embedded Systems

Well-known developer,  Keith Packard has recently announced the launch of “picolibc” through his blog.  Picolibc is a C Library for embedded systems which  is suitable for small micro-controllers, and this standard C library API’s allows to run even in low memory (RAM) devices. This is an upgraded version of “newlib-nano” with few interesting changes which includes replacement of “stdio” lib with ATMEL-specific printf code adopted from avrlibc. As part of this library, Keith also launched picocrt,  which is responsible for initializing memory and invoking various constructors before calling its own C program, the main function.


  • picolibc is a revised version of newlibc, without full-fledged stdio lib and uses lightweight stdio lib from avrlibc, which is more suitable to low memory embedded devices.
  • Meson build-system eases the build process of picolibc source tree for various target platform and hardware.
  • Updated the math test suite to use Glibc as a reference
  • The library is BSD licensed, and non-BSD components were removed from the source tree.
  • picocrt- picolibc startup code that initializes an embedded system without having to write your own code. This can be enabled by using -specs=picolibc.specs at compile time
  • Uses built-in Thread-local storage (TLS) which offers several benefits :
    • Source code is simpler as thread-local variables are
      accessed directly by name.
    • Thread local storage contains only values used by the
    • Generated code is smaller and faster.

Getting Start with picolibc

Picolibc uses the meson build system to compile the source tree for various hardware platforms on a Linux host using GCC. Apart from the default parameters,  this library allows to build with multiple attributes for enabling and disabling various functionalities by using the attribute line” -D=”.

Even though Picolibc is running on small stdio library from avrlibc, user having the option to enable old newlibc’s stdio lib by using the attribute (newlib-tinystdio=false). By default, it will be newlib-tinystdio=true, means it will get compiled with small avrlibc based stdio.

Before starting to build picolibc, you have to make sure that meson build system is part of your build environment, please refer to meson setup instructions.

As meson standard, all build configurations for cross-compilation build is part of separate configuration files, which is part of the source tree. Below the sample config file for various build environments.

Config file for RISC-V  (cross-riscv32-unknown-elf.txt)

Compiling picolibc source tree using meson

The source tree itself provides scripts to configure, for various targets, includes riscv, arm, x86, etc. Below the sample compile script for the target arm.

And once you are ready with the meson and desired cross-compiler gcc lib environment, follow the steps to build picolibc with a specific target (for arm). My test build environment was ubuntu 18.04.

Installing meson

Install Cross Compiler GCC (for arm)

Compile & Build picolibc

Once it’s built successfully,  you can verify by running the sample test case applications for printf and scanf in the “test” directory which is part of the build folder.

Picolibc code compilation process

Picolibc uses the GCC.spec file to compile source code. This will set the system header file path and the linker to point Picolibc.  Below the example to compile a single file and generate a .o file:

Picocrt (picolibc.specs)—  startup code

Picocrt is part of picolib named as crt0.o,  been enabled by
default when using -specs=picolibc.specs. Picocrt enables the initialization steps, which includes –

  • Architecture-specific runtime initialization.
  • Data initialization. Refer code snippet of picocrt, which handles data initialization –

      •  __data_start points to the RAM location where the .data segment
      • __data_source points to the Flash location where the .data segment
        initialization values are stored.
      • __data_size is an absolute symbol noting the size of the
        initialized data segment
  • BSS initialization. . Refer code snippet of picocrt, which handles data initialization –

      • __bss_start points to the RAM location where the .bss segment
      • __bss_size is an absolute symbol noting the size of the cleared
        data segment
  • The __libc_init_array and __libc_fini_array functions in Picolibc are called by Picocrt during  application startup and shutdown (__libc_init_array() (AppStart)      —>     main()      —>     –libc_fini_array() (App Stop) )



Support CNX Software - Donate via PayPal or become a Patron on Patreon
Notify of
newest most voted
8 months ago

I hope this triggers a bit of a revival in these libraries (newlib, lwip etc). Everyone seems to use them, no one seems to maintain them.

8 months ago

I think the main problem is the industry. I am originally from the web. Compared the web world, embedded is a lot of closed source. There is also a missing mind-set for open source contributions. This is slowly coming. Probably with new people joining the industry. Projects like Arduino, RIOT OS or Platform IO give me some hope. Just takes some time.

8 months ago

Embedded is broken because vendors behave like gollum with their “IP” even though a good chunk of it isn’t theirs. I think so much of the market moving from in-house cores to ARM has made it even worse. They can’t publish stuff knowing that it’s only useful on their chips so they do stupid stuff like adding fixes for GCC in their own private builds behind an NDA-wall. At $DAYJOB I’ve been waiting on fixes in a library that is shipped as a binary for about 6 months now. I reverse engineered the library and told them where the issue… Read more »

Jean-Luc Aufranc (CNXSoft)

PicoLibC 1.1 released: https://keithp.com/blogs/picolibc-1.1/
Mostly addition of a simple ‘hello world’ demo app

6 months ago

Hedzup! Jonathan McDowell has just contributed xtensa-lx106 additions to Keith’s project:-