blob: 77919821cca42205c47aad570f806bd59d25eac2 [file] [log] [blame]
Raef Coles9ec67e62020-07-10 09:40:35 +01001#-------------------------------------------------------------------------------
Raef Coles88ff7992024-01-11 10:27:05 +00002# Copyright (c) 2020-2024, Arm Limited. All rights reserved.
Chris Brand4b381f82022-12-01 16:30:23 -08003# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
4# or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
Raef Coles9ec67e62020-07-10 09:40:35 +01005#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8#-------------------------------------------------------------------------------
David Hu1249f0d2023-12-04 22:57:56 +08009cmake_minimum_required(VERSION 3.21)
Raef Coles9ec67e62020-07-10 09:40:35 +010010
Raef Coles9ec67e62020-07-10 09:40:35 +010011SET(CMAKE_SYSTEM_NAME Generic)
Raef Coles9ec67e62020-07-10 09:40:35 +010012
13set(CMAKE_C_COMPILER armclang)
Rajkumar Kanagarajcd831592022-05-04 11:44:03 +020014set(CMAKE_CXX_COMPILER armclang)
Dávid Házi162b4212024-10-16 21:59:24 +000015set(CMAKE_ASM_COMPILER armclang)
Raef Coles9ec67e62020-07-10 09:40:35 +010016
17set(LINKER_VENEER_OUTPUT_FLAG --import_cmse_lib_out=)
Raef Coles69817322020-10-19 14:14:14 +010018set(COMPILER_CMSE_FLAG $<$<COMPILE_LANGUAGE:C>:-mcmse>)
Raef Coles9ec67e62020-07-10 09:40:35 +010019
20# This variable name is a bit of a misnomer. The file it is set to is included
21# at a particular step in the compiler initialisation. It is used here to
22# configure the extensions for object files. Despite the name, it also works
23# with the Ninja generator.
24set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_LIST_DIR}/cmake/set_extensions.cmake)
25
Dávid Házi50c18282024-10-10 12:37:28 +000026# CMAKE_C_COMPILER_VERSION is not guaranteed to be defined.
27EXECUTE_PROCESS( COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE ARMCLANG_VERSION )
28string(REGEX MATCH "([0-9]+\.[0-9]+)" ARMCLANG_VERSION "${ARMCLANG_VERSION}")
29set(ARMCLANG_VERSION ${CMAKE_MATCH_1})
30
Raef Coles6d987ba2023-07-24 12:06:15 +010031if(NOT DEFINED CMAKE_OBJCOPY)
32 set(CMAKE_OBJCOPY ${CROSS_COMPILE}-objcopy CACHE FILEPATH "Path to objcopy")
33endif()
34
Dávid Házi50c18282024-10-10 12:37:28 +000035if (DEFINED TFM_SYSTEM_PROCESSOR)
36 set(CMAKE_SYSTEM_PROCESSOR ${TFM_SYSTEM_PROCESSOR})
Raef Coles69817322020-10-19 14:14:14 +010037
Dávid Házi50c18282024-10-10 12:37:28 +000038 if (TFM_SYSTEM_ARCHITECTURE STREQUAL "armv8.1-m.main")
39 message(WARNING "MVE is not yet supported using ARMCLANG")
40 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nomve")
41 endif()
42
43 if (DEFINED TFM_SYSTEM_DSP)
44 if(NOT TFM_SYSTEM_DSP)
45 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nodsp")
46 endif()
47 endif()
48
49 # ARMCLANG specifies that '+nofp' is available on following M-profile cpus:
50 # 'cortex-m4', 'cortex-m7', 'cortex-m33', 'cortex-m35p', 'cortex-m55' and 'cortex-m85'.
51 # Build fails if other M-profile cpu, such as 'cortex-m23', is added with '+nofp'.
52 # Explicitly list those cpu to align with ARMCLANG description.
53 if (NOT CONFIG_TFM_FLOAT_ABI STREQUAL "hard" AND
54 (TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m4"
55 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m7"
56 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m33"
57 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m35p"
58 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m55"
59 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m85"))
60 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nofp")
61 endif()
Dávid Házi50c18282024-10-10 12:37:28 +000062endif()
63
64# CMAKE_SYSTEM_ARCH is an ARMCLANG CMAKE internal variable, used to set
65# compile and linker flags up until CMake 3.21 where CMP0123 was introduced:
66# https://cmake.org/cmake/help/latest/policy/CMP0123.html
67# Another use of this variable is to statisfy a requirement for ARMCLANG to
68# set either the target CPU or the Architecture. This variable needs to be
69# set to allow targeting architectures without a specific CPU.
70set(CMAKE_SYSTEM_ARCH ${TFM_SYSTEM_ARCHITECTURE})
71
72set(CMAKE_C_COMPILER_TARGET arm-${CROSS_COMPILE})
73set(CMAKE_CXX_COMPILER_TARGET arm-${CROSS_COMPILE})
74set(CMAKE_ASM_COMPILER_TARGET arm-${CROSS_COMPILE})
75
76# MVE is currently not supported in case of armclang
77if (TFM_SYSTEM_ARCHITECTURE STREQUAL "armv8.1-m.main")
78 string(APPEND CMAKE_SYSTEM_ARCH "+nomve")
79endif()
80
81if (DEFINED TFM_SYSTEM_DSP)
82 if(NOT TFM_SYSTEM_DSP)
83 string(APPEND CMAKE_SYSTEM_ARCH "+nodsp")
84 endif()
85endif()
86
87# Cmake's ARMClang support has several issues with compiler validation. To
88# avoid these, we set the list of supported -mcpu and -march variables to
89# the ones we intend to use so that the validation will never fail.
90include(Compiler/ARMClang)
91set(CMAKE_C_COMPILER_PROCESSOR_LIST ${CMAKE_SYSTEM_PROCESSOR})
92set(CMAKE_C_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_ARCH})
93set(CMAKE_CXX_COMPILER_PROCESSOR_LIST ${CMAKE_SYSTEM_PROCESSOR})
94set(CMAKE_CXX_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_ARCH})
95set(CMAKE_ASM_COMPILER_PROCESSOR_LIST ${CMAKE_SYSTEM_PROCESSOR})
96set(CMAKE_ASM_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_ARCH})
97
98add_compile_options(
99 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-ignored-optimization-argument>
100 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-unused-command-line-argument>
101 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wall>
102 # Don't error when the MBEDTLS_NULL_ENTROPY warning is shown
103 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-error=cpp>
104 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-c>
105 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fdata-sections>
106 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-ffunction-sections>
107 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fno-builtin>
108 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fshort-enums>
109 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fshort-wchar>
110 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-funsigned-char>
111 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-masm=auto>
112 $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-nostdlib>
113 $<$<COMPILE_LANGUAGE:C>:-std=c99>
114 $<$<COMPILE_LANGUAGE:CXX>:-std=c++11>
Dávid Házi162b4212024-10-16 21:59:24 +0000115 $<$<COMPILE_LANGUAGE:ASM>:-masm=armasm>
Dávid Házi50c18282024-10-10 12:37:28 +0000116 $<$<AND:$<COMPILE_LANGUAGE:C>,$<BOOL:${TFM_DEBUG_SYMBOLS}>>:-g>
117 $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:${TFM_DEBUG_SYMBOLS}>>:-g>
Bohdan Hunkoc7d222b2024-11-05 16:37:21 +0200118 $<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<BOOL:${CONFIG_TFM_WARNINGS_ARE_ERRORS}>>:-Werror>
Dávid Házi50c18282024-10-10 12:37:28 +0000119)
120
121add_link_options(
122 ${MEMORY_USAGE_FLAG}
123 --strict
124 --symbols
125 --xref
126 $<$<AND:$<VERSION_GREATER:${TFM_ISOLATION_LEVEL},1>,$<STREQUAL:"${TEST_PSA_API}","IPC">>:--no-merge>
127 # Suppress link warnings that are consistant (and therefore hopefully
128 # harmless)
129 # https://developer.arm.com/documentation/100074/0608/linker-errors-and-warnings/list-of-the-armlink-error-and-warning-messages
130 # Empty region description
131 --diag_suppress=6312
132 # Ns section matches pattern
133 --diag_suppress=6314
134 # Duplicate input files
135 --diag_suppress=6304
136 # Pattern only matches removed unused sections.
137 --diag_suppress=6329
138)
Raef Coles69817322020-10-19 14:14:14 +0100139
Kevin Pengc32279d2022-02-10 11:11:55 +0800140if(CONFIG_TFM_MEMORY_USAGE_QUIET)
Jimmy Brisson1f9b7c82021-12-14 10:53:36 -0600141 set(MEMORY_USAGE_FLAG "")
142else()
143 set(MEMORY_USAGE_FLAG --info=summarysizes,sizes,totals,unused,veneers)
144endif()
145
Dávid Házi50c18282024-10-10 12:37:28 +0000146if (ARMCLANG_VERSION VERSION_LESS 6.13)
147 message(FATAL_ERROR "Please select newer Arm compiler version starting from 6.13.")
148endif()
Raef Coles69817322020-10-19 14:14:14 +0100149
Dávid Házi50c18282024-10-10 12:37:28 +0000150if (ARMCLANG_VERSION VERSION_GREATER_EQUAL 6.15 AND
151 ARMCLANG_VERSION VERSION_LESS 6.18)
152 message(FATAL_ERROR "Armclang 6.15~6.17 may cause MemManage fault."
153 " This defect has been fixed since Armclang 6.18."
154 " See [SDCOMP-59788] in Armclang 6.18 release note for details."
155 " Please use other Armclang versions instead.")
156endif()
157
158if (CMAKE_SYSTEM_PROCESSOR)
159 set(CMAKE_C_FLAGS "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
160 set(CMAKE_CXX_FLAGS "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
Dávid Házi162b4212024-10-16 21:59:24 +0000161 set(CMAKE_ASM_FLAGS "--target=${CMAKE_ASM_COMPILER_TARGET} -mcpu=${CMAKE_SYSTEM_PROCESSOR}")
Dávid Házi50c18282024-10-10 12:37:28 +0000162 set(CMAKE_C_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
163 set(CMAKE_CXX_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
164 set(CMAKE_ASM_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
165 # But armlink doesn't support this +dsp syntax
166 string(REGEX REPLACE "\\+nodsp" "" CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}")
167 string(REGEX REPLACE "\\+nodsp" "" CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
168 string(REGEX REPLACE "\\+nodsp" "" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
169 # And uses different syntax for +nofp
170 string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}")
171 string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
172 string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
173
174 string(REGEX REPLACE "\\+nomve" ".no_mve" CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}")
175 string(REGEX REPLACE "\\+nomve" ".no_mve" CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
176 string(REGEX REPLACE "\\+nomve" ".no_mve" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
177else()
178 set(CMAKE_C_FLAGS "-march=${CMAKE_SYSTEM_ARCH}")
179 set(CMAKE_CXX_FLAGS "-march=${CMAKE_SYSTEM_ARCH}")
180endif()
181
Dávid Házi50c18282024-10-10 12:37:28 +0000182set(BL2_COMPILER_CP_FLAG
Dávid Házi162b4212024-10-16 21:59:24 +0000183 -mfpu=softvfp
Dávid Házi50c18282024-10-10 12:37:28 +0000184)
185# As BL2 does not use hardware FPU, specify '--fpu=SoftVFP' explicitly to use software
186# library functions for BL2 to override any implicit FPU option, such as '--cpu' option.
187# Because the implicit hardware FPU option enforces BL2 to initialize FPU but hardware FPU
188# is not actually enabled in BL2, it will cause BL2 runtime fault.
189set(BL2_LINKER_CP_OPTION --fpu=SoftVFP)
190
191set(BL1_COMPILER_CP_FLAG
Dávid Házi162b4212024-10-16 21:59:24 +0000192 -mfpu=softvfp
Dávid Házi50c18282024-10-10 12:37:28 +0000193)
194set(BL1_LINKER_CP_OPTION --fpu=SoftVFP)
195
196if (CONFIG_TFM_FLOAT_ABI STREQUAL "hard")
197 set(COMPILER_CP_FLAG
198 $<$<COMPILE_LANGUAGE:C>:-mfloat-abi=hard>
Raef Coles9ec67e62020-07-10 09:40:35 +0100199 )
Dávid Házi50c18282024-10-10 12:37:28 +0000200 if (CONFIG_TFM_ENABLE_FP)
201 set(COMPILER_CP_FLAG
Dávid Házi162b4212024-10-16 21:59:24 +0000202 -mfpu=${CONFIG_TFM_FP_ARCH};-mfloat-abi=hard
Dávid Házi50c18282024-10-10 12:37:28 +0000203 )
204 # armasm and armlink have the same option "--fpu" and are both used to
205 # specify the target FPU architecture. So the supported FPU architecture
206 # names can be shared by armasm and armlink.
207 set(LINKER_CP_OPTION --fpu=${CONFIG_TFM_FP_ARCH_ASM})
Gabor Abonyi866571c2021-10-07 13:56:19 +0200208 endif()
Dávid Házi50c18282024-10-10 12:37:28 +0000209else()
210 set(COMPILER_CP_FLAG
Dávid Házi162b4212024-10-16 21:59:24 +0000211 -mfpu=softvfp
chesun01a94a9c72023-02-14 16:19:51 +0800212 )
Dávid Házi50c18282024-10-10 12:37:28 +0000213 set(LINKER_CP_OPTION --fpu=SoftVFP)
214endif()
chesun01ea11c822022-12-15 15:53:05 +0800215
Dávid Házi50c18282024-10-10 12:37:28 +0000216set(CMAKE_C_FLAGS_MINSIZEREL "-Oz -DNDEBUG")
217
218#
219# Pointer Authentication Code and Branch Target Identification (PACBTI) Options
220#
221if (${CONFIG_TFM_BRANCH_PROTECTION_FEAT} STREQUAL BRANCH_PROTECTION_NONE)
222 set(BRANCH_PROTECTION_OPTIONS "none")
223elseif(${CONFIG_TFM_BRANCH_PROTECTION_FEAT} STREQUAL BRANCH_PROTECTION_STANDARD)
224 set(BRANCH_PROTECTION_OPTIONS "standard")
225elseif(${CONFIG_TFM_BRANCH_PROTECTION_FEAT} STREQUAL BRANCH_PROTECTION_PACRET)
226 set(BRANCH_PROTECTION_OPTIONS "pac-ret")
227elseif(${CONFIG_TFM_BRANCH_PROTECTION_FEAT} STREQUAL BRANCH_PROTECTION_PACRET_LEAF)
228 set(BRANCH_PROTECTION_OPTIONS "pac-ret+leaf")
229elseif(${CONFIG_TFM_BRANCH_PROTECTION_FEAT} STREQUAL BRANCH_PROTECTION_BTI)
230 set(BRANCH_PROTECTION_OPTIONS "bti")
231endif()
232
233if(NOT ${CONFIG_TFM_BRANCH_PROTECTION_FEAT} STREQUAL BRANCH_PROTECTION_DISABLED)
234 if(ARMCLANG_VERSION VERSION_LESS 6.18)
235 message(FATAL_ERROR "Your compiler does not support BRANCH_PROTECTION")
chesun01ea11c822022-12-15 15:53:05 +0800236 else()
Dávid Házi50c18282024-10-10 12:37:28 +0000237 if((TFM_SYSTEM_PROCESSOR MATCHES "cortex-m85") AND
238 (TFM_SYSTEM_ARCHITECTURE STREQUAL "armv8.1-m.main"))
239 message(NOTICE "BRANCH_PROTECTION enabled with: ${BRANCH_PROTECTION_OPTIONS}")
chesun01ea11c822022-12-15 15:53:05 +0800240
Dávid Házi50c18282024-10-10 12:37:28 +0000241 string(APPEND CMAKE_C_FLAGS " -mbranch-protection=${BRANCH_PROTECTION_OPTIONS}")
242 string(APPEND CMAKE_CXX_FLAGS " -mbranch-protection=${BRANCH_PROTECTION_OPTIONS}")
Raef Colesd29c7f72020-11-05 14:12:06 +0000243
Dávid Házi50c18282024-10-10 12:37:28 +0000244 add_link_options(--library_security=pacbti-m)
Nicola Mazzucatofc1bf772024-05-07 16:21:33 +0100245 else()
Dávid Házi50c18282024-10-10 12:37:28 +0000246 message(FATAL_ERROR "Your architecture does not support BRANCH_PROTECTION")
Nicola Mazzucatofc1bf772024-05-07 16:21:33 +0100247 endif()
248 endif()
Dávid Házi50c18282024-10-10 12:37:28 +0000249endif()
Raef Coles69817322020-10-19 14:14:14 +0100250
Raef Coles9ec67e62020-07-10 09:40:35 +0100251# Behaviour for handling scatter files is so wildly divergent between compilers
252# that this macro is required.
253macro(target_add_scatter_file target)
254 target_link_options(${target}
255 PRIVATE
256 --scatter=$<TARGET_OBJECTS:${target}_scatter>
257 )
258
Raef Coles9ec67e62020-07-10 09:40:35 +0100259 add_library(${target}_scatter OBJECT)
260 foreach(scatter_file ${ARGN})
261 target_sources(${target}_scatter
262 PRIVATE
263 ${scatter_file}
264 )
265 # Cmake cannot use generator expressions in the
266 # set_source_file_properties command, so instead we just parse the regex
267 # for the filename and set the property on all files, regardless of if
268 # the generator expression would evaluate to true or not.
269 string(REGEX REPLACE ".*>:(.*)>$" "\\1" SCATTER_FILE_PATH "${scatter_file}")
270 set_source_files_properties(${SCATTER_FILE_PATH}
271 PROPERTIES
272 LANGUAGE C
Anton Komlev04cac672024-07-23 17:11:59 +0100273 KEEP_EXTENSION True # Don't use .o extension for the preprocessed file
Raef Coles9ec67e62020-07-10 09:40:35 +0100274 )
275 endforeach()
276
Anton Komlev1a103552022-02-11 15:40:26 +0000277 add_dependencies(${target}
278 ${target}_scatter
279 )
280
Anubhav Raina8a5d3b12024-07-10 18:15:57 +0100281 set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS $<TARGET_OBJECTS:${target}_scatter>)
Anton Komlev1a103552022-02-11 15:40:26 +0000282
Raef Coles9ec67e62020-07-10 09:40:35 +0100283 target_link_libraries(${target}_scatter
284 platform_region_defs
285 psa_interface
Xinyu Zhangeeb19ac2023-06-19 18:09:20 +0800286 tfm_config
Raef Coles9ec67e62020-07-10 09:40:35 +0100287 )
288
289 target_compile_options(${target}_scatter
290 PRIVATE
291 -E
292 -xc
293 )
Anton Komlev04cac672024-07-23 17:11:59 +0100294
295 # Scatter file shall be preprocessed by manifest tool in isolation level 2,3
296 add_dependencies(${target}_scatter
297 manifest_tool
298 )
Raef Coles9ec67e62020-07-10 09:40:35 +0100299endmacro()
300
301macro(add_convert_to_bin_target target)
302 get_target_property(bin_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
303
304 add_custom_target(${target}_bin
305 SOURCES ${bin_dir}/${target}.bin
306 )
307 add_custom_command(OUTPUT ${bin_dir}/${target}.bin
308 DEPENDS ${target}
309 COMMAND fromelf
310 --bincombined $<TARGET_FILE:${target}>
311 --output=${bin_dir}/${target}.bin
312 )
313
314 add_custom_target(${target}_elf
315 SOURCES ${bin_dir}/${target}.elf
316 )
317 add_custom_command(OUTPUT ${bin_dir}/${target}.elf
318 DEPENDS ${target}
319 COMMAND fromelf
320 --elf $<TARGET_FILE:${target}>
321 --output=${bin_dir}/${target}.elf
322 )
323
324 add_custom_target(${target}_hex
325 SOURCES ${bin_dir}/${target}.hex
326 )
327 add_custom_command(OUTPUT ${bin_dir}/${target}.hex
328 DEPENDS ${target}
329 COMMAND fromelf
330 --i32combined $<TARGET_FILE:${target}>
331 --output=${bin_dir}/${target}.hex
332 )
333
334 add_custom_target(${target}_binaries
335 ALL
336 DEPENDS ${target}_bin
337 DEPENDS ${target}_elf
338 DEPENDS ${target}_hex
339 )
340endmacro()
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000341
Anubhav Raina54c359a2023-12-07 14:09:06 +0000342macro(target_share_symbols target)
Raef Coles4351ec22021-04-26 09:20:50 +0100343 get_target_property(TARGET_TYPE ${target} TYPE)
344 if (NOT TARGET_TYPE STREQUAL "EXECUTABLE")
345 message(FATAL_ERROR "${target} is not an executable. Symbols cannot be shared from libraries.")
346 endif()
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000347
Bence Balogh027b6ba2024-04-09 16:34:06 +0200348 foreach(symbol_file ${ARGN})
Anubhav Raina54c359a2023-12-07 14:09:06 +0000349 FILE(STRINGS ${symbol_file} SYMBOLS
350 LENGTH_MINIMUM 1
351 )
352 list(APPEND KEEP_SYMBOL_LIST ${SYMBOLS})
353 endforeach()
354
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000355
Anubhav Raina053923e2024-07-11 11:57:49 +0100356 # strip all the symbols except those provided as arguments. Long inline
Raef Coles4351ec22021-04-26 09:20:50 +0100357 # python scripts aren't ideal, but this is both portable and possibly easier
358 # to maintain than trying to filter files at build time in cmake.
Anubhav Raina053923e2024-07-11 11:57:49 +0100359 add_custom_target(${target}_shared_symbols
Raef Coles4351ec22021-04-26 09:20:50 +0100360 VERBATIM
Anubhav Raina053923e2024-07-11 11:57:49 +0100361 COMMAND python3
362 -c "from sys import argv; import re; f = open(argv[1], 'rt'); p = [x.replace('*', '.*') for x in argv[2:]]; l = [x for x in f.readlines() if re.search(r'(?=('+'$|'.join(p + ['SYMDEFS']) + r'))', x)]; f.close(); f = open(argv[1], 'wt'); f.writelines(l); f.close();"
363 $<TARGET_FILE_DIR:${target}>/${target}${CODE_SHARING_OUTPUT_FILE_SUFFIX}
364 ${KEEP_SYMBOL_LIST}
365 )
366
367 # Ensure ${target} is build before $<TARGET_FILE:${target}> is used to generate ${target}_shared_symbols
368 add_dependencies(${target}_shared_symbols ${target})
369 # Allow the global clean target to rm the ${target}_shared_symbols created
370 set_target_properties(${target}_shared_symbols PROPERTIES
371 ADDITIONAL_CLEAN_FILES $<TARGET_FILE_DIR:${target}>/${target}${CODE_SHARING_OUTPUT_FILE_SUFFIX}
372 )
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000373
Raef Coles08b0c5c2023-05-03 11:56:28 +0100374 # Force the target to not remove the symbols if they're unused.
375 list(TRANSFORM KEEP_SYMBOL_LIST PREPEND --undefined=)
Raef Coles4351ec22021-04-26 09:20:50 +0100376 target_link_options(${target}
377 PRIVATE
378 ${KEEP_SYMBOL_LIST}
Bence Balogh52198b02024-06-20 15:50:12 +0200379 # This is needed because the symbol file can contain functions
380 # that are not defined in every build configuration.
381 # The L6474E is:
382 # "Symbol referenced by --undefined or --undefined_and_export
383 # switch could not be resolved by a static library."
384 --diag_warning 6474
Raef Coles4351ec22021-04-26 09:20:50 +0100385 )
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000386
Anubhav Raina053923e2024-07-11 11:57:49 +0100387 # Ask armclang to produce a symdefs file
Raef Coles4351ec22021-04-26 09:20:50 +0100388 target_link_options(${target}
389 PRIVATE
Raef Coles88ff7992024-01-11 10:27:05 +0000390 --symdefs=$<TARGET_FILE_DIR:${target}>/${target}${CODE_SHARING_OUTPUT_FILE_SUFFIX}
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000391 )
392endmacro()
393
Raef Coles4351ec22021-04-26 09:20:50 +0100394macro(target_link_shared_code target)
395 get_target_property(TARGET_SOURCE_DIR ${target} SOURCE_DIR)
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000396
Raef Coles4351ec22021-04-26 09:20:50 +0100397 foreach(symbol_provider ${ARGN})
398 if (TARGET ${symbol_provider})
399 get_target_property(SYMBOL_PROVIDER_TYPE ${symbol_provider} TYPE)
400 if (NOT SYMBOL_PROVIDER_TYPE STREQUAL "EXECUTABLE")
401 message(FATAL_ERROR "${symbol_provider} is not an executable. Symbols cannot be shared from libraries.")
402 endif()
403 endif()
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000404
Anubhav Raina053923e2024-07-11 11:57:49 +0100405 # Ensure ${symbol_provider}_shared_symbols is built before ${target}
406 add_dependencies(${target} ${symbol_provider}_shared_symbols)
407 # ${symbol_provider}_shared_symbols - a custom target is always considered out-of-date
408 # To only link when necessary, depend on ${symbol_provider} instead
409 set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS $<TARGET_OBJECTS:${symbol_provider}>)
Dávid Házif7ef8f02024-02-20 22:04:53 +0100410 target_link_options(${target} PRIVATE LINKER:$<TARGET_FILE_DIR:${symbol_provider}>/${symbol_provider}${CODE_SHARING_INPUT_FILE_SUFFIX})
Raef Coles4351ec22021-04-26 09:20:50 +0100411 endforeach()
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000412endmacro()
413
Raef Coles4351ec22021-04-26 09:20:50 +0100414macro(target_strip_symbols target)
415 set(SYMBOL_LIST "${ARGN}")
416 list(TRANSFORM SYMBOL_LIST PREPEND --strip-symbol=)
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000417
Raef Coles4351ec22021-04-26 09:20:50 +0100418 # TODO we assume that arm-none-eabi-objcopy is available - since we're using
419 # armclang this isn't necessarily true.
420 add_custom_command(
421 TARGET ${target}
422 POST_BUILD
Raef Coles6d987ba2023-07-24 12:06:15 +0100423 COMMAND ${CMAKE_OBJCOPY}
Raef Coles4351ec22021-04-26 09:20:50 +0100424 ARGS $<TARGET_FILE:${target}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${target}>
425 )
426endmacro()
427
428macro(target_strip_symbols_from_dependency target dependency)
429 set(SYMBOL_LIST "${ARGN}")
430 list(TRANSFORM SYMBOL_LIST PREPEND --strip-symbol=)
431
432 # TODO we assume that arm-none-eabi-objcopy is available - since we're using
433 # armclang this isn't necessarily true.
434 add_custom_command(
435 TARGET ${target}
436 PRE_LINK
Raef Coles6d987ba2023-07-24 12:06:15 +0100437 COMMAND ${CMAKE_OBJCOPY}
Raef Coles4351ec22021-04-26 09:20:50 +0100438 ARGS $<TARGET_FILE:${dependency}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${dependency}>
439 )
440endmacro()
441
442macro(target_weaken_symbols target)
443 set(SYMBOL_LIST "${ARGN}")
444 list(TRANSFORM SYMBOL_LIST PREPEND --weaken-symbol=)
445
446 # TODO we assume that arm-none-eabi-objcopy is available - since we're using
447 # armclang this isn't necessarily true.
448 add_custom_command(
449 TARGET ${target}
450 POST_BUILD
Raef Coles6d987ba2023-07-24 12:06:15 +0100451 COMMAND ${CMAKE_OBJCOPY}
Raef Coles4351ec22021-04-26 09:20:50 +0100452 ARGS $<TARGET_FILE:${target}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${target}>
453 )
454endmacro()
455
456macro(target_weaken_symbols_from_dependency target dependency)
457 set(SYMBOL_LIST "${ARGN}")
458 list(TRANSFORM SYMBOL_LIST PREPEND --weaken-symbol=)
459
460 # TODO we assume that arm-none-eabi-objcopy is available - since we're using
461 # armclang this isn't necessarily true.
462 add_custom_command(
463 TARGET ${target}
464 PRE_LINK
Raef Coles6d987ba2023-07-24 12:06:15 +0100465 COMMAND ${CMAKE_OBJCOPY}
Raef Coles4351ec22021-04-26 09:20:50 +0100466 ARGS $<TARGET_FILE:${dependency}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${dependency}>
Tamas Banf8b0b2d2020-10-26 13:03:13 +0000467 )
468endmacro()