1# SPDX-License-Identifier: Apache-2.0 2set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start") 3 4find_package(GnuLd REQUIRED) 5set(CMAKE_LINKER ${GNULD_LINKER}) 6 7set_ifndef(LINKERFLAGPREFIX -Wl) 8 9if((${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd") OR 10 ${GNULD_LINKER_IS_BFD}) 11 # ld.bfd was found so let's explicitly use that for linking, see #32237 12 list(APPEND TOOLCHAIN_LD_FLAGS -fuse-ld=bfd) 13 list(APPEND CMAKE_REQUIRED_FLAGS -fuse-ld=bfd) 14 string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") 15endif() 16 17# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} 18# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time 19macro(configure_linker_script linker_script_gen linker_pass_define) 20 set(extra_dependencies ${ARGN}) 21 set(cmake_linker_script_settings 22 ${PROJECT_BINARY_DIR}/include/generated/ld_script_settings_${linker_pass_define}.cmake 23 ) 24 25 if(CONFIG_CMAKE_LINKER_GENERATOR) 26 27 zephyr_linker_generate_linker_settings_file(${cmake_linker_script_settings}) 28 29 add_custom_command( 30 OUTPUT ${linker_script_gen} 31 DEPENDS 32 ${extra_dependencies} 33 ${cmake_linker_script_settings} 34 ${DEVICE_API_LD_TARGET} 35 COMMAND ${CMAKE_COMMAND} 36 -C ${cmake_linker_script_settings} 37 -DPASS="${linker_pass_define}" 38 -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} 39 -P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake 40 ) 41 else() 42 set(template_script_defines ${linker_pass_define}) 43 list(TRANSFORM template_script_defines PREPEND "-D") 44 45 # Only Ninja and Makefile generators support DEPFILE. 46 if((CMAKE_GENERATOR STREQUAL "Ninja") 47 OR (CMAKE_GENERATOR MATCHES "Makefiles") 48 ) 49 set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep) 50 else() 51 # TODO: How would the linker script dependencies work for non-linker 52 # script generators. 53 message(STATUS "Warning; this generator is not well supported. The 54 Linker script may not be regenerated when it should.") 55 set(linker_script_dep "") 56 endif() 57 58 zephyr_get_include_directories_for_lang(C current_includes) 59 if(DEFINED SOC_LINKER_SCRIPT) 60 cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) 61 set(soc_linker_script_includes -I${soc_linker_script_includes}) 62 endif() 63 64 add_custom_command( 65 OUTPUT ${linker_script_gen} 66 DEPENDS 67 ${LINKER_SCRIPT} 68 ${AUTOCONF_H} 69 ${extra_dependencies} 70 # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS' 71 ${linker_script_dep} 72 COMMAND ${CMAKE_C_COMPILER} 73 -x assembler-with-cpp 74 ${NOSYSDEF_CFLAG} 75 -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen} 76 -D_LINKER 77 -D_ASMLANGUAGE 78 -D__GCC_LINKER_CMD__ 79 -imacros ${AUTOCONF_H} 80 ${current_includes} 81 ${soc_linker_script_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 ${TOPT} 124 ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} 125 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} 126 127 ${LINKERFLAGPREFIX},-Map,${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} 128 ${LINKERFLAGPREFIX},--whole-archive 129 ${WHOLE_ARCHIVE_LIBS} 130 ${LINKERFLAGPREFIX},--no-whole-archive 131 ${NO_WHOLE_ARCHIVE_LIBS} 132 $<TARGET_OBJECTS:${OFFSETS_LIB}> 133 -L${PROJECT_BINARY_DIR} 134 135 ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} 136 ) 137endfunction(toolchain_ld_link_elf) 138 139# Function for finalizing link setup after Zephyr configuration has completed. 140# 141# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE 142# rule to ensure that standard c and runtime libraries are correctly placed 143# and the end of link invocation and doesn't appear in the middle of the link 144# command invocation. 145macro(toolchain_linker_finalize) 146 get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir) 147 get_property(link_order TARGET linker PROPERTY link_order_library) 148 foreach(lib ${link_order}) 149 get_property(link_flag TARGET linker PROPERTY ${lib}_library) 150 list(APPEND zephyr_std_libs "${link_flag}") 151 endforeach() 152 string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") 153 154 set(link_libraries "<OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${zephyr_std_libs}") 155 set(common_link "<LINK_FLAGS> ${link_libraries}") 156 157 set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <FLAGS> <CMAKE_ASM_LINK_FLAGS> ${common_link}") 158 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> ${common_link}") 159 160 set(cpp_link "${common_link}") 161 if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host") 162 compiler_file_path(crtbegin.o CRTBEGIN_PATH) 163 compiler_file_path(crtend.o CRTEND_PATH) 164 if(CONFIG_CPP_EXCEPTIONS AND CRTBEGIN_PATH AND CRTEND_PATH) 165 # When building with C++ Exceptions, it is important that crtbegin and crtend 166 # are linked at specific locations. 167 set(cpp_link "<LINK_FLAGS> ${CRTBEGIN_PATH} ${link_libraries} ${CRTEND_PATH}") 168 endif() 169 endif() 170 set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> ${cpp_link}") 171endmacro() 172 173# Function to map compiler flags into suitable linker flags 174# When using the compiler driver to run the linker, just pass 175# them all through 176 177function(toolchain_linker_add_compiler_options) 178 add_link_options(${ARGV}) 179endfunction() 180 181# Load toolchain_ld-family macros 182include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake) 183include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake) 184