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 get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) 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 -imacros ${AUTOCONF_H} 79 ${current_includes} 80 ${current_defines} 81 ${template_script_defines} 82 -E ${LINKER_SCRIPT} 83 -P # Prevent generation of debug `#line' directives. 84 -o ${linker_script_gen} 85 VERBATIM 86 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 87 COMMAND_EXPAND_LISTS 88 ) 89 endif() 90endmacro() 91 92# Force symbols to be entered in the output file as undefined symbols 93function(toolchain_ld_force_undefined_symbols) 94 foreach(symbol ${ARGN}) 95 zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol}) 96 endforeach() 97endfunction() 98 99# Link a target to given libraries with toolchain-specific argument order 100# 101# Usage: 102# toolchain_ld_link_elf( 103# TARGET_ELF <target_elf> 104# OUTPUT_MAP <output_map_file_of_target> 105# LIBRARIES_PRE_SCRIPT [libraries_pre_script] 106# LINKER_SCRIPT <linker_script> 107# LIBRARIES_POST_SCRIPT [libraries_post_script] 108# DEPENDENCIES [dependencies] 109# ) 110function(toolchain_ld_link_elf) 111 cmake_parse_arguments( 112 TOOLCHAIN_LD_LINK_ELF # prefix of output variables 113 "" # list of names of the boolean arguments 114 "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments 115 "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments 116 ${ARGN} # input args to parse 117 ) 118 119 target_link_libraries( 120 ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} 121 ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} 122 ${use_linker} 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 ${LIB_INCLUDE_DIR} 134 -L${PROJECT_BINARY_DIR} 135 ${TOOLCHAIN_LIBS} 136 137 ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} 138 ) 139endfunction(toolchain_ld_link_elf) 140 141# xt-ld is Xtensa's own version of binutils' ld. 142# So we can reuse most of the ld configurations. 143include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake) 144include(${ZEPHYR_BASE}/cmake/linker/ld/target_baremetal.cmake) 145include(${ZEPHYR_BASE}/cmake/linker/ld/target_cpp.cmake) 146include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake) 147include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake) 148