Zephyr is a bare metal build where standard libs are disabled. This means that c and runtime libraries must manually be linked in. This has generally been handled by using CMake's link libraries handling but the issue with that is both de-duplication but also library link order. Standard libraries must be linked at last location to ensure symbols are always available, however this is not optimal with target_link_libraries() because this would ultimately require every library to know the c library to link with, which is not desired. Therefore, setup standard C and runtime library linking in linker CMake files for toolchains where this is required. This commit expands the principle introduced with toolchain abstraction, see PR#24851. This means that a toolchain implementation may specify standard C, runtime, C++, etc libraries, as well as their link order. Because a property approach is used, then Zephyr modules, such as the Picolibc module can adjust such properties. An optional `zephyr_linker_finalize()` macro is called at the end of Zephyr's CMakeList process and can be used by the toolchain implementation to define the final linker invocation. This aligns the linker handling flow to the principle introduced in PR#24851 and improves the flexibility and robustness of Zephyr build system. Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
51 lines
2 KiB
CMake
51 lines
2 KiB
CMake
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
zephyr_library()
|
|
zephyr_library_sources(libc-hooks.c)
|
|
|
|
# Do not allow LTO when compiling libc-hooks.c file
|
|
set_source_files_properties(libc-hooks.c PROPERTIES COMPILE_OPTIONS $<TARGET_PROPERTY:compiler,prohibit_lto>)
|
|
|
|
# Zephyr normally uses -ffreestanding, which with current GNU toolchains
|
|
# means that the flag macros used by newlib 3.x <inttypes.h> 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_LIBRARY_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_LIBRARY_DIR vars to
|
|
# point to a newlib implementation.
|
|
if(LIBC_LIBRARY_DIR)
|
|
set(LIBC_LIBRARY_DIR_FLAG -L${LIBC_LIBRARY_DIR})
|
|
endif()
|
|
|
|
# Define _ANSI_SOURCE in order to prevent Newlib from defining POSIX primitives
|
|
# in its headers when GNU dialect is used (-std=gnu*). Newlib features.h
|
|
# defines _DEFAULT_SOURCE when __STRICT_ANSI__ is not defined by GCC (i.e. when
|
|
# -std=gnu*), which leads to various POSIX definitions being provided by the
|
|
# Newlib headers and conflicts with the POSIX definitions provided by Zephyr.
|
|
zephyr_compile_definitions(_ANSI_SOURCE)
|
|
|
|
# define __LINUX_ERRNO_EXTENSIONS__ so we get errno defines like -ESHUTDOWN
|
|
# used by the network stack
|
|
zephyr_compile_definitions(__LINUX_ERRNO_EXTENSIONS__)
|
|
|
|
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
|
zephyr_link_libraries(
|
|
${LIBC_LIBRARY_DIR_FLAG} # NB: Optional
|
|
$<$<BOOL:${CONFIG_NEWLIB_LIBC_FLOAT_PRINTF}>:-u_printf_float>
|
|
$<$<BOOL:${CONFIG_NEWLIB_LIBC_FLOAT_SCANF}>:-u_scanf_float>
|
|
)
|
|
endif()
|
|
|
|
if(CONFIG_NEWLIB_LIBC_NANO)
|
|
zephyr_link_libraries(
|
|
-specs=nano.specs
|
|
)
|
|
zephyr_compile_options(
|
|
-specs=nano.specs
|
|
)
|
|
endif()
|