123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- # SPDX-License-Identifier: Apache-2.0
- set_property(TARGET linker PROPERTY devices_start_symbol "__device_start")
- if(DEFINED TOOLCHAIN_HOME)
- # When Toolchain home is defined, then we are cross-compiling, so only look
- # for linker in that path, else we are using host tools.
- set(LD_SEARCH_PATH PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
- endif()
- find_program(CMAKE_LINKER ${CROSS_COMPILE}ld.bfd ${LD_SEARCH_PATH})
- if(NOT CMAKE_LINKER)
- find_program(CMAKE_LINKER ${CROSS_COMPILE}ld ${LD_SEARCH_PATH})
- endif()
- set_ifndef(LINKERFLAGPREFIX -Wl)
- if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host")
- if(CONFIG_EXCEPTIONS)
- # When building with C++ Exceptions, it is important that crtbegin and crtend
- # are linked at specific locations.
- # The location is so important that we cannot let this be controlled by normal
- # link libraries, instead we must control the link command specifically as
- # part of toolchain.
- set(CMAKE_CXX_LINK_EXECUTABLE
- "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${LIBGCC_DIR}/crtbegin.o <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${LIBGCC_DIR}/crtend.o")
- endif()
- endif()
- # Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
- # NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time
- macro(configure_linker_script linker_script_gen linker_pass_define)
- set(extra_dependencies ${ARGN})
- if(CONFIG_CMAKE_LINKER_GENERATOR)
- if("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_PREBUILT")
- set(PASS 1)
- elseif("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_FINAL;-DLINKER_PASS2")
- set(PASS 2)
- endif()
- add_custom_command(
- OUTPUT ${linker_script_gen}
- COMMAND ${CMAKE_COMMAND}
- -DPASS=${PASS}
- -DFORMAT="$<TARGET_PROPERTY:linker,FORMAT>"
- -DENTRY="$<TARGET_PROPERTY:linker,ENTRY>"
- -DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>"
- -DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>"
- -DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>"
- -DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>"
- -DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>"
- -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
- -P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake
- )
- else()
- # Different generators deal with depfiles differently.
- if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
- # Note that the IMPLICIT_DEPENDS option is currently supported only
- # for Makefile generators and will be ignored by other generators.
- set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
- elseif(CMAKE_GENERATOR STREQUAL "Ninja")
- # Using DEPFILE with other generators than Ninja is an error.
- set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
- else()
- # TODO: How would the linker script dependencies work for non-linker
- # script generators.
- message(STATUS "Warning; this generator is not well supported. The
- Linker script may not be regenerated when it should.")
- set(linker_script_dep "")
- endif()
- zephyr_get_include_directories_for_lang(C current_includes)
- get_filename_component(base_name ${CMAKE_CURRENT_BINARY_DIR} NAME)
- get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES)
- add_custom_command(
- OUTPUT ${linker_script_gen}
- DEPENDS
- ${LINKER_SCRIPT}
- ${AUTOCONF_H}
- ${extra_dependencies}
- # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
- ${linker_script_dep}
- COMMAND ${CMAKE_C_COMPILER}
- -x assembler-with-cpp
- ${NOSYSDEF_CFLAG}
- -MD -MF ${linker_script_gen}.dep -MT ${base_name}/${linker_script_gen}
- -D_LINKER
- -D_ASMLANGUAGE
- -imacros ${AUTOCONF_H}
- ${current_includes}
- ${current_defines}
- ${linker_pass_define}
- -E ${LINKER_SCRIPT}
- -P # Prevent generation of debug `#line' directives.
- -o ${linker_script_gen}
- VERBATIM
- WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
- COMMAND_EXPAND_LISTS
- )
- endif()
- endmacro()
- # Force symbols to be entered in the output file as undefined symbols
- function(toolchain_ld_force_undefined_symbols)
- foreach(symbol ${ARGN})
- zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol})
- endforeach()
- endfunction()
- # Link a target to given libraries with toolchain-specific argument order
- #
- # Usage:
- # toolchain_ld_link_elf(
- # TARGET_ELF <target_elf>
- # OUTPUT_MAP <output_map_file_of_target>
- # LIBRARIES_PRE_SCRIPT [libraries_pre_script]
- # LINKER_SCRIPT <linker_script>
- # LIBRARIES_POST_SCRIPT [libraries_post_script]
- # DEPENDENCIES [dependencies]
- # )
- function(toolchain_ld_link_elf)
- cmake_parse_arguments(
- TOOLCHAIN_LD_LINK_ELF # prefix of output variables
- "" # list of names of the boolean arguments
- "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments
- "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
- ${ARGN} # input args to parse
- )
- if(${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd")
- # ld.bfd was found so let's explicitly use that for linking, see #32237
- set(use_linker "-fuse-ld=bfd")
- endif()
- target_link_libraries(
- ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
- ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
- ${use_linker}
- ${TOPT}
- ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
- ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
- ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
- ${LINKERFLAGPREFIX},--whole-archive
- ${ZEPHYR_LIBS_PROPERTY}
- ${LINKERFLAGPREFIX},--no-whole-archive
- kernel
- $<TARGET_OBJECTS:${OFFSETS_LIB}>
- ${LIB_INCLUDE_DIR}
- -L${PROJECT_BINARY_DIR}
- ${TOOLCHAIN_LIBS}
- ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
- )
- endfunction(toolchain_ld_link_elf)
- # Load toolchain_ld-family macros
- include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake)
- include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_baremetal.cmake)
- include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_cpp.cmake)
- include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake)
- include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake)
|