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