The support of PROPERTY_LINKER_SCRIPT_DEFINES has been broken since
the transition to CMake in 12f8f76165
.
The intention was probably to allow users / projects to adjust
PROPERTY_LINKER_SCRIPT_DEFINES by setting a CMake cache variable.
The implementation tests for the CMake variable (local scope or cache)
PROPERTY_LINKER_SCRIPT_DEFINES, but it never uses such CMake variable.
Instead it uses a CMake global property named
PROPERTY_LINKER_SCRIPT_DEFINES. CMake variables and CMake global
properties are two very different things, and therefore the current
implementation has never worked. The fact that no one has never noticed
this flaw, means that the feature has never been used as intended.
Simplify the code by removing the use of the global CMake property and
instead set the value of the property on the linker script
pre-processing invocation.
Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
146 lines
5.5 KiB
CMake
146 lines
5.5 KiB
CMake
# SPDX-License-Identifier: Apache-2.0
|
|
set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start")
|
|
|
|
if(DEFINED TOOLCHAIN_HOME)
|
|
# When Toolchain home is defined, then we are cross-compiling, so only look
|
|
# for linker in that path, else we are using host tools.
|
|
set(LD_SEARCH_PATH PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
|
endif()
|
|
|
|
find_program(CMAKE_LINKER xt-ld ${LD_SEARCH_PATH})
|
|
|
|
set_ifndef(LINKERFLAGPREFIX -Wl)
|
|
|
|
if(CONFIG_CPP_EXCEPTIONS)
|
|
# When building with C++ Exceptions, it is important that crtbegin and crtend
|
|
# are linked at specific locations.
|
|
# The location is so important that we cannot let this be controlled by normal
|
|
# link libraries, instead we must control the link command specifically as
|
|
# part of toolchain.
|
|
set(CMAKE_CXX_LINK_EXECUTABLE
|
|
"<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${LIBGCC_DIR}/crtbegin.o <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${LIBGCC_DIR}/crtend.o")
|
|
endif()
|
|
|
|
# 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)
|
|
set(extra_dependencies ${ARGN})
|
|
|
|
if(CONFIG_CMAKE_LINKER_GENERATOR)
|
|
add_custom_command(
|
|
OUTPUT ${linker_script_gen}
|
|
COMMAND ${CMAKE_COMMAND}
|
|
-DPASS="${linker_pass_define}"
|
|
-DFORMAT="$<TARGET_PROPERTY:linker,FORMAT>"
|
|
-DENTRY="$<TARGET_PROPERTY:linker,ENTRY>"
|
|
-DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>"
|
|
-DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>"
|
|
-DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>"
|
|
-DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>"
|
|
-DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>"
|
|
-DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
|
|
-P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake
|
|
)
|
|
else()
|
|
set(template_script_defines ${linker_pass_define})
|
|
list(TRANSFORM template_script_defines PREPEND "-D")
|
|
|
|
# Only Ninja and Makefile generators support DEPFILE.
|
|
if((CMAKE_GENERATOR STREQUAL "Ninja")
|
|
OR (CMAKE_GENERATOR MATCHES "Makefiles")
|
|
)
|
|
set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
|
|
else()
|
|
# TODO: How would the linker script dependencies work for non-linker
|
|
# script generators.
|
|
message(STATUS "Warning; this generator is not well supported. The
|
|
Linker script may not be regenerated when it should.")
|
|
set(linker_script_dep "")
|
|
endif()
|
|
|
|
zephyr_get_include_directories_for_lang(C current_includes)
|
|
|
|
add_custom_command(
|
|
OUTPUT ${linker_script_gen}
|
|
DEPENDS
|
|
${LINKER_SCRIPT}
|
|
${AUTOCONF_H}
|
|
${extra_dependencies}
|
|
# NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
|
|
${linker_script_dep}
|
|
COMMAND ${CMAKE_C_COMPILER}
|
|
-x assembler-with-cpp
|
|
${NOSYSDEF_CFLAG}
|
|
-MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen}
|
|
-D_LINKER
|
|
-D_ASMLANGUAGE
|
|
-D__GCC_LINKER_CMD__
|
|
-imacros ${AUTOCONF_H}
|
|
${current_includes}
|
|
${template_script_defines}
|
|
-E ${LINKER_SCRIPT}
|
|
-P # Prevent generation of debug `#line' directives.
|
|
-o ${linker_script_gen}
|
|
VERBATIM
|
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
|
COMMAND_EXPAND_LISTS
|
|
)
|
|
endif()
|
|
endmacro()
|
|
|
|
# Force symbols to be entered in the output file as undefined symbols
|
|
function(toolchain_ld_force_undefined_symbols)
|
|
foreach(symbol ${ARGN})
|
|
zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol})
|
|
endforeach()
|
|
endfunction()
|
|
|
|
# Link a target to given libraries with toolchain-specific argument order
|
|
#
|
|
# Usage:
|
|
# toolchain_ld_link_elf(
|
|
# TARGET_ELF <target_elf>
|
|
# OUTPUT_MAP <output_map_file_of_target>
|
|
# LIBRARIES_PRE_SCRIPT [libraries_pre_script]
|
|
# LINKER_SCRIPT <linker_script>
|
|
# LIBRARIES_POST_SCRIPT [libraries_post_script]
|
|
# DEPENDENCIES [dependencies]
|
|
# )
|
|
function(toolchain_ld_link_elf)
|
|
cmake_parse_arguments(
|
|
TOOLCHAIN_LD_LINK_ELF # prefix of output variables
|
|
"" # list of names of the boolean arguments
|
|
"TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments
|
|
"LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
|
|
${ARGN} # input args to parse
|
|
)
|
|
|
|
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}
|
|
|
|
${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
|
|
${LINKERFLAGPREFIX},--whole-archive
|
|
${WHOLE_ARCHIVE_LIBS}
|
|
${LINKERFLAGPREFIX},--no-whole-archive
|
|
${NO_WHOLE_ARCHIVE_LIBS}
|
|
$<TARGET_OBJECTS:${OFFSETS_LIB}>
|
|
${LIB_INCLUDE_DIR}
|
|
-L${PROJECT_BINARY_DIR}
|
|
${TOOLCHAIN_LIBS}
|
|
|
|
${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
|
|
)
|
|
endfunction(toolchain_ld_link_elf)
|
|
|
|
# xt-ld is Xtensa's own version of binutils' ld.
|
|
# So we can reuse most of the ld configurations.
|
|
include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake)
|
|
include(${ZEPHYR_BASE}/cmake/linker/ld/target_baremetal.cmake)
|
|
include(${ZEPHYR_BASE}/cmake/linker/ld/target_cpp.cmake)
|
|
include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake)
|
|
include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake)
|