target.cmake 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. # SPDX-License-Identifier: Apache-2.0
  2. set_property(TARGET linker PROPERTY devices_start_symbol "__device_start")
  3. if(DEFINED TOOLCHAIN_HOME)
  4. # When Toolchain home is defined, then we are cross-compiling, so only look
  5. # for linker in that path, else we are using host tools.
  6. set(LD_SEARCH_PATH PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
  7. endif()
  8. find_program(CMAKE_LINKER ${CROSS_COMPILE}ld.bfd ${LD_SEARCH_PATH})
  9. if(NOT CMAKE_LINKER)
  10. find_program(CMAKE_LINKER ${CROSS_COMPILE}ld ${LD_SEARCH_PATH})
  11. endif()
  12. set_ifndef(LINKERFLAGPREFIX -Wl)
  13. if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host")
  14. if(CONFIG_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")
  22. endif()
  23. endif()
  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
  26. macro(configure_linker_script linker_script_gen linker_pass_define)
  27. set(extra_dependencies ${ARGN})
  28. if(CONFIG_CMAKE_LINKER_GENERATOR)
  29. if("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_PREBUILT")
  30. set(PASS 1)
  31. elseif("${linker_pass_define}" STREQUAL "-DLINKER_ZEPHYR_FINAL;-DLINKER_PASS2")
  32. set(PASS 2)
  33. endif()
  34. add_custom_command(
  35. OUTPUT ${linker_script_gen}
  36. COMMAND ${CMAKE_COMMAND}
  37. -DPASS=${PASS}
  38. -DFORMAT="$<TARGET_PROPERTY:linker,FORMAT>"
  39. -DENTRY="$<TARGET_PROPERTY:linker,ENTRY>"
  40. -DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>"
  41. -DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>"
  42. -DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>"
  43. -DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>"
  44. -DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>"
  45. -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
  46. -P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake
  47. )
  48. else()
  49. # Different generators deal with depfiles differently.
  50. if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
  51. # Note that the IMPLICIT_DEPENDS option is currently supported only
  52. # for Makefile generators and will be ignored by other generators.
  53. set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
  54. elseif(CMAKE_GENERATOR STREQUAL "Ninja")
  55. # Using DEPFILE with other generators than Ninja is an error.
  56. set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
  57. else()
  58. # TODO: How would the linker script dependencies work for non-linker
  59. # script generators.
  60. message(STATUS "Warning; this generator is not well supported. The
  61. Linker script may not be regenerated when it should.")
  62. set(linker_script_dep "")
  63. endif()
  64. zephyr_get_include_directories_for_lang(C current_includes)
  65. get_filename_component(base_name ${CMAKE_CURRENT_BINARY_DIR} NAME)
  66. get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES)
  67. add_custom_command(
  68. OUTPUT ${linker_script_gen}
  69. DEPENDS
  70. ${LINKER_SCRIPT}
  71. ${AUTOCONF_H}
  72. ${extra_dependencies}
  73. # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
  74. ${linker_script_dep}
  75. COMMAND ${CMAKE_C_COMPILER}
  76. -x assembler-with-cpp
  77. ${NOSYSDEF_CFLAG}
  78. -MD -MF ${linker_script_gen}.dep -MT ${base_name}/${linker_script_gen}
  79. -D_LINKER
  80. -D_ASMLANGUAGE
  81. -imacros ${AUTOCONF_H}
  82. ${current_includes}
  83. ${current_defines}
  84. ${linker_pass_define}
  85. -E ${LINKER_SCRIPT}
  86. -P # Prevent generation of debug `#line' directives.
  87. -o ${linker_script_gen}
  88. VERBATIM
  89. WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
  90. COMMAND_EXPAND_LISTS
  91. )
  92. endif()
  93. endmacro()
  94. # Force symbols to be entered in the output file as undefined symbols
  95. function(toolchain_ld_force_undefined_symbols)
  96. foreach(symbol ${ARGN})
  97. zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol})
  98. endforeach()
  99. endfunction()
  100. # Link a target to given libraries with toolchain-specific argument order
  101. #
  102. # Usage:
  103. # toolchain_ld_link_elf(
  104. # TARGET_ELF <target_elf>
  105. # OUTPUT_MAP <output_map_file_of_target>
  106. # LIBRARIES_PRE_SCRIPT [libraries_pre_script]
  107. # LINKER_SCRIPT <linker_script>
  108. # LIBRARIES_POST_SCRIPT [libraries_post_script]
  109. # DEPENDENCIES [dependencies]
  110. # )
  111. function(toolchain_ld_link_elf)
  112. cmake_parse_arguments(
  113. TOOLCHAIN_LD_LINK_ELF # prefix of output variables
  114. "" # list of names of the boolean arguments
  115. "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments
  116. "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
  117. ${ARGN} # input args to parse
  118. )
  119. if(${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd")
  120. # ld.bfd was found so let's explicitly use that for linking, see #32237
  121. set(use_linker "-fuse-ld=bfd")
  122. endif()
  123. target_link_libraries(
  124. ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
  125. ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
  126. ${use_linker}
  127. ${TOPT}
  128. ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
  129. ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
  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. ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
  140. )
  141. endfunction(toolchain_ld_link_elf)
  142. # Load toolchain_ld-family macros
  143. include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_base.cmake)
  144. include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_baremetal.cmake)
  145. include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_cpp.cmake)
  146. include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake)
  147. include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake)