Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding picolibc as a module #44143

Closed
Tracked by #49922
keith-packard opened this issue Mar 23, 2022 · 15 comments · Fixed by #44096
Closed
Tracked by #49922

Adding picolibc as a module #44143

keith-packard opened this issue Mar 23, 2022 · 15 comments · Fixed by #44096
Labels
area: C Library C Standard Library RFC Request For Comments: want input from the community

Comments

@keith-packard
Copy link
Collaborator

keith-packard commented Mar 23, 2022

Origin

Picolibc is available on github. The "official" upstream
repository is hosted in my own domain keithp.com/picolibc

Purpose

Picolibc provides a full libc implementation based on a combination of code from newlib, avr libc along with substantial new code, including the ryu floating point conversion code which provides malloc-free exact decimal/binary conversion of 32 and 64 bit IEEE floating point values.

Mode of integration

As picolibc is used in numerous other projects, it should be integrated into zephyr as a module.

Pull Request

The PR is #44096 has been modified to take advantage of cmake support which has been added to picolibc.

Description

Right now, Zephyr provides developers with several C library options, Newlib, Newlib-nano and a tiny 'minimal C library' included in tree. Picolibc fits in between these offerings with a full POSIX implementation like newlib/newlib-nano, but with a footprint similar to the included minimal library.

I think Picolibc could replace the current minimal C library, reducing the maintenance burden on the Zephyr project while offering users a better tested and more standards-conforming implementation, while potentially decreasing the amount of memory used by the resulting applications.

Picolibc could be made available through the Zephyr SDK as Crosstool-ng has the necessary support. However, that would mean selecting from the small number of binary configurations provided in that SDK, and would mean it wasn't available when using a different toolchain. Picolibc is routinely tested using GCC and Clang, and has been used with the CompCert verified C compiler. The codebase is tested using --std=c18 to ensure it remains in compliance with ISO/IEC 9899:2018.

Compared with newlib or newlib-nano, picolibc eliminates the 'struct _reent' by using TLS variables, replaces the large stdio stack with a lighter weight implementation which doesn't require malloc and has an integrated test suite which is used as part of the CI system to validate changes. Picolibc is also regularly tested using significant portions of the glibc test suite. All of that testing has led to dozens of bug fixes, many of which have been sent upstream to newlib, but many cannot as the picolibc code has diverged in significant ways, especially the math library.

Picolibc has very clear BSD licensing for the library source code; all of the non-BSD code included in the newlib repository has been removed. There are some tests and sample scripts which are not BSD licensed, but none of those are involved in building the library itself.

Dependencies

The library itself only requires a C compiler (tested with GCC in C99, C11 and C18 modes), and Picolibc now has native cmake support. Picolibc is designed to work with systems that support thread local storage; all C library APIs which need per-thread storage use this mechanism, including errno.

Revision

Picolibc includes a zephyr branch which has the necessary fixes and cmake support. When we're ready to merge this PR, that should shift to using a specific revision in the west configuration file.

License

Picolibc is "BSD" licensed, but that includes numerous versions of BSD-2 and BSD-3 licenses, along with some other variants.

Resources

@keith-packard keith-packard added the TSC Topics that need TSC discussion label Mar 23, 2022
@stephanosio stephanosio added area: C Library C Standard Library RFC Request For Comments: want input from the community labels Mar 24, 2022
@stephanosio
Copy link
Member

RE: Rependencies

The library itself only requires a C18 compiler

At project level, we tend to conform to the C99 mostly, and C11 at times.

C18 is fairly recent and the compiler support for it may be somewhat limited -- for instance, the Xtensa XCC, one of the supported toolchains for Zephyr, is based on GCC 4.x and does not support C18; but, I am sure we can find workarounds should any problems arise.

but the build system is currently meson-based, which requires a Python3 interpreter on the host system and the 'ninja' build tool

Requiring a Python 3 interpreter is not a problem at all because so does the Zephyr build system.

As for requiring Ninja, this is a somewhat problematic because we support both Ninja and Makefile through CMake, and users may opt to not install/use Ninja at all; though, Ninja is much more popular than the traditional Makefile among the Zephyr users.

