1# SPDX-License-Identifier: Apache-2.0 2set_property(TARGET linker PROPERTY devices_start_symbol "__device_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 ${CROSS_COMPILE}ld.bfd ${LD_SEARCH_PATH}) 11if(NOT CMAKE_LINKER) 12 find_program(CMAKE_LINKER ${CROSS_COMPILE}ld ${LD_SEARCH_PATH}) 13endif() 14 15set_ifndef(LINKERFLAGPREFIX -Wl) 16 17if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host") 18 if(CONFIG_EXCEPTIONS) 19 # When building with C++ Exceptions, it is important that crtbegin and crtend 20 # are linked at specific locations. 21 # The location is so important that we cannot let this be controlled by normal 22 # link libraries, instead we must control the link command specifically as 23 # part of toolchain. 24 set(CMAKE_CXX_LINK_EXECUTABLE 25 "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${LIBGCC_DIR}/crtbegin.o <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${LIBGCC_DIR}/crtend.o") 26 endif() 27endif() 28 29# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} 30# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time 31macro(configure_linker_script linker_script_gen linker_pass_define) 32 set(extra_dependencies ${ARGN}) 33 34 if(CONFIG_CMAKE_LINKER_GENERATOR) 35 if("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_PREBUILT") 36 set(PASS 1) 37 elseif("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_FINAL;-DLINKER_PASS2") 38 set(PASS 2) 39 endif() 40 41 add_custom_command( 42 OUTPUT ${linker_script_gen} 43 COMMAND ${CMAKE_COMMAND} 44 -DPASS=${PASS} 45 -DFORMAT="$<TARGET_PROPERTY:linker,FORMAT>" 46 -DENTRY="$<TARGET_PROPERTY:linker,ENTRY>" 47 -DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>" 48 -DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>" 49 -DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>" 50 -DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>" 51 -DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>" 52 -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} 53 -P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake 54 ) 55 else() 56 # Different generators deal with depfiles differently. 57 if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") 58 # Note that the IMPLICIT_DEPENDS option is currently supported only 59 # for Makefile generators and will be ignored by other generators. 60 set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT}) 61 elseif(CMAKE_GENERATOR STREQUAL "Ninja") 62 # Using DEPFILE with other generators than Ninja is an error. 63 set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep) 64 else() 65 # TODO: How would the linker script dependencies work for non-linker 66 # script generators. 67 message(STATUS "Warning; this generator is not well supported. The 68 Linker script may not be regenerated when it should.") 69 set(linker_script_dep "") 70 endif() 71 72 zephyr_get_include_directories_for_lang(C current_includes) 73 get_filename_component(base_name ${CMAKE_CURRENT_BINARY_DIR} NAME) 74 get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) 75 76 add_custom_command( 77 OUTPUT ${linker_script_gen} 78 DEPENDS 79 ${LINKER_SCRIPT} 80 ${AUTOCONF_H} 81 ${extra_dependencies} 82 # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS' 83 ${linker_script_dep} 84 COMMAND ${CMAKE_C_COMPILER} 85 -x assembler-with-cpp 86 ${NOSYSDEF_CFLAG} 87 -MD -MF ${linker_script_gen}.dep -MT ${base_name}/${linker_script_gen} 88 -D_LINKER 89 -D_ASMLANGUAGE 90 -imacros ${AUTOCONF_H} 91 ${current_includes} 92 ${current_defines} 93 ${linker_pass_define} 94 -E ${LINKER_SCRIPT} 95 -P # Prevent generation of debug `#line' directives. 96 -o ${linker_script_gen} 97 VERBATIM 98 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 99 COMMAND_EXPAND_LISTS 100 ) 101 endif() 102endmacro() 103 104# Force symbols to be entered in the output file as undefined symbols 105function(toolchain_ld_force_undefined_symbols) 106 foreach(symbol ${ARGN}) 107 zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol}) 108 endforeach() 109endfunction() 110 111# Link a target to given libraries with toolchain-specific argument order 112# 113# Usage: 114# toolchain_ld_link_elf( 115# TARGET_ELF <target_elf> 116# OUTPUT_MAP <output_map_file_of_target> 117# LIBRARIES_PRE_SCRIPT [libraries_pre_script] 118# LINKER_SCRIPT <linker_script> 119# LIBRARIES_POST_SCRIPT [libraries_post_script] 120# DEPENDENCIES [dependencies] 121# ) 122function(toolchain_ld_link_elf) 123 cmake_parse_arguments( 124 TOOLCHAIN_LD_LINK_ELF # prefix of output variables 125 "" # list of names of the boolean arguments 126 "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments 127 "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments 128 ${ARGN} # input args to parse 129 ) 130 131 if(${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd") 132 # ld.bfd was found so let's explicitly use that for linking, see #32237 133 set(use_linker "-fuse-ld=bfd") 134 endif() 135 136 target_link_libraries( 137 ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} 138 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} 139 ${use_linker} 140 ${TOPT} 141 ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} 142 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} 143 144 ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} 145 ${LINKERFLAGPREFIX},--whole-archive 146 ${ZEPHYR_LIBS_PROPERTY} 147 ${LINKERFLAGPREFIX},--no-whole-archive 148 kernel 149 $<TARGET_OBJECTS:${OFFSETS_LIB}> 150 ${LIB_INCLUDE_DIR} 151 -L${PROJECT_BINARY_DIR} 152 ${TOOLCHAIN_LIBS} 153 154 ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} 155 ) 156endfunction(toolchain_ld_link_elf) 157 158# Load toolchain_ld-family macros 159include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake) 160include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_baremetal.cmake) 161include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_cpp.cmake) 162include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake) 163include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake) 164