1# SPDX-License-Identifier: Apache-2.0
2set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start")
3
4find_package(LlvmLld 14.0.0 REQUIRED)
5set(CMAKE_LINKER ${LLVMLLD_LINKER})
6
7set_ifndef(LINKERFLAGPREFIX -Wl)
8
9# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
10# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time
11macro(configure_linker_script linker_script_gen linker_pass_define)
12  set(extra_dependencies ${ARGN})
13  set(template_script_defines ${linker_pass_define})
14  list(TRANSFORM template_script_defines PREPEND "-D")
15
16  # Different generators deal with depfiles differently.
17  if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
18    # Note that the IMPLICIT_DEPENDS option is currently supported only
19    # for Makefile generators and will be ignored by other generators.
20    set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
21  elseif(CMAKE_GENERATOR STREQUAL "Ninja")
22    # Using DEPFILE with other generators than Ninja is an error.
23    set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
24  else()
25    # TODO: How would the linker script dependencies work for non-linker
26    # script generators.
27    message(WARNING "This generator is not well supported. The
28                    Linker script may not be regenerated when it should.")
29    set(linker_script_dep "")
30  endif()
31
32  zephyr_get_include_directories_for_lang(C current_includes)
33  get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES)
34
35  add_custom_command(
36    OUTPUT ${linker_script_gen}
37    DEPENDS
38    ${LINKER_SCRIPT}
39    ${extra_dependencies}
40    # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
41    ${linker_script_dep}
42    COMMAND ${CMAKE_C_COMPILER}
43    -x assembler-with-cpp
44    ${NOSYSDEF_CFLAG}
45    -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen}
46    -D_LINKER
47    -D_ASMLANGUAGE
48    -imacros ${AUTOCONF_H}
49    ${current_includes}
50    ${current_defines}
51    ${template_script_defines}
52    -E ${LINKER_SCRIPT}
53    -P # Prevent generation of debug `#line' directives.
54    -o ${linker_script_gen}
55    VERBATIM
56    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
57    COMMAND_EXPAND_LISTS
58  )
59endmacro()
60
61# Force symbols to be entered in the output file as undefined symbols
62function(toolchain_ld_force_undefined_symbols)
63  foreach(symbol ${ARGN})
64    zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol})
65  endforeach()
66endfunction()
67
68# Link a target to given libraries with toolchain-specific argument order
69#
70# Usage:
71#   toolchain_ld_link_elf(
72#     TARGET_ELF             <target_elf>
73#     OUTPUT_MAP             <output_map_file_of_target>
74#     LIBRARIES_PRE_SCRIPT   [libraries_pre_script]
75#     LINKER_SCRIPT          <linker_script>
76#     LIBRARIES_POST_SCRIPT  [libraries_post_script]
77#     DEPENDENCIES           [dependencies]
78#   )
79function(toolchain_ld_link_elf)
80  cmake_parse_arguments(
81    TOOLCHAIN_LD_LINK_ELF                                     # prefix of output variables
82    ""                                                        # list of names of the boolean arguments
83    "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT"                     # list of names of scalar arguments
84    "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
85    ${ARGN}                                                   # input args to parse
86  )
87
88  target_link_libraries(
89    ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
90    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
91    ${TOPT}
92    ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
93    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
94
95    ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
96    ${LINKERFLAGPREFIX},--whole-archive
97    ${WHOLE_ARCHIVE_LIBS}
98    ${LINKERFLAGPREFIX},--no-whole-archive
99    ${NO_WHOLE_ARCHIVE_LIBS}
100    $<TARGET_OBJECTS:${OFFSETS_LIB}>
101    ${LIB_INCLUDE_DIR}
102    -L${PROJECT_BINARY_DIR}
103    ${TOOLCHAIN_LIBS}
104
105    ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
106  )
107endfunction(toolchain_ld_link_elf)
108
109
110# Load toolchain_ld-family macros
111include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake)
112include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_baremetal.cmake)
113include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_cpp.cmake)
114include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake)
115include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake)
116