From 96c1b05125e8d08a5e1d7db21f35f68c9ee87420 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Tue, 13 Aug 2019 17:24:45 -0500 Subject: [PATCH] lib/newlib: revert treatment of libc files as system includes The solution from #14312 of using -isystem to prioritize the position of the libc directory bypasses the effect of -ffreestanding with respect to libc symbols expected to be present in a non-hosted environment. Further, it breaks C++ with the ARM Embedded toolchain as the system fails to find the right file with #include_next. Use a more fine-grained solution that explicitly includes the underlying newlib header required for support before moving on to include the next available one, whether system or non-system. Closes #17564 Signed-off-by: Peter Bigot --- lib/libc/newlib/CMakeLists.txt | 17 +++++++++++------ lib/libc/newlib/include/stdint.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 lib/libc/newlib/include/stdint.h diff --git a/lib/libc/newlib/CMakeLists.txt b/lib/libc/newlib/CMakeLists.txt index d368d1b89a8e10..e18a856eb941b4 100644 --- a/lib/libc/newlib/CMakeLists.txt +++ b/lib/libc/newlib/CMakeLists.txt @@ -3,18 +3,23 @@ zephyr_library() zephyr_library_sources(libc-hooks.c) +# Zephyr normally uses -ffreestanding, which with current GNU toolchains +# means that the flag macros used by newlib 3.x to signal +# support for PRI.64 macros are not present. To make them available we +# need to hook into the include path before the system files and +# explicitly include the newlib header that provides those macros. +zephyr_include_directories(include) + # LIBC_*_DIR may or may not have been set by the toolchain. E.g. when # using ZEPHYR_TOOLCHAIN_VARIANT=cross-compile it will be either up to the # toolchain to know where it's libc implementation is, or if it is # unable to, it will be up to the user to specify LIBC_*_DIR vars to -# point to a newlib implementation. +# point to a newlib implementation. Note that this does not change the +# directory order if LIBC_INCLUDE_DIR is already a system header +# directory. -# We need to make sure this is included before the standard system -# header include path's since we build with -ffreestanding and need -# our libc headers to be picked instead of the toolchain's ffreestanding -# headers. if(LIBC_INCLUDE_DIR) - zephyr_system_include_directories(${LIBC_INCLUDE_DIR}) + zephyr_include_directories(${LIBC_INCLUDE_DIR}) endif() if(LIBC_LIBRARY_DIR) diff --git a/lib/libc/newlib/include/stdint.h b/lib/libc/newlib/include/stdint.h new file mode 100644 index 00000000000000..a7d4874a4d9b83 --- /dev/null +++ b/lib/libc/newlib/include/stdint.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_NEWLIB_INCLUDE_STDINT_H_ +#define ZEPHYR_LIB_LIBC_NEWLIB_INCLUDE_STDINT_H_ + +/* Work around -ffreestanding absence of defines required to support + * PRI.64 macros in by including the newlib header that + * provides the flag macros. + */ + +#include + +#ifdef __NEWLIB__ +/* Has this header. Older versions do it in . */ +#include +#endif /* __NEWLIB__ */ + +/* This should work on GCC and clang. + * + * If we need to support a toolchain without #include_next the CMake + * infrastructure should be used to identify it and provide an + * alternative solution. + */ +#include_next + +#endif /* ZEPHYR_LIB_LIBC_NEWLIB_INCLUDE_STDINT_H_ */