cmake: linker: move toolchain_ld_<base|cpp> to linker flag property

Transition the linker flag for the toolchain_ld_base and
toolchain_ld_cpp macros to linker flag properties.
This work follows the toolchain abstraction started in PR#24851.

toolchain_ld_base() was intended for base linker flags, but has slowly
become a 'set-any-linker-flag-here' and thus having several
`if(<check>)` or `<func>_ifdef(<check> ...)`.

Move the check to the top-level Zephyr CMakeLists.txt file, so that it
becomes cleaner which part is responsible for setting a value, and then
move the actual value (the linker flag) definition to the linker flag
property location.

It also helps adding support for new linkers, as it becomes clearer
which linker flags Zephyr always expects, for example `base` and
`cpp_base`, as well as those settings which are targeting for a given
purpose, such as linker sort alignment.

It also makes it clearer when those are used, for example in top-level
CMakeLists.txt with CONFIG_LINKER_SORT_BY_ALIGNMENT compared to this
information being buried in a linker support macro.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
Torsten Rasmussen 2024-08-30 22:15:40 +02:00 committed by Carles Cufí
commit 9a9e252d16
13 changed files with 107 additions and 129 deletions

View file

@ -363,6 +363,20 @@ zephyr_compile_options(
# @Intent: Set fundamental linker specific flags
toolchain_ld_base()
if(DEFINED TOOLCHAIN_LD_FLAGS)
zephyr_ld_options(${TOOLCHAIN_LD_FLAGS})
endif()
zephyr_link_libraries(PROPERTY base)
zephyr_link_libraries_ifndef(CONFIG_LINKER_USE_RELAX PROPERTY no_relax)
zephyr_link_libraries_ifdef(CONFIG_LINKER_USE_RELAX PROPERTY relax)
# Sort the common symbols and each input section by alignment
# in descending order to minimize padding between these symbols.
zephyr_link_libraries_ifdef(CONFIG_LINKER_SORT_BY_ALIGNMENT PROPERTY sort_alignment)
toolchain_ld_force_undefined_symbols(
_OffsetAbsSyms
_ConfigAbsSyms
@ -373,9 +387,13 @@ if(NOT CONFIG_NATIVE_BUILD)
toolchain_ld_baremetal()
endif()
if(CONFIG_CPP AND NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY)
# @Intent: Set linker specific flags for C++
toolchain_ld_cpp()
if(CONFIG_CPP)
if(NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY)
# @Intent: Set linker specific flags for C++
toolchain_ld_cpp()
endif()
zephyr_link_libraries(PROPERTY cpp_base)
endif()
# @Intent: Add the basic toolchain warning flags

View file

@ -1,4 +1,10 @@
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: Apache-2.0
set_property(TARGET linker PROPERTY cpp_base -Hcplus)
# Extra warnings options for twister run
set_property(TARGET linker PROPERTY warnings_as_errors -Wl,--fatal-warnings)
check_set_linker_property(TARGET linker PROPERTY sort_alignment -Wl,--sort-section=alignment)

View file

@ -159,12 +159,6 @@ endmacro()
# base linker options
macro(toolchain_ld_base)
# Sort the common symbols and each input section by alignment
# in descending order to minimize padding between these symbols.
zephyr_ld_option_ifdef(
CONFIG_LINKER_SORT_BY_ALIGNMENT
${LINKERFLAGPREFIX}--sort-section=alignment
)
endmacro()
# generate linker script snippets from configure files
@ -188,9 +182,6 @@ endmacro()
# link C++ libraries
macro(toolchain_ld_cpp)
zephyr_link_libraries(
-Hcplus
)
endmacro()
# use linker for relocation

View file

@ -6,4 +6,10 @@ elseif(CONFIG_COVERAGE_NATIVE_SOURCE)
endif()
# Extra warnings options for twister run
set_property(TARGET linker PROPERTY ld_extra_warning_options -Wl,--fatal-warnings)
set_property(TARGET linker PROPERTY ld_extra_warning_options ${LINKERFLAGPREFIX},--fatal-warnings)
# GNU ld and LLVM lld complains when used with llvm/clang:
# error: section: init_array is not contiguous with other relro sections
#
# So do not create RELRO program header.
set_property(TARGET linker APPEND PROPERTY cpp_base ${LINKERFLAGPREFIX},-z,norelro)

View file

@ -1,3 +1,16 @@
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: Apache-2.0
check_set_linker_property(TARGET linker PROPERTY base
${LINKERFLAGPREFIX},--gc-sections
${LINKERFLAGPREFIX},--build-id=none
)
if(NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY AND NOT CONFIG_EXTERNAL_MODULE_LIBCPP)
set_property(TARGET linker PROPERTY cpp_base -lstdc++)
endif()
check_set_linker_property(TARGET linker PROPERTY memusage "${LINKERFLAGPREFIX},--print-memory-usage")
# -no-pie is not supported until binutils 2.37.
@ -14,6 +27,13 @@ set_property(TARGET linker PROPERTY partial_linking "-r")
set_property(TARGET linker PROPERTY lto_arguments -flto -fno-ipa-sra -ffunction-sections -fdata-sections)
check_set_linker_property(TARGET linker PROPERTY no_relax ${LINKERFLAGPREFIX},--no-relax)
check_set_linker_property(TARGET linker PROPERTY sort_alignment
${LINKERFLAGPREFIX},--sort-common=descending
${LINKERFLAGPREFIX},--sort-section=alignment
)
# Some linker flags might not be purely ld specific, but a combination of
# linker and compiler, such as:
# --coverage for clang

View file

@ -3,39 +3,4 @@
# See root CMakeLists.txt for description and expectations of these macros
macro(toolchain_ld_base)
# TOOLCHAIN_LD_FLAGS comes from compiler/gcc/target.cmake
# LINKERFLAGPREFIX comes from linker/ld/target.cmake
zephyr_ld_options(
${TOOLCHAIN_LD_FLAGS}
)
zephyr_ld_options(
${LINKERFLAGPREFIX},--gc-sections
${LINKERFLAGPREFIX},--build-id=none
)
# Sort the common symbols and each input section by alignment
# in descending order to minimize padding between these symbols.
zephyr_ld_option_ifdef(
CONFIG_LINKER_SORT_BY_ALIGNMENT
${LINKERFLAGPREFIX},--sort-common=descending
${LINKERFLAGPREFIX},--sort-section=alignment
)
if (NOT CONFIG_LINKER_USE_RELAX)
zephyr_ld_options(
${LINKERFLAGPREFIX},--no-relax
)
endif()
if(CONFIG_CPP AND (CMAKE_C_COMPILER_ID STREQUAL "Clang"))
# GNU ld complains when used with llvm/clang:
# error: section: init_array is not contiguous with other relro sections
#
# So do not create RELRO program header.
zephyr_link_libraries(
-Wl,-z,norelro
)
endif()
endmacro()

View file

@ -3,11 +3,4 @@
# See root CMakeLists.txt for description and expectations of these macros
macro(toolchain_ld_cpp)
if(NOT CONFIG_EXTERNAL_MODULE_LIBCPP)
zephyr_link_libraries(
-lstdc++
)
endif()
endmacro()

View file

@ -1,3 +1,16 @@
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: Apache-2.0
# Base properties.
# Basic linker properties which should always be applied for a Zephyr build.
set_property(TARGET linker PROPERTY base)
# Base properties when C++ support is enabled.
# Basic linker properties which should always be applied for a Zephyr build
# using C++.
set_property(TARGET linker PROPERTY cpp_base)
# coverage is a property holding the linker flag required for coverage support on the toolchain.
# For example, on ld/gcc this would be: -lgcov
# Set the property for the corresponding flags of the given toolchain.
@ -20,3 +33,12 @@ set_property(TARGET linker PROPERTY no_position_independent)
# Linker flag for doing partial linking
# such as, "-r" or "--relocatable" for LD and LLD.
set_property(TARGET linker PROPERTY partial_linking)
# Linker flag for section sorting by alignment
set_property(TARGET linker PROPERTY sort_alignment)
# Linker flag for disabling relaxation of address optimization for jump calls.
set_property(TARGET linker PROPERTY no_relax)
# Linker flag for enabling relaxation of address optimization for jump calls.
set_property(TARGET linker PROPERTY relax)

View file

@ -1,11 +1,20 @@
# Copyright (c) 2022 Google LLC
# SPDX-License-Identifier: Apache-2.0
# Since lld is a drop in replacement for ld, we can just use ld's flags
include(${ZEPHYR_BASE}/cmake/linker/ld/${COMPILER}/linker_flags.cmake OPTIONAL)
# Since lld is a drop in replacement for ld, we can just use ld's flags as a base
# and adjust for lld specifics afterwards.
include(${ZEPHYR_BASE}/cmake/linker/ld/linker_flags.cmake OPTIONAL)
check_set_linker_property(TARGET linker PROPERTY memusage "${LINKERFLAGPREFIX},--print-memory-usage")
if(NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY AND NOT CONFIG_EXTERNAL_MODULE_LIBCPP)
set_property(TARGET linker PROPERTY cpp_base -lc++ ${LINKERFLAGPREFIX},-z,norelro)
endif()
set_property(TARGET linker PROPERTY no_position_independent "${LINKERFLAGPREFIX},--no-pie")
set_property(TARGET linker PROPERTY partial_linking "-r")
set_property(TARGET linker PROPERTY lto_arguments)
check_set_linker_property(TARGET linker PROPERTY sort_alignment ${LINKERFLAGPREFIX},--sort-section=alignment)
if(CONFIG_RISCV_GP)
check_set_linker_property(TARGET linker PROPERTY relax ${LINKERFLAGPREFIX},--relax-gp)
endif()

View file

@ -3,44 +3,4 @@
# See root CMakeLists.txt for description and expectations of these macros
macro(toolchain_ld_base)
# TOOLCHAIN_LD_FLAGS comes from compiler/clang/target.cmake
# LINKERFLAGPREFIX comes from linker/lld/target.cmake
zephyr_ld_options(
${TOOLCHAIN_LD_FLAGS}
)
zephyr_ld_options(
${LINKERFLAGPREFIX},--gc-sections
${LINKERFLAGPREFIX},--build-id=none
)
# Sort each input section by alignment.
zephyr_ld_option_ifdef(
CONFIG_LINKER_SORT_BY_ALIGNMENT
${LINKERFLAGPREFIX},--sort-section=alignment
)
if (NOT CONFIG_LINKER_USE_RELAX)
zephyr_ld_options(
${LINKERFLAGPREFIX},--no-relax
)
endif()
# Global pointer relaxation is off by default in lld. Explicitly enable it if
# linker relaxations and gp usage are both allowed.
if (CONFIG_LINKER_USE_RELAX AND CONFIG_RISCV_GP)
zephyr_ld_options(
${LINKERFLAGPREFIX},--relax-gp
)
endif()
if(CONFIG_CPP)
# LLVM lld complains:
# error: section: init_array is not contiguous with other relro sections
#
# So do not create RELRO program header.
zephyr_link_libraries(
-Wl,-z,norelro
)
endif()
endmacro()

View file

@ -3,9 +3,4 @@
# See root CMakeLists.txt for description and expectations of these macros
macro(toolchain_ld_cpp)
zephyr_link_libraries(
-lc++
)
endmacro()

View file

@ -1,3 +1,21 @@
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: Apache-2.0
check_set_linker_property(TARGET linker PROPERTY base
${LINKERFLAGPREFIX},--gc-sections
${LINKERFLAGPREFIX},--build-id=none
)
if(NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY AND NOT CONFIG_EXTERNAL_MODULE_LIBCPP)
set_property(TARGET linker PROPERTY cpp_base -lstdc++)
endif()
set_property(TARGET linker PROPERTY partial_linking "-r")
check_set_linker_property(TARGET linker PROPERTY no_relax ${LINKERFLAGPREFIX},--no-relax)
)
check_set_linker_property(TARGET linker PROPERTY sort_alignment
${LINKERFLAGPREFIX},--sort-common=descending
${LINKERFLAGPREFIX},--sort-section=alignment
)

View file

@ -3,29 +3,4 @@
# See root CMakeLists.txt for description and expectations of these macros
macro(toolchain_ld_base)
# TOOLCHAIN_LD_FLAGS comes from compiler/gcc/target.cmake
# LINKERFLAGPREFIX comes from linker/xt-ld/target.cmake
zephyr_ld_options(
${TOOLCHAIN_LD_FLAGS}
)
zephyr_ld_options(
${LINKERFLAGPREFIX},--gc-sections
${LINKERFLAGPREFIX},--build-id=none
)
# Sort the common symbols and each input section by alignment
# in descending order to minimize padding between these symbols.
zephyr_ld_option_ifdef(
CONFIG_LINKER_SORT_BY_ALIGNMENT
${LINKERFLAGPREFIX},--sort-common=descending
${LINKERFLAGPREFIX},--sort-section=alignment
)
if (NOT CONFIG_LINKER_USE_RELAX)
zephyr_ld_options(
${LINKERFLAGPREFIX},--no-relax
)
endif()
endmacro()