-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
Make picolibc the default C library for Zephyr #49922
Comments
I think we should use an SDK version that includes picolibc -- that way we can run both C and C++ tests and use the picolibc module and the SDK version. I think that means getting picolibc into a version of the SDK that we can use from the github CI system? |
Yes, zephyrproject-rtos/sdk-ng#287 will need to be completed as part of this. |
Toolchain WG on 2022-09-20
|
Is the eventual plan to get rid of the minimal libc? |
Not in the foreseeable future (it will be too controversial). The minimal libc will stay to provide somewhat self-contained? way of testing the kernel. To quote what @nashif posted in the Teams chat:
|
My point above was that we need to just be cautious with such a move (picolibc as the default libc, dropping minimal, etc.) and think about all possible consequences that might affect users. Last time we tried to make such a move (make newlib default), there were countless issues and that did not happen. (#3102) |
Thanks for that link, really useful to be able to review what happened in the past. It looks like picolibc has a few benefits that should help resolve some of the issues from the past:
We also need to ensure that picolibc sees more testing and that bugs related to using picolibc are resolved. I had been working on this slowly during the early picolibc integration work, and many of the patches required to work with picolibc have been merged. We also need to get Zephyr-specific changes integrated into picolibc -- to make sure the right POSIX APIs are exposed in Picolibc headers when compiling Zephyr code. There are already bits for a few operating systems present, so it's easy and natural to add another one. Finally, we need to get the Zephyr SDK built to include picolibc along with libstdc++ support. When building with C++, it would be quite a bit of work to get libstdc++ built as a module, so instead we should use the existing crosstool-ng support to get libstdc++ built for picolibc and then use picolibc from the SDK instead of as a module. That's blocked on deciding how to package the SDK to include picolibc. Simply adding picolibc will increase the SDK size quite a bit, potentially going over 2GB. Add to that the requests for including debug symbols in the SDK to ease development. |
@stephanosio @keith-packard how far can we get by enabling picolibc as the default in Zephyr as a module? Would this work with all supported toolchains? Adding picolibc to the SDK is fine, however we need to make sure other non-SDK toolchains still work and are not left behind and there need to be parity. We should not get into the situation where using zephyr with some features enabled forces the use the Zephyr SDK. |
Noting that even the minimal libc seems to be having issues with some proprietary toolchains (e.g. with armclang as mentioned by @tejlmand during the meeting), it will likely need some tweaking. But, in principle, it is no different to the minimal libc in that it can be adapted to work with any toolchains we support now and in the future because it is integrated to the Zephyr build process and we build it from source.
As long as the toolchain itself allows using a custom C library (i.e. not linking to the default C library embedded in the toolchain), there is nothing fundamentally preventing the picolibc module from working with them (basically, the same requirement as the minimal libc). p.s. one of the reasons for adding picolibc as a module was to allow it to be used in a toolchain agnostic way (see #44143). |
What kind of per-architecture testing are you looking for? Do you want external picolibc tests? Or internal Zephyr tests? External picolibc tests rely on architecture-specific support for stand-alone applications to be included in picolibc, which would be nice, but is a pretty big lift for some architectures. Picolibc currently has this for arm, aarch64, power9, risc-v and x86. Internal zephyr tests don't use much of the library, so coverage is weak. I'd be happy to include additional architectures in the picolibc test suite, if someone wants to provide the code. |
Just a note for the case of ARC (both arc and arc64) & ARC MWDT toolchain we want to keep Zephyr minimal libc as a default - as we doesn't support piclolib with MWDT toolchain. Not fully sure if we want to switch ARC & GNU toolchain to have picolibc as default (as we don't support it for ARC officially) |
During the discussion of #57340 in the TSC meeting on 2023-05-03, the following concerns were raised:
I will look into addressing these concerns by:
|
I think this duplicates 4. below?
I suggest that this should be explicit about whether Zephyr expects these functions to follow the POSIX or C standard, as well as a general policy about whether functions that exist only in the POSIX standard could be considered for inclusion in this list.
Should this instead say "that only allowed standard C library functions are used"? Seems like an allow list will be easier to manage than a disallow list. |
Or just "the allowed list is whatever is in minimal libc", and the needed CI check is "build everything in tests/kernel with minimal libc". |
That's certainly easier than scanning code for use of symbols present in picolibc but not present in the minimal C library. |
I hacked up a script that generates a list of symbols exported by picolibc and not exported by the minimal C library by scanning the public header files from both. It's a terrible combination of coccinelle and classic Unix tools; there's probably a much cleaner way of doing this ... It reads the picolibc headers from the SDK and the minimal C library headers from Zephyr sources. |
That was the original plan and the TSC was not satisfied with that. As mentioned in #49922 (comment), first of all, we need to clearly define the scope of "Zephyr kernel" because limiting its scope to The second part is to come up with an allow list of the allowed standard C library functions (and naturally a disallow list of the non-standard and deprecated standard C library functions available in Picolibc and other common "full" LIBCs) for the broader Zephyr codebase (i.e. not just the kernel), because we do not want people abusing the non-standard functions and the deprecated standard functions provided in Picolibc. The first part is quite straight forward once we clearly define the scope of "Zephyr kernel" (though, that it is by no means an easy task because everyone will have a slightly different opinion on what "Zephyr kernel" or "core parts of Zephyr" really is). The second part can be implemented in a few different ways; for example:
I am leaning towards the second option because it is a more general solution (as in not libc-specific) and can be used to enforce the our "libc function usage policy" across multiple LIBCs, which is important because we may have CI workflows for third-party toolchains that do not use Picolibc in the future. |
Another simpler option could be to:
This will effectively allow us to restrict the Picolibc function usage to what is proposed in #57598, without coming up with an explicit disallow list for the CI check. Given that any other C standard libraries implementing extensions will have some form of feature test macros, this should also be adaptable across multiple LIBCs. |
Alternatively, adding support for
There are existing uses of
This would also allow code which happens to use these names not get caught by the disallow list on accident. It wouldn't catch code which includes explicit prototypes for these functions from gaining access to the underlying C library function. Which error would you prefer?
What other C libraries are relevant here? Aside from newlib, I thought most of the others were basic C libraries without POSIX support? And I would not be surprised if we could get newlib to adopt the |
No problem with this approach whatsoever; in fact, I prefer this to #57619. I am kind of rushing because I want to get this done in one way or another before the 3.4 feature freeze.
Yes, fixing those should be quite trivial (in theory).
Correct.
Sure; but, brute-force attempts like that will be easily noticed and rejected during a human code review.
This was more or less hypothetical -- if we ever want to add support for a libc that includes extensions in the future.
|
Which kernel tests do you want built with the minimal C library? I'm working on a PR to add kernel tests that use |
Potential issue: printing 64bit integers (long long support) using the pre-built libraries requires using the full floating point library variant. Currently |
All code in the Zephyr core must use only the Zephyr C library API according to rules A.4 and A.5. Such code is not permitted to request API extensions from the C library via any of the API request mechanisms. This addition to checkpatch.pl verifies that patches don't #define any of these: __STRICT_ANSI__ _POSIX_SOURCE _POSIX_C_SOURCE _XOPEN_SOURCE _ISOC99_SOURCE _ISOC11_SOURCE _ATFILE_SOURCE _GNU_SOURCE _BSD_SOURCE _SVID_SOURCE _DEFAULT_SOURCE Reference: zephyrproject-rtos#49922 Signed-off-by: Keith Packard <[email protected]>
All code in the Zephyr core must use only the Zephyr C library API according to rules A.4 and A.5. Such code is not permitted to request API extensions from the C library via any of the API request mechanisms. This addition to checkpatch.pl verifies that patches don't #define any of these: __STRICT_ANSI__ _POSIX_SOURCE _POSIX_C_SOURCE _XOPEN_SOURCE _ISOC99_SOURCE _ISOC11_SOURCE _ATFILE_SOURCE _GNU_SOURCE _BSD_SOURCE _SVID_SOURCE _DEFAULT_SOURCE Reference: zephyrproject-rtos#49922 Signed-off-by: Keith Packard <[email protected]>
All code in the Zephyr core must use only the Zephyr C library API according to rules A.4 and A.5. Such code is not permitted to request API extensions from the C library via any of the API request mechanisms. This addition to checkpatch.pl verifies that patches don't #define any of these: __STRICT_ANSI__ _POSIX_SOURCE _POSIX_C_SOURCE _XOPEN_SOURCE _ISOC99_SOURCE _ISOC11_SOURCE _ATFILE_SOURCE _GNU_SOURCE _BSD_SOURCE _SVID_SOURCE _DEFAULT_SOURCE Reference: zephyrproject-rtos#49922 Signed-off-by: Keith Packard <[email protected]>
All code in the Zephyr core must use only the Zephyr C library API according to rules A.4 and A.5. Such code is not permitted to request API extensions from the C library via any of the API request mechanisms. This addition to checkpatch.pl verifies that patches don't #define any of these: __STRICT_ANSI__ _POSIX_SOURCE _POSIX_C_SOURCE _XOPEN_SOURCE _ISOC99_SOURCE _ISOC11_SOURCE _ATFILE_SOURCE _GNU_SOURCE _BSD_SOURCE _SVID_SOURCE _DEFAULT_SOURCE Reference: #49922 Signed-off-by: Keith Packard <[email protected]>
All code in the Zephyr core must use only the Zephyr C library API according to rules A.4 and A.5. Such code is not permitted to request API extensions from the C library via any of the API request mechanisms. This addition to checkpatch.pl verifies that patches don't #define any of these: __STRICT_ANSI__ _POSIX_SOURCE _POSIX_C_SOURCE _XOPEN_SOURCE _ISOC99_SOURCE _ISOC11_SOURCE _ATFILE_SOURCE _GNU_SOURCE _BSD_SOURCE _SVID_SOURCE _DEFAULT_SOURCE Reference: zephyrproject-rtos#49922 Signed-off-by: Keith Packard <[email protected]>
Toolchain wg: @keith-packard anything left before this is ready for merge ? |
The last run of #57340 appears to have hit a regression, so we should get that fixed. Otherwise, yes, this is ready to merge. |
The regression isn't related to picolibc at all; it's caused by a change in how the microbit emulator is run. #61719 has the details. |
#44096 introduced the picolibc, a full-featured yet light-weight C library and fork of newlib, as a module for Zephyr that can be configured and fine-tuned at the Zephyr build time to minimise its footprint.
This issue describes the tasks required for making the picolibc the default C library support in the Zephyr RTOS.
Tasks
(Add picolibc sdk-ng#602)
subsys/bluetooth: Avoid RX overflow in lt_tx_real_no_encode #54119(no longer appears to cause test suite failures)void main(void)
#58458tests/c_lib: strerror_r is POSIX #58460(Removes_POSIX_C_SOURCE
from CFLAGS: not a compatibility fix)tests/iterable_sections: Set common stack arena size to zero #58464(no longer necessary for this test to work)tests/spinlock: Terminate temporary thread after tests #60123(Fixed via Testcases fixes #60567)_ZEPHYR_SOURCE
support to Picolibc to limit the visibility of non-standard functions from the Zephyr codebase. modules/lib/picolibc: Use version with _ZEPHYR_SOURCE support #58106PICOLIBC
the defaultLIBC_IMPLEMENTATION
Related discussions
The text was updated successfully, but these errors were encountered: