-
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
Allow use of SDK version of picolibc with C++ #53338
Allow use of SDK version of picolibc with C++ #53338
Conversation
7232068
to
badee00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the number of picolibc related settings seems to be growing for no appearent reason.
I believe reducing the number to a single user facing setting will improve usability and remove the circular dependency.
Agreed. Help here would be greatly appreciated. Here's what the current symbols do:
There are some cross-system configuration adventures that need to be addressed -- the picolibc source code includes some cmake bits which check for the Zephyr-specific symbol
How about this as a solution:
Alternatively, figure out how to use |
badee00
to
113c711
Compare
Ok, I've removed the extra PICOLIBC_SELECT_MODULE variable and have created PICOLIBC_MODULE at the libc level to control whether to prefer the module to the toolchain for picolibc. PICOLIBC_USE_MODULE is now only used to pass information to the cmake files in the picolibc module and can be removed when the picolibc module is updated to use CONFIG_PICOLIBC and CONFIG_PICOLIBC_MODULE directly. This has the effect of changing the user-visible symbol used to select whether to use the picolibc module in zephyr from PICOLIBC_USE_MODULE to PICOLIBC_MODULE. If that doesn't seem like a good idea, I can update the picolibc module first and then switch PICOLIBC_USE_MODULE to be the user-visible variable again. |
113c711
to
eb84c8c
Compare
Let me try to give a bit of extra background knowledge on the module. The
According to my search, this Kconfig was originally not used anywhere in CMake.
according to this code
Ref: https://github.com/zephyrproject-rtos/picolibc/blob/98e59b70d6ef8eb18f7dccc3d39cecaa0658fa4f/CMakeLists.txt#L52-L54 So in original proposal there weren't a need for both, but I will take closer look in the updated proposal, sounds like you have done some cleanup already 👍 . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new PICOLIBC_MODULE
in lib/libc/Kconfig
is now outside of the if PICOLIBC
guard.
This means this symbol is always accessible, irrespectively of the PICOLIBC
libc selection.
In fact that's already the case today because of the way this module is defined in the Zephyr picolibc module Kconfig, but that's a different story.
I think I understand the purpose you want to achieve, so let me try to it down, and then I can try to create a patch with the described behavior.
Setting: PICOLIBC_SUPPORTED
, should be yes when it should be possible to enable picolibc as C library.
This means for pure C development when compiler is gcc based (ie. not ARC mwdt).
Or for C++ development when Zephyr SDK >=0.16 (should be handled by the Zephyr SDK)
Setting: PICOLIBC
choice entry, depends on PICOLIBC_SUPPORTED=y
.
Setting: PICOLIBC_USE_MODULE
config. Only valid if Picolibc is selected a C library.
Requires that Zephyr Picolibc module is available.
Cannot be used together with C++
Will let you know when it's done.
@keith-packard I hope I got your intentions right. This specifies the additional dependencies and ensures that users can only build picolibc as module when C++ is not used. When Zephyr SDK 0.16 is ready, then Zephyr SDK itself should be able to inform that it supports picolibc, even if C++ is used, but in that case not allowing Picolibc to be build as a module. Picolibc itself can then follow later with the removal of Feel free to give feedback. |
Right, it "has" to be so that it can help drive
Or any external toolchain -- the Zephyr SDK is somewhat unique in not yet having C++ support for picolibc; crosstool-ng and the arm embedded toolkit already do. So, the only constraint is that we not use the module when C++ is selected.
Ok, I wasn't aware that the picolibc module itself was optional, although it makes sense. |
@stephanosio what is the plan with making picolibc the default C library, will it be getting moved into the zephyr repository itself? |
Thanks, that was the piece of info I was missing.
In theory you can remove any project from the Zephyr manifest you like, although you might want to keep some. |
@keith-packard pushed an update. When using 3rd party toolchains, like gnu ARM emb or crosstool-ng, users themselves are responsible for what is supported in the toolchain version they decide to use. |
Picolibc is in the Zephyr SDK and available as a Zephyr module. Both of those are built from the picolibc version in the Zephyr github account, https://github.com/zephyrproject-rtos/picolibc/ At this point, switching to using picolibc by default is a simple matter of adjusting the Kconfig settings. I've got a pile of PRs queued which are required to resolve test suite issues when using picolibc. Help reviewing those would be greatly appreciated, as that is one of the things blocking this transition. |
When using picolibc from the toolchain, we need to use the standard include paths to make sure the library headers are found, especially for libstdc++. Add toolchain picolibc to the list of cases for which this is the case. Signed-off-by: Keith Packard <[email protected]>
eb84c8c
to
55d2805
Compare
Ok, thanks to Torsten Rasmussen, I think I've got this sorted out. The goals of this series are a bit different now that Stephanos Ioannidis has rewritten the C++ library stuff. Now, the end goal is to prevent use of the Picolibc module when the application needs the GNU libstdc++ bits as those can only be provided by the toolchain in combination with a toolchain-provided picolibc. For Zephyr SDK 0.15, that's not quite achievable as I couldn't figure out how to avoid a dependency loop. Once we have SDK 0.16, then you can use the Picolibc module for any C++ applications which aren't usng libstdc++. This series removes the |
libstdc++ is supported with Picolibc only when the toolchain version of Picolibc is use -- libstdc++ must be built using a specific Picolibc build and libstdc++ is included with the toolchain. Ideally, we'd allow the use of the Picolibc module whenever we weren't using the GNU libstdc++, including when using the minimal libc++. However, the obvious dependency settings create a loop: config PICOLIBC depends on PICOLIBC_SUPPORTED config PICOLIBC_SUPPORTED depends on !(GLIBCXX_LIBCPP && "$(ZEPHYR_TOOCHAIN_VARIANT" = "zephyr") config GLIBCXX_LIBCPP depends on NEWLIB_LIBC || PICOLIBC To break this loop, we replace GLIBCXX_LIBCPP in the second block with CPP: config PICOLIBC_SUPPORTED depends on !(CPP && "$(ZEPHYR_TOOCHAIN_VARIANT" = "zephyr") This means that picolibc cannot be used with any C++ apps when using the Zephyr SDK, even when not using the GNU libstdc++. However, Zephyr SDK 0.16 will come with an additional Kconfig file that includes: config PICOLIBC_SUPPORTED def_bool y depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr" This will override the Kconfig bits included in Zephyr and allow use of the Picolibc module with C++ code, including using the minimal libc++ bits. Signed-off-by: Keith Packard <[email protected]>
When the toolchain has picolibc support, run samples/subsys/cpp/cpp_synchronization and tests/subsys/cpp/libcxx tests using it. Signed-off-by: Keith Packard <[email protected]>
55d2805
to
fe11427
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your help, @tejlmand, seems like we ended up in a much simpler place. |
# Picolibc with C++ support in Zephyr SDK is handled by Zephyr SDK's own Kconfig. | ||
config PICOLIBC_SUPPORTED | ||
bool | ||
depends on ARC || ARM || ARM64 || MIPS || RISCV | ||
depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "arcmwdt" | ||
depends on !(CPP && "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the late review.
I think we have tried to work backwards on this and ended up with something quite convoluted -- what we really should be specifying here is when GLIBCXX (aka. libstdc++) is supported, not when PICOLIBC is supported.
GLIBCXX is supported when the toolchain provides the GLIBCXX specifically built for the selected LIBC. This means:
- When NEWLIB (toolchain-provided) is selected, GLIBCXX is supported if the toolchain provides a GLIBCXX built for NEWLIB.
- When PICOLIBC (toolchain-provided) is selected, GLIBCXX is supported if the toolchain provides a GLIBCXX built for PICOLIBC.
Since NEWLIB, when available, is currently only toolchain-provided and a C/C++ toolchain that includes NEWLIB almost certainly includes the GLIBCXX built for NEWLIB, we simply specify GLIBCXX_LIBCPP depends on NEWLIB_LIBC
; but, in reality, it should really be something like GLIBCXX_LIBCPP depends on NEWLIB_LIBC && TOOLCHAIN_HAS_GLIBCXX_NEWLIB
.
Similarly, for PICOLIBC, the condition should essentially be GLIBCXX_LIBCPP depends on PICOLIBC && TOOLCHAIN_HAS_GLIBCXX_PICOLIBC
. But, unlike NEWLIB, PICOLIBC can also be non-toolchain-provided, in which case the GLIBCXX built for the PICOLIBC is unavailable, so it needs to be GLIBCXX_LIBCPP depends on PICOLIBC && !PICOLIBC_USE_MODULE && TOOLCHAIN_HAS_GLIBCXX_PICOLIBC
.
So, ideally, we should have ended up with something like:
config GLIBCXX_LIBCPP
bool "GNU C++ Standard Library"
depends on !NATIVE_APPLICATION
depends on (NEWLIB_LIBC && TOOLCHAIN_HAS_GLIBCXX_NEWLIB) ||
(PICOLIBC && !PICOLIBC_USE_MODULE && TOOLCHAIN_HAS_GLIBCXX_PICOLIBC)
where TOOLCHAIN_HAS_GLIBCXX_NEWLIB
and TOOLCHAIN_HAS_GLIBCXX_PICOLIBC
are set by the Zephyr SDK CMake package (or automatic toolchain feature detection logic in the future).
Also, C++ library, in its current form, can be considered an extension to the C library and should exist as an upper layer of the C library support; so, the libc choice should dictate which libcpp can be selected, not the other way around.
Since we are near the feature freeze for 3.3, I will leave this alone. I will rework this in the future to make it more logically consistent and straight forward.
SDK version 0.16 will include picolibc along with libstdc++ support. Once that is released, this short series will be needed in Zephyr to allow use of picolibc with C++ applications.