-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Description
Status quo
The Zephyr build system does not specify -nostdinc argument when newlib is enabled (CONFIG_NEWLIB_LIBC=y):
zephyr/cmake/compiler/gcc/compiler_flags.cmake
Lines 115 to 121 in ae85da1
| if (NOT CONFIG_NEWLIB_LIBC AND | |
| NOT COMPILER STREQUAL "xcc" AND | |
| NOT ZEPHYR_TOOLCHAIN_VARIANT STREQUAL "espressif" AND | |
| NOT CONFIG_NATIVE_APPLICATION) | |
| set_compiler_property(PROPERTY nostdinc -nostdinc) | |
| set_compiler_property(APPEND PROPERTY nostdinc_include ${NOSTDINC}) | |
| endif() |
This has the effect of making the toolchain-provided standard headers (which includes newlib standard C library headers for the currently supported toolchains) available for inclusion.
When CONFIG_LIB_CPLUSPLUS=y, which semantically enables the use of libstdc++, this also has the intended effect since the toolchain-provided libstdc++ C++ standard library headers are available for inclusion when -nostdinc is not specified.
When CONFIG_NEWLIB_LIBC=y and CONFIG_LIB_CPLUSPLUS=n however, this has an unintended effect of making the libstdc++ headers available for inclusion even when it was never the developer's intention to make use of the toolchain-provided libstdc++ features, as observed in #36612 (comment).
The libstdc++, also known as the GNU C++ library, mainly consists of the standard C++ library header files, which include both definitions and implementations, and the standard C++ library object archive, which provides the implementations for the methods that do not come with implementation in the headers.
The current definition of CONFIG_LIB_CPLUSPLUS is "Link with STD C++ library":
Lines 47 to 48 in 6153719
| config LIB_CPLUSPLUS | |
| bool "Link with STD C++ library" |
One may possibly argue that allowing the use of libstdc++ headers without linking the libstdc++ archive, alongside the minimal C++ runtime implemented by the Zephyr C++ subsystem (one might call this a "hybrid" scheme), is a both valid and intended scheme; but, in reality, this is simply not a correct thing to do for the following reasons and need to be classified as a bug:
- In traditional sense, headers are supposed to provide definitions and the object archive (
.afile) is supposed to provide the implementations. In terms of C++, this separation often gets blurred and, as with the libstdc++, many small method implementations tend to get put in the header file. This does not mean that you can rely on the headers to provide the full implementation and making use of the headers without linking the relevant object files leaves the build success at the mercy of what gets put in the headers and source files on the libstdc++ side. This is non-deterministic and not a correct behaviour. - libstdc++ headers are provided by the toolchain and its version may vary with the toolchain being used. Mixing libstdc++ headers with the minimal C++ library provided by what is currently known as the Zephyr C++ subsystem can lead to version-dependent compatibility issues as well as unexpected behaviours. We cannot afford to have this.
- gcc is currently the toolchain of choice for Zephyr and libstdc++ is shown as an example here for that reason. In the future, we will be adding support for other toolchains (e.g. Clang/LLVM), and this "hybrid" scheme, once again, makes that very non-deterministic and leaves things at the mercy of the toolchain type and version. We cannot afford to maintain such a non-deterministic scheme.
To be
As briefly noted in #36612 (comment):
- Disallow using libstdc++ headers when
CONFIG_LIB_CPLUSPLUS=nby specifying-nostdinc++. - Refactor C++ subsystem (
subsys/cpp) such that the separation between the "minimal C++ runtime library" and the toolchain-specific C++ runtime library integration (glue/shim) is clear. - Possibly downgrade "C++ subsystem" to "C++ library" (
lib/cpp) and adopt the same scheme as the C library (lib/libc). - Consider expanding the scope of "minimal C++ runtime library" such that basic standard C++ features are available in a toolchain-agnostic way (similar to the concept of minimal C library --
lib/libc/minimal). - Consider adopting a BSD or Apache licensed C++ runtime library (e.g. Apache C++ Standard Library, LLVM C++ Standard Library, ...).