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