From 9a9e252d1677c047929f5602eace209123fafe3e Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 30 Aug 2024 22:15:40 +0200 Subject: [PATCH] cmake: linker: move toolchain_ld_ 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()` or `_ifdef( ...)`. 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 --- CMakeLists.txt | 24 ++++++++++++-- cmake/linker/arcmwdt/linker_flags.cmake | 6 ++++ cmake/linker/arcmwdt/target.cmake | 9 ------ cmake/linker/ld/clang/linker_flags.cmake | 8 ++++- cmake/linker/ld/linker_flags.cmake | 20 ++++++++++++ cmake/linker/ld/target_base.cmake | 35 --------------------- cmake/linker/ld/target_cpp.cmake | 7 ----- cmake/linker/linker_flags_template.cmake | 22 +++++++++++++ cmake/linker/lld/linker_flags.cmake | 17 +++++++--- cmake/linker/lld/target_base.cmake | 40 ------------------------ cmake/linker/lld/target_cpp.cmake | 5 --- cmake/linker/xt-ld/linker_flags.cmake | 18 +++++++++++ cmake/linker/xt-ld/target_base.cmake | 25 --------------- 13 files changed, 107 insertions(+), 129 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4f19abb9c1..540202fc4b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/cmake/linker/arcmwdt/linker_flags.cmake b/cmake/linker/arcmwdt/linker_flags.cmake index 4675e97e14e..bd8ec002226 100644 --- a/cmake/linker/arcmwdt/linker_flags.cmake +++ b/cmake/linker/arcmwdt/linker_flags.cmake @@ -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) diff --git a/cmake/linker/arcmwdt/target.cmake b/cmake/linker/arcmwdt/target.cmake index 3480749c32a..af14f89f06f 100644 --- a/cmake/linker/arcmwdt/target.cmake +++ b/cmake/linker/arcmwdt/target.cmake @@ -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 diff --git a/cmake/linker/ld/clang/linker_flags.cmake b/cmake/linker/ld/clang/linker_flags.cmake index cc53fab40c0..3155f386a7c 100644 --- a/cmake/linker/ld/clang/linker_flags.cmake +++ b/cmake/linker/ld/clang/linker_flags.cmake @@ -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) diff --git a/cmake/linker/ld/linker_flags.cmake b/cmake/linker/ld/linker_flags.cmake index 5660b410760..f7d7a17743a 100644 --- a/cmake/linker/ld/linker_flags.cmake +++ b/cmake/linker/ld/linker_flags.cmake @@ -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 diff --git a/cmake/linker/ld/target_base.cmake b/cmake/linker/ld/target_base.cmake index 8e7768476d4..c521d196c20 100644 --- a/cmake/linker/ld/target_base.cmake +++ b/cmake/linker/ld/target_base.cmake @@ -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() diff --git a/cmake/linker/ld/target_cpp.cmake b/cmake/linker/ld/target_cpp.cmake index a6601347172..f728a478342 100644 --- a/cmake/linker/ld/target_cpp.cmake +++ b/cmake/linker/ld/target_cpp.cmake @@ -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() diff --git a/cmake/linker/linker_flags_template.cmake b/cmake/linker/linker_flags_template.cmake index 2ef080d6216..39db87e6c7f 100644 --- a/cmake/linker/linker_flags_template.cmake +++ b/cmake/linker/linker_flags_template.cmake @@ -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) diff --git a/cmake/linker/lld/linker_flags.cmake b/cmake/linker/lld/linker_flags.cmake index 8ed5f7a65b9..9183f60eadb 100644 --- a/cmake/linker/lld/linker_flags.cmake +++ b/cmake/linker/lld/linker_flags.cmake @@ -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() diff --git a/cmake/linker/lld/target_base.cmake b/cmake/linker/lld/target_base.cmake index 1342867f993..c521d196c20 100644 --- a/cmake/linker/lld/target_base.cmake +++ b/cmake/linker/lld/target_base.cmake @@ -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() diff --git a/cmake/linker/lld/target_cpp.cmake b/cmake/linker/lld/target_cpp.cmake index 1004c0e6865..f728a478342 100644 --- a/cmake/linker/lld/target_cpp.cmake +++ b/cmake/linker/lld/target_cpp.cmake @@ -3,9 +3,4 @@ # See root CMakeLists.txt for description and expectations of these macros macro(toolchain_ld_cpp) - - zephyr_link_libraries( - -lc++ - ) - endmacro() diff --git a/cmake/linker/xt-ld/linker_flags.cmake b/cmake/linker/xt-ld/linker_flags.cmake index 040b10fe46f..b812ed5a1d8 100644 --- a/cmake/linker/xt-ld/linker_flags.cmake +++ b/cmake/linker/xt-ld/linker_flags.cmake @@ -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 +) diff --git a/cmake/linker/xt-ld/target_base.cmake b/cmake/linker/xt-ld/target_base.cmake index 6d486cbc86e..c521d196c20 100644 --- a/cmake/linker/xt-ld/target_base.cmake +++ b/cmake/linker/xt-ld/target_base.cmake @@ -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()