1# SPDX-License-Identifier: Apache-2.0 2set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start") 3 4if(DEFINED TOOLCHAIN_HOME) 5 # When Toolchain home is defined, then we are cross-compiling, so only look 6 # for linker in that path, else we are using host tools. 7 set(LD_SEARCH_PATH PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) 8endif() 9 10find_program(CMAKE_LINKER xt-ld ${LD_SEARCH_PATH}) 11 12set_ifndef(LINKERFLAGPREFIX -Wl) 13 14compiler_file_path(crtbegin.o CRTBEGIN_PATH) 15compiler_file_path(crtend.o CRTEND_PATH) 16if(CONFIG_CPP_EXCEPTIONS AND CRTBEGIN_PATH AND CRTEND_PATH) 17 # When building with C++ Exceptions, it is important that crtbegin and crtend 18 # are linked at specific locations. 19 # The location is so important that we cannot let this be controlled by normal 20 # link libraries, instead we must control the link command specifically as 21 # part of toolchain. 22 set(CMAKE_CXX_LINK_EXECUTABLE 23 "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${CRTBEGIN_PATH} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${CRTEND_PATH}") 24endif() 25 26# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} 27# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time 28macro(configure_linker_script linker_script_gen linker_pass_define) 29 set(extra_dependencies ${ARGN}) 30 31 if(CONFIG_CMAKE_LINKER_GENERATOR) 32 add_custom_command( 33 OUTPUT ${linker_script_gen} 34 COMMAND ${CMAKE_COMMAND} 35 -DPASS="${linker_pass_define}" 36 -DFORMAT="$<TARGET_PROPERTY:linker,FORMAT>" 37 -DENTRY="$<TARGET_PROPERTY:linker,ENTRY>" 38 -DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>" 39 -DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>" 40 -DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>" 41 -DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>" 42 -DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>" 43 -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} 44 -P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake 45 ) 46 else() 47 set(template_script_defines ${linker_pass_define}) 48 list(TRANSFORM template_script_defines PREPEND "-D") 49 50 # Only Ninja and Makefile generators support DEPFILE. 51 if((CMAKE_GENERATOR STREQUAL "Ninja") 52 OR (CMAKE_GENERATOR MATCHES "Makefiles") 53 ) 54 set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep) 55 else() 56 # TODO: How would the linker script dependencies work for non-linker 57 # script generators. 58 message(STATUS "Warning; this generator is not well supported. The 59 Linker script may not be regenerated when it should.") 60 set(linker_script_dep "") 61 endif() 62 63 zephyr_get_include_directories_for_lang(C current_includes) 64 65 add_custom_command( 66 OUTPUT ${linker_script_gen} 67 DEPENDS 68 ${LINKER_SCRIPT} 69 ${AUTOCONF_H} 70 ${extra_dependencies} 71 # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS' 72 ${linker_script_dep} 73 COMMAND ${CMAKE_C_COMPILER} 74 -x assembler-with-cpp 75 ${NOSYSDEF_CFLAG} 76 -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen} 77 -D_LINKER 78 -D_ASMLANGUAGE 79 -D__GCC_LINKER_CMD__ 80 -imacros ${AUTOCONF_H} 81 ${current_includes} 82 ${template_script_defines} 83 -E ${LINKER_SCRIPT} 84 -P # Prevent generation of debug `#line' directives. 85 -o ${linker_script_gen} 86 VERBATIM 87 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 88 COMMAND_EXPAND_LISTS 89 ) 90 endif() 91endmacro() 92 93# Force symbols to be entered in the output file as undefined symbols 94function(toolchain_ld_force_undefined_symbols) 95 foreach(symbol ${ARGN}) 96 zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol}) 97 endforeach() 98endfunction() 99 100# Link a target to given libraries with toolchain-specific argument order 101# 102# Usage: 103# toolchain_ld_link_elf( 104# TARGET_ELF <target_elf> 105# OUTPUT_MAP <output_map_file_of_target> 106# LIBRARIES_PRE_SCRIPT [libraries_pre_script] 107# LINKER_SCRIPT <linker_script> 108# LIBRARIES_POST_SCRIPT [libraries_post_script] 109# DEPENDENCIES [dependencies] 110# ) 111function(toolchain_ld_link_elf) 112 cmake_parse_arguments( 113 TOOLCHAIN_LD_LINK_ELF # prefix of output variables 114 "" # list of names of the boolean arguments 115 "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments 116 "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments 117 ${ARGN} # input args to parse 118 ) 119 120 target_link_libraries( 121 ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} 122 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} 123 ${use_linker} 124 ${TOPT} 125 ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} 126 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} 127 128 ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} 129 ${LINKERFLAGPREFIX},--whole-archive 130 ${WHOLE_ARCHIVE_LIBS} 131 ${LINKERFLAGPREFIX},--no-whole-archive 132 ${NO_WHOLE_ARCHIVE_LIBS} 133 $<TARGET_OBJECTS:${OFFSETS_LIB}> 134 -L${PROJECT_BINARY_DIR} 135 136 ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} 137 ) 138endfunction(toolchain_ld_link_elf) 139 140# Function for finalizing link setup after Zephyr configuration has completed. 141# 142# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE 143# rule to ensure that standard c and runtime libraries are correctly placed 144# and the end of link invocation and doesn't appear in the middle of the link 145# command invocation. 146macro(toolchain_linker_finalize) 147 get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir) 148 get_property(link_order TARGET linker PROPERTY link_order_library) 149 foreach(lib ${link_order}) 150 get_property(link_flag TARGET linker PROPERTY ${lib}_library) 151 list(APPEND zephyr_std_libs "${link_flag}") 152 endforeach() 153 string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") 154 155 set(common_link "<LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${zephyr_std_libs}") 156 set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <FLAGS> <CMAKE_ASM_LINK_FLAGS> ${common_link}") 157 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> ${common_link}") 158 set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> ${common_link}") 159endmacro() 160 161# Function to map compiler flags into suitable linker flags 162# When using the compiler driver to run the linker, just pass 163# them all through 164 165function(toolchain_linker_add_compiler_options) 166 add_link_options(${ARGV}) 167endfunction() 168 169# xt-ld is Xtensa's own version of binutils' ld. 170# So we can reuse most of the ld configurations. 171include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake) 172include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake) 173