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

Build excludes paths to standard C++ headers when using GNUARMEMB toolchain variant #36823

Closed
palchak-google opened this issue Jul 8, 2021 · 5 comments
Assignees
Labels
area: C++ bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Milestone

Comments

@palchak-google
Copy link
Contributor

palchak-google commented Jul 8, 2021

Describe the bug
Using the gnuarmemb toolchain variant to build a trivial application fails if any source file in the application includes a standard C++ header.

To Reproduce
Steps to reproduce the behavior:

  1. Create a trivial Zephyr C++ app with CONFIG_CPLUSPLUS=y. Put the following in main.cc (or main.cpp if you prefer):
#include <cstdint>
void main() {}
  1. Attempt to to build the app using the 'gnuarmemb` toolchain variant for an appropriate board (such as nrf52dk_nrf52832):
$ ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb west build -b nrf52dk_nrf52832
  1. Build fails.

Expected behavior
Build should complete without error.

Impact
Unable to generate any firmware images for target hardware.

Logs and console output
The compiler invocation command that fails is shown below. Newlines have been added for readability, and some path information has been redacted.

ccache <REDACTED>/prebuilt/gcc-arm-none-eabi-10-2020-q4/linux/bin/arm-none-eabi-g++
-DBUILD_VERSION=v2.4.99-ncs2
-DKERNEL
-DNRF52832_XXAA
-DUSE_PARTITION_MANAGER=0
-D_FORTIFY_SOURCE=2
-D__PROGRAM_START
-D__ZEPHYR__=1
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/zephyr/include
-Izephyr/include/generated
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/zephyr/soc/arm/nordic_nrf/nrf52
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/nrf/include
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/modules/hal/nordic/nrfx
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/modules/hal/nordic/nrfx/drivers/include
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/modules/hal/nordic/nrfx/mdk
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/zephyr/modules/hal_nordic/nrfx/.
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/modules/hal/cmsis/CMSIS/Core/Include
-I<REDACTED>/third_party/nordic/ncs_v1.5.1/modules/debug/segger/rtt
-isystem <REDACTED>/third_party/nordic/ncs_v1.5.1/zephyr/lib/libc/minimal/include
-isystem <REDACTED>/prebuilt/gcc-arm-none-eabi-10-2020-q4/linux/bin/../lib/gcc/arm-none-eabi/10.2.1/include
-isystem <REDACTED>/prebuilt/gcc-arm-none-eabi-10-2020-q4/linux/bin/../lib/gcc/arm-none-eabi/10.2.1/include-fixed
-Os
-fcheck-new
-std=c++11
-Wno-register
-fno-exceptions
-fno-rtti
-imacros <REDACTED>/firmware/app/trivial/BUILD/zephyr/include/generated/autoconf.h
-ffreestanding
-fno-common
-g
-mcpu=cortex-m4
-mthumb
-mabi=aapcs
-imacros <REDACTED>/third_party/nordic/ncs_v1.5.1/zephyr/include/toolchain/zephyr_stdint.h
-Wall
-Wformat
-Wformat-security
-Wno-format-zero-length
-Wno-main
-Wpointer-arith
-Wno-address-of-packed-member
-Wno-unused-but-set-variable
-fno-asynchronous-unwind-tables
-fno-pie
-fno-pic
-fno-strict-overflow
-fno-reorder-functions
-fno-defer-pop
-fmacro-prefix-map=<REDACTED>/firmware/app/trivial=CMAKE_SOURCE_DIR
-fmacro-prefix-map=<REDACTED>/third_party/nordic/ncs_v1.5.1/zephyr=ZEPHYR_BASE
-fmacro-prefix-map=<REDACTED>=WEST_TOPDIR
-ffunction-sections
-fdata-sections
-nostdinc
-MD
-MT CMakeFiles/app.dir/src/main.cc.obj
-MF CMakeFiles/app.dir/src/main.cc.obj.d
-o CMakeFiles/app.dir/src/main.cc.obj
-c ../src/main.cc

../src/main.cc:2:10: fatal error: cstdint: No such file or directory
    2 | #include <cstdint>
      |          ^~~~~~~~~
compilation terminated.

Environment (please complete the following information):

  • OS: linux
  • Toolchain: GNU ARM Embedded v10 (gcc-arm-none-eabi-10-2020-q4)
  • Version: v2.4.99

Additional context

The reason that this failure is occurring for this toolchain variant is that the Zephyr build system adds the -nostdinc flag to the build. (zephyr/CMakeLists.txt) This is done with the (obviously wrong) assumption that the build system has discovered all of the implicit system include paths and added them as explicit system include paths. (zephyr/cmake/compiler/gcc/compiler_flags.cmake).

Zephyr's assumption that it is safe to add -nostdinc to the build is wrong. This is because the locations of the standard C++ headers are never discovered. The discovery routine only looks for the paths to the C headers include/stddef.h and include-fixed/limits.h. (zephyr/cmake/compiler/gcc/target.cmake) No attempt is made to look for any C++ headers, even if CONFIG_CPLUSPLUS is enabled. Without the paths to the standard C++ headers, the build fails.

Note that this problem doesn't occur with the host-gcc toolchain variant because in that circumstance the -nostdinc flag is not added to the build.

Proposed Fix(es)
The easiest fix would be to exclude the -nostdinc flag from the build when CONFIG_CPLUSPLUS is set.

The harder fix would be to properly discover all of the system include paths for the C++ compiler when CONFIG_CPLUSPLUS is set and explicitly add those paths to the build. This approach is challenging because the technique used for discovering the location of the C headers does not work for discovering the location of C++ headers (at least with GCC/G++). Passing the -print-file-name flag to g++ does not print full path to the specified header.

The best alternative option this developer could discover would be to use the following compiler invocation (borrowed from StackOverflow here ):

g++ -E -x c++ -v /dev/null

and to parse the resulting output.

EDIT:
Related to #36644.

@palchak-google palchak-google added the bug The issue is a bug, or the PR is fixing a bug label Jul 8, 2021
@palchak-google
Copy link
Contributor Author

Further investigation shows that if CONFIG_NEWLIB_LIBC is set, then the -nostdinc flag is not added to the build. However, even when not linking against newlib, headers such as <cstdint> and <cstddef> should be available.

@alexanderwachter
Copy link
Member

@palchak-google C++ needs newlib to build. You cannot use C++ on Zephyr without newlib, because it relies on the lib C implementation.
@stephanosio we had this topic several times already. Maybe we should add a dependency to newlib for C++ builds.

@stephanosio
Copy link
Member

@palchak-google Similar issue has been observed and discussed here: #36644.

In general, although not currently enforced, you should consider that, in order to utilise C++ standard headers, you must set CONFIG_LIB_CPLUSPLUS=y (i.e. use libstdc++), which depends on CONFIG_NEWLIB_LIBC, which has the effect of omitting -nostdinc flag.

This problem will eventually be addressed when #36644 is resolved.

@stephanosio stephanosio self-assigned this Jul 12, 2021
@cfriedt cfriedt added the priority: medium Medium impact/importance bug label Jul 12, 2021
@cfriedt cfriedt added this to the v2.7.0 milestone Jul 12, 2021
@github-actions
Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

@stephanosio
Copy link
Member

Closing this issue since the access to the C++ headers requires CONFIG_LIB_CPLUSPLUS=y, and the header availability issues described here are already described in #36644 and will be fixed there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: C++ bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Projects
None yet
Development

No branches or pull requests

4 participants