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(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host") 10 if(CONFIG_CPP_EXCEPTIONS AND LIBGCC_DIR) 11 # When building with C++ Exceptions, it is important that crtbegin and crtend 12 # are linked at specific locations. 13 # The location is so important that we cannot let this be controlled by normal 14 # link libraries, instead we must control the link command specifically as 15 # part of toolchain. 16 set(CMAKE_CXX_LINK_EXECUTABLE 17 "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${LIBGCC_DIR}/crtbegin.o <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${LIBGCC_DIR}/crtend.o") 18 endif() 19endif() 20 21# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} 22# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time 23macro(configure_linker_script linker_script_gen linker_pass_define) 24 set(extra_dependencies ${ARGN}) 25 26 if(CONFIG_CMAKE_LINKER_GENERATOR) 27 add_custom_command( 28 OUTPUT ${linker_script_gen} 29 COMMAND ${CMAKE_COMMAND} 30 -DPASS="${linker_pass_define}" 31 -DFORMAT="$<TARGET_PROPERTY:linker,FORMAT>" 32 -DENTRY="$<TARGET_PROPERTY:linker,ENTRY>" 33 -DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>" 34 -DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>" 35 -DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>" 36 -DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>" 37 -DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>" 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 get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) 60 61 add_custom_command( 62 OUTPUT ${linker_script_gen} 63 DEPENDS 64 ${LINKER_SCRIPT} 65 ${AUTOCONF_H} 66 ${extra_dependencies} 67 # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS' 68 ${linker_script_dep} 69 COMMAND ${CMAKE_C_COMPILER} 70 -x assembler-with-cpp 71 ${NOSYSDEF_CFLAG} 72 -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen} 73 -D_LINKER 74 -D_ASMLANGUAGE 75 -imacros ${AUTOCONF_H} 76 ${current_includes} 77 ${current_defines} 78 ${template_script_defines} 79 -E ${LINKER_SCRIPT} 80 -P # Prevent generation of debug `#line' directives. 81 -o ${linker_script_gen} 82 VERBATIM 83 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 84 COMMAND_EXPAND_LISTS 85 ) 86 endif() 87endmacro() 88 89# Force symbols to be entered in the output file as undefined symbols 90function(toolchain_ld_force_undefined_symbols) 91 foreach(symbol ${ARGN}) 92 zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol}) 93 endforeach() 94endfunction() 95 96# Link a target to given libraries with toolchain-specific argument order 97# 98# Usage: 99# toolchain_ld_link_elf( 100# TARGET_ELF <target_elf> 101# OUTPUT_MAP <output_map_file_of_target> 102# LIBRARIES_PRE_SCRIPT [libraries_pre_script] 103# LINKER_SCRIPT <linker_script> 104# LIBRARIES_POST_SCRIPT [libraries_post_script] 105# DEPENDENCIES [dependencies] 106# ) 107function(toolchain_ld_link_elf) 108 cmake_parse_arguments( 109 TOOLCHAIN_LD_LINK_ELF # prefix of output variables 110 "" # list of names of the boolean arguments 111 "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments 112 "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments 113 ${ARGN} # input args to parse 114 ) 115 116 if((${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd") OR 117 ${GNULD_LINKER_IS_BFD}) 118 # ld.bfd was found so let's explicitly use that for linking, see #32237 119 set(use_linker "-fuse-ld=bfd") 120 endif() 121 122 target_link_libraries( 123 ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} 124 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} 125 ${use_linker} 126 ${TOPT} 127 ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} 128 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} 129 130 ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} 131 ${LINKERFLAGPREFIX},--whole-archive 132 ${ZEPHYR_LIBS_PROPERTY} 133 ${LINKERFLAGPREFIX},--no-whole-archive 134 kernel 135 $<TARGET_OBJECTS:${OFFSETS_LIB}> 136 ${LIB_INCLUDE_DIR} 137 -L${PROJECT_BINARY_DIR} 138 ${TOOLCHAIN_LIBS} 139 140 ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} 141 ) 142endfunction(toolchain_ld_link_elf) 143 144# Load toolchain_ld-family macros 145include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake) 146include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_baremetal.cmake) 147include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_cpp.cmake) 148include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake) 149include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake) 150