@keith-packard
Copy link
Collaborator Author

RE: Rependencies

The library itself only requires a C18 compiler

At project level, we tend to conform to the C99 mostly, and C11 at times.

This comment was trying to explain that picolibc doesn't require GCC or Clang features not present in other toolchains, and that is validated by always building it with --std=c18 in the build. I think it would also build with c99 or c11, but that isn't currently tested.

As for requiring Ninja, this is a somewhat problematic because we support both Ninja and Makefile through CMake, and users may opt to not install/use Ninja at all; though, Ninja is much more popular than the traditional Makefile among the Zephyr users.

That's probably the biggest reason to consider creating a parallel cmake build system for picolibc -- meson only supports ninja. Picolibc's build issues aren't that complicated, if you don't need multi-lib support, and don't need to run tests.

@keith-packard
Copy link
Collaborator Author

This comment was trying to explain that picolibc doesn't require GCC or Clang features not present in other toolchains, and that is validated by always building it with --std=c18 in the build. I think it would also build with c99 or c11, but that isn't currently tested.

I just did a brief test for the arm port and picolibc passes its internal tests compiled with -std=c99 and -std=c11 using gcc. It does not build with -std=c89. I found one minor issue when compiling with -std=c2x caused by the new [[fallthrough]] annotation supported for switch statements.

@stephanosio
Copy link
Member

As per the TSC meeting today (31 March 2022), the motion to include the picolibc as a module has been approved.

@keith-packard
Copy link
Collaborator Author

That's good news. What's the process going forward? Mirroring picolibc inside the zephyr repo? Do we merge the meson-based module integration bits? Or do we re-create that on top of a cmake build system inside picolibc?

@carlescufi
Copy link
Member

That's good news. What's the process going forward? Mirroring picolibc inside the zephyr repo? Do we merge the meson-based module integration bits? Or do we re-create that on top of a cmake build system inside picolibc?

The next steps would be:

  1. Create a repo to mirror picolibc, which I have now done and you can find it here. You also have write access to that repo if you accept the invite
  2. Decide whether we add the zephyr/ folder in the zephyr fork I just created or upstream in your picolibc repo. Find out more about this here
  3. Decide whether we want to reuse Meson by invoking it from CMake or we want to create a parallel CMake build system in the Zephyr main tree (zephyr/modules/picolibc)

In any case anything (aside from zephyr/module.yml) that is specific for Zephyr should be in the zephyr main tree, in zephyr/modules/picolibc.

CC @tejlmand @stephanosio

@stephanosio
Copy link
Member

I will test drive #44096 some time this week and try to provide feedback.

In general, we would want to avoid reusing Meson for the reasons given in #44143 (comment), and also because we would then need to ask the users who want to use picolibc (i.e. most Zephyr users) to now install Meson and also force them to use Ninja.

@nashif nashif removed the TSC Topics that need TSC discussion label Apr 5, 2022
@carlescufi
Copy link
Member

As for requiring Ninja, this is a somewhat problematic because we support both Ninja and Makefile through CMake, and users may opt to not install/use Ninja at all; though, Ninja is much more popular than the traditional Makefile among the Zephyr users.

Honestly I think we can live with requiring ninja, given that we already instruct users to install it in our Getting Started Guide. I see no problem there.

@stephanosio
Copy link
Member

Honestly I think we can live with requiring ninja, given that we already instruct users to install it in our Getting Started Guide. I see no problem there.

While I mostly agree with that, the Makefile support is still mentioned in the documentation and I do not think we ever declared it to be "unsupported," meaning we are still committed to making the Zephyr build system work in absence of Ninja. @tejlmand can probably provide a more definite answer to this.

Either way, adding Meson dependency for Zephyr users to use the picolibc is far from ideal. In my opinion, we need to implement a CMake-based build script for the picolibc in order to be consistent with the way we have been doing things.

I am aware that adding a CMake-based build system alongside the existing Meson-based one in the upstream picolibc may result in an increased maintenance overhead with little benefit, which I am sure @keith-packard would want to avoid -- noting that, I think it would be best for us to implement one either in the Zephyr fork of the picolibc, or as part of the Zephyr main repo under modules/picolibc.

As noted by @keith-packard in #44143 (comment), since we do not need the multilib support, implementing a CMake-based picolibc build system for our own use should be simple enough.

@keith-packard
Copy link
Collaborator Author

I'm happy to host a cmake-based build system in the upstream picolibc repository, if that's what you all need to make it work for Zephyr. Moving it upstream means I could add CI tests that use cmake to ensure both build systems always work, which would otherwise end up happening when Zephyr pulled the code. I'd like to limit the sets of configuration options offered, in particular:

  1. Don't attempt to support multilib. Zephyr doesn't need this, and it makes the build significantly more complicated.
  2. Leave out the legacy stdio options. Using this eliminates most of the Picolibc memory savings.
  3. Leave out the locale and iconv support (unless Zephyr actually needs this). The newlib code is very spotty in functionality on systems other than Cygwin, and I haven't made substantial progress in improving that.
  4. Leave out atexit/onexit support -- I don't think Zephyr uses this?
  5. Figure out what constructor/destructor support Zephyr needs and use that. I suspect that doesn't include _init() and _fini() functions, and probably doesn't include any destructor support at all?
  6. Select the right tinystdio OS-dependent options (posix-io=true, posix-console=false, I think?).

There are a couple of other areas we might want to reduce choices in:

  1. "new" math library code. This code, provided by ARM in 2018, is supposed to be an improvement over the old SunPro code from the early 90's, but it's generally less accurate and relies on 64-bit floating point for even 32-bit float functions. It probably is faster when generating 64-bit results.
  2. Larger malloc. This has binned-allocations, and can use mmap for large blocks. Designed for applications doing a lot of malloc/free operations. The smaller malloc is more efficient for single-heap systems like most embedded platforms.
  3. TLS support -- I suggest enabling this whenever the toolchain (and Zephyr) support it.

That leaves the printf options (float/integer, long long, positional args), the optimization type (size/speed) and maybe things like fast-strcmp?

In any case, we should look through https://github.com/picolibc/picolibc/blob/main/doc/build.md to see what options make sense for Zephyr.

@keith-packard
Copy link
Collaborator Author

Cmake build system is working; minor picolibc bug fixes have been applied and the picolibc-module branch has been updated. Zephyr now builds on arm using picolibc and passes all twister tests for that architecture.

@perceiver-tony
Copy link

Hi @keith-packard, @carlescufi, and @stephanosio. I apologize in advance if this isn't the right place to ask, but I didn't see a picolibc thread in the Zephyr discord server and don't have a email address ending in an acceptable domain to join the Zephyr slack channel. Anyhow, we at Perceive are very excited about this work and would love to leverage it as soon as it becomes available for our inference processors. At this point, do you have a feel for when a Zephyr RTOS release containing picolibc might be made available, and moreover, when it may become part of a LTS release? Also, where is the best place for my team to track progress on this development? Thanks, Tony.

@keith-packard
Copy link
Collaborator Author

You can test the current picolibc integration if you want to help validate whether this is ready for merging into Zephyr. That's available via either PR #44096 or in my zephyr repository https://github.com/keith-packard/zephyr/commits/picolibc-module

@stephanosio
Copy link
Member

Closed by #44096

@carlescufi
Copy link
Member

Hi @keith-packard, @carlescufi, and @stephanosio. I apologize in advance if this isn't the right place to ask, but I didn't see a picolibc thread in the Zephyr discord server and don't have a email address ending in an acceptable domain to join the Zephyr slack channel. Anyhow, we at Perceive are very excited about this work and would love to leverage it as soon as it becomes available for our inference processors. At this point, do you have a feel for when a Zephyr RTOS release containing picolibc might be made available, and moreover, when it may become part of a LTS release? Also, where is the best place for my team to track progress on this development? Thanks, Tony.

@tony-bianco this is now merged in mainline Zephyr, which means it will be part of Zephyr 3.2.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: C Library C Standard Library RFC Request For Comments: want input from the community
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants