cmake: linker: Use the same linker for cmake checks and final build
Currently, the linker that is used when performing various cmake checks (check_c_compiler_flag, for example) may be different than the linker that will be used during the actual build. This happens as we currently specify '-fuse-ld' to force the appropriate linker a) after many such checks have already happened and b) in a way which is not automatically propagated to check_c_compiler_flag (and friends). As a result, the toolchain's default linker will generally be used for such checks regardless of which linker was selected in Zephyr. This can lead to a number of surprises when building Zephyr, particularly when building with clang. For example: - If the linker is misconfigured, where the build will fail can vary depending on whether the linker is the toolchain's default. When the configured linker happens to be the toolchain's default, the build (helpfully) fails quickly on the checks for a basic working toochain. When the configured linker isn't the default, the build won't fail until the final link steps. - The build can fail due to issues with a linker other than the one configured by the user in Zephyr. For example, LLVM toolchains without lld will generally fail to build Zephyr (the checks for a basic working toochain will fail) for targets where lld is the default in LLVM even if GNU ld is configured in Zephyr and would otherwise be used in the final build. - Flags which are only added if check_c_compiler_flag (or similar) succeeds may be unexpectedly omitted during the final build if the flag is supported in the configured linker but is unsupported in the toolchain's default linker (as check_c_compiler_flag will test using the default one). Note that this isn't limited to clang--even when we are building with Zephyr's SDK and force ld.bfd, we seem to use the 'ld' variant during the cmake checks (though this generally seems fairly harmless compared to mixing ld/lld or other proprietary linkers). To fix this, ensure the appropriate 'fuse-ld' is set early enough and in such a way that the same linker will be used throughout the entire build. Signed-off-by: Jonathon Penix <jpenix@quicinc.com> Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
parent
dc97bbd35f
commit
9fe6c5e3fb
2 changed files with 12 additions and 7 deletions
|
@ -6,6 +6,14 @@ set(CMAKE_LINKER ${GNULD_LINKER})
|
|||
|
||||
set_ifndef(LINKERFLAGPREFIX -Wl)
|
||||
|
||||
if((${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd") OR
|
||||
${GNULD_LINKER_IS_BFD})
|
||||
# ld.bfd was found so let's explicitly use that for linking, see #32237
|
||||
list(APPEND TOOLCHAIN_LD_FLAGS -fuse-ld=bfd)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -fuse-ld=bfd)
|
||||
string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host")
|
||||
if(CONFIG_CPP_EXCEPTIONS AND LIBGCC_DIR)
|
||||
# When building with C++ Exceptions, it is important that crtbegin and crtend
|
||||
|
@ -117,16 +125,9 @@ function(toolchain_ld_link_elf)
|
|||
${ARGN} # input args to parse
|
||||
)
|
||||
|
||||
if((${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd") OR
|
||||
${GNULD_LINKER_IS_BFD})
|
||||
# ld.bfd was found so let's explicitly use that for linking, see #32237
|
||||
set(use_linker "-fuse-ld=bfd")
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
|
||||
${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
|
||||
${use_linker}
|
||||
${TOPT}
|
||||
${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
|
||||
${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
|
||||
|
|
|
@ -6,6 +6,10 @@ set(CMAKE_LINKER ${LLVMLLD_LINKER})
|
|||
|
||||
set_ifndef(LINKERFLAGPREFIX -Wl)
|
||||
|
||||
list(APPEND TOOLCHAIN_LD_FLAGS -fuse-ld=lld)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -fuse-ld=lld)
|
||||
string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
|
||||
# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
|
||||
# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time
|
||||
macro(configure_linker_script linker_script_gen linker_pass_define)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue