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
9list(APPEND TOOLCHAIN_LD_FLAGS -fuse-ld=lld)
10list(APPEND CMAKE_REQUIRED_FLAGS -fuse-ld=lld)
11string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
12
13# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
14# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time
15macro(configure_linker_script linker_script_gen linker_pass_define)
16  set(extra_dependencies ${ARGN})
17  set(template_script_defines ${linker_pass_define})
18  list(TRANSFORM template_script_defines PREPEND "-D")
19
20  # Different generators deal with depfiles differently.
21  if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
22    # Note that the IMPLICIT_DEPENDS option is currently supported only
23    # for Makefile generators and will be ignored by other generators.
24    set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
25  elseif(CMAKE_GENERATOR STREQUAL "Ninja")
26    # Using DEPFILE with other generators than Ninja is an error.
27    set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
28  else()
29    # TODO: How would the linker script dependencies work for non-linker
30    # script generators.
31    message(WARNING "This generator is not well supported. The
32                    Linker script may not be regenerated when it should.")
33    set(linker_script_dep "")
34  endif()
35
36  zephyr_get_include_directories_for_lang(C current_includes)
37
38  add_custom_command(
39    OUTPUT ${linker_script_gen}
40    DEPENDS
41    ${LINKER_SCRIPT}
42    ${extra_dependencies}
43    # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
44    ${linker_script_dep}
45    COMMAND ${CMAKE_C_COMPILER}
46    -x assembler-with-cpp
47    ${NOSYSDEF_CFLAG}
48    -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen}
49    -D_LINKER
50    -D_ASMLANGUAGE
51    -D__LLD_LINKER_CMD__
52    -imacros ${AUTOCONF_H}
53    ${current_includes}
54    ${template_script_defines}
55    -E ${LINKER_SCRIPT}
56    -P # Prevent generation of debug `#line' directives.
57    -o ${linker_script_gen}
58    VERBATIM
59    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
60    COMMAND_EXPAND_LISTS
61  )
62endmacro()
63
64# Force symbols to be entered in the output file as undefined symbols
65function(toolchain_ld_force_undefined_symbols)
66  foreach(symbol ${ARGN})
67    zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol})
68  endforeach()
69endfunction()
70
71# Link a target to given libraries with toolchain-specific argument order
72#
73# Usage:
74#   toolchain_ld_link_elf(
75#     TARGET_ELF             <target_elf>
76#     OUTPUT_MAP             <output_map_file_of_target>
77#     LIBRARIES_PRE_SCRIPT   [libraries_pre_script]
78#     LINKER_SCRIPT          <linker_script>
79#     LIBRARIES_POST_SCRIPT  [libraries_post_script]
80#     DEPENDENCIES           [dependencies]
81#   )
82function(toolchain_ld_link_elf)
83  cmake_parse_arguments(
84    TOOLCHAIN_LD_LINK_ELF                                     # prefix of output variables
85    ""                                                        # list of names of the boolean arguments
86    "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT"                     # list of names of scalar arguments
87    "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
88    ${ARGN}                                                   # input args to parse
89  )
90
91  target_link_libraries(
92    ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
93    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
94    ${TOPT}
95    ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
96    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
97
98    ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
99    ${LINKERFLAGPREFIX},--whole-archive
100    ${WHOLE_ARCHIVE_LIBS}
101    ${LINKERFLAGPREFIX},--no-whole-archive
102    ${NO_WHOLE_ARCHIVE_LIBS}
103    $<TARGET_OBJECTS:${OFFSETS_LIB}>
104    -L${PROJECT_BINARY_DIR}
105
106    ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
107  )
108endfunction(toolchain_ld_link_elf)
109
110# Function for finalizing link setup after Zephyr configuration has completed.
111#
112# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE
113# signature to ensure that standard c and runtime libraries are correctly placed
114# and the end of link invocation and doesn't appear in the middle of the link
115# command invocation.
116macro(toolchain_linker_finalize)
117  get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir)
118  get_property(link_order TARGET linker PROPERTY link_order_library)
119  foreach(lib ${link_order})
120    get_property(link_flag TARGET linker PROPERTY ${lib}_library)
121    list(APPEND zephyr_std_libs "${link_flag}")
122  endforeach()
123  string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}")
124
125 set(common_link "<LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${zephyr_std_libs}")
126 set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <FLAGS> <CMAKE_ASM_LINK_FLAGS> ${common_link}")
127 set(CMAKE_C_LINK_EXECUTABLE   "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> ${common_link}")
128 set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> ${common_link}")
129endmacro()
130
131# Load toolchain_ld-family macros
132include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake)
133include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake)
134