1# SPDX-License-Identifier: Apache-2.0 2 3# *DOCUMENTATION* 4# 5# Note that this is *NOT* the top-level CMakeLists.txt. That's in the 6# application. See the Application Development Primer documentation 7# for details. 8# 9# To see a list of typical targets execute "make usage" 10# More info can be located in ./README.rst 11# Comments in this file are targeted only to the developer, do not 12# expect to learn how to build the kernel reading this file. 13 14if(NOT DEFINED ZEPHYR_BINARY_DIR) 15 message(FATAL_ERROR "A user error has occurred. 16cmake was invoked with '${CMAKE_CURRENT_LIST_DIR}' specified as the source directory, 17but it must be invoked with an application source directory, 18such as '${CMAKE_CURRENT_LIST_DIR}/samples/hello_world'. 19Debug variables: 20CMAKE_CACHEFILE_DIR: ${CMAKE_CACHEFILE_DIR} 21") 22endif() 23 24 25# See https://gitlab.kitware.com/cmake/cmake/issues/16228 26# and https://cmake.org/pipermail/cmake/2019-May/thread.html#69496 27if(NOT ZEPHYR_BASE STREQUAL CMAKE_CURRENT_SOURCE_DIR) 28message(WARNING "ZEPHYR_BASE doesn't match CMAKE_CURRENT_SOURCE_DIR 29 ZEPHYR_BASE = ${ZEPHYR_BASE} 30 PWD = $ENV{PWD} 31 CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR} 32You may be using a mix of symbolic links and real paths which causes \ 33subtle and hard to debug CMake issues.") 34endif() 35# For Zephyr more specifically this breaks (at least) 36# -fmacro-prefix-map=${ZEPHYR_BASE}= 37 38 39# In some cases the "final" things are not used at all and "_prebuilt" 40# is the last station. See "logical_target_for_zephyr_elf" below for 41# details. 42set(CMAKE_EXECUTABLE_SUFFIX .elf) 43 44# Zephyr build system will use a dynamic number of linking stages based on build 45# configuration. 46# 47# Currently up to three linking stages may be executed: 48# zephyr_pre0: First linking stage 49# zephyr_pre1: Second linking stage 50# zephyr_final: Final linking stage 51# 52# There will at minimum be a single linking stage. 53# When only a single linking stage is required, the `zephyr_pre0` will be mapped 54# into the `zephyr_final` target. 55# 56# Multiple linking stages are required in the following cases: 57# - device dependencies structs must be generated (CONFIG_DEVICE_DEPS=y) 58# - ISR tables must be generated (CONFIG_GEN_ISR_TABLES=y) 59# - Kernel objects hash tables (CONFIG_USERSPACE=y) 60# - Application memory partitions (CONFIG_USERSPACE=y) 61# 62# Some generators require that memory locations has been fixed, thus those are 63# placed at the second linking stage. 64# 65# When all three linking stages are active, then the following properties applies: 66# - zephyr_pre0: linker sections may resize / addresses may relocate 67# - zephyr_pre1: All linker section sizes are fixed, addresses cannot change 68# - zephyr_final: Final image. 69# 70set(ZEPHYR_CURRENT_LINKER_PASS 0) 71set(ZEPHYR_CURRENT_LINKER_CMD linker_zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}.cmd) 72set(ZEPHYR_LINK_STAGE_EXECUTABLE zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}) 73 74# ZEPHYR_PREBUILT_EXECUTABLE is used outside of this file, therefore keep the 75# existing variable to allow slowly cleanup of linking stage handling. 76# Three stage linking active: pre0 -> pre1 -> final, this will correspond to `pre1` 77# Two stage linking active: pre0 -> final, this will correspond to `pre0` 78if(CONFIG_USERSPACE OR CONFIG_DEVICE_DEPS) 79 set(ZEPHYR_PREBUILT_EXECUTABLE zephyr_pre1) 80else() 81 set(ZEPHYR_PREBUILT_EXECUTABLE zephyr_pre0) 82endif() 83set(ZEPHYR_FINAL_EXECUTABLE zephyr_final) 84 85# Set some phony targets to collect dependencies 86set(OFFSETS_H_TARGET offsets_h) 87set(SYSCALL_LIST_H_TARGET syscall_list_h_target) 88set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target) 89set(KOBJ_TYPES_H_TARGET kobj_types_h_target) 90set(PARSE_SYSCALLS_TARGET parse_syscalls_target) 91 92define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ") 93set_property( GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little${ARCH}) # BFD format 94 95# Contains the list of files with syscall function prototypes. 96add_library(syscalls_interface INTERFACE) 97set(syscalls_file_list_output 98 ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_file_list.txt) 99 100# "zephyr_interface" is a source-less library that encapsulates all the global 101# compiler options needed by all source files. All zephyr libraries, 102# including the library named "zephyr" link with this library to 103# obtain these flags. 104# https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#interface-libraries 105add_library(zephyr_interface INTERFACE) 106 107# "zephyr" is a catch-all CMake library for source files that can be 108# built purely with the include paths, defines, and other compiler 109# flags that come with zephyr_interface. 110zephyr_library_named(zephyr) 111 112if(CONFIG_LEGACY_GENERATED_INCLUDE_PATH) 113 zephyr_include_directories(${PROJECT_BINARY_DIR}/include/generated/zephyr) 114endif() 115 116zephyr_include_directories( 117 include 118 ${PROJECT_BINARY_DIR}/include/generated 119 ${USERINCLUDE} 120 ${STDINCLUDE} 121) 122 123include(${ZEPHYR_BASE}/cmake/linker_script/${ARCH}/linker.cmake OPTIONAL) 124 125zephyr_include_directories(${SOC_FULL_DIR}) 126 127# Don't inherit compiler flags from the environment 128foreach(var AFLAGS CFLAGS CXXFLAGS CPPFLAGS LDFLAGS) 129 if(DEFINED ENV{${var}}) 130 message(WARNING "The environment variable '${var}' was set to $ENV{${var}}, " 131 "but Zephyr ignores flags from the environment. Use 'cmake " 132 "-DEXTRA_${var}=$ENV{${var}}' instead." 133 ) 134 unset(ENV{${var}}) 135 endif() 136endforeach() 137 138zephyr_compile_definitions( 139 KERNEL 140 __ZEPHYR__=1 141) 142 143# Ensure that include/zephyr/toolchain.h includes toolchain/other.h for all off-tree toolchains 144if(TOOLCHAIN_USE_CUSTOM) 145 zephyr_compile_definitions(__TOOLCHAIN_CUSTOM__) 146endif() 147 148# @Intent: Set compiler specific flag for disabling strict aliasing rule 149zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,no_strict_aliasing>>) 150zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,no_strict_aliasing>>) 151 152# Extra warnings options for twister run 153if (CONFIG_COMPILER_WARNINGS_AS_ERRORS) 154 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warnings_as_errors>>) 155 zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:$<TARGET_PROPERTY:asm,warnings_as_errors>>) 156 zephyr_link_libraries($<TARGET_PROPERTY:linker,warnings_as_errors>) 157endif() 158 159# @Intent: Set compiler flags to enable buffer overflow checks in libc functions 160# @details: 161# Kconfig.zephyr "Detect buffer overflows in libc calls" is a kconfig choice, 162# ensuring at most *one* of CONFIG_FORTIFY_SOURCE_{COMPILE_TIME,RUN_TIME} is 163# set. Refer to Kconfig.zephyr for selection logic and description of these 164# choices. Toolchains set both of the security_fortify_{compile_time,run_time} 165# properties and the Kconfig settings are used here to select between those. 166# 167if(CONFIG_FORTIFY_SOURCE_RUN_TIME) 168 zephyr_compile_definitions($<TARGET_PROPERTY:compiler,security_fortify_run_time> ) 169elseif(CONFIG_FORTIFY_SOURCE_COMPILE_TIME) 170 zephyr_compile_definitions($<TARGET_PROPERTY:compiler,security_fortify_compile_time> ) 171endif() 172 173# @Intent: Set compiler flags to detect general stack overflows across all functions 174if(CONFIG_STACK_CANARIES) 175 zephyr_compile_options($<TARGET_PROPERTY:compiler,security_canaries>) 176endif() 177 178# @Intent: Obtain compiler optimizations flags and store in variables 179# @details: 180# Kconfig.zephyr "Optimization level" is a kconfig choice, ensuring 181# only *one* of CONFIG_{NO,DEBUG,SPEED,SIZE}_OPTIMIZATIONS is set. 182# Refer to Kconfig.zephyr for selection logic and description of these choices. 183# toolchain_cc_optimize_*() macros must provide the mapping from these kconfigs 184# to compiler flags. Each macro will store the flags in a CMake variable, whose 185# name is passed as argument (somewhat like by reference). 186# 187# If the user wants to tweak the optimizations, there are two ways: 188# 1) Using EXTRA_CFLAGS which is applied regardless of kconfig choice, or 189# 2) Rely on override support being implemented by your toolchain_cc_optimize_*() 190# 191get_property(OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG TARGET compiler PROPERTY no_optimization) 192get_property(OPTIMIZE_FOR_DEBUG_FLAG TARGET compiler PROPERTY optimization_debug) 193get_property(OPTIMIZE_FOR_SPEED_FLAG TARGET compiler PROPERTY optimization_speed) 194get_property(OPTIMIZE_FOR_SIZE_FLAG TARGET compiler PROPERTY optimization_size) 195get_property(OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG TARGET compiler PROPERTY optimization_size_aggressive) 196 197# From kconfig choice, pick the actual OPTIMIZATION_FLAG to use. 198# Kconfig choice ensures only one of these CONFIG_*_OPTIMIZATIONS is set. 199if(CONFIG_NO_OPTIMIZATIONS) 200 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG}) 201elseif(CONFIG_DEBUG_OPTIMIZATIONS) 202 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_DEBUG_FLAG}) 203elseif(CONFIG_SPEED_OPTIMIZATIONS) 204 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SPEED_FLAG}) 205elseif(CONFIG_SIZE_OPTIMIZATIONS) 206 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SIZE_FLAG}) # Default in kconfig 207elseif(CONFIG_SIZE_OPTIMIZATIONS_AGGRESSIVE) 208 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG}) 209else() 210 message(FATAL_ERROR 211 "Unreachable code. Expected optimization level to have been chosen. See Kconfig.zephyr") 212endif() 213 214if(NOT CONFIG_ARCH_IS_SET) 215 message(WARNING "\ 216None of the CONFIG_<arch> (e.g. CONFIG_X86) symbols are set. \ 217Select one of them from the SOC_SERIES_* symbol or, lacking that, from the \ 218SOC_* symbol.") 219endif() 220 221# Apply the final optimization flag(s) 222zephyr_compile_options(${OPTIMIZATION_FLAG}) 223 224if(CONFIG_LTO) 225 zephyr_compile_options($<TARGET_PROPERTY:compiler,optimization_lto>) 226 add_link_options($<TARGET_PROPERTY:linker,lto_arguments>) 227endif() 228 229if(CONFIG_STD_C23) 230 set(CSTD c2x) 231elseif(CONFIG_STD_C17) 232 set(CSTD c17) 233elseif(CONFIG_STD_C11) 234 set(CSTD c11) 235elseif(CONFIG_STD_C99) 236 set(CSTD c99) 237elseif(CONFIG_STD_C90) 238 set(CSTD c90) 239else() 240 message(FATAL_ERROR "Unreachable code. Expected C standard to have been chosen.") 241endif() 242 243if(CONFIG_GNU_C_EXTENSIONS) 244 string(REPLACE "c" "gnu" CSTD "${CSTD}") 245endif() 246 247list(APPEND CMAKE_C_COMPILE_FEATURES ${compile_features_${CSTD}}) 248 249# @Intent: Obtain compiler specific flags related to C++ that are not influenced by kconfig 250zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,required>>) 251 252# @Intent: Obtain compiler specific flags for compiling under different ISO standards of C++ 253if(CONFIG_CPP) 254 # From kconfig choice, pick a single dialect. 255 # Kconfig choice ensures only one of these CONFIG_STD_CPP* is set. 256 if(CONFIG_STD_CPP98) 257 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp98>) 258 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp98}) 259 elseif(CONFIG_STD_CPP11) 260 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp11>) # Default in kconfig 261 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp11}) 262 elseif(CONFIG_STD_CPP14) 263 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp14>) 264 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp14}) 265 elseif(CONFIG_STD_CPP17) 266 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp17>) 267 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp17}) 268 elseif(CONFIG_STD_CPP2A) 269 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp2a>) 270 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp20}) 271 elseif(CONFIG_STD_CPP20) 272 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp20>) 273 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp20}) 274 elseif(CONFIG_STD_CPP2B) 275 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp2b>) 276 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp20}) 277 else() 278 message(FATAL_ERROR 279 "Unreachable code. Expected C++ standard to have been chosen. See Kconfig.zephyr.") 280 endif() 281 set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE) 282 283 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:${STD_CPP_DIALECT_FLAGS}>) 284endif() 285 286if(NOT CONFIG_CPP_EXCEPTIONS) 287 # @Intent: Obtain compiler specific flags related to C++ Exceptions 288 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,no_exceptions>>) 289endif() 290 291if(NOT CONFIG_CPP_RTTI) 292 # @Intent: Obtain compiler specific flags related to C++ Run Time Type Information 293 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,no_rtti>>) 294endif() 295 296if(CONFIG_MISRA_SANE) 297 # @Intent: Obtain toolchain compiler flags relating to MISRA. 298 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_misra_sane>>) 299 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_error_misra_sane>>) 300endif() 301 302# This is intend to be temporary. Once we have fixed the violations that 303# prevents build Zephyr, these flags shall be part of the default flags. 304if(CONFIG_CODING_GUIDELINE_CHECK) 305 # @Intent: Obtain toolchain compiler flags relating to coding guideline 306 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_coding_guideline>>) 307endif() 308 309# @Intent: Set compiler specific macro inclusion of AUTOCONF_H 310zephyr_compile_options("SHELL: $<TARGET_PROPERTY:compiler,imacros> ${AUTOCONF_H}") 311 312if(CONFIG_COMPILER_FREESTANDING) 313 # @Intent: Set compiler specific flag for bare metal freestanding option 314 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,freestanding>>) 315 zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:$<TARGET_PROPERTY:compiler,freestanding>>) 316endif() 317 318if (CONFIG_PICOLIBC AND NOT CONFIG_PICOLIBC_IO_FLOAT) 319 # @Intent: Set compiler specific flag to disable printf-related optimizations 320 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,no_printf_return_value>>) 321endif() 322 323# @Intent: Set compiler specific flag for tentative definitions, no-common 324zephyr_compile_options($<TARGET_PROPERTY:compiler,no_common>) 325 326# @Intent: Set compiler specific flag for production of debug information 327zephyr_compile_options($<TARGET_PROPERTY:compiler,debug>) 328 329if(CONFIG_COMPILER_SAVE_TEMPS) 330 # @Intent: Set compiler specific flag for saving temporary object files 331 zephyr_compile_options($<TARGET_PROPERTY:compiler,save_temps>) 332endif() 333 334if(NOT CONFIG_COMPILER_TRACK_MACRO_EXPANSION) 335 # @Intent: Set compiler specific flags to not track macro expansion 336 zephyr_compile_options($<TARGET_PROPERTY:compiler,no_track_macro_expansion>) 337endif() 338 339if(CONFIG_COMPILER_COLOR_DIAGNOSTICS) 340# @Intent: Set compiler specific flag for diagnostic messages 341zephyr_compile_options($<TARGET_PROPERTY:compiler,diagnostic>) 342endif() 343 344zephyr_compile_options( 345 ${TOOLCHAIN_C_FLAGS} 346) 347 348# @Intent: Obtain compiler specific flags related to assembly 349# ToDo: Remember to get feedback from Oticon on this, as they might use the `ASM_BASE_FLAG` since this is done this way. 350zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:$<TARGET_PROPERTY:asm,required>>) 351 352# @Intent: Enforce standard integer type correspondence to match Zephyr usage. 353# (must be after compiler specific flags) 354if(CONFIG_ENFORCE_ZEPHYR_STDINT) 355 zephyr_compile_options("SHELL: $<TARGET_PROPERTY:compiler,imacros> ${ZEPHYR_BASE}/include/zephyr/toolchain/zephyr_stdint.h") 356endif() 357 358# Common toolchain-agnostic assembly flags 359zephyr_compile_options( 360 $<$<COMPILE_LANGUAGE:ASM>:-D_ASMLANGUAGE> 361) 362 363# @Intent: Set fundamental linker specific flags 364toolchain_ld_base() 365 366toolchain_ld_force_undefined_symbols( 367 _OffsetAbsSyms 368 _ConfigAbsSyms 369) 370 371if(NOT CONFIG_NATIVE_BUILD) 372 # @Intent: Set linker specific flags for bare metal target 373 toolchain_ld_baremetal() 374endif() 375 376if(CONFIG_CPP AND NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY) 377 # @Intent: Set linker specific flags for C++ 378 toolchain_ld_cpp() 379endif() 380 381# @Intent: Add the basic toolchain warning flags 382zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_base>>) 383zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_base>>) 384 385# ========================================================================== 386# 387# cmake -DW=... settings 388# 389# W=1 - warnings that may be relevant and does not occur too often 390# W=2 - warnings that occur quite often but may still be relevant 391# W=3 - the more obscure warnings, can most likely be ignored 392# ========================================================================== 393# @Intent: Add cmake -DW toolchain supported warnings, if any 394if(W MATCHES "1") 395 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_1>>) 396 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_1>>) 397endif() 398 399if(W MATCHES "2") 400 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_2>>) 401 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_2>>) 402endif() 403 404if(W MATCHES "3") 405 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_3>>) 406 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_3>>) 407endif() 408 409# @Intent: Add extended, more specific, toolchain warning flags 410zephyr_compile_options($<TARGET_PROPERTY:compiler,warning_extended>) 411 412# @Intent: Trigger an error when a declaration does not specify a type 413zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_implicit_int>>) 414zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_error_implicit_int>>) 415 416# @Intent: Do not make position independent code / executable 417zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,no_position_independent>>) 418zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler,no_position_independent>>) 419 420# In case of CONFIG_NATIVE_LIBRARY we also don't want position independent code, 421# but we cannot tell that to the linker yet as we are first only doing a 422# relocatable link into a static library 423zephyr_link_libraries_ifndef(CONFIG_NATIVE_LIBRARY 424 $<TARGET_PROPERTY:linker,no_position_independent>) 425 426# Allow the user to inject options when calling cmake, e.g. 427# 'cmake -DEXTRA_CFLAGS="-Werror -Wno-deprecated-declarations" ..' 428include(cmake/extra_flags.cmake) 429 430zephyr_cc_option(-fno-asynchronous-unwind-tables) 431 432if(CONFIG_USERSPACE) 433 zephyr_compile_options($<TARGET_PROPERTY:compiler,no_global_merge>) 434endif() 435 436if(CONFIG_THREAD_LOCAL_STORAGE) 437# Only support local exec TLS model at this point. 438zephyr_cc_option(-ftls-model=local-exec) 439endif() 440 441if(CONFIG_OVERRIDE_FRAME_POINTER_DEFAULT) 442 if(CONFIG_OMIT_FRAME_POINTER) 443 zephyr_cc_option(-fomit-frame-pointer) 444 else() 445 zephyr_cc_option(-fno-omit-frame-pointer) 446 endif() 447endif() 448 449separate_arguments(COMPILER_OPT_AS_LIST UNIX_COMMAND ${CONFIG_COMPILER_OPT}) 450zephyr_compile_options(${COMPILER_OPT_AS_LIST}) 451 452# TODO: Include arch compiler options at this point. 453 454if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang" AND 455 NOT CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM" AND 456 NOT CMAKE_C_COMPILER_ID STREQUAL "ARMClang") 457 # GCC assumed 458 zephyr_cc_option(-fno-reorder-functions) 459 460 # GCC 11 and above may generate a warning when dereferencing a constant 461 # address pointer whose address is below the value specified by the 462 # `min-pagesize` parameter (defaults to 0x1000). The `min-pagesize` parameter 463 # is set to 0 such that GCC never generates any warnings for the constant 464 # address pointers. For more details, refer to the GCC PR99578. 465 zephyr_cc_option(--param=min-pagesize=0) 466 467 if(NOT ${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "xcc") 468 zephyr_cc_option(-fno-defer-pop) 469 endif() 470else() 471 # Clang produces false positive vla warnings 472 zephyr_cc_option(-Wno-vla) 473endif() 474 475zephyr_cc_option_ifdef(CONFIG_STACK_USAGE -fstack-usage) 476 477# If the compiler supports it, strip the ${ZEPHYR_BASE} prefix from the 478# __FILE__ macro used in __ASSERT*, in the 479# .noinit."/home/joe/zephyr/fu/bar.c" section names and in any 480# application code. This saves some memory, stops leaking user locations 481# in binaries, makes failure logs more deterministic and most 482# importantly makes builds more deterministic 483if(CONFIG_BUILD_OUTPUT_STRIP_PATHS) 484 # If several match then the last one wins. This matters for instances 485 # like tests/ and samples/: they're inside all of them! Then let's 486 # strip as little as possible. 487 zephyr_cc_option(-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=CMAKE_SOURCE_DIR) 488 zephyr_cc_option(-fmacro-prefix-map=${ZEPHYR_BASE}=ZEPHYR_BASE) 489 if(WEST_TOPDIR) 490 zephyr_cc_option(-fmacro-prefix-map=${WEST_TOPDIR}=WEST_TOPDIR) 491 endif() 492endif() 493 494# TODO: Archiver arguments 495# ar_option(D) 496 497# Declare MPU userspace dependencies before the linker scripts to make 498# sure the order of dependencies are met 499if(CONFIG_USERSPACE) 500 add_custom_target(app_smem) 501 set(APP_SMEM_ALIGNED_DEP app_smem_aligned_linker) 502 set(APP_SMEM_UNALIGNED_DEP app_smem_unaligned_linker) 503endif() 504 505if(CONFIG_USERSPACE) 506 set(KOBJECT_LINKER_DEP kobject_linker) 507endif() 508 509if(DEFINED BUILD_VERSION) 510 set(build_version_argument "-DBUILD_VERSION=${BUILD_VERSION}") 511elseif(NOT ZEPHYR_GIT_INDEX) 512 if(EXISTS ${ZEPHYR_BASE}/.git/index) 513 set(ZEPHYR_GIT_INDEX ${ZEPHYR_BASE}/.git/index CACHE PATH 514 "Path to Zephyr git repository index file") 515 elseif(EXISTS ${ZEPHYR_BASE}/.git) 516 # Likely a git-submodule. Let's ask git where the real database is located. 517 find_package(Git QUIET) 518 if(GIT_FOUND) 519 execute_process( 520 COMMAND ${GIT_EXECUTABLE} rev-parse --absolute-git-dir 521 WORKING_DIRECTORY ${ZEPHYR_BASE} 522 OUTPUT_VARIABLE zephyr_git_dir 523 OUTPUT_STRIP_TRAILING_WHITESPACE 524 ERROR_STRIP_TRAILING_WHITESPACE 525 ERROR_VARIABLE stderr 526 RESULT_VARIABLE return_code) 527 if(return_code) 528 message(WARNING "BUILD_VERSION: git rev-parse failed: ${stderr}") 529 else() 530 if(NOT "${stderr}" STREQUAL "") 531 message(WARNING "BUILD_VERSION: git rev-parse warned: ${stderr}") 532 endif() 533 set(ZEPHYR_GIT_INDEX ${zephyr_git_dir}/index CACHE PATH 534 "Path to Zephyr git repository index file") 535 endif() 536 else() 537 message(WARNING "Could not find git installation, " 538 "please specify '-DBUILD_VERSION=<version>'") 539 endif() 540 else() 541 message(WARNING "ZEPHYR_BASE=${ZEPHYR_BASE} doesn't appear to be a git " 542 "repository, please specify '-DBUILD_VERSION=<version>'") 543 endif() 544endif() 545 546if(ZEPHYR_GIT_INDEX) 547 set(git_dependency ${ZEPHYR_GIT_INDEX}) 548endif() 549 550add_custom_command( 551 OUTPUT ${PROJECT_BINARY_DIR}/include/generated/zephyr/version.h 552 COMMAND ${CMAKE_COMMAND} -DZEPHYR_BASE=${ZEPHYR_BASE} 553 -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/zephyr/version.h 554 -DVERSION_TYPE=KERNEL 555 -DVERSION_FILE=${ZEPHYR_BASE}/VERSION 556 -DKERNEL_VERSION_CUSTOMIZATION="$<TARGET_PROPERTY:version_h,KERNEL_VERSION_CUSTOMIZATION>" 557 ${build_version_argument} 558 -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake 559 DEPENDS ${ZEPHYR_BASE}/VERSION ${git_dependency} 560 COMMAND_EXPAND_LISTS 561) 562add_custom_target(version_h DEPENDS ${PROJECT_BINARY_DIR}/include/generated/zephyr/version.h) 563 564if(EXISTS ${APPLICATION_SOURCE_DIR}/VERSION) 565 add_custom_command( 566 OUTPUT ${PROJECT_BINARY_DIR}/include/generated/zephyr/app_version.h 567 COMMAND ${CMAKE_COMMAND} -DZEPHYR_BASE=${ZEPHYR_BASE} 568 -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/zephyr/app_version.h 569 -DVERSION_TYPE=APP 570 -DVERSION_FILE=${APPLICATION_SOURCE_DIR}/VERSION 571 -DAPP_VERSION_CUSTOMIZATION="$<TARGET_PROPERTY:app_version_h,APP_VERSION_CUSTOMIZATION>" 572 ${build_version_argument} 573 -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake 574 DEPENDS ${APPLICATION_SOURCE_DIR}/VERSION ${git_dependency} 575 COMMAND_EXPAND_LISTS 576 ) 577 add_custom_target( 578 app_version_h 579 DEPENDS ${PROJECT_BINARY_DIR}/include/generated/zephyr/app_version.h) 580 add_dependencies(zephyr_interface app_version_h) 581endif() 582 583# Unfortunately, the order in which CMakeLists.txt code is processed 584# matters so we need to be careful about how we order the processing 585# of subdirectories. One example is "Compiler flags added late in the 586# build are not exported to external build systems #5605"; when we 587# integrate with an external build system we read out all compiler 588# flags when the external project is created. So an external project 589# defined in subsys or ext will not get global flags added by drivers/ 590# or tests/ as the subdirectories are ordered now. 591# 592# Another example of when the order matters is the reading and writing 593# of global properties such as ZEPHYR_LIBS or 594# GENERATED_KERNEL_OBJECT_FILES. 595# 596# Arch is placed early because it defines important compiler flags 597# that must be exported to external build systems defined in 598# e.g. subsys/. 599add_subdirectory(arch) 600add_subdirectory(lib) 601# We use include instead of add_subdirectory to avoid creating a new directory scope. 602# This is because source file properties are directory scoped, including the GENERATED 603# property which is set implicitly for custom command outputs 604include(misc/generated/CMakeLists.txt) 605 606add_subdirectory(soc) 607add_subdirectory(boards) 608add_subdirectory(subsys) 609add_subdirectory(drivers) 610 611# Include zephyr modules generated CMake file. 612foreach(module_name ${ZEPHYR_MODULE_NAMES}) 613 # Note the second, binary_dir parameter requires the added 614 # subdirectory to have its own, local cmake target(s). If not then 615 # this binary_dir is created but stays empty. Object files land in 616 # the main binary dir instead. 617 # https://cmake.org/pipermail/cmake/2019-June/069547.html 618 zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name}) 619 if(NOT ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR} STREQUAL "") 620 set(ZEPHYR_CURRENT_MODULE_NAME ${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_NAME}) 621 set(ZEPHYR_CURRENT_MODULE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}) 622 set(ZEPHYR_CURRENT_CMAKE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR}) 623 add_subdirectory(${ZEPHYR_CURRENT_CMAKE_DIR} ${CMAKE_BINARY_DIR}/modules/${module_name}) 624 endif() 625endforeach() 626# Done processing modules, clear module variables 627set(ZEPHYR_CURRENT_MODULE_NAME) 628set(ZEPHYR_CURRENT_MODULE_DIR) 629set(ZEPHYR_CURRENT_CMAKE_DIR) 630 631get_property(LIBC_LINK_LIBRARIES TARGET zephyr_interface PROPERTY LIBC_LINK_LIBRARIES) 632zephyr_link_libraries(${LIBC_LINK_LIBRARIES}) 633 634set(syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/include/generated/zephyr/syscall_list.h) 635set(edk_syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/edk/include/generated/zephyr/syscall_list.h) 636set(syscalls_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls.json) 637set(struct_tags_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/struct_tags.json) 638 639# The syscalls subdirs txt file is constructed by python containing a list of folders to use for 640# dependency handling, including empty folders. 641# Windows: The list is used to specify DIRECTORY list with CMAKE_CONFIGURE_DEPENDS attribute. 642# Other OS: The list will update whenever a file is added/removed/modified and ensure a re-build. 643set(syscalls_subdirs_txt ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_subdirs.txt) 644 645# As syscalls_subdirs_txt is updated whenever a file is modified, this file can not be used for 646# monitoring of added / removed folders. A trigger file is thus used for correct dependency 647# handling. The trigger file will update when a folder is added / removed. 648set(syscalls_subdirs_trigger ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_subdirs.trigger) 649 650if(NOT (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows)) 651 set(syscalls_links --create-links ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_links) 652endif() 653 654# When running CMake it must be ensured that all dependencies are correctly acquired. 655execute_process( 656 COMMAND 657 ${PYTHON_EXECUTABLE} 658 ${ZEPHYR_BASE}/scripts/build/subfolder_list.py 659 --directory ${ZEPHYR_BASE}/include # Walk this directory 660 --out-file ${syscalls_subdirs_txt} # Write file with discovered folder 661 --trigger-file ${syscalls_subdirs_trigger} # Trigger file that is used for json generation 662 ${syscalls_links} # If defined, create symlinks for dependencies 663) 664file(STRINGS ${syscalls_subdirs_txt} PARSE_SYSCALLS_PATHS_DEPENDS ENCODING UTF-8) 665 666if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) 667 # On windows only adding/removing files or folders will be reflected in depends. 668 # Hence adding a file requires CMake to re-run to add this file to the file list. 669 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PARSE_SYSCALLS_PATHS_DEPENDS}) 670 671 # Also On Windows each header file must be monitored as file modifications are not reflected 672 # on directory level. 673 file(GLOB_RECURSE PARSE_SYSCALLS_HEADER_DEPENDS ${ZEPHYR_BASE}/include/*.h) 674else() 675 # The syscall parsing depends on the folders in order to detect add/removed/modified files. 676 # When a folder is removed, CMake will try to find a target that creates that dependency. 677 # This command sets up the target for CMake to find. 678 # Without this code, CMake will fail with the following error: 679 # <folder> needed by '<target>', missing and no known rule to make it 680 # when a folder is removed. 681 add_custom_command(OUTPUT ${PARSE_SYSCALLS_PATHS_DEPENDS} 682 COMMAND ${CMAKE_COMMAND} -E echo "" 683 COMMENT "Preparing syscall dependency handling" 684 ) 685 686 add_custom_command( 687 OUTPUT 688 ${syscalls_subdirs_trigger} 689 COMMAND 690 ${PYTHON_EXECUTABLE} 691 ${ZEPHYR_BASE}/scripts/build/subfolder_list.py 692 --directory ${ZEPHYR_BASE}/include # Walk this directory 693 --out-file ${syscalls_subdirs_txt} # Write file with discovered folder 694 --trigger-file ${syscalls_subdirs_trigger} # Trigger file that is used for json generation 695 ${syscalls_links} # If defined, create symlinks for dependencies 696 DEPENDS ${PARSE_SYSCALLS_PATHS_DEPENDS} 697 ) 698 699 # Ensure subdir file always exists when specifying CMake dependency. 700 if(NOT EXISTS ${syscalls_subdirs_txt}) 701 file(WRITE ${syscalls_subdirs_txt} "") 702 endif() 703 704 # On other OS'es, modifying a file is reflected on the folder timestamp and hence detected 705 # when using depend on directory level. 706 # Thus CMake only needs to re-run when sub-directories are added / removed, which is indicated 707 # using a trigger file. 708 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${syscalls_subdirs_txt}) 709endif() 710 711# syscall declarations are searched for in the SYSCALL_INCLUDE_DIRS 712if(CONFIG_APPLICATION_DEFINED_SYSCALL) 713 list(APPEND SYSCALL_INCLUDE_DIRS ${APPLICATION_SOURCE_DIR}) 714endif() 715 716if(CONFIG_ZTEST) 717 list(APPEND SYSCALL_INCLUDE_DIRS ${ZEPHYR_BASE}/subsys/testsuite/ztest/include) 718 719 if(CONFIG_NO_OPTIMIZATIONS AND CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS) 720 message(WARNING "Running tests with CONFIG_NO_OPTIMIZATIONS is generally " 721 "not supported and known to break in many cases due to stack overflow or " 722 "other problems. Please do not file issues about it unless the test is " 723 "specifically tuned to run in this configuration. To disable this warning " 724 "set CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS=n.") 725 endif() 726 727endif() 728 729get_property( 730 syscalls_include_list 731 TARGET syscalls_interface 732 PROPERTY INTERFACE_INCLUDE_DIRECTORIES 733) 734list(APPEND SYSCALL_INCLUDE_DIRS ${syscalls_include_list}) 735 736foreach(d ${SYSCALL_INCLUDE_DIRS}) 737 list(APPEND parse_syscalls_include_args 738 --include ${d} 739 ) 740endforeach() 741 742add_custom_command( 743 OUTPUT 744 ${syscalls_json} 745 ${struct_tags_json} 746 COMMAND 747 ${PYTHON_EXECUTABLE} 748 ${ZEPHYR_BASE}/scripts/build/parse_syscalls.py 749 --scan ${ZEPHYR_BASE}/include # Read files from this dir 750 --scan ${ZEPHYR_BASE}/drivers # For net sockets 751 --scan ${ZEPHYR_BASE}/subsys/net # More net sockets 752 ${parse_syscalls_include_args} # Read files from these dirs also 753 --json-file ${syscalls_json} # Write this file 754 --tag-struct-file ${struct_tags_json} # Write subsystem list to this file 755 --file-list ${syscalls_file_list_output} 756 $<$<BOOL:${CONFIG_EMIT_ALL_SYSCALLS}>:--emit-all-syscalls> 757 DEPENDS ${syscalls_subdirs_trigger} ${PARSE_SYSCALLS_HEADER_DEPENDS} 758 ${syscalls_file_list_output} ${syscalls_interface} 759 ) 760 761# Make sure Picolibc is built before the rest of the system; there's no explicit 762# reference to any of the files as they're all picked up by various compiler 763# settings 764if(CONFIG_PICOLIBC_USE_MODULE) 765 set(picolibc_dependency PicolibcBuild) 766endif() 767 768add_custom_target(${SYSCALL_LIST_H_TARGET} DEPENDS ${syscall_list_h} ${picolibc_dependency}) 769 770set_property(TARGET ${SYSCALL_LIST_H_TARGET} 771 APPEND PROPERTY 772 ADDITIONAL_CLEAN_FILES 773 ${CMAKE_CURRENT_BINARY_DIR}/include/generated/zephyr/syscalls 774) 775 776add_custom_target(${PARSE_SYSCALLS_TARGET} 777 DEPENDS 778 ${syscalls_json} 779 ${struct_tags_json} 780 ) 781 782# 64-bit systems do not require special handling of 64-bit system call 783# parameters or return values, indicate this to the system call boilerplate 784# generation script. 785if(CONFIG_64BIT) 786 set(SYSCALL_LONG_REGISTERS_ARG --long-registers) 787endif() 788 789if(CONFIG_TIMEOUT_64BIT) 790 set(SYSCALL_SPLIT_TIMEOUT_ARG --split-type k_timeout_t --split-type k_ticks_t) 791endif() 792 793# percepio/TraceRecorder/kernelports/Zephyr/scripts/tz_parse_syscalls.py hardcodes the path 794# to the `syscall_list.h`, make a copy of the generated file so that percepio is able to build 795if(CONFIG_LEGACY_GENERATED_INCLUDE_PATH) 796 set(LEGACY_SYSCALL_LIST_H_ARGS 797 ${CMAKE_COMMAND} -E copy 798 ${syscall_list_h} 799 ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscall_list.h) 800endif() 801 802add_custom_command(OUTPUT include/generated/zephyr/syscall_dispatch.c ${syscall_list_h} 803 # Also, some files are written to include/generated/zephyr/syscalls/ 804 COMMAND 805 ${PYTHON_EXECUTABLE} 806 ${ZEPHYR_BASE}/scripts/build/gen_syscalls.py 807 --json-file ${syscalls_json} # Read this file 808 --base-output include/generated/zephyr/syscalls # Write to this dir 809 --syscall-dispatch include/generated/zephyr/syscall_dispatch.c # Write this file 810 --syscall-export-llext include/generated/zephyr/syscall_export_llext.c 811 --syscall-list ${syscall_list_h} 812 $<$<BOOL:${CONFIG_USERSPACE}>:--gen-mrsh-files> 813 ${SYSCALL_LONG_REGISTERS_ARG} 814 ${SYSCALL_SPLIT_TIMEOUT_ARG} 815 COMMAND 816 ${LEGACY_SYSCALL_LIST_H_ARGS} 817 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 818 DEPENDS ${PARSE_SYSCALLS_TARGET} 819 ) 820 821# This is passed into all calls to the gen_kobject_list.py script. 822set(gen_kobject_list_include_args --include-subsystem-list ${struct_tags_json}) 823 824set(DRV_VALIDATION ${PROJECT_BINARY_DIR}/include/generated/zephyr/driver-validation.h) 825add_custom_command( 826 OUTPUT ${DRV_VALIDATION} 827 COMMAND 828 ${PYTHON_EXECUTABLE} 829 ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py 830 --validation-output ${DRV_VALIDATION} 831 ${gen_kobject_list_include_args} 832 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 833 DEPENDS 834 ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py 835 ${PARSE_SYSCALLS_TARGET} 836 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 837 ) 838add_custom_target(${DRIVER_VALIDATION_H_TARGET} DEPENDS ${DRV_VALIDATION}) 839 840include(${ZEPHYR_BASE}/cmake/kobj.cmake) 841gen_kobj(KOBJ_INCLUDE_PATH) 842 843# Add a pseudo-target that is up-to-date when all generated headers 844# are up-to-date. 845 846add_custom_target(zephyr_generated_headers) 847add_dependencies(zephyr_generated_headers 848 offsets_h version_h 849 ) 850 851# Generate offsets.c.obj from offsets.c 852# Generate offsets.h from offsets.c.obj 853 854set(OFFSETS_LIB offsets) 855 856set(OFFSETS_C_PATH ${ARCH_DIR}/${ARCH}/core/offsets/offsets.c) 857set(OFFSETS_H_PATH ${PROJECT_BINARY_DIR}/include/generated/zephyr/offsets.h) 858 859add_library( ${OFFSETS_LIB} OBJECT ${OFFSETS_C_PATH}) 860target_include_directories(${OFFSETS_LIB} PRIVATE 861 kernel/include 862 ${ARCH_DIR}/${ARCH}/include 863 ) 864 865# Make sure that LTO will never be enabled when compiling offsets.c 866set_source_files_properties(${OFFSETS_C_PATH} PROPERTIES COMPILE_OPTIONS $<TARGET_PROPERTY:compiler,prohibit_lto>) 867 868target_link_libraries(${OFFSETS_LIB} zephyr_interface) 869add_dependencies(zephyr_interface 870 ${SYSCALL_LIST_H_TARGET} 871 ${DRIVER_VALIDATION_H_TARGET} 872 ${KOBJ_TYPES_H_TARGET} 873 ) 874 875add_custom_command( 876 OUTPUT ${OFFSETS_H_PATH} 877 COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/gen_offset_header.py 878 -i $<TARGET_OBJECTS:${OFFSETS_LIB}> 879 -o ${OFFSETS_H_PATH} 880 DEPENDS 881 ${OFFSETS_LIB} 882 $<TARGET_OBJECTS:${OFFSETS_LIB}> 883) 884add_custom_target(${OFFSETS_H_TARGET} DEPENDS ${OFFSETS_H_PATH}) 885 886zephyr_get_include_directories_for_lang(C ZEPHYR_INCLUDES) 887 888add_subdirectory(kernel) 889 890get_property( 891 syscalls_file_list 892 TARGET syscalls_interface 893 PROPERTY INTERFACE_SOURCES 894) 895file(CONFIGURE OUTPUT ${syscalls_file_list_output} 896 CONTENT "@syscalls_file_list@" @ONLY) 897 898# Read list content 899get_property(ZEPHYR_LIBS_PROPERTY GLOBAL PROPERTY ZEPHYR_LIBS) 900 901foreach(zephyr_lib ${ZEPHYR_LIBS_PROPERTY}) 902 get_property(lib_type TARGET ${zephyr_lib} PROPERTY TYPE) 903 # To prevent CMake failure when a driver is enabled, for example: REGULATOR=y 904 # we disable any Zephyr libraries without sources and adds the `empty_file.c`. 905 if(${lib_type} STREQUAL STATIC_LIBRARY 906 AND NOT ${zephyr_lib} STREQUAL app 907 ) 908 get_property(source_list TARGET ${zephyr_lib} PROPERTY SOURCES) 909 get_property(lib_imported TARGET ${zephyr_lib} PROPERTY IMPORTED) 910 if(NOT source_list 911 AND NOT ${lib_imported} 912 ) 913 get_property(allow_empty TARGET ${zephyr_lib} PROPERTY ALLOW_EMPTY) 914 if(NOT "${allow_empty}") 915 message(WARNING 916 "No SOURCES given to Zephyr library: ${zephyr_lib}\nExcluding target from build." 917 ) 918 endif() 919 target_sources(${zephyr_lib} PRIVATE ${ZEPHYR_BASE}/misc/empty_file.c) 920 set_property(TARGET ${zephyr_lib} PROPERTY EXCLUDE_FROM_ALL TRUE) 921 list(REMOVE_ITEM ZEPHYR_LIBS_PROPERTY ${zephyr_lib}) 922 continue() 923 endif() 924 endif() 925 926 # TODO: Could this become an INTERFACE property of zephyr_interface? 927 add_dependencies(${zephyr_lib} zephyr_generated_headers) 928endforeach() 929 930if(CONFIG_KERNEL_WHOLE_ARCHIVE) 931 set(WHOLE_ARCHIVE_LIBS ${ZEPHYR_LIBS_PROPERTY} kernel) 932else() 933 set(WHOLE_ARCHIVE_LIBS ${ZEPHYR_LIBS_PROPERTY}) 934 set(NO_WHOLE_ARCHIVE_LIBS kernel) 935endif() 936 937get_property(OUTPUT_FORMAT GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT) 938 939if (CONFIG_CODE_DATA_RELOCATION) 940 set(CODE_RELOCATION_DEP code_relocation_source_lib) 941endif() # CONFIG_CODE_DATA_RELOCATION 942 943# Give the linker script targets all of the include directories so 944# that cmake can successfully find the linker scripts' header 945# dependencies. 946zephyr_get_include_directories_for_lang(C 947 ZEPHYR_INCLUDE_DIRS 948 STRIP_PREFIX # Don't use a -I prefix 949 ) 950 951if(CONFIG_DEVICE_DEPS) 952 if(CONFIG_DEVICE_DEPS_DYNAMIC) 953 set(dynamic_deps --dynamic-deps) 954 endif() 955 956 if(CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC) 957 set(number_of_dynamic_devices ${CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM}) 958 else() 959 set(number_of_dynamic_devices 0) 960 endif() 961 962 # device_deps.c is generated from ${ZEPHYR_LINK_STAGE_EXECUTABLE} by 963 # gen_device_deps.py 964 add_custom_command( 965 OUTPUT device_deps.c 966 COMMAND 967 ${PYTHON_EXECUTABLE} 968 ${ZEPHYR_BASE}/scripts/build/gen_device_deps.py 969 --output-source device_deps.c 970 --output-graphviz dev_graph.dot 971 ${dynamic_deps} 972 --num-dynamic-devices ${number_of_dynamic_devices} 973 --kernel $<TARGET_FILE:${ZEPHYR_LINK_STAGE_EXECUTABLE}> 974 --zephyr-base ${ZEPHYR_BASE} 975 --start-symbol "$<TARGET_PROPERTY:linker,devices_start_symbol>" 976 VERBATIM 977 DEPENDS ${ZEPHYR_LINK_STAGE_EXECUTABLE} 978 ) 979 set_property(GLOBAL APPEND PROPERTY GENERATED_APP_SOURCE_FILES device_deps.c) 980 981 # gen_device_deps runs on `__device_deps_pass1` so pass this info to the linker script generator 982 list(APPEND LINKER_PASS_${ZEPHYR_CURRENT_LINKER_PASS}_DEFINE "LINKER_DEVICE_DEPS_PASS1") 983endif() 984 985if(CONFIG_CODE_DATA_RELOCATION) 986 # @Intent: Linker script to relocate .text, data and .bss sections 987 toolchain_ld_relocation() 988endif() 989 990if(CONFIG_USERSPACE) 991 zephyr_get_compile_options_for_lang_as_string(C compiler_flags_priv) 992 string(REPLACE "$<TARGET_PROPERTY:compiler,coverage>" "" 993 NO_COVERAGE_FLAGS "${compiler_flags_priv}" 994 ) 995 996 set(GEN_KOBJ_LIST ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py) 997 set(PROCESS_GPERF ${ZEPHYR_BASE}/scripts/build/process_gperf.py) 998endif() 999 1000get_property(GLOBAL_CSTD GLOBAL PROPERTY CSTD) 1001if(DEFINED GLOBAL_CSTD) 1002 message(DEPRECATION 1003 "Global CSTD property is deprecated, see Kconfig.zephyr for C Standard options.") 1004 set(CSTD ${GLOBAL_CSTD}) 1005 list(APPEND CMAKE_C_COMPILE_FEATURES ${compile_features_${CSTD}}) 1006endif() 1007 1008# @Intent: Obtain compiler specific flag for specifying the c standard 1009zephyr_compile_options( 1010 $<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,cstd>${CSTD}> 1011) 1012set(CMAKE_C_COMPILE_FEATURES ${CMAKE_C_COMPILE_FEATURES} PARENT_SCOPE) 1013 1014# @Intent: Configure linker scripts, i.e. generate linker scripts with variables substituted 1015toolchain_ld_configure_files() 1016 1017get_property(TOPT GLOBAL PROPERTY TOPT) 1018get_property(COMPILER_TOPT TARGET compiler PROPERTY linker_script) 1019set_ifndef( TOPT "${COMPILER_TOPT}") 1020set_ifndef( TOPT -Wl,-T) # Use this if the compiler driver doesn't set a value 1021 1022if(CONFIG_HAVE_CUSTOM_LINKER_SCRIPT) 1023 set(LINKER_SCRIPT ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT}) 1024 if(NOT EXISTS ${LINKER_SCRIPT}) 1025 set(LINKER_SCRIPT ${CONFIG_CUSTOM_LINKER_SCRIPT}) 1026 assert_exists(CONFIG_CUSTOM_LINKER_SCRIPT) 1027 endif() 1028elseif(DEFINED BOARD_LINKER_SCRIPT) 1029 set(LINKER_SCRIPT ${BOARD_LINKER_SCRIPT}) 1030elseif(DEFINED SOC_LINKER_SCRIPT) 1031 set(LINKER_SCRIPT ${SOC_LINKER_SCRIPT}) 1032else() 1033 find_package(Deprecated COMPONENTS SEARCHED_LINKER_SCRIPT) 1034endif() 1035 1036if(NOT EXISTS ${LINKER_SCRIPT}) 1037 message(FATAL_ERROR "Could not find linker script: '${LINKER_SCRIPT}'. Corrupted configuration?") 1038endif() 1039 1040if(CONFIG_USERSPACE) 1041 set(APP_SMEM_ALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld") 1042 set(APP_SMEM_UNALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld") 1043 1044 if(CONFIG_LINKER_USE_PINNED_SECTION) 1045 set(APP_SMEM_PINNED_ALIGNED_LD 1046 "${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_aligned.ld") 1047 set(APP_SMEM_PINNED_UNALIGNED_LD 1048 "${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_unaligned.ld") 1049 1050 if(NOT CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT) 1051 # The libc partition may hold symbols that are required during boot process, 1052 # for example, stack guard (if enabled). So the libc partition must be pinned 1053 # if not sections are in physical memory at boot, as the paging mechanism is 1054 # only initialized post-kernel. 1055 set_property(TARGET app_smem APPEND PROPERTY pinned_partitions "z_libc_partition") 1056 endif() 1057 1058 get_property(APP_SMEM_PINNED_PARTITION_LIST TARGET app_smem PROPERTY pinned_partitions) 1059 if(APP_SMEM_PINNED_PARTITION_LIST) 1060 list(JOIN APP_SMEM_PINNED_PARTITION_LIST "," APP_SMEM_PINNED_PARTITION_LIST_ARG_CSL) 1061 set(APP_SMEM_PINNED_PARTITION_LIST_ARG "--pinpartitions=${APP_SMEM_PINNED_PARTITION_LIST_ARG_CSL}") 1062 endif() 1063 endif() 1064 1065 set(OBJ_FILE_DIR "${PROJECT_BINARY_DIR}/../") 1066 1067 if(CONFIG_NEWLIB_LIBC) 1068 set(LIBC_PART -l libc.a z_libc_partition -l libm.a z_libc_partition) 1069 endif() 1070 if(CONFIG_NEWLIB_LIBC_NANO) 1071 set(LIBC_PART -l libc_nano.a z_libc_partition -l libm_nano.a z_libc_partition) 1072 endif() 1073 if(CONFIG_PICOLIBC) 1074 set(LIBC_PART -l libc.a z_libc_partition) 1075 endif() 1076 1077 add_custom_command( 1078 OUTPUT ${APP_SMEM_UNALIGNED_LD} ${APP_SMEM_PINNED_UNALIGNED_LD} 1079 COMMAND ${PYTHON_EXECUTABLE} 1080 ${ZEPHYR_BASE}/scripts/build/gen_app_partitions.py 1081 -f ${CMAKE_BINARY_DIR}/compile_commands.json 1082 -o ${APP_SMEM_UNALIGNED_LD} 1083 $<$<BOOL:${APP_SMEM_PINNED_UNALIGNED_LD}>:--pinoutput=${APP_SMEM_PINNED_UNALIGNED_LD}> 1084 ${APP_SMEM_PINNED_PARTITION_LIST_ARG} 1085 ${LIBC_PART} 1086 $<TARGET_PROPERTY:zephyr_property_target,COMPILE_OPTIONS> 1087 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1088 DEPENDS 1089 kernel 1090 ${CMAKE_BINARY_DIR}/compile_commands.json 1091 ${ZEPHYR_LIBS_PROPERTY} 1092 WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/ 1093 COMMAND_EXPAND_LISTS 1094 COMMENT "Generating app_smem_unaligned linker section" 1095 ) 1096 1097 add_custom_target( 1098 ${APP_SMEM_ALIGNED_DEP} 1099 DEPENDS 1100 ${APP_SMEM_ALIGNED_LD} 1101 ${APP_SMEM_PINNED_ALIGNED_LD} 1102 ) 1103 1104 add_custom_target( 1105 ${APP_SMEM_UNALIGNED_DEP} 1106 DEPENDS 1107 ${APP_SMEM_UNALIGNED_LD} 1108 ${APP_SMEM_PINNED_UNALIGNED_LD} 1109 ) 1110 1111 set(APP_SMEM_UNALIGNED_LIB app_smem_unaligned_output_obj_renamed_lib) 1112 list(APPEND LINKER_PASS_${ZEPHYR_CURRENT_LINKER_PASS}_DEFINE "LINKER_APP_SMEM_UNALIGNED") 1113endif() 1114 1115if (CONFIG_USERSPACE) 1116 add_custom_command( 1117 OUTPUT ${APP_SMEM_ALIGNED_LD} ${APP_SMEM_PINNED_ALIGNED_LD} 1118 COMMAND ${PYTHON_EXECUTABLE} 1119 ${ZEPHYR_BASE}/scripts/build/gen_app_partitions.py 1120 -e $<TARGET_FILE:${ZEPHYR_LINK_STAGE_EXECUTABLE}> 1121 -o ${APP_SMEM_ALIGNED_LD} 1122 $<$<BOOL:${APP_SMEM_PINNED_ALIGNED_LD}>:--pinoutput=${APP_SMEM_PINNED_ALIGNED_LD}> 1123 ${APP_SMEM_PINNED_PARTITION_LIST_ARG} 1124 ${LIBC_PART} 1125 $<TARGET_PROPERTY:zephyr_property_target,COMPILE_OPTIONS> 1126 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1127 DEPENDS 1128 kernel 1129 ${ZEPHYR_LIBS_PROPERTY} 1130 ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1131 WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/ 1132 COMMAND_EXPAND_LISTS 1133 COMMENT "Generating app_smem_aligned linker section" 1134 ) 1135endif() 1136 1137if(CONFIG_USERSPACE) 1138 # This CONFIG_USERSPACE block is to create place holders to reserve space 1139 # for the gperf generated structures for zephyr_prebuilt.elf. 1140 # These place holders are there so that the placement of kobjects would be 1141 # the same between linking zephyr_prebuilt.elf and zephyr.elf, as 1142 # the gperf hash table is hashed on the addresses of kobjects. 1143 # The placeholders are generated from app_smem_unaligned_prebuilt.elf. 1144 1145 set(KOBJECT_PREBUILT_HASH_LIST kobject_prebuilt_hash.gperf) 1146 set(KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE kobject_prebuilt_hash_preprocessed.c) 1147 set(KOBJECT_PREBUILT_HASH_OUTPUT_SRC kobject_prebuilt_hash.c) 1148 1149 add_custom_command( 1150 OUTPUT ${KOBJECT_PREBUILT_HASH_LIST} 1151 COMMAND 1152 ${PYTHON_EXECUTABLE} 1153 ${GEN_KOBJ_LIST} 1154 --kernel $<TARGET_FILE:${ZEPHYR_LINK_STAGE_EXECUTABLE}> 1155 --gperf-output ${KOBJECT_PREBUILT_HASH_LIST} 1156 ${gen_kobject_list_include_args} 1157 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1158 DEPENDS 1159 ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1160 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1161 ) 1162 add_custom_target( 1163 kobj_prebuilt_hash_list 1164 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_LIST} 1165 ) 1166 1167 add_custom_command( 1168 OUTPUT ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1169 COMMAND 1170 ${GPERF} 1171 --output-file ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1172 --multiple-iterations 10 1173 ${KOBJECT_PREBUILT_HASH_LIST} 1174 DEPENDS kobj_prebuilt_hash_list ${KOBJECT_PREBUILT_HASH_LIST} 1175 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1176 ) 1177 add_custom_target( 1178 kobj_prebuilt_hash_output_src_pre 1179 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1180 ) 1181 1182 add_custom_command( 1183 OUTPUT ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1184 COMMAND 1185 ${PYTHON_EXECUTABLE} 1186 ${PROCESS_GPERF} 1187 -i ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1188 -o ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1189 -p "struct k_object" 1190 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1191 DEPENDS kobj_prebuilt_hash_output_src_pre ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1192 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1193 ) 1194 add_custom_target( 1195 kobj_prebuilt_hash_output_src 1196 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1197 ) 1198 1199 add_library( 1200 kobj_prebuilt_hash_output_lib 1201 OBJECT ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1202 ) 1203 1204 set_source_files_properties(${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1205 PROPERTIES COMPILE_FLAGS 1206 "${NO_COVERAGE_FLAGS} -fno-function-sections -fno-data-sections") 1207 1208 target_compile_definitions(kobj_prebuilt_hash_output_lib 1209 PRIVATE $<TARGET_PROPERTY:zephyr_interface,INTERFACE_COMPILE_DEFINITIONS> 1210 ) 1211 1212 target_include_directories(kobj_prebuilt_hash_output_lib 1213 PUBLIC $<TARGET_PROPERTY:zephyr_interface,INTERFACE_INCLUDE_DIRECTORIES> 1214 ) 1215 1216 target_include_directories(kobj_prebuilt_hash_output_lib SYSTEM 1217 PUBLIC $<TARGET_PROPERTY:zephyr_interface,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> 1218 ) 1219 1220 set(KOBJECT_LINKER_HEADER_DATA "${PROJECT_BINARY_DIR}/include/generated/zephyr/linker-kobject-prebuilt-data.h") 1221 1222 add_custom_command( 1223 OUTPUT ${KOBJECT_LINKER_HEADER_DATA} 1224 COMMAND 1225 ${PYTHON_EXECUTABLE} 1226 ${ZEPHYR_BASE}/scripts/build/gen_kobject_placeholders.py 1227 --object $<TARGET_OBJECTS:kobj_prebuilt_hash_output_lib> 1228 --outdir ${PROJECT_BINARY_DIR}/include/generated/zephyr 1229 --datapct ${CONFIG_KOBJECT_DATA_AREA_RESERVE_EXTRA_PERCENT} 1230 --rodata ${CONFIG_KOBJECT_RODATA_AREA_EXTRA_BYTES} 1231 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1232 DEPENDS 1233 kobj_prebuilt_hash_output_lib $<TARGET_OBJECTS:kobj_prebuilt_hash_output_lib> 1234 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1235 ) 1236 1237 add_custom_target( 1238 ${KOBJECT_LINKER_DEP} 1239 DEPENDS 1240 ${KOBJECT_LINKER_HEADER_DATA} 1241 ) 1242endif() 1243 1244if(CONFIG_USERSPACE OR CONFIG_DEVICE_DEPS) 1245 configure_linker_script( 1246 ${ZEPHYR_CURRENT_LINKER_CMD} 1247 "${LINKER_PASS_${ZEPHYR_CURRENT_LINKER_PASS}_DEFINE}" 1248 ${CODE_RELOCATION_DEP} 1249 ${APP_SMEM_UNALIGNED_DEP} 1250 ${APP_SMEM_UNALIGNED_LD} 1251 ${APP_SMEM_PINNED_UNALIGNED_LD} 1252 zephyr_generated_headers 1253 ) 1254 1255 add_custom_target( 1256 linker_zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}_script 1257 DEPENDS 1258 ${ZEPHYR_CURRENT_LINKER_CMD} 1259 ) 1260 1261 set_property(TARGET 1262 linker_zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}_script 1263 PROPERTY INCLUDE_DIRECTORIES 1264 ${ZEPHYR_INCLUDE_DIRS} 1265 ) 1266 1267 add_executable(${ZEPHYR_LINK_STAGE_EXECUTABLE} misc/empty_file.c) 1268 toolchain_ld_link_elf( 1269 TARGET_ELF ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1270 OUTPUT_MAP ${PROJECT_BINARY_DIR}/${ZEPHYR_LINK_STAGE_EXECUTABLE}.map 1271 LIBRARIES_PRE_SCRIPT "" 1272 LINKER_SCRIPT ${PROJECT_BINARY_DIR}/${ZEPHYR_CURRENT_LINKER_CMD} 1273 LIBRARIES_POST_SCRIPT "" 1274 DEPENDENCIES ${CODE_RELOCATION_DEP} 1275 ) 1276 target_link_libraries_ifdef(CONFIG_NATIVE_LIBRARY ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1277 $<TARGET_PROPERTY:linker,no_position_independent>) 1278 target_byproducts(TARGET ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1279 BYPRODUCTS ${PROJECT_BINARY_DIR}/${ZEPHYR_LINK_STAGE_EXECUTABLE}.map 1280 ) 1281 set_property(TARGET ${ZEPHYR_LINK_STAGE_EXECUTABLE} PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/${ZEPHYR_CURRENT_LINKER_CMD}) 1282 add_dependencies(${ZEPHYR_LINK_STAGE_EXECUTABLE} linker_zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}_script ${OFFSETS_LIB}) 1283 1284 math(EXPR ZEPHYR_CURRENT_LINKER_PASS "1 + ${ZEPHYR_CURRENT_LINKER_PASS}") 1285endif() 1286 1287set(ZEPHYR_CURRENT_LINKER_CMD linker_zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}.cmd) 1288set(ZEPHYR_LINK_STAGE_EXECUTABLE zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}) 1289list(APPEND LINKER_PASS_${ZEPHYR_CURRENT_LINKER_PASS}_DEFINE "LINKER_ZEPHYR_PREBUILT") 1290 1291if(CONFIG_GEN_ISR_TABLES) 1292 if(CONFIG_GEN_SW_ISR_TABLE) 1293 list(APPEND GEN_ISR_TABLE_EXTRA_ARG --sw-isr-table) 1294 endif() 1295 1296 if(CONFIG_GEN_IRQ_VECTOR_TABLE) 1297 list(APPEND GEN_ISR_TABLE_EXTRA_ARG --vector-table) 1298 endif() 1299 1300 # isr_tables.c is generated from ${ZEPHYR_LINK_STAGE_EXECUTABLE} by 1301 # gen_isr_tables.py 1302 add_custom_command( 1303 OUTPUT isr_tables.c isr_tables_vt.ld isr_tables_swi.ld 1304 COMMAND ${PYTHON_EXECUTABLE} 1305 ${ZEPHYR_BASE}/scripts/build/gen_isr_tables.py 1306 --output-source isr_tables.c 1307 --linker-output-files isr_tables_vt.ld isr_tables_swi.ld 1308 --kernel $<TARGET_FILE:${ZEPHYR_LINK_STAGE_EXECUTABLE}> 1309 --intlist-section .intList 1310 --intlist-section intList 1311 $<$<BOOL:${CONFIG_BIG_ENDIAN}>:--big-endian> 1312 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--debug> 1313 ${GEN_ISR_TABLE_EXTRA_ARG} 1314 DEPENDS ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1315 COMMAND_EXPAND_LISTS 1316 ) 1317 set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES isr_tables.c) 1318endif() 1319 1320if(CONFIG_SYMTAB) 1321 add_custom_command( 1322 OUTPUT symtab.c 1323 COMMAND 1324 ${PYTHON_EXECUTABLE} 1325 ${ZEPHYR_BASE}/scripts/build/gen_symtab.py 1326 -k $<TARGET_FILE:${ZEPHYR_LINK_STAGE_EXECUTABLE}> 1327 -o symtab.c 1328 DEPENDS ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1329 COMMAND_EXPAND_LISTS 1330 ) 1331 set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES symtab.c) 1332endif() 1333 1334if(CONFIG_USERSPACE) 1335 set(KOBJECT_HASH_LIST kobject_hash.gperf) 1336 set(KOBJECT_HASH_OUTPUT_SRC_PRE kobject_hash_preprocessed.c) 1337 set(KOBJECT_HASH_OUTPUT_SRC kobject_hash.c) 1338 set(KOBJECT_HASH_OUTPUT_OBJ_RENAMED kobject_hash_renamed.o) 1339 1340 # Essentially what we are doing here is extracting some information 1341 # out of the nearly finished elf file, generating the source code 1342 # for a hash table based on that information, and then compiling and 1343 # linking the hash table back into a now even more nearly finished 1344 # elf file. More information in gen_kobject_list.py --help. 1345 1346 # Use the script GEN_KOBJ_LIST to scan the kernel binary's 1347 # (${ZEPHYR_LINK_STAGE_EXECUTABLE}) DWARF information to produce a table of kernel 1348 # objects (KOBJECT_HASH_LIST) which we will then pass to gperf 1349 add_custom_command( 1350 OUTPUT ${KOBJECT_HASH_LIST} 1351 COMMAND 1352 ${PYTHON_EXECUTABLE} 1353 ${GEN_KOBJ_LIST} 1354 --kernel $<TARGET_FILE:${ZEPHYR_LINK_STAGE_EXECUTABLE}> 1355 --gperf-output ${KOBJECT_HASH_LIST} 1356 ${gen_kobject_list_include_args} 1357 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1358 DEPENDS 1359 ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1360 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1361 ) 1362 add_custom_target( 1363 kobj_hash_list 1364 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_LIST} 1365 ) 1366 1367 # Use gperf to generate C code (KOBJECT_HASH_OUTPUT_SRC_PRE) which implements a 1368 # perfect hashtable based on KOBJECT_HASH_LIST 1369 add_custom_command( 1370 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC_PRE} 1371 COMMAND 1372 ${GPERF} 1373 --output-file ${KOBJECT_HASH_OUTPUT_SRC_PRE} 1374 --multiple-iterations 10 1375 ${KOBJECT_HASH_LIST} 1376 DEPENDS kobj_hash_list ${KOBJECT_HASH_LIST} 1377 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1378 ) 1379 add_custom_target( 1380 kobj_hash_output_src_pre 1381 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC_PRE} 1382 ) 1383 1384 # For our purposes the code/data generated by gperf is not optimal. 1385 # 1386 # The script PROCESS_GPERF creates a new c file KOBJECT_HASH_OUTPUT_SRC based on 1387 # KOBJECT_HASH_OUTPUT_SRC_PRE to greatly reduce the amount of code/data generated 1388 # since we know we are always working with pointer values 1389 add_custom_command( 1390 OUTPUT ${KOBJECT_HASH_OUTPUT_SRC} 1391 COMMAND 1392 ${PYTHON_EXECUTABLE} 1393 ${PROCESS_GPERF} 1394 -i ${KOBJECT_HASH_OUTPUT_SRC_PRE} 1395 -o ${KOBJECT_HASH_OUTPUT_SRC} 1396 -p "struct k_object" 1397 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1398 DEPENDS kobj_hash_output_src_pre ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC_PRE} 1399 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1400 ) 1401 add_custom_target( 1402 kobj_hash_output_src 1403 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC} 1404 ) 1405 1406 # We need precise control of where generated text/data ends up in the final 1407 # kernel image. Disable function/data sections and use objcopy to move 1408 # generated data into special section names 1409 add_library( 1410 kobj_hash_output_lib 1411 OBJECT ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC} 1412 ) 1413 1414 set_source_files_properties(${KOBJECT_HASH_OUTPUT_SRC} 1415 PROPERTIES COMPILE_FLAGS 1416 "${NO_COVERAGE_FLAGS} -fno-function-sections -fno-data-sections") 1417 1418 target_compile_definitions(kobj_hash_output_lib 1419 PRIVATE $<TARGET_PROPERTY:zephyr_interface,INTERFACE_COMPILE_DEFINITIONS> 1420 ) 1421 1422 target_include_directories(kobj_hash_output_lib 1423 PUBLIC $<TARGET_PROPERTY:zephyr_interface,INTERFACE_INCLUDE_DIRECTORIES> 1424 ) 1425 1426 target_include_directories(kobj_hash_output_lib SYSTEM 1427 PUBLIC $<TARGET_PROPERTY:zephyr_interface,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> 1428 ) 1429 1430 add_custom_command( 1431 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 1432 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1433 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1434 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.literal=.kobject_data.literal 1435 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.data=.kobject_data.data 1436 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.sdata=.kobject_data.sdata 1437 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.text=.kobject_data.text 1438 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.rodata=.kobject_data.rodata 1439 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>$<TARGET_OBJECTS:kobj_hash_output_lib> 1440 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 1441 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1442 DEPENDS kobj_hash_output_lib $<TARGET_OBJECTS:kobj_hash_output_lib> 1443 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1444 COMMAND_EXPAND_LISTS 1445 ) 1446 add_custom_target( 1447 kobj_hash_output_obj_renamed 1448 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 1449 ) 1450 1451 add_library(kobj_hash_output_obj_renamed_lib STATIC IMPORTED GLOBAL) 1452 set_property( 1453 TARGET kobj_hash_output_obj_renamed_lib 1454 PROPERTY 1455 IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 1456 ) 1457 add_dependencies( 1458 kobj_hash_output_obj_renamed_lib 1459 kobj_hash_output_obj_renamed 1460 ) 1461 1462 set_property( 1463 GLOBAL APPEND PROPERTY 1464 GENERATED_KERNEL_OBJECT_FILES kobj_hash_output_obj_renamed_lib 1465 ) 1466endif() 1467 1468configure_linker_script( 1469 ${ZEPHYR_CURRENT_LINKER_CMD} 1470 "${LINKER_PASS_${ZEPHYR_CURRENT_LINKER_PASS}_DEFINE}" 1471 ${APP_SMEM_ALIGNED_DEP} 1472 ${KOBJECT_LINKER_DEP} 1473 ${CODE_RELOCATION_DEP} 1474 zephyr_generated_headers 1475 ) 1476 1477add_custom_target( 1478 linker_zephyr_prebuilt_script_target 1479 DEPENDS 1480 ${ZEPHYR_CURRENT_LINKER_CMD} 1481 ) 1482 1483set_property(TARGET 1484 linker_zephyr_prebuilt_script_target 1485 PROPERTY INCLUDE_DIRECTORIES 1486 ${ZEPHYR_INCLUDE_DIRS} 1487 ) 1488 1489# Read global variables into local variables 1490get_property(GASF GLOBAL PROPERTY GENERATED_APP_SOURCE_FILES) 1491get_property(GKOF GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES) 1492get_property(GKSF GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES) 1493 1494# FIXME: Is there any way to get rid of empty_file.c? 1495add_executable( ${ZEPHYR_LINK_STAGE_EXECUTABLE} misc/empty_file.c ${GASF}) 1496toolchain_ld_link_elf( 1497 TARGET_ELF ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1498 OUTPUT_MAP ${PROJECT_BINARY_DIR}/${ZEPHYR_LINK_STAGE_EXECUTABLE}.map 1499 LIBRARIES_PRE_SCRIPT "" 1500 LINKER_SCRIPT ${PROJECT_BINARY_DIR}/${ZEPHYR_CURRENT_LINKER_CMD} 1501 DEPENDENCIES ${CODE_RELOCATION_DEP} 1502) 1503target_link_libraries_ifdef(CONFIG_NATIVE_LIBRARY ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1504 $<TARGET_PROPERTY:linker,partial_linking>) 1505target_byproducts(TARGET ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1506 BYPRODUCTS ${PROJECT_BINARY_DIR}/${ZEPHYR_LINK_STAGE_EXECUTABLE}.map 1507) 1508set(BYPRODUCT_KERNEL_ELF_NAME "${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" CACHE FILEPATH "Kernel elf file" FORCE) 1509set_property(TARGET 1510 ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1511 PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/${ZEPHYR_CURRENT_LINKER_CMD} 1512 ) 1513add_dependencies( 1514 ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1515 linker_zephyr_prebuilt_script_target 1516 ${OFFSETS_LIB} 1517 ) 1518 1519set(generated_kernel_files ${GKSF} ${GKOF}) 1520if(NOT generated_kernel_files) 1521 # Use the prebuilt elf as the final elf since we don't have a 1522 # generation stage. 1523 set(logical_target_for_zephyr_elf ${ZEPHYR_LINK_STAGE_EXECUTABLE}) 1524else() 1525 # The final linker pass uses the same source linker script of the 1526 # previous passes, but this time with a different output 1527 # file and preprocessed with the define LINKER_ZEPHYR_FINAL. 1528 configure_linker_script( 1529 linker.cmd 1530 "LINKER_ZEPHYR_FINAL" 1531 ${CODE_RELOCATION_DEP} 1532 ${ZEPHYR_LINK_STAGE_EXECUTABLE} 1533 zephyr_generated_headers 1534 ) 1535 1536 add_custom_target( 1537 linker_zephyr_final_script_target 1538 DEPENDS 1539 linker.cmd 1540 ) 1541 set_property(TARGET 1542 linker_zephyr_final_script_target 1543 PROPERTY INCLUDE_DIRECTORIES 1544 ${ZEPHYR_INCLUDE_DIRS} 1545 ) 1546 1547 add_executable( ${ZEPHYR_FINAL_EXECUTABLE} misc/empty_file.c ${GASF} ${GKSF}) 1548 toolchain_ld_link_elf( 1549 TARGET_ELF ${ZEPHYR_FINAL_EXECUTABLE} 1550 OUTPUT_MAP ${PROJECT_BINARY_DIR}/${ZEPHYR_FINAL_EXECUTABLE}.map 1551 LIBRARIES_PRE_SCRIPT ${GKOF} 1552 LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker.cmd 1553 LIBRARIES_POST_SCRIPT "" 1554 DEPENDENCIES ${CODE_RELOCATION_DEP} 1555 ) 1556 set_property(TARGET ${ZEPHYR_FINAL_EXECUTABLE} PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker.cmd) 1557 add_dependencies( ${ZEPHYR_FINAL_EXECUTABLE} linker_zephyr_final_script_target) 1558 1559 # Use the pass2 elf as the final elf 1560 set(logical_target_for_zephyr_elf ${ZEPHYR_FINAL_EXECUTABLE}) 1561endif() 1562 1563# Export the variable to the application's scope to allow the 1564# application to know what the name of the final elf target is. 1565set(logical_target_for_zephyr_elf ${logical_target_for_zephyr_elf} PARENT_SCOPE) 1566 1567# Override the base name of the last, "logical" .elf output (and last .map) so: 1568# 1. it doesn't depend on the number of passes above and the 1569# post_build_commands below can always find it no matter which is it; 1570# 2. it can be defined in Kconfig 1571set_target_properties(${logical_target_for_zephyr_elf} PROPERTIES OUTPUT_NAME ${KERNEL_NAME}) 1572 1573set(post_build_commands "") 1574set(post_build_byproducts "") 1575 1576list(APPEND 1577 post_build_commands 1578 COMMAND 1579 ${CMAKE_COMMAND} -E copy ${logical_target_for_zephyr_elf}.map ${KERNEL_MAP_NAME} 1580) 1581list(APPEND post_build_byproducts ${KERNEL_MAP_NAME}) 1582 1583if(NOT CONFIG_BUILD_NO_GAP_FILL) 1584 # Use ';' as separator to get proper space in resulting command. 1585 set(GAP_FILL "$<TARGET_PROPERTY:bintools,elfconvert_flag_gapfill>0xff") 1586endif() 1587 1588if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) 1589 target_link_libraries(${logical_target_for_zephyr_elf} $<TARGET_PROPERTY:linker,memusage>) 1590 1591 get_property(memusage_build_command TARGET bintools PROPERTY memusage_command) 1592 if(memusage_build_command) 1593 # Note: The use of generator expressions allows downstream extensions to add/change the post build. 1594 # Unfortunately, the BYPRODUCTS does not allow for generator expression, so question is if we 1595 # should remove the downstream ability from start. 1596 # Or fix the output name, by the use of `get_property` 1597 list(APPEND 1598 post_build_commands 1599 COMMAND $<TARGET_PROPERTY:bintools,memusage_command> 1600 $<TARGET_PROPERTY:bintools,memusage_flag> 1601 $<TARGET_PROPERTY:bintools,memusage_infile>${KERNEL_ELF_NAME} 1602 ) 1603 1604 # For now, the byproduct can only be supported upstream on byproducts name, 1605 # cause byproduct does not support generator expressions 1606 get_property(memusage_byproducts TARGET bintools PROPERTY memusage_byproducts) 1607 list(APPEND 1608 post_build_byproducts 1609 ${memusage_byproducts} 1610 ) 1611 endif() 1612endif() 1613 1614if(CONFIG_BUILD_OUTPUT_ADJUST_LMA) 1615 math(EXPR adjustment "${CONFIG_BUILD_OUTPUT_ADJUST_LMA}" OUTPUT_FORMAT DECIMAL) 1616 list(APPEND 1617 post_build_commands 1618 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1619 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1620 $<TARGET_PROPERTY:bintools,elfconvert_flag_lma_adjust>${adjustment} 1621 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1622 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_ELF_NAME} 1623 ) 1624endif() 1625 1626if(NOT CONFIG_CPP_EXCEPTIONS) 1627 set(eh_frame_section ".eh_frame") 1628else() 1629 set(eh_frame_section "") 1630endif() 1631set(remove_sections_argument_list "") 1632foreach(section .comment COMMON ${eh_frame_section}) 1633 list(APPEND remove_sections_argument_list 1634 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>${section}) 1635endforeach() 1636 1637if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd) 1638 get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) 1639 if(ihex IN_LIST elfconvert_formats) 1640 list(APPEND 1641 post_build_commands 1642 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1643 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1644 ${GAP_FILL} 1645 $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>ihex 1646 ${remove_sections_argument_list} 1647 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1648 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_HEX_NAME} 1649 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1650 ) 1651 list(APPEND 1652 post_build_byproducts 1653 ${KERNEL_HEX_NAME} 1654 ) 1655 set(BYPRODUCT_KERNEL_HEX_NAME "${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" CACHE FILEPATH "Kernel hex file" FORCE) 1656 endif() 1657endif() 1658 1659if(CONFIG_BUILD_OUTPUT_BIN) 1660 get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) 1661 if(binary IN_LIST elfconvert_formats) 1662 list(APPEND 1663 post_build_commands 1664 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1665 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1666 ${GAP_FILL} 1667 $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>binary 1668 ${remove_sections_argument_list} 1669 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1670 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_BIN_NAME} 1671 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1672 ) 1673 list(APPEND 1674 post_build_byproducts 1675 ${KERNEL_BIN_NAME} 1676 ) 1677 set(BYPRODUCT_KERNEL_BIN_NAME "${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}" CACHE FILEPATH "Kernel binary file" FORCE) 1678 endif() 1679endif() 1680 1681if(CONFIG_BUILD_OUTPUT_BIN AND CONFIG_BUILD_OUTPUT_UF2) 1682 if(CONFIG_BUILD_OUTPUT_UF2_USE_FLASH_BASE) 1683 set(flash_addr "${CONFIG_FLASH_BASE_ADDRESS}") 1684 else() 1685 set(flash_addr "${CONFIG_FLASH_LOAD_OFFSET}") 1686 endif() 1687 1688 if(CONFIG_BUILD_OUTPUT_UF2_USE_FLASH_OFFSET) 1689 # Note, the `+ 0` in formula below avoids errors in cases where a Kconfig 1690 # variable is undefined and thus expands to nothing. 1691 math(EXPR flash_addr 1692 "${flash_addr} + ${CONFIG_FLASH_LOAD_OFFSET} + 0" 1693 OUTPUT_FORMAT HEXADECIMAL 1694 ) 1695 endif() 1696 1697 list(APPEND 1698 post_build_commands 1699 COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/uf2conv.py 1700 -c 1701 -f ${CONFIG_BUILD_OUTPUT_UF2_FAMILY_ID} 1702 -b ${flash_addr} 1703 -o ${KERNEL_UF2_NAME} 1704 ${KERNEL_BIN_NAME} 1705 ) 1706 list(APPEND 1707 post_build_byproducts 1708 ${KERNEL_UF2_NAME} 1709 ) 1710 set(BYPRODUCT_KERNEL_UF2_NAME "${PROJECT_BINARY_DIR}/${KERNEL_UF2_NAME}" CACHE FILEPATH "Kernel uf2 file" FORCE) 1711endif() 1712 1713set(KERNEL_META_PATH ${PROJECT_BINARY_DIR}/${KERNEL_META_NAME} CACHE INTERNAL "") 1714if(CONFIG_BUILD_OUTPUT_META) 1715 list(APPEND 1716 post_build_commands 1717 COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/zephyr_module.py 1718 ${ZEPHYR_MODULES_ARG} 1719 ${EXTRA_ZEPHYR_MODULES_ARG} 1720 --meta-out ${KERNEL_META_PATH} 1721 --zephyr-base=${ZEPHYR_BASE} 1722 $<$<BOOL:${CONFIG_BUILD_OUTPUT_META_STATE_PROPAGATE}>:--meta-state-propagate> 1723 ) 1724 list(APPEND 1725 post_build_byproducts 1726 ${KERNEL_META_PATH} 1727 ) 1728else(CONFIG_BUILD_OUTPUT_META) 1729 # Prevent spdx to use invalid data 1730 file(REMOVE ${KERNEL_META_PATH}) 1731endif() 1732 1733# Cleanup intermediate files 1734if(CONFIG_CLEANUP_INTERMEDIATE_FILES) 1735 foreach(index RANGE ${ZEPHYR_CURRENT_LINKER_PASS}) 1736 # Those files can be very large in some cases, delete them as we do not need them. 1737 list(APPEND 1738 post_build_commands 1739 COMMAND 1740 ${CMAKE_COMMAND} -E remove zephyr_pre${index}.elf 1741 ) 1742 endforeach() 1743endif() 1744 1745if(CONFIG_BUILD_OUTPUT_S19) 1746 get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) 1747 if(srec IN_LIST elfconvert_formats) 1748 # Should we print a warning if case the tools does not support converting to s19 ? 1749 list(APPEND 1750 post_build_commands 1751 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1752 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1753 ${GAP_FILL} 1754 $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>srec 1755 $<TARGET_PROPERTY:bintools,elfconvert_flag_srec_len>1 1756 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1757 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_S19_NAME} 1758 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1759 ) 1760 list(APPEND 1761 post_build_byproducts 1762 ${KERNEL_S19_NAME} 1763 ) 1764 set(BYPRODUCT_KERNEL_S19_NAME "${PROJECT_BINARY_DIR}/${KERNEL_S19_NAME}" CACHE FILEPATH "Kernel s19 file" FORCE) 1765 endif() 1766endif() 1767 1768if(CONFIG_OUTPUT_DISASSEMBLY) 1769if(CONFIG_OUTPUT_DISASSEMBLE_ALL) 1770 set(disassembly_type "$<TARGET_PROPERTY:bintools,disassembly_flag_all>") 1771 elseif (CONFIG_OUTPUT_DISASSEMBLY_WITH_SOURCE) 1772 set(disassembly_type "$<TARGET_PROPERTY:bintools,disassembly_flag_inline_source>") 1773 endif() 1774 list(APPEND 1775 post_build_commands 1776 COMMAND $<TARGET_PROPERTY:bintools,disassembly_command> 1777 $<TARGET_PROPERTY:bintools,disassembly_flag> 1778 ${disassembly_type} 1779 $<TARGET_PROPERTY:bintools,disassembly_flag_infile>${KERNEL_ELF_NAME} 1780 $<TARGET_PROPERTY:bintools,disassembly_flag_outfile>${KERNEL_LST_NAME} 1781 $<TARGET_PROPERTY:bintools,disassembly_flag_final> 1782 ) 1783 list(APPEND 1784 post_build_byproducts 1785 ${KERNEL_LST_NAME} 1786 ) 1787endif() 1788 1789if(CONFIG_OUTPUT_SYMBOLS) 1790 list(APPEND 1791 post_build_commands 1792 COMMAND $<TARGET_PROPERTY:bintools,symbols_command> 1793 $<TARGET_PROPERTY:bintools,symbols_flag> 1794 $<TARGET_PROPERTY:bintools,symbols_infile>${KERNEL_ELF_NAME} 1795 $<TARGET_PROPERTY:bintools,symbols_outfile>${KERNEL_SYMBOLS_NAME} 1796 $<TARGET_PROPERTY:bintools,symbols_final> 1797 ) 1798 list(APPEND 1799 post_build_byproducts 1800 ${KERNEL_SYMBOLS_NAME} 1801 ) 1802endif() 1803 1804if(CONFIG_OUTPUT_STAT) 1805 list(APPEND 1806 post_build_commands 1807 COMMAND $<TARGET_PROPERTY:bintools,readelf_command> 1808 $<TARGET_PROPERTY:bintools,readelf_flag> 1809 $<TARGET_PROPERTY:bintools,readelf_flag_headers> 1810 $<TARGET_PROPERTY:bintools,readelf_flag_infile>${KERNEL_ELF_NAME} 1811 $<TARGET_PROPERTY:bintools,readelf_flag_outfile>${KERNEL_STAT_NAME} 1812 $<TARGET_PROPERTY:bintools,readelf_flag_final> 1813 ) 1814 list(APPEND 1815 post_build_byproducts 1816 ${KERNEL_STAT_NAME} 1817 ) 1818endif() 1819 1820if(CONFIG_BUILD_OUTPUT_STRIPPED) 1821 list(APPEND 1822 post_build_commands 1823 COMMAND $<TARGET_PROPERTY:bintools,strip_command> 1824 $<TARGET_PROPERTY:bintools,strip_flag> 1825 $<TARGET_PROPERTY:bintools,strip_flag_all> 1826 $<TARGET_PROPERTY:bintools,strip_flag_infile>${KERNEL_ELF_NAME} 1827 $<TARGET_PROPERTY:bintools,strip_flag_outfile>${KERNEL_STRIP_NAME} 1828 $<TARGET_PROPERTY:bintools,strip_flag_final> 1829 ) 1830 list(APPEND 1831 post_build_byproducts 1832 ${KERNEL_STRIP_NAME} 1833 ) 1834endif() 1835 1836if(CONFIG_BUILD_OUTPUT_COMPRESS_DEBUG_SECTIONS) 1837 list(APPEND 1838 post_build_commands 1839 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1840 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1841 $<TARGET_PROPERTY:bintools,elfconvert_flag_compress_debug_sections> 1842 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1843 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1844) 1845endif() 1846 1847if(CONFIG_BUILD_OUTPUT_EXE) 1848 if (NOT CONFIG_NATIVE_LIBRARY) 1849 list(APPEND 1850 post_build_commands 1851 COMMAND 1852 ${CMAKE_COMMAND} -E copy ${KERNEL_ELF_NAME} ${KERNEL_EXE_NAME} 1853 ) 1854 list(APPEND 1855 post_build_byproducts 1856 ${KERNEL_EXE_NAME} 1857 ) 1858 else() 1859 if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") 1860 set(MAKE "${CMAKE_MAKE_PROGRAM}" CACHE FILEPATH "cmake defined make") 1861 endif() 1862 find_program(MAKE make REQUIRED) 1863 add_custom_target(native_runner_executable 1864 ALL 1865 COMMENT "Building native simulator runner, and linking final executable" 1866 COMMAND 1867 ${MAKE} -f ${ZEPHYR_BASE}/scripts/native_simulator/Makefile all --warn-undefined-variables 1868 -r NSI_CONFIG_FILE=${APPLICATION_BINARY_DIR}/zephyr/NSI/nsi_config 1869 # nsi_config is created by the board cmake file 1870 DEPENDS ${logical_target_for_zephyr_elf} 1871 BYPRODUCTS ${KERNEL_EXE_NAME} 1872 ) 1873 endif() 1874 set(BYPRODUCT_KERNEL_EXE_NAME "${PROJECT_BINARY_DIR}/${KERNEL_EXE_NAME}" CACHE FILEPATH "Kernel exe file" FORCE) 1875endif() 1876 1877if(CONFIG_BUILD_OUTPUT_INFO_HEADER) 1878 list(APPEND 1879 post_build_commands 1880 COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/gen_image_info.py 1881 --elf-file=${KERNEL_ELF_NAME} 1882 --header-file=${PROJECT_BINARY_DIR}/include/public/zephyr_image_info.h 1883 $<$<BOOL:${adjustment}>:--adjusted-lma=${adjustment}> 1884 ) 1885 list(APPEND 1886 post_build_byproducts 1887 ${PROJECT_BINARY_DIR}/include/public/zephyr_image_info.h 1888 ) 1889endif() 1890 1891if (CONFIG_LLEXT AND CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) 1892 #slidgen must be the first post-build command to be executed 1893 #on the Zephyr ELF to ensure that all other commands, such as 1894 #binary file generation, are operating on a preparated ELF. 1895 list(PREPEND 1896 post_build_commands 1897 COMMAND ${PYTHON_EXECUTABLE} 1898 ${ZEPHYR_BASE}/scripts/build/llext_prepare_exptab.py 1899 --elf-file ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} 1900 --slid-listing ${PROJECT_BINARY_DIR}/slid_listing.txt 1901 ) 1902 1903endif() 1904 1905if(NOT CMAKE_C_COMPILER_ID STREQUAL "ARMClang") 1906 set(check_init_priorities_input 1907 $<IF:$<TARGET_EXISTS:native_runner_executable>,${BYPRODUCT_KERNEL_EXE_NAME},${BYPRODUCT_KERNEL_ELF_NAME}> 1908 ) 1909 set(check_init_priorities_command 1910 ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py 1911 --elf-file=${check_init_priorities_input} 1912 ) 1913 set(check_init_priorities_dependencies 1914 ${logical_target_for_zephyr_elf} 1915 $<$<TARGET_EXISTS:native_runner_executable>:native_runner_executable> 1916 ) 1917 1918 if(CONFIG_CHECK_INIT_PRIORITIES) 1919 if(TARGET native_runner_executable) 1920 add_custom_command(TARGET native_runner_executable POST_BUILD 1921 COMMAND ${check_init_priorities_command} 1922 ) 1923 else() 1924 list(APPEND post_build_commands COMMAND ${check_init_priorities_command}) 1925 endif() 1926 endif() 1927 1928 add_custom_target( 1929 initlevels 1930 COMMAND ${check_init_priorities_command} --initlevels 1931 DEPENDS ${check_init_priorities_dependencies} 1932 USES_TERMINAL 1933 ) 1934endif() 1935 1936# Generate signed (MCUboot or other) related artifacts as needed. Priority is: 1937# * Sysbuild (if set) 1938# * SIGNING_SCRIPT target property (if set) 1939# * MCUboot signing script (if MCUboot is enabled) 1940zephyr_get(signing_script VAR SIGNING_SCRIPT SYSBUILD) 1941 1942if(NOT signing_script) 1943 get_target_property(signing_script zephyr_property_target SIGNING_SCRIPT) 1944 1945 if(NOT signing_script AND CONFIG_BOOTLOADER_MCUBOOT) 1946 set(signing_script ${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake) 1947 endif() 1948endif() 1949 1950# Include signing script, if set 1951if(signing_script) 1952 message(STATUS "Including signing script: ${signing_script}") 1953 1954 include(${signing_script}) 1955endif() 1956 1957# Generate USB-C VIF policies in XML format 1958if (CONFIG_BUILD_OUTPUT_VIF) 1959 include(${CMAKE_CURRENT_LIST_DIR}/cmake/vif.cmake) 1960endif() 1961 1962get_property(extra_post_build_commands 1963 GLOBAL PROPERTY 1964 extra_post_build_commands 1965 ) 1966 1967list(APPEND 1968 post_build_commands 1969 ${extra_post_build_commands} 1970 ) 1971 1972get_property(extra_post_build_byproducts 1973 GLOBAL PROPERTY 1974 extra_post_build_byproducts 1975 ) 1976 1977list(APPEND 1978 post_build_byproducts 1979 ${extra_post_build_byproducts} 1980 ) 1981 1982if(CONFIG_LOG_DICTIONARY_DB) 1983 set(LOG_DICT_DB_NAME ${PROJECT_BINARY_DIR}/log_dictionary.json) 1984 set(LOG_DICT_DB_NAME_ARG --json) 1985elseif(CONFIG_LOG_MIPI_SYST_USE_CATALOG) 1986 set(LOG_DICT_DB_NAME ${PROJECT_BINARY_DIR}/mipi_syst_collateral.xml) 1987 set(LOG_DICT_DB_NAME_ARG --syst) 1988endif() 1989 1990if(LOG_DICT_DB_NAME_ARG) 1991 set(log_dict_gen_command 1992 ${PYTHON_EXECUTABLE} 1993 ${ZEPHYR_BASE}/scripts/logging/dictionary/database_gen.py 1994 ${KERNEL_ELF_NAME} 1995 ${LOG_DICT_DB_NAME_ARG}=${LOG_DICT_DB_NAME} 1996 --build-header ${PROJECT_BINARY_DIR}/include/generated/zephyr/version.h 1997 ) 1998 1999 if (NOT CONFIG_LOG_DICTIONARY_DB_TARGET) 2000 # If not using a separate target for generating logging dictionary 2001 # database, add the generation to post build command to make sure 2002 # the database is actually being generated. 2003 list(APPEND 2004 post_build_commands 2005 COMMAND ${CMAKE_COMMAND} -E echo "Generating logging dictionary database: ${LOG_DICT_DB_NAME}" 2006 COMMAND ${log_dict_gen_command} 2007 ) 2008 list(APPEND 2009 post_build_byproducts 2010 ${LOG_DICT_DB_NAME} 2011 ) 2012 else() 2013 # Seprate build target for generating logging dictionary database. 2014 # This needs to be explicitly called/used to generate the database. 2015 add_custom_command( 2016 OUTPUT ${LOG_DICT_DB_NAME} 2017 COMMAND ${log_dict_gen_command} 2018 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 2019 COMMENT "Generating logging dictionary database: ${LOG_DICT_DB_NAME}" 2020 DEPENDS ${logical_target_for_zephyr_elf} 2021 ) 2022 add_custom_target(log_dict_db_gen DEPENDS ${LOG_DICT_DB_NAME}) 2023 endif() 2024endif() 2025 2026# Add post_build_commands to post-process the final .elf file produced by 2027# either the ZEPHYR_LINK_STAGE_EXECUTABLE or the KERNEL_ELF executable 2028# targets above. 2029add_custom_command( 2030 TARGET ${logical_target_for_zephyr_elf} 2031 POST_BUILD 2032 COMMAND ${CMAKE_COMMAND} -E echo "Generating files from ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} for board: ${BOARD}" 2033 ${post_build_commands} 2034 BYPRODUCTS 2035 ${post_build_byproducts} 2036 COMMAND_EXPAND_LISTS 2037 ) 2038 2039# To populate with hex files to merge, do the following: 2040# set_property(GLOBAL APPEND PROPERTY HEX_FILES_TO_MERGE ${my_local_list}) 2041# Note that the zephyr.hex file will not be included automatically. 2042get_property(HEX_FILES_TO_MERGE GLOBAL PROPERTY HEX_FILES_TO_MERGE) 2043if(HEX_FILES_TO_MERGE) 2044 # Merge in out-of-tree hex files. 2045 set(MERGED_HEX_NAME merged.hex) 2046 2047 add_custom_command( 2048 OUTPUT ${MERGED_HEX_NAME} 2049 COMMAND 2050 ${PYTHON_EXECUTABLE} 2051 ${ZEPHYR_BASE}/scripts/build/mergehex.py 2052 -o ${MERGED_HEX_NAME} 2053 ${HEX_FILES_TO_MERGE} 2054 DEPENDS ${HEX_FILES_TO_MERGE} ${logical_target_for_zephyr_elf} 2055 ) 2056 2057 add_custom_target(mergehex ALL DEPENDS ${MERGED_HEX_NAME}) 2058 list(APPEND RUNNERS_DEPS mergehex) 2059 2060 message(VERBOSE "Merging hex files: ${HEX_FILES_TO_MERGE}") 2061endif() 2062 2063if(SUPPORTED_EMU_PLATFORMS) 2064 list(GET SUPPORTED_EMU_PLATFORMS 0 default_emu) 2065 if(EXISTS ${ZEPHYR_BASE}/cmake/emu/${default_emu}.cmake) 2066 add_custom_target(run DEPENDS run_${default_emu}) 2067 endif() 2068 2069 foreach(EMU_PLATFORM ${SUPPORTED_EMU_PLATFORMS}) 2070 if(EXISTS ${ZEPHYR_BASE}/cmake/emu/${EMU_PLATFORM}.cmake) 2071 include(${ZEPHYR_BASE}/cmake/emu/${EMU_PLATFORM}.cmake) 2072 endif() 2073 endforeach() 2074 2075 if(TARGET debugserver_${default_emu}) 2076 add_custom_target(debugserver DEPENDS debugserver_${default_emu}) 2077 endif() 2078else() 2079 add_custom_target(run 2080 COMMAND 2081 ${CMAKE_COMMAND} -E echo 2082 "===================================================" 2083 "Emulation/Simulation not supported with this board." 2084 "===================================================" 2085 ) 2086endif() 2087 2088add_subdirectory(cmake/flash) 2089add_subdirectory(cmake/usage) 2090add_subdirectory(cmake/reports) 2091 2092if(NOT CONFIG_TEST) 2093if(CONFIG_ASSERT AND (NOT CONFIG_FORCE_NO_ASSERT)) 2094 message(WARNING "__ASSERT() statements are globally ENABLED") 2095endif() 2096endif() 2097 2098if(CONFIG_BOARD_DEPRECATED_RELEASE) 2099 message(WARNING " 2100 WARNING: The board '${BOARD}' is deprecated and will be 2101 removed in version ${CONFIG_BOARD_DEPRECATED_RELEASE}" 2102 ) 2103endif() 2104 2105if(CONFIG_SOC_DEPRECATED_RELEASE) 2106 message(WARNING " 2107 WARNING: The SoC '${SOC_NAME}' is deprecated and will be 2108 removed in version ${CONFIG_SOC_DEPRECATED_RELEASE}" 2109 ) 2110endif() 2111 2112# In CMake projects, 'CMAKE_BUILD_TYPE' usually determines the 2113# optimization flag, but in Zephyr it is determined through 2114# Kconfig. Here we give a warning when there is a mismatch between the 2115# two in case the user is not aware of this. 2116set(build_types None Debug Release RelWithDebInfo MinSizeRel) 2117 2118if((CMAKE_BUILD_TYPE IN_LIST build_types) AND (NOT NO_BUILD_TYPE_WARNING)) 2119 string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_uppercase) 2120 # The CMAKE_C_FLAGS_<build_type> is a string, so we do a regex to see if the 2121 # optimization flag is present in that string. 2122 # To avoid false-positive matches, the flag must either be matched first 2123 # or last in string, or come after / followed by minimum a space. 2124 if(NOT (CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_uppercase} MATCHES "(^| )${OPTIMIZATION_FLAG}($| )")) 2125 message(WARNING " 2126 The CMake build type was set to '${CMAKE_BUILD_TYPE}', but the optimization flag was set to '${OPTIMIZATION_FLAG}'. 2127 This may be intentional and the warning can be turned off by setting the CMake variable 'NO_BUILD_TYPE_WARNING'" 2128 ) 2129 endif() 2130endif() 2131 2132# Extension Development Kit (EDK) generation. 2133set(llext_edk_file ${PROJECT_BINARY_DIR}/${CONFIG_LLEXT_EDK_NAME}.tar.xz) 2134 2135# TODO maybe generate flags for C CXX ASM 2136zephyr_get_compile_options_for_lang(C zephyr_flags) 2137 2138# Filter out non LLEXT and LLEXT_EDK flags - and add required ones 2139llext_filter_zephyr_flags(LLEXT_REMOVE_FLAGS ${zephyr_flags} llext_edk_cflags) 2140llext_filter_zephyr_flags(LLEXT_EDK_REMOVE_FLAGS ${llext_edk_cflags} llext_edk_cflags) 2141 2142list(APPEND llext_edk_cflags ${LLEXT_APPEND_FLAGS}) 2143list(APPEND llext_edk_cflags ${LLEXT_EDK_APPEND_FLAGS}) 2144 2145add_custom_command( 2146 OUTPUT ${llext_edk_file} 2147 # Regenerate syscalls in case CONFIG_LLEXT_EDK_USERSPACE_ONLY 2148 COMMAND ${CMAKE_COMMAND} 2149 -E make_directory edk/include/generated/zephyr 2150 COMMAND 2151 ${PYTHON_EXECUTABLE} 2152 ${ZEPHYR_BASE}/scripts/build/gen_syscalls.py 2153 --json-file ${syscalls_json} # Read this file 2154 --base-output edk/include/generated/zephyr/syscalls # Write to this dir 2155 --syscall-dispatch edk/include/generated/zephyr/syscall_dispatch.c # Write this file 2156 --syscall-list ${edk_syscall_list_h} 2157 $<$<BOOL:${CONFIG_LLEXT_EDK_USERSPACE_ONLY}>:--userspace-only> 2158 ${SYSCALL_LONG_REGISTERS_ARG} 2159 ${SYSCALL_SPLIT_TIMEOUT_ARG} 2160 COMMAND ${CMAKE_COMMAND} 2161 -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} 2162 -DAPPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR} 2163 -DINTERFACE_INCLUDE_DIRECTORIES="$<TARGET_PROPERTY:zephyr_interface,INTERFACE_INCLUDE_DIRECTORIES>" 2164 -Dllext_edk_file=${llext_edk_file} 2165 -Dllext_cflags="${llext_edk_cflags}" 2166 -Dllext_edk_name=${CONFIG_LLEXT_EDK_NAME} 2167 -DWEST_TOPDIR=${WEST_TOPDIR} 2168 -DZEPHYR_BASE=${ZEPHYR_BASE} 2169 -DCONFIG_LLEXT_EDK_USERSPACE_ONLY=${CONFIG_LLEXT_EDK_USERSPACE_ONLY} 2170 -P ${ZEPHYR_BASE}/cmake/llext-edk.cmake 2171 DEPENDS ${logical_target_for_zephyr_elf} 2172 COMMAND_EXPAND_LISTS 2173) 2174add_custom_target(llext-edk DEPENDS ${llext_edk_file}) 2175 2176# @Intent: Set compiler specific flags for standard C/C++ includes 2177# Done at the very end, so any other system includes which may 2178# be added by Zephyr components were first in list. 2179# Note, the compile flags are moved, but the system include is still present here. 2180zephyr_compile_options($<TARGET_PROPERTY:compiler,nostdinc>) 2181target_include_directories(zephyr_interface SYSTEM INTERFACE $<TARGET_PROPERTY:compiler,nostdinc_include>) 2182 2183if(CONFIG_MINIMAL_LIBCPP) 2184 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,nostdincxx>>) 2185endif() 2186 2187# Finally export all build flags from Zephyr 2188add_subdirectory_ifdef( 2189 CONFIG_MAKEFILE_EXPORTS 2190 cmake/makefile_exports 2191 ) 2192