target.cmake 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # SPDX-License-Identifier: Apache-2.0
  2. set_property(TARGET linker PROPERTY devices_start_symbol "__device_start")
  3. find_program(CMAKE_LINKER ${CROSS_COMPILE}lldac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
  4. # the prefix to transfer linker options from compiler
  5. set_ifndef(LINKERFLAGPREFIX -Wl,)
  6. # Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
  7. # NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time
  8. macro(configure_linker_script linker_script_gen linker_pass_define)
  9. set(extra_dependencies ${ARGN})
  10. # Different generators deal with depfiles differently.
  11. if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
  12. # Note that the IMPLICIT_DEPENDS option is currently supported only
  13. # for Makefile generators and will be ignored by other generators.
  14. set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
  15. elseif(CMAKE_GENERATOR STREQUAL "Ninja")
  16. # Using DEPFILE with other generators than Ninja is an error.
  17. set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
  18. else()
  19. # TODO: How would the linker script dependencies work for non-linker
  20. # script generators.
  21. message(STATUS "Warning; this generator is not well supported. The
  22. Linker script may not be regenerated when it should.")
  23. set(linker_script_dep "")
  24. endif()
  25. zephyr_get_include_directories_for_lang(C current_includes)
  26. get_filename_component(base_name ${CMAKE_CURRENT_BINARY_DIR} NAME)
  27. get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES)
  28. # the command to generate linker file from template
  29. add_custom_command(
  30. OUTPUT ${linker_script_gen}
  31. DEPENDS
  32. ${LINKER_SCRIPT}
  33. ${AUTOCONF_H}
  34. ${extra_dependencies}
  35. # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
  36. ${linker_script_dep}
  37. COMMAND ${CMAKE_C_COMPILER}
  38. -x c
  39. ${NOSYSDEF_CFLAG}
  40. -Hnocopyr
  41. -MD -MF ${linker_script_gen}.dep -MT ${base_name}/${linker_script_gen}
  42. -D_LINKER
  43. -D_ASMLANGUAGE
  44. -imacros ${AUTOCONF_H}
  45. ${current_includes}
  46. ${current_defines}
  47. ${linker_pass_define}
  48. ${LINKER_SCRIPT}
  49. -E
  50. -o ${linker_script_gen}
  51. VERBATIM
  52. WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
  53. COMMAND_EXPAND_LISTS
  54. )
  55. endmacro()
  56. # Force symbols to be entered in the output file as undefined symbols
  57. function(toolchain_ld_force_undefined_symbols)
  58. foreach(symbol ${ARGN})
  59. zephyr_link_libraries(${LINKERFLAGPREFIX}-u${symbol})
  60. endforeach()
  61. endfunction()
  62. # Link a target to given libraries with toolchain-specific argument order
  63. #
  64. # Usage:
  65. # toolchain_ld_link_elf(
  66. # TARGET_ELF <target_elf>
  67. # OUTPUT_MAP <output_map_file_of_target>
  68. # LIBRARIES_PRE_SCRIPT [libraries_pre_script]
  69. # LINKER_SCRIPT <linker_script>
  70. # LIBRARIES_POST_SCRIPT [libraries_post_script]
  71. # DEPENDENCIES [dependencies]
  72. # )
  73. function(toolchain_ld_link_elf)
  74. cmake_parse_arguments(
  75. TOOLCHAIN_LD_LINK_ELF # prefix of output variables
  76. "" # list of names of the boolean arguments
  77. "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments
  78. "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
  79. ${ARGN} # input args to parse
  80. )
  81. target_link_libraries(
  82. ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
  83. ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
  84. ${LINKERFLAGPREFIX}-T${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
  85. ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
  86. ${LINKERFLAGPREFIX}--gc-sections
  87. ${LINKERFLAGPREFIX}--entry=__start
  88. ${LINKERFLAGPREFIX}--Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
  89. ${LINKERFLAGPREFIX}--whole-archive
  90. ${ZEPHYR_LIBS_PROPERTY}
  91. ${LINKERFLAGPREFIX}--no-whole-archive
  92. kernel
  93. $<TARGET_OBJECTS:${OFFSETS_LIB}>
  94. ${LIB_INCLUDE_DIR}
  95. -L${PROJECT_BINARY_DIR}
  96. ${TOOLCHAIN_LIBS}
  97. ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
  98. )
  99. endfunction(toolchain_ld_link_elf)
  100. # linker options of temporary linkage for code generation
  101. macro(toolchain_ld_baremetal)
  102. zephyr_ld_options(
  103. -Hlld
  104. -Hnosdata
  105. -Xtimer0 # to suppress the warning message
  106. -Hnoxcheck_obj
  107. -Hnocplus
  108. -Hhostlib=
  109. -Hheap=0
  110. -Hnoivt
  111. -Hnocrt
  112. )
  113. # There are two options:
  114. # - We have full MWDT libc support and we link MWDT libc - this is default
  115. # behavior and we don't need to do something for that.
  116. # - We use minimal libc provided by Zephyr itself. In that case we must not
  117. # link MWDT libc, but we still need to link libmw
  118. if(CONFIG_MINIMAL_LIBC)
  119. zephyr_ld_options(
  120. -Hnolib
  121. -Hldopt=-lmw
  122. )
  123. endif()
  124. # Funny thing is if this is set to =error, some architectures will
  125. # skip this flag even though the compiler flag check passes
  126. # (e.g. ARC and Xtensa). So warning should be the default for now.
  127. #
  128. # Skip this for native application as Zephyr only provides
  129. # additions to the host toolchain linker script. The relocation
  130. # sections (.rel*) requires us to override those provided
  131. # by host toolchain. As we can't account for all possible
  132. # combination of compiler and linker on all machines used
  133. # for development, it is better to turn this off.
  134. #
  135. # CONFIG_LINKER_ORPHAN_SECTION_PLACE is to place the orphan sections
  136. # without any warnings or errors, which is the default behavior.
  137. # So there is no need to explicitly set a linker flag.
  138. if(CONFIG_LINKER_ORPHAN_SECTION_WARN)
  139. message(WARNING "MWDT toolchain does not support
  140. CONFIG_LINKER_ORPHAN_SECTION_WARN")
  141. elseif(CONFIG_LINKER_ORPHAN_SECTION_ERROR)
  142. zephyr_ld_options(
  143. ${LINKERFLAGPREFIX}--orphan-handling=error)
  144. endif()
  145. endmacro()
  146. # base linker options
  147. macro(toolchain_ld_base)
  148. if(NOT PROPERTY_LINKER_SCRIPT_DEFINES)
  149. set_property(GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES -D__MWDT_LINKER_CMD__)
  150. endif()
  151. # Sort the common symbols and each input section by alignment
  152. # in descending order to minimize padding between these symbols.
  153. zephyr_ld_option_ifdef(
  154. CONFIG_LINKER_SORT_BY_ALIGNMENT
  155. ${LINKERFLAGPREFIX}--sort-section=alignment
  156. )
  157. endmacro()
  158. # generate linker script snippts from configure files
  159. macro(toolchain_ld_configure_files)
  160. configure_file(
  161. $ENV{ZEPHYR_BASE}/include/arch/common/app_data_alignment.ld
  162. ${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld)
  163. configure_file(
  164. $ENV{ZEPHYR_BASE}/include/linker/app_smem.ld
  165. ${PROJECT_BINARY_DIR}/include/generated/app_smem.ld)
  166. configure_file(
  167. $ENV{ZEPHYR_BASE}/include/linker/app_smem_aligned.ld
  168. ${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld)
  169. configure_file(
  170. $ENV{ZEPHYR_BASE}/include/linker/app_smem_unaligned.ld
  171. ${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld)
  172. endmacro()
  173. # link C++ libraries
  174. macro(toolchain_ld_cpp)
  175. zephyr_link_libraries(
  176. -Hcplus
  177. )
  178. endmacro()
  179. # use linker for relocation
  180. macro(toolchain_ld_relocation)
  181. set(MEM_RELOCATION_LD "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld")
  182. set(MEM_RELOCATION_SRAM_DATA_LD
  183. "${PROJECT_BINARY_DIR}/include/generated/linker_sram_data_relocate.ld")
  184. set(MEM_RELOCATION_SRAM_BSS_LD
  185. "${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld")
  186. set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c")
  187. add_custom_command(
  188. OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD}
  189. COMMAND
  190. ${PYTHON_EXECUTABLE}
  191. ${ZEPHYR_BASE}/scripts/gen_relocate_app.py
  192. $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
  193. -d ${APPLICATION_BINARY_DIR}
  194. -i \"$<TARGET_PROPERTY:code_data_relocation_target,COMPILE_DEFINITIONS>\"
  195. -o ${MEM_RELOCATION_LD}
  196. -s ${MEM_RELOCATION_SRAM_DATA_LD}
  197. -b ${MEM_RELOCATION_SRAM_BSS_LD}
  198. -c ${MEM_RELOCATION_CODE}
  199. DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY}
  200. )
  201. add_library(code_relocation_source_lib STATIC ${MEM_RELOCATION_CODE})
  202. target_link_libraries(code_relocation_source_lib zephyr_interface)
  203. endmacro()