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()