You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
5.6 KiB
150 lines
5.6 KiB
# SPDX-License-Identifier: Apache-2.0 |
|
set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start") |
|
|
|
find_package(GnuLd REQUIRED) |
|
set(CMAKE_LINKER ${GNULD_LINKER}) |
|
|
|
set_ifndef(LINKERFLAGPREFIX -Wl) |
|
|
|
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 |
|
# 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() |
|
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) |
|
if(DEFINED SOC_LINKER_SCRIPT) |
|
cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) |
|
set(soc_linker_script_includes -I${soc_linker_script_includes}) |
|
endif() |
|
|
|
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} |
|
${soc_linker_script_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 |
|
) |
|
|
|
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} |
|
|
|
${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) |
|
|
|
# Load toolchain_ld-family macros |
|
include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake) |
|
include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake)
|
|
|