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 file(GENERATE OUTPUT ${cmake_linker_script_settings} CONTENT 27 "set(FORMAT \"$<TARGET_PROPERTY:linker,FORMAT>\" CACHE INTERNAL \"\")\n 28 set(ENTRY \"$<TARGET_PROPERTY:linker,ENTRY>\" CACHE INTERNAL \"\")\n 29 set(MEMORY_REGIONS \"$<TARGET_PROPERTY:linker,MEMORY_REGIONS>\" CACHE INTERNAL \"\")\n 30 set(GROUPS \"$<TARGET_PROPERTY:linker,GROUPS>\" CACHE INTERNAL \"\")\n 31 set(SECTIONS \"$<TARGET_PROPERTY:linker,SECTIONS>\" CACHE INTERNAL \"\")\n 32 set(SECTION_SETTINGS \"$<TARGET_PROPERTY:linker,SECTION_SETTINGS>\" CACHE INTERNAL \"\")\n 33 set(SYMBOLS \"$<TARGET_PROPERTY:linker,SYMBOLS>\" CACHE INTERNAL \"\")\n 34 " 35 ) 36 add_custom_command( 37 OUTPUT ${linker_script_gen} 38 COMMAND ${CMAKE_COMMAND} 39 -C ${DEVICE_API_LINKER_SECTIONS_CMAKE} 40 -C ${cmake_linker_script_settings} 41 -DPASS="${linker_pass_define}" 42 -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} 43 -P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake 44 DEPENDS ${DEVICE_API_LD_TARGET} 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 if(DEFINED SOC_LINKER_SCRIPT) 65 cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) 66 set(soc_linker_script_includes -I${soc_linker_script_includes}) 67 endif() 68 69 add_custom_command( 70 OUTPUT ${linker_script_gen} 71 DEPENDS 72 ${LINKER_SCRIPT} 73 ${AUTOCONF_H} 74 ${extra_dependencies} 75 # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS' 76 ${linker_script_dep} 77 COMMAND ${CMAKE_C_COMPILER} 78 -x assembler-with-cpp 79 ${NOSYSDEF_CFLAG} 80 -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen} 81 -D_LINKER 82 -D_ASMLANGUAGE 83 -D__GCC_LINKER_CMD__ 84 -imacros ${AUTOCONF_H} 85 ${current_includes} 86 ${soc_linker_script_includes} 87 ${template_script_defines} 88 -E ${LINKER_SCRIPT} 89 -P # Prevent generation of debug `#line' directives. 90 -o ${linker_script_gen} 91 VERBATIM 92 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 93 COMMAND_EXPAND_LISTS 94 ) 95 endif() 96endmacro() 97 98# Force symbols to be entered in the output file as undefined symbols 99function(toolchain_ld_force_undefined_symbols) 100 foreach(symbol ${ARGN}) 101 zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol}) 102 endforeach() 103endfunction() 104 105# Link a target to given libraries with toolchain-specific argument order 106# 107# Usage: 108# toolchain_ld_link_elf( 109# TARGET_ELF <target_elf> 110# OUTPUT_MAP <output_map_file_of_target> 111# LIBRARIES_PRE_SCRIPT [libraries_pre_script] 112# LINKER_SCRIPT <linker_script> 113# LIBRARIES_POST_SCRIPT [libraries_post_script] 114# DEPENDENCIES [dependencies] 115# ) 116function(toolchain_ld_link_elf) 117 cmake_parse_arguments( 118 TOOLCHAIN_LD_LINK_ELF # prefix of output variables 119 "" # list of names of the boolean arguments 120 "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments 121 "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments 122 ${ARGN} # input args to parse 123 ) 124 125 target_link_libraries( 126 ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} 127 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} 128 ${TOPT} 129 ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} 130 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} 131 132 ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} 133 ${LINKERFLAGPREFIX},--whole-archive 134 ${WHOLE_ARCHIVE_LIBS} 135 ${LINKERFLAGPREFIX},--no-whole-archive 136 ${NO_WHOLE_ARCHIVE_LIBS} 137 $<TARGET_OBJECTS:${OFFSETS_LIB}> 138 -L${PROJECT_BINARY_DIR} 139 140 ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} 141 ) 142endfunction(toolchain_ld_link_elf) 143 144# Function for finalizing link setup after Zephyr configuration has completed. 145# 146# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE 147# rule to ensure that standard c and runtime libraries are correctly placed 148# and the end of link invocation and doesn't appear in the middle of the link 149# command invocation. 150macro(toolchain_linker_finalize) 151 get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir) 152 get_property(link_order TARGET linker PROPERTY link_order_library) 153 foreach(lib ${link_order}) 154 get_property(link_flag TARGET linker PROPERTY ${lib}_library) 155 list(APPEND zephyr_std_libs "${link_flag}") 156 endforeach() 157 string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") 158 159 set(link_libraries "<OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${zephyr_std_libs}") 160 set(common_link "<LINK_FLAGS> ${link_libraries}") 161 162 set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <FLAGS> <CMAKE_ASM_LINK_FLAGS> ${common_link}") 163 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> ${common_link}") 164 165 set(cpp_link "${common_link}") 166 if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host") 167 if(CONFIG_CPP_EXCEPTIONS AND LIBGCC_DIR) 168 # When building with C++ Exceptions, it is important that crtbegin and crtend 169 # are linked at specific locations. 170 set(cpp_link "<LINK_FLAGS> ${LIBGCC_DIR}/crtbegin.o ${link_libraries} ${LIBGCC_DIR}/crtend.o") 171 endif() 172 endif() 173 set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> ${cpp_link}") 174endmacro() 175 176# Load toolchain_ld-family macros 177include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake) 178include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake) 179