1#------------------------------------------------------------------------------- 2# Copyright (c) 2020-2024, Arm Limited. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6#------------------------------------------------------------------------------- 7 8set(CMAKE_SYSTEM_NAME Generic) 9 10find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}-gcc) 11find_program(CMAKE_CXX_COMPILER ${CROSS_COMPILE}-g++) 12 13if(CMAKE_C_COMPILER STREQUAL "CMAKE_C_COMPILER-NOTFOUND") 14 message(FATAL_ERROR "Could not find compiler: '${CROSS_COMPILE}-gcc'") 15endif() 16 17if(CMAKE_CXX_COMPILER STREQUAL "CMAKE_CXX_COMPILER-NOTFOUND") 18 message(FATAL_ERROR "Could not find compiler: '${CROSS_COMPILE}-g++'") 19endif() 20 21set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) 22 23set(LINKER_VENEER_OUTPUT_FLAG -Wl,--cmse-implib,--out-implib=) 24set(COMPILER_CMSE_FLAG -mcmse) 25 26# This variable name is a bit of a misnomer. The file it is set to is included 27# at a particular step in the compiler initialisation. It is used here to 28# configure the extensions for object files. Despite the name, it also works 29# with the Ninja generator. 30set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_LIST_DIR}/cmake/set_extensions.cmake) 31 32# CMAKE_C_COMPILER_VERSION is not guaranteed to be defined. 33EXECUTE_PROCESS( COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION ) 34 35# ===================== SEt toolchain CPU and Arch ============================= 36 37if (DEFINED TFM_SYSTEM_PROCESSOR) 38 if(TFM_SYSTEM_PROCESSOR MATCHES "cortex-m85" AND GCC_VERSION VERSION_LESS "13.0.0") 39 # GNUARM until version 13 does not support the -mcpu=cortex-m85 flag 40 message(WARNING "Cortex-m85 is only supported from GCC13. " 41 "Falling back to -march usage for earlier versions.") 42 else() 43 set(CMAKE_SYSTEM_PROCESSOR ${TFM_SYSTEM_PROCESSOR}) 44 45 if (DEFINED TFM_SYSTEM_DSP) 46 if (NOT TFM_SYSTEM_DSP) 47 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nodsp") 48 endif() 49 endif() 50 # GCC specifies that '+nofp' is available on following M-profile cpus: 'cortex-m4', 51 # 'cortex-m7', 'cortex-m33', 'cortex-m35p' and 'cortex-m55'. 52 # Build fails if other M-profile cpu, such as 'cortex-m23', is added with '+nofp'. 53 # Explicitly list those cpu to align with GCC description. 54 if(GCC_VERSION VERSION_GREATER_EQUAL "8.0.0") 55 if(NOT CONFIG_TFM_ENABLE_FP AND 56 (TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m4" 57 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m7" 58 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m33" 59 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m35p" 60 OR TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m55")) 61 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nofp") 62 endif() 63 endif() 64 65 if(TFM_SYSTEM_ARCHITECTURE STREQUAL "armv8.1-m.main") 66 if(NOT CONFIG_TFM_ENABLE_MVE) 67 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nomve") 68 endif() 69 if(NOT CONFIG_TFM_ENABLE_MVE_FP) 70 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nomve.fp") 71 endif() 72 endif() 73 endif() 74 75endif() 76 77# CMAKE_SYSTEM_ARCH variable is not a built-in CMAKE variable. It is used to 78# set the compile and link flags when TFM_SYSTEM_PROCESSOR is not specified. 79# The variable name is choosen to align with the ARMCLANG toolchain file. 80set(CMAKE_SYSTEM_ARCH ${TFM_SYSTEM_ARCHITECTURE}) 81 82if(TFM_SYSTEM_ARCHITECTURE STREQUAL "armv8.1-m.main") 83 if(CONFIG_TFM_ENABLE_MVE) 84 string(APPEND CMAKE_SYSTEM_ARCH "+mve") 85 endif() 86 if(CONFIG_TFM_ENABLE_MVE_FP) 87 string(APPEND CMAKE_SYSTEM_ARCH "+mve.fp") 88 endif() 89endif() 90 91if (DEFINED TFM_SYSTEM_DSP) 92 # +nodsp modifier is only supported from GCC version 8. 93 if(GCC_VERSION VERSION_GREATER_EQUAL "8.0.0") 94 # armv8.1-m.main arch does not have +nodsp option 95 if ((NOT TFM_SYSTEM_ARCHITECTURE STREQUAL "armv8.1-m.main") AND 96 NOT TFM_SYSTEM_DSP) 97 string(APPEND CMAKE_SYSTEM_ARCH "+nodsp") 98 endif() 99 endif() 100endif() 101 102if(GCC_VERSION VERSION_GREATER_EQUAL "8.0.0") 103 if(CONFIG_TFM_ENABLE_FP) 104 string(APPEND CMAKE_SYSTEM_ARCH "+fp") 105 endif() 106endif() 107 108add_compile_options( 109 -specs=nano.specs 110 -specs=nosys.specs 111 -Wall 112 -Wno-format 113 -Wno-return-type 114 -Wno-unused-but-set-variable 115 -c 116 -fdata-sections 117 -ffunction-sections 118 -fno-builtin 119 -fshort-enums 120 -funsigned-char 121 -mthumb 122 $<$<COMPILE_LANGUAGE:C>:-std=c99> 123 $<$<COMPILE_LANGUAGE:CXX>:-std=c++11> 124 # Force DWARF version 4 for zephyr as pyelftools does not support version 5 at present 125 -gdwarf-4 126 $<$<OR:$<BOOL:${TFM_DEBUG_SYMBOLS}>,$<BOOL:${TFM_CODE_COVERAGE}>>:-g> 127) 128 129add_link_options( 130 --entry=Reset_Handler 131 -specs=nano.specs 132 -specs=nosys.specs 133 LINKER:-check-sections 134 LINKER:-fatal-warnings 135 LINKER:--gc-sections 136 LINKER:--no-wchar-size-warning 137) 138 139if(NOT CONFIG_TFM_MEMORY_USAGE_QUIET) 140 add_link_options(LINKER:--print-memory-usage) 141endif() 142 143if (GCC_VERSION VERSION_LESS 7.3.1) 144 message(FATAL_ERROR "Please use newer GNU Arm compiler version starting from 7.3.1.") 145endif() 146 147if (GCC_VERSION VERSION_EQUAL 10.2.1) 148 message(FATAL_ERROR "GNU Arm compiler version 10-2020-q4-major has an issue in CMSE support." 149 " Select other GNU Arm compiler versions instead." 150 " See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99157 for the issue detail.") 151endif() 152 153# GNU Arm compiler version greater equal than *11.3.Rel1* 154# has a linker issue that required system calls are missing, 155# such as _read and _write. Add stub functions of required 156# system calls to solve this issue. 157# 158# READONLY linker script attribute is not supported in older 159# GNU Arm compilers. For these version the preprocessor will 160# remove the READONLY string from the linker scripts. 161if (GCC_VERSION VERSION_GREATER_EQUAL 11.3.1) 162 set(CONFIG_GNU_SYSCALL_STUB_ENABLED TRUE) 163 set(CONFIG_GNU_LINKER_READONLY_ATTRIBUTE TRUE) 164endif() 165 166if (CMAKE_SYSTEM_PROCESSOR) 167 set(CMAKE_C_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}") 168 set(CMAKE_CXX_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}") 169 set(CMAKE_ASM_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}") 170 set(CMAKE_C_LINK_FLAGS "-mcpu=${CMAKE_SYSTEM_PROCESSOR}") 171 set(CMAKE_ASM_LINK_FLAGS "-mcpu=${CMAKE_SYSTEM_PROCESSOR}") 172else() 173 set(CMAKE_C_FLAGS_INIT "-march=${CMAKE_SYSTEM_ARCH}") 174 set(CMAKE_CXX_FLAGS_INIT "-march=${CMAKE_SYSTEM_ARCH}") 175 set(CMAKE_ASM_FLAGS_INIT "-march=${CMAKE_SYSTEM_ARCH}") 176 set(CMAKE_C_LINK_FLAGS "-march=${CMAKE_SYSTEM_ARCH}") 177 set(CMAKE_ASM_LINK_FLAGS "-march=${CMAKE_SYSTEM_ARCH}") 178endif() 179 180set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_INIT}) 181set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_INIT}) 182set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT}) 183 184set(BL2_COMPILER_CP_FLAG -mfloat-abi=soft) 185set(BL2_LINKER_CP_OPTION -mfloat-abi=soft) 186 187set(BL1_COMPILER_CP_FLAG -mfloat-abi=soft) 188set(BL1_LINKER_CP_OPTION -mfloat-abi=soft) 189 190if (CONFIG_TFM_FLOAT_ABI STREQUAL "hard") 191 set(COMPILER_CP_FLAG -mfloat-abi=hard) 192 set(LINKER_CP_OPTION -mfloat-abi=hard) 193 if (CONFIG_TFM_ENABLE_FP OR CONFIG_TFM_ENABLE_MVE_FP) 194 set(COMPILER_CP_FLAG -mfloat-abi=hard -mfpu=${CONFIG_TFM_FP_ARCH}) 195 set(LINKER_CP_OPTION -mfloat-abi=hard -mfpu=${CONFIG_TFM_FP_ARCH}) 196 endif() 197else() 198 set(COMPILER_CP_FLAG -mfloat-abi=soft) 199 set(LINKER_CP_OPTION -mfloat-abi=soft) 200endif() 201 202# For GNU Arm Embedded Toolchain doesn't emit __ARM_ARCH_8_1M_MAIN__, adding this macro manually. 203add_compile_definitions($<$<STREQUAL:${TFM_SYSTEM_ARCHITECTURE},armv8.1-m.main>:__ARM_ARCH_8_1M_MAIN__=1>) 204 205macro(target_add_scatter_file target) 206 target_link_options(${target} 207 PRIVATE 208 -T $<TARGET_OBJECTS:${target}_scatter> 209 ) 210 211 add_library(${target}_scatter OBJECT) 212 foreach(scatter_file ${ARGN}) 213 target_sources(${target}_scatter 214 PRIVATE 215 ${scatter_file} 216 ) 217 # Cmake cannot use generator expressions in the 218 # set_source_file_properties command, so instead we just parse the regex 219 # for the filename and set the property on all files, regardless of if 220 # the generator expression would evaluate to true or not. 221 string(REGEX REPLACE ".*>:(.*)>$" "\\1" SCATTER_FILE_PATH "${scatter_file}") 222 set_source_files_properties(${SCATTER_FILE_PATH} 223 PROPERTIES 224 LANGUAGE C 225 KEEP_EXTENSION True # Don't use .o extension for the preprocessed file 226 ) 227 endforeach() 228 229 add_dependencies(${target} 230 ${target}_scatter 231 ) 232 233 set_target_properties(${target} PROPERTIES LINK_DEPENDS $<TARGET_OBJECTS:${target}_scatter>) 234 235 target_link_libraries(${target}_scatter 236 platform_region_defs 237 psa_interface 238 tfm_config 239 ) 240 241 target_compile_options(${target}_scatter 242 PRIVATE 243 -E 244 -P 245 -xc 246 ) 247 248 target_compile_definitions(${target}_scatter 249 PRIVATE 250 $<$<NOT:$<BOOL:${CONFIG_GNU_LINKER_READONLY_ATTRIBUTE}>>:READONLY=> 251 ) 252endmacro() 253 254macro(add_convert_to_bin_target target) 255 get_target_property(bin_dir ${target} RUNTIME_OUTPUT_DIRECTORY) 256 257 add_custom_target(${target}_bin 258 SOURCES ${bin_dir}/${target}.bin 259 ) 260 add_custom_command(OUTPUT ${bin_dir}/${target}.bin 261 DEPENDS ${target} 262 COMMAND ${CMAKE_OBJCOPY} 263 -O binary $<TARGET_FILE:${target}> 264 ${bin_dir}/${target}.bin 265 ) 266 267 add_custom_target(${target}_elf 268 SOURCES ${bin_dir}/${target}.elf 269 ) 270 add_custom_command(OUTPUT ${bin_dir}/${target}.elf 271 DEPENDS ${target} 272 COMMAND ${CMAKE_OBJCOPY} 273 -O elf32-littlearm $<TARGET_FILE:${target}> 274 ${bin_dir}/${target}.elf 275 ) 276 277 add_custom_target(${target}_hex 278 SOURCES ${bin_dir}/${target}.hex 279 ) 280 add_custom_command(OUTPUT ${bin_dir}/${target}.hex 281 DEPENDS ${target} 282 COMMAND ${CMAKE_OBJCOPY} 283 -O ihex $<TARGET_FILE:${target}> 284 ${bin_dir}/${target}.hex 285 ) 286 287 add_custom_target(${target}_binaries 288 ALL 289 DEPENDS ${target}_bin 290 DEPENDS ${target}_elf 291 DEPENDS ${target}_hex 292 ) 293endmacro() 294 295macro(target_share_symbols target) 296 get_target_property(TARGET_TYPE ${target} TYPE) 297 if (NOT TARGET_TYPE STREQUAL "EXECUTABLE") 298 message(FATAL_ERROR "${target} is not an executable. Symbols cannot be shared from libraries.") 299 endif() 300 301 foreach(symbol_file ${ARGN}) 302 FILE(STRINGS ${symbol_file} SYMBOLS 303 LENGTH_MINIMUM 1 304 ) 305 list(APPEND KEEP_SYMBOL_LIST ${SYMBOLS}) 306 endforeach() 307 308 set(STRIP_SYMBOL_KEEP_LIST ${KEEP_SYMBOL_LIST}) 309 310 # Force the target to not remove the symbols if they're unused. 311 list(TRANSFORM KEEP_SYMBOL_LIST PREPEND "-Wl,--undefined=") 312 target_link_options(${target} 313 PRIVATE 314 ${KEEP_SYMBOL_LIST} 315 ) 316 317 list(TRANSFORM STRIP_SYMBOL_KEEP_LIST PREPEND --keep-symbol=) 318 # strip all the symbols except those proveded as arguments 319 add_custom_command( 320 TARGET ${target} 321 POST_BUILD 322 COMMAND ${CMAKE_OBJCOPY} 323 ARGS $<TARGET_FILE:${target}> --wildcard ${STRIP_SYMBOL_KEEP_LIST} --strip-all $<TARGET_FILE_DIR:${target}>/${target}${CODE_SHARING_OUTPUT_FILE_SUFFIX} 324 ) 325endmacro() 326 327macro(target_link_shared_code target) 328 foreach(symbol_provider ${ARGN}) 329 if (TARGET ${symbol_provider}) 330 get_target_property(SYMBOL_PROVIDER_TYPE ${symbol_provider} TYPE) 331 if (NOT SYMBOL_PROVIDER_TYPE STREQUAL "EXECUTABLE") 332 message(FATAL_ERROR "${symbol_provider} is not an executable. Symbols cannot be shared from libraries.") 333 endif() 334 endif() 335 336 add_dependencies(${target} ${symbol_provider}) 337 target_link_options(${target} PRIVATE LINKER:-R$<TARGET_FILE_DIR:${symbol_provider}>/${symbol_provider}${CODE_SHARING_INPUT_FILE_SUFFIX}) 338 endforeach() 339endmacro() 340 341macro(target_strip_symbols target) 342 set(SYMBOL_LIST "${ARGN}") 343 list(TRANSFORM SYMBOL_LIST PREPEND --strip-symbol=) 344 345 add_custom_command( 346 TARGET ${target} 347 POST_BUILD 348 COMMAND ${CMAKE_OBJCOPY} 349 ARGS $<TARGET_FILE:${target}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${target}> 350 ) 351endmacro() 352 353macro(target_strip_symbols_from_dependency target dependency) 354 set(SYMBOL_LIST "${ARGN}") 355 list(TRANSFORM SYMBOL_LIST PREPEND --strip-symbol=) 356 357 add_custom_command( 358 TARGET ${target} 359 PRE_LINK 360 COMMAND ${CMAKE_OBJCOPY} 361 ARGS $<TARGET_FILE:${dependency}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${dependency}> 362 ) 363endmacro() 364 365macro(target_weaken_symbols target) 366 set(SYMBOL_LIST "${ARGN}") 367 list(TRANSFORM SYMBOL_LIST PREPEND --weaken-symbol=) 368 369 add_custom_command( 370 TARGET ${target} 371 POST_BUILD 372 COMMAND ${CMAKE_OBJCOPY} 373 ARGS $<TARGET_FILE:${target}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${target}> 374 ) 375endmacro() 376 377macro(target_weaken_symbols_from_dependency target dependency) 378 set(SYMBOL_LIST "${ARGN}") 379 list(TRANSFORM SYMBOL_LIST PREPEND --weaken-symbol=) 380 381 add_custom_command( 382 TARGET ${target} 383 PRE_LINK 384 COMMAND ${CMAKE_OBJCOPY} 385 ARGS $<TARGET_FILE:${dependency}> --wildcard ${SYMBOL_LIST} $<TARGET_FILE:${dependency}> 386 ) 387endmacro() 388 389# A dummy macro to align with Armclang workaround 390macro(tfm_toolchain_reload_compiler) 391endmacro() 392