Skip to content

lib: add picolibc compatibility for embedded builds - #308

Open
anujdeshpande wants to merge 2 commits into
pantoniou:masterfrom
anujdeshpande:picolibc-support
Open

lib: add picolibc compatibility for embedded builds#308
anujdeshpande wants to merge 2 commits into
pantoniou:masterfrom
anujdeshpande:picolibc-support

Conversation

@anujdeshpande

Copy link
Copy Markdown

picolibc is the C library used by most Zephyr (and other bare-metal) targets. Unlike glibc/newlib it does not expose a number of POSIX facilities, which previously broke the build. This adds support in the same spirit as the existing Windows layer (fy-win32.h): a small compatibility shim plus capability-gated branches, keyed on the C library's own PICOLIBC macro rather than on any OS.

  • src/util/fy-picolibc.h: new compat header (the picolibc analog of fy-win32.h) providing isatty() and the STD*_FILENO macros that picolibc omits.
  • libfyaml-util.h: provide struct iovec and SSIZE_MAX (no <sys/uio.h>).
  • libfyaml-endian.h: derive byte order from the compiler's BYTE_ORDER builtins (no <endian.h>).
  • libfyaml-align.h: use C11 aligned_alloc() (no posix_memalign()).
  • fy-utils.{c,h}: skip <termios.h>/<sys/uio.h>; stub the terminal-size query; emit-to-string (open_memstream) reported unsupported.
  • fy-diag.c, fy-emit.c: include <unistd.h> for isatty()/STD*_FILENO (previously relied on transitive inclusion that picolibc lacks).

anujdeshpande and others added 2 commits June 4, 2026 09:51
picolibc is the C library used by most bare-metal and RTOS targets
(Zephyr, etc.). Like the Windows layer in fy-win32.h, it lacks a few
POSIX facilities that previously broke the build. This adds support in
the same spirit: a small compatibility header plus capability-gated
branches, keyed on the C library's own __PICOLIBC__ macro rather than on
any OS, so builds against a full-featured C library (glibc, newlib) are
unaffected.

  - src/util/fy-picolibc.h: new compatibility header, the picolibc analog
    of fy-win32.h. Double-guarded (FY_PICOLIBC_H + #ifdef __PICOLIBC__) so
    it is a no-op everywhere else. Provides isatty() and the STD*_FILENO
    macros that picolibc omits, each #ifndef-guarded, via fy_picolibc_*
    helpers macro-aliased to the POSIX names.
  - libfyaml-util.h: provide struct iovec and SSIZE_MAX (no <sys/uio.h>),
    mirroring the existing _WIN32 arm.
  - libfyaml-endian.h: derive byte order from the compiler __BYTE_ORDER__
    builtins, extending the existing per-OS include selection.
  - libfyaml-align.h: use C11 aligned_alloc() (no posix_memalign()).
  - fy-input.c: picolibc has no <sys/mman.h>; skip the mmap optimization
    and fall through to the existing stdio/read path.
  - fy-utils.{c,h}: skip <termios.h>/<sys/uio.h>; stub the terminal-size
    query; report emit-to-string (open_memstream) unsupported.
  - fy-diag.c, fy-emit.c: include the picolibc shim for isatty()/STD*_FILENO.

All picolibc branches nest inside the existing non-Windows paths; the
Windows and POSIX/glibc branches are byte-for-byte unchanged. The new
header is registered in both build systems (src/Makefile.am EXTRA_DIST
and CMakeLists.txt). No public API or ABI change.

Signed-off-by: Anuj Deshpande <anuj@makerville.io>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make libfyaml usable as a Zephyr west module for in-memory YAML 1.2 /
JSON parsing (parse from a RAM buffer or a streamed pull callback; no
filesystem required).

  - zephyr/module.yml, CMakeLists.txt, Kconfig: build glue. CONFIG_LIBFYAML
    builds the core parser, document model and emitter. The allocator
    subsystem, parse cache, BLAKE3, threading, generic and reflection
    subsystems are excluded (not needed for the classic document tree).
  - zephyr/include/config.h: forced build configuration, replacing the
    autotools/CMake-probed config.h.
  - samples/parse_string: parses a YAML config blob from an in-memory
    buffer and reads values back; builds and runs on native_sim and
    builds for nrf52840dk (picolibc). Includes a twister sample.yaml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Anuj Deshpande <anuj@makerville.io>
@anujdeshpande

Copy link
Copy Markdown
Author

@pantoniou thoughts? Anything I can do better here to help this get through

@pantoniou

pantoniou commented Jun 18, 2026 via email

Copy link
Copy Markdown
Owner

@pantoniou pantoniou left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a few changes.

On a different note, I don't want to see a Claude sign off message, and I don't like the verbose style of claude commit messages.

We all use AI agents but for something to be mergeable a human must take ownership. First part of that is having the commit message being written by one.
I don't mind over-terse messages, but I want to know that someone looked over it.


size = FY_ALIGN(align, size);
#ifndef _WIN32
#if defined(__PICOLIBC__)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you already have a picolib.h file that implements the set of posix apis that you need, add a posix_memalign wrapper there.

Then this #ifdef can be removed.

Comment thread src/lib/fy-diag.c
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>
#ifndef _WIN32

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to do that, add your picolib include in fy-utils.h

Comment thread src/lib/fy-emit.c
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#ifndef _WIN32

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Comment thread src/lib/fy-input.c
case fyit_fd:

if (fyi->addr) {
#if !defined(__PICOLIBC__)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add mmap/munmap wrappers in your picolib.h header.
They will fail and then fall-back.

Comment thread src/lib/fy-input.c

/* only map if not zero (and is not disabled) */
/* only map if not zero (and is not disabled);
* picolibc has no mmap, fall through to the stdio/read path */

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to avoid peppering PICOLIB all over the place - use your wrapper header.

Comment thread src/util/fy-utils.c
return NULL;
memset(fyms, 0, sizeof(*fyms));
#if !defined(_WIN32)
#if defined(__PICOLIBC__)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is fully working open_memstream implementation in src/util/fy-utils.c originally added for older mac os version that lacked one that was internal. See if you can use it if picolib supports funopen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants