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>
224 lines
8 KiB
CMake
224 lines
8 KiB
CMake
# SPDX-License-Identifier: Apache-2.0
|
|
set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start")
|
|
|
|
find_program(CMAKE_LINKER ${CROSS_COMPILE}lldac PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
|
|
|
# the prefix to transfer linker options from compiler
|
|
set_ifndef(LINKERFLAGPREFIX -Wl,)
|
|
|
|
# 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})
|
|
set(template_script_defines ${linker_pass_define})
|
|
list(TRANSFORM template_script_defines PREPEND "-D")
|
|
|
|
# Different generators deal with depfiles differently.
|
|
if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
|
|
# Note that the IMPLICIT_DEPENDS option is currently supported only
|
|
# for Makefile generators and will be ignored by other generators.
|
|
set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
|
|
elseif(CMAKE_GENERATOR STREQUAL "Ninja")
|
|
# Using DEPFILE with other generators than Ninja is an error.
|
|
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)
|
|
|
|
# the command to generate linker file from template
|
|
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 c
|
|
${NOSYSDEF_CFLAG}
|
|
-Hnocopyr
|
|
-MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen}
|
|
-D_LINKER
|
|
-D_ASMLANGUAGE
|
|
-D__MWDT_LINKER_CMD__
|
|
-imacros ${AUTOCONF_H}
|
|
${current_includes}
|
|
${template_script_defines}
|
|
${LINKER_SCRIPT}
|
|
-E
|
|
-o ${linker_script_gen}
|
|
VERBATIM
|
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
|
COMMAND_EXPAND_LISTS
|
|
)
|
|
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}
|
|
${LINKERFLAGPREFIX}-T${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
|
|
${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
|
|
${LINKERFLAGPREFIX}--gc-sections
|
|
${LINKERFLAGPREFIX}--entry=__start
|
|
${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)
|
|
|
|
# linker options of temporary linkage for code generation
|
|
macro(toolchain_ld_baremetal)
|
|
zephyr_ld_options(
|
|
-Hlld
|
|
-Hnosdata
|
|
-Xtimer0 # to suppress the warning message
|
|
-Hnoxcheck_obj
|
|
-Hnocplus
|
|
-Hhostlib=
|
|
-Hheap=0
|
|
-Hnoivt
|
|
-Hnocrt
|
|
)
|
|
|
|
# There are two options:
|
|
# - We have full MWDT libc support and we link MWDT libc - this is default
|
|
# behavior and we don't need to do something for that.
|
|
# - We use minimal libc provided by Zephyr itself. In that case we must not
|
|
# link MWDT libc, but we still need to link libmw
|
|
if(CONFIG_MINIMAL_LIBC)
|
|
zephyr_ld_options(
|
|
-Hnolib
|
|
-Hldopt=-lmw
|
|
)
|
|
endif()
|
|
|
|
# Funny thing is if this is set to =error, some architectures will
|
|
# skip this flag even though the compiler flag check passes
|
|
# (e.g. ARC and Xtensa). So warning should be the default for now.
|
|
#
|
|
# Skip this for native application as Zephyr only provides
|
|
# additions to the host toolchain linker script. The relocation
|
|
# sections (.rel*) requires us to override those provided
|
|
# by host toolchain. As we can't account for all possible
|
|
# combination of compiler and linker on all machines used
|
|
# for development, it is better to turn this off.
|
|
#
|
|
# CONFIG_LINKER_ORPHAN_SECTION_PLACE is to place the orphan sections
|
|
# without any warnings or errors, which is the default behavior.
|
|
# So there is no need to explicitly set a linker flag.
|
|
if(CONFIG_LINKER_ORPHAN_SECTION_WARN)
|
|
message(WARNING "MWDT toolchain does not support
|
|
CONFIG_LINKER_ORPHAN_SECTION_WARN")
|
|
elseif(CONFIG_LINKER_ORPHAN_SECTION_ERROR)
|
|
zephyr_ld_options(
|
|
${LINKERFLAGPREFIX}--orphan-handling=error)
|
|
endif()
|
|
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
|
|
macro(toolchain_ld_configure_files)
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/zephyr/arch/common/app_data_alignment.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld)
|
|
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_smem.ld)
|
|
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_aligned.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld)
|
|
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_unaligned.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld)
|
|
endmacro()
|
|
|
|
# link C++ libraries
|
|
macro(toolchain_ld_cpp)
|
|
zephyr_link_libraries(
|
|
-Hcplus
|
|
)
|
|
endmacro()
|
|
|
|
# use linker for relocation
|
|
macro(toolchain_ld_relocation)
|
|
set(MEM_RELOCATION_LD "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld")
|
|
set(MEM_RELOCATION_SRAM_DATA_LD
|
|
"${PROJECT_BINARY_DIR}/include/generated/linker_sram_data_relocate.ld")
|
|
set(MEM_RELOCATION_SRAM_BSS_LD
|
|
"${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld")
|
|
set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c")
|
|
|
|
add_custom_command(
|
|
OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD}
|
|
COMMAND
|
|
${PYTHON_EXECUTABLE}
|
|
${ZEPHYR_BASE}/scripts/build/gen_relocate_app.py
|
|
$<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
|
|
-d ${APPLICATION_BINARY_DIR}
|
|
-i \"$<TARGET_PROPERTY:code_data_relocation_target,COMPILE_DEFINITIONS>\"
|
|
-o ${MEM_RELOCATION_LD}
|
|
-s ${MEM_RELOCATION_SRAM_DATA_LD}
|
|
-b ${MEM_RELOCATION_SRAM_BSS_LD}
|
|
-c ${MEM_RELOCATION_CODE}
|
|
DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY}
|
|
)
|
|
|
|
add_library(code_relocation_source_lib STATIC ${MEM_RELOCATION_CODE})
|
|
target_include_directories(code_relocation_source_lib PRIVATE
|
|
${ZEPHYR_BASE}/kernel/include ${ARCH_DIR}/${ARCH}/include)
|
|
target_link_libraries(code_relocation_source_lib zephyr_interface)
|
|
endmacro()
|