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