2d78cb74bd
This changes to cache variable GNULD_VERSION_STRING across cmake runs. This variable is used to determine whether -Wl,-no-pie is being passed to linker. However, if cmake is run multiple times without clearing the build directory, GNULD_VERSION_STRING was lost and the script falsely assumed the linker could not take this argument, and thus omitting it during linking. Depending on the host, it would warn on something like this: /usr/bin/ld.bfd: app/libapp.a(main.c.obj): warning: relocation in read-only section `.text._posix_zephyr_main' /usr/bin/ld.bfd: warning: creating DT_TEXTREL in a PIE To fix this, simply caches GNULD_VERSION_STRING so it can be used during subsequent cmake runs. Fixes #61725 Signed-off-by: Daniel Leung <daniel.leung@intel.com>
100 lines
3.2 KiB
CMake
100 lines
3.2 KiB
CMake
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Copyright (c) 2022, Nordic Semiconductor ASA
|
|
# Copyright (c) 2023, Intel Corporation
|
|
|
|
# FindGnuLd module for locating GNU ld (linker from binutils).
|
|
#
|
|
# The module defines the following variables:
|
|
#
|
|
# 'GNULD_LINKER'
|
|
# Path to GNU ld linker
|
|
# Set to 'GNULD_LINKER-NOTFOUND' if ld was not found.
|
|
#
|
|
# 'GnuLd_FOUND', 'GNULD_FOUND'
|
|
# True if GNU ld was found.
|
|
#
|
|
# 'GNULD_VERSION_STRING'
|
|
# The version of GNU ld.
|
|
#
|
|
# 'GNULD_LINKER_IS_BFD'
|
|
# True if linker is ld.bfd (or compatible)
|
|
#
|
|
# Note that this will use CROSS_COMPILE, if defined,
|
|
# as a prefix to the linker executable.
|
|
|
|
include(FindPackageHandleStandardArgs)
|
|
|
|
# GNULD_LINKER exists on repeated builds or defined manually...
|
|
if(EXISTS "${GNULD_LINKER}")
|
|
if(NOT DEFINED GNULD_LINKER_IS_BFD)
|
|
# ... issue warning if GNULD_LINKER_IS_BFD is not already set.
|
|
message(
|
|
WARNING
|
|
"GNULD_LINKER specified directly in cache, but GNULD_LINKER_IS_BFD is not "
|
|
"defined. Assuming GNULD_LINKER_IS_BFD as OFF, please set GNULD_LINKER_IS_BFD "
|
|
"to correct value in cache to silence this warning"
|
|
)
|
|
set(GNULD_LINKER_IS_BFD OFF)
|
|
endif()
|
|
|
|
# Since GNULD_LINKER already exists, there is no need to find it again (below).
|
|
return()
|
|
endif()
|
|
|
|
# See if the compiler has a preferred linker
|
|
execute_process(COMMAND ${CMAKE_C_COMPILER} --print-prog-name=ld.bfd
|
|
OUTPUT_VARIABLE GNULD_LINKER
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
|
|
if(EXISTS "${GNULD_LINKER}")
|
|
set(GNULD_LINKER_IS_BFD ON CACHE BOOL "Linker BFD compatibility (compiler reported)" FORCE)
|
|
else()
|
|
# Need to clear it or else find_program() won't replace the value.
|
|
set(GNULD_LINKER)
|
|
|
|
if(DEFINED TOOLCHAIN_HOME)
|
|
# Search for linker under TOOLCHAIN_HOME if it is defined
|
|
# to limit which linker to use, or else we would be using
|
|
# host tools.
|
|
set(LD_SEARCH_PATH PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
|
endif()
|
|
|
|
find_program(GNULD_LINKER ${CROSS_COMPILE}ld.bfd ${LD_SEARCH_PATH})
|
|
if(GNULD_LINKER)
|
|
set(GNULD_LINKER_IS_BFD ON CACHE BOOL "Linker BFD compatibility (inferred from binary)" FORCE)
|
|
else()
|
|
find_program(GNULD_LINKER ${CROSS_COMPILE}ld ${LD_SEARCH_PATH})
|
|
set(GNULD_LINKER_IS_BFD OFF CACHE BOOL "Linker BFD compatibility (inferred from binary)" FORCE)
|
|
endif()
|
|
endif()
|
|
|
|
if(GNULD_LINKER)
|
|
# Parse the 'ld.bfd --version' output to find the installed version.
|
|
execute_process(
|
|
COMMAND
|
|
${GNULD_LINKER} --version
|
|
OUTPUT_VARIABLE gnuld_version_output
|
|
ERROR_VARIABLE gnuld_error_output
|
|
RESULT_VARIABLE gnuld_status
|
|
)
|
|
|
|
if(${gnuld_status} EQUAL 0)
|
|
# Extract GNU ld version. Different distros have their
|
|
# own version scheme so we need to account for that.
|
|
# Examples:
|
|
# - "GNU ld (GNU Binutils for Ubuntu) 2.34"
|
|
# - "GNU ld (Zephyr SDK 0.15.2) 2.38"
|
|
# - "GNU ld (Gentoo 2.39 p5) 2.39.0"
|
|
string(REGEX MATCH
|
|
"GNU ld \\(.+\\) ([0-9]+[.][0-9]+[.]?[0-9]*).*"
|
|
out_var ${gnuld_version_output})
|
|
set(GNULD_VERSION_STRING ${CMAKE_MATCH_1} CACHE STRING "GNU ld version" FORCE)
|
|
endif()
|
|
endif()
|
|
|
|
find_package_handle_standard_args(GnuLd
|
|
REQUIRED_VARS GNULD_LINKER
|
|
VERSION_VAR GNULD_VERSION_STRING
|
|
)
|