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# Verify that the toolchain can compile a dummy file, if it is not we 40# won't be able to test for compatibility with certain C flags. 41zephyr_check_compiler_flag(C "" toolchain_is_ok) 42assert(toolchain_is_ok "The toolchain is unable to build a dummy C file. See CMakeError.log.") 43 44# In some cases the "final" things are not used at all and "_prebuilt" 45# is the last station. See "logical_target_for_zephyr_elf" below for 46# details. 47set(CMAKE_EXECUTABLE_SUFFIX .elf) 48set(ZEPHYR_PREBUILT_EXECUTABLE zephyr_prebuilt) 49set(ZEPHYR_FINAL_EXECUTABLE zephyr_final) 50 51# Set some phony targets to collect dependencies 52set(OFFSETS_H_TARGET offsets_h) 53set(SYSCALL_LIST_H_TARGET syscall_list_h_target) 54set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target) 55set(KOBJ_TYPES_H_TARGET kobj_types_h_target) 56set(PARSE_SYSCALLS_TARGET parse_syscalls_target) 57 58define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ") 59set_property( GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little${ARCH}) # BFD format 60 61# "zephyr_interface" is a source-less library that encapsulates all the global 62# compiler options needed by all source files. All zephyr libraries, 63# including the library named "zephyr" link with this library to 64# obtain these flags. 65# https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#interface-libraries 66add_library(zephyr_interface INTERFACE) 67 68# "zephyr" is a catch-all CMake library for source files that can be 69# built purely with the include paths, defines, and other compiler 70# flags that come with zephyr_interface. 71zephyr_library_named(zephyr) 72 73zephyr_include_directories( 74 include 75 ${PROJECT_BINARY_DIR}/include/generated 76 ${USERINCLUDE} 77 ${STDINCLUDE} 78) 79 80include(${ZEPHYR_BASE}/cmake/linker_script/${ARCH}/linker.cmake OPTIONAL) 81 82# Don't add non-existing include directories, it creates noise and 83# warnings in some tooling 84foreach(optional_include_dir 85 ${SOC_DIR}/${ARCH}/${SOC_PATH} 86 ${SOC_DIR}/${ARCH}/${SOC_PATH}/include 87 ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/include 88 ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/include 89 ) 90 if(EXISTS ${optional_include_dir}) 91 zephyr_include_directories(${optional_include_dir}) 92 endif() 93endforeach() 94 95zephyr_compile_definitions( 96 KERNEL 97 __ZEPHYR__=1 98) 99 100# Ensure that include/toolchain.h includes toolchain/other.h for all off-tree toolchains 101if(TOOLCHAIN_USE_CUSTOM) 102 zephyr_compile_definitions(__TOOLCHAIN_CUSTOM__) 103endif() 104 105# @Intent: Set compiler flags to enable buffer overflow checks in libc functions 106# @config in CONFIG_NO_OPTIMIZATIONS optional : Optimizations may affect security 107zephyr_compile_definitions($<TARGET_PROPERTY:compiler,security_fortify> ) 108 109# @Intent: Set compiler flags to detect general stack overflows across all functions 110if(CONFIG_STACK_CANARIES) 111 zephyr_compile_options($<TARGET_PROPERTY:compiler,security_canaries>) 112endif() 113 114if(BUILD_VERSION) 115 zephyr_compile_definitions( 116 BUILD_VERSION=${BUILD_VERSION} 117 ) 118endif() 119 120# @Intent: Obtain compiler optimizations flags and store in variables 121# @details: 122# Kconfig.zephyr "Optimization level" is a kconfig choice, ensuring 123# only *one* of CONFIG_{NO,DEBUG,SPEED,SIZE}_OPTIMIZATIONS is set. 124# Refer to Kconfig.zephyr for selection logic and description of these choices. 125# toolchain_cc_optimize_*() macros must provide the mapping from these kconfigs 126# to compiler flags. Each macro will store the flags in a CMake variable, whose 127# name is passed as argument (somewhat like by reference). 128# 129# If the user wants to tweak the optimizations, there are two ways: 130# 1) Using EXTRA_CFLAGS which is applied regardless of kconfig choice, or 131# 2) Rely on override support being implemented by your toolchain_cc_optimize_*() 132# 133get_property(OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG TARGET compiler PROPERTY no_optimization) 134get_property(OPTIMIZE_FOR_DEBUG_FLAG TARGET compiler PROPERTY optimization_debug) 135get_property(OPTIMIZE_FOR_SPEED_FLAG TARGET compiler PROPERTY optimization_speed) 136get_property(OPTIMIZE_FOR_SIZE_FLAG TARGET compiler PROPERTY optimization_size) 137 138# From kconfig choice, pick the actual OPTIMIZATION_FLAG to use. 139# Kconfig choice ensures only one of these CONFIG_*_OPTIMIZATIONS is set. 140if(CONFIG_NO_OPTIMIZATIONS) 141 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG}) 142elseif(CONFIG_DEBUG_OPTIMIZATIONS) 143 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_DEBUG_FLAG}) 144elseif(CONFIG_SPEED_OPTIMIZATIONS) 145 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SPEED_FLAG}) 146elseif(CONFIG_SIZE_OPTIMIZATIONS) 147 set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SIZE_FLAG}) # Default in kconfig 148else() 149 assert(0 "Unreachable code. Expected optimization level to have been chosen. See Kconfig.zephyr") 150endif() 151 152if(NOT CONFIG_ARCH_IS_SET) 153 message(WARNING "\ 154None of the CONFIG_<arch> (e.g. CONFIG_X86) symbols are set. \ 155Select one of them from the SOC_SERIES_* symbol or, lacking that, from the \ 156SOC_* symbol.") 157endif() 158 159# Apply the final optimization flag(s) 160zephyr_compile_options(${OPTIMIZATION_FLAG}) 161 162# @Intent: Obtain compiler specific flags related to C++ that are not influenced by kconfig 163zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,required>>) 164 165# Extra warnings options for twister run 166if (CONFIG_COMPILER_WARNINGS_AS_ERRORS) 167 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warnings_as_errors>>) 168 zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:$<TARGET_PROPERTY:asm,warnings_as_errors>>) 169 zephyr_link_libraries($<TARGET_PROPERTY:linker,warnings_as_errors>) 170endif() 171 172# @Intent: Obtain compiler specific flags for compiling under different ISO standards of C++ 173if(CONFIG_CPLUSPLUS) 174 # From kconfig choice, pick a single dialect. 175 # Kconfig choice ensures only one of these CONFIG_STD_CPP* is set. 176 if(CONFIG_STD_CPP98) 177 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp98>) 178 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp98}) 179 elseif(CONFIG_STD_CPP11) 180 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp11>) # Default in kconfig 181 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp11}) 182 elseif(CONFIG_STD_CPP14) 183 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp14>) 184 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp14}) 185 elseif(CONFIG_STD_CPP17) 186 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp17>) 187 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp17}) 188 elseif(CONFIG_STD_CPP2A) 189 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp2a>) 190 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp20}) 191 elseif(CONFIG_STD_CPP20) 192 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp20>) 193 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp20}) 194 elseif(CONFIG_STD_CPP2B) 195 set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp2b>) 196 list(APPEND CMAKE_CXX_COMPILE_FEATURES ${compile_features_cpp20}) 197 else() 198 assert(0 "Unreachable code. Expected C++ standard to have been chosen. See Kconfig.zephyr.") 199 endif() 200 set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE) 201 202 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:${STD_CPP_DIALECT_FLAGS}>) 203endif() 204 205if(NOT CONFIG_EXCEPTIONS) 206 # @Intent: Obtain compiler specific flags related to C++ Exceptions 207 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,no_exceptions>>) 208endif() 209 210if(NOT CONFIG_RTTI) 211 # @Intent: Obtain compiler specific flags related to C++ Run Time Type Information 212 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,no_rtti>>) 213endif() 214 215if(CONFIG_MISRA_SANE) 216 # @Intent: Obtain toolchain compiler flags relating to MISRA. 217 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_misra_sane>>) 218 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_error_misra_sane>>) 219endif() 220 221# This is intend to be temporary. Once we have fixed the violations that 222# prevents build Zephyr, these flags shall be part of the default flags. 223if(CONFIG_CODING_GUIDELINE_CHECK) 224 # @Intent: Obtain toolchain compiler flags relating to coding guideline 225 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_coding_guideline>>) 226endif() 227 228# @Intent: Set compiler specific macro inclusion of AUTOCONF_H 229zephyr_compile_options("SHELL: $<TARGET_PROPERTY:compiler,imacros> ${AUTOCONF_H}") 230 231# @Intent: Set compiler specific flag for bare metal freestanding option 232zephyr_compile_options($<TARGET_PROPERTY:compiler,freestanding>) 233 234# @Intent: Set compiler specific flag for tentative definitions, no-common 235zephyr_compile_options($<TARGET_PROPERTY:compiler,no_common>) 236 237# @Intent: Set compiler specific flag for production of debug information 238zephyr_compile_options($<TARGET_PROPERTY:compiler,debug>) 239 240if(CONFIG_COMPILER_COLOR_DIAGNOSTICS) 241# @Intent: Set compiler specific flag for diagnostic messages 242zephyr_compile_options($<TARGET_PROPERTY:compiler,diagnostic>) 243endif() 244 245zephyr_compile_options( 246 ${TOOLCHAIN_C_FLAGS} 247) 248 249# @Intent: Obtain compiler specific flags related to assembly 250# ToDo: Remember to get feedback from Oticon on this, as they might use the `ASM_BASE_FLAG` since this is done this way. 251zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:$<TARGET_PROPERTY:asm,required>>) 252 253# @Intent: Enforce standard integer type correspondance to match Zephyr usage. 254# (must be after compiler specific flags) 255if(NOT CONFIG_ARCH_POSIX) 256 # `zephyr_stdint.h` is not included for the POSIX (native) arch because it 257 # compiles with the host toolchain/headers and there can be conflicts if we 258 # arbitrarily redefine our own type system (see #37718). 259 zephyr_compile_options("SHELL: $<TARGET_PROPERTY:compiler,imacros> ${ZEPHYR_BASE}/include/toolchain/zephyr_stdint.h") 260endif() 261 262# Common toolchain-agnostic assembly flags 263zephyr_compile_options( 264 $<$<COMPILE_LANGUAGE:ASM>:-D_ASMLANGUAGE> 265) 266 267# @Intent: Set fundamental linker specific flags 268toolchain_ld_base() 269 270toolchain_ld_force_undefined_symbols( 271 _OffsetAbsSyms 272 _ConfigAbsSyms 273) 274 275if(NOT CONFIG_NATIVE_APPLICATION) 276 # @Intent: Set linker specific flags for bare metal target 277 toolchain_ld_baremetal() 278endif() 279 280if(CONFIG_LIB_CPLUSPLUS) 281 # @Intent: Set linker specific flags for C++ 282 toolchain_ld_cpp() 283endif() 284 285# @Intent: Add the basic toolchain warning flags 286zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_base>>) 287zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_base>>) 288 289# ========================================================================== 290# 291# cmake -DW=... settings 292# 293# W=1 - warnings that may be relevant and does not occur too often 294# W=2 - warnings that occur quite often but may still be relevant 295# W=3 - the more obscure warnings, can most likely be ignored 296# ========================================================================== 297# @Intent: Add cmake -DW toolchain supported warnings, if any 298if(W MATCHES "1") 299 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_1>>) 300 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_1>>) 301endif() 302 303if(W MATCHES "2") 304 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_2>>) 305 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_2>>) 306endif() 307 308if(W MATCHES "3") 309 zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_3>>) 310 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_3>>) 311endif() 312 313# @Intent: Add extended, more specific, toolchain warning flags 314zephyr_compile_options($<TARGET_PROPERTY:compiler,warning_extended>) 315 316# @Intent: Trigger an error when a declaration does not specify a type 317zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_implicit_int>>) 318zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_error_implicit_int>>) 319 320# Allow the user to inject options when calling cmake, e.g. 321# 'cmake -DEXTRA_CFLAGS="-Werror -Wno-deprecated-declarations" ..' 322include(cmake/extra_flags.cmake) 323 324zephyr_cc_option(-fno-asynchronous-unwind-tables) 325zephyr_cc_option(-fno-pie) 326zephyr_cc_option(-fno-pic) 327zephyr_cc_option(-fno-strict-overflow) 328 329if(CONFIG_THREAD_LOCAL_STORAGE) 330# Only support local exec TLS model at this point. 331zephyr_cc_option(-ftls-model=local-exec) 332endif() 333 334if(CONFIG_OVERRIDE_FRAME_POINTER_DEFAULT) 335 if(CONFIG_OMIT_FRAME_POINTER) 336 zephyr_cc_option(-fomit-frame-pointer) 337 else() 338 zephyr_cc_option(-fno-omit-frame-pointer) 339 endif() 340endif() 341 342separate_arguments(COMPILER_OPT_AS_LIST UNIX_COMMAND ${CONFIG_COMPILER_OPT}) 343zephyr_compile_options(${COMPILER_OPT_AS_LIST}) 344 345# TODO: Include arch compiler options at this point. 346 347if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang") 348 # GCC assumed 349 zephyr_cc_option(-fno-reorder-functions) 350 351 if(NOT ${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "xcc") 352 zephyr_cc_option(-fno-defer-pop) 353 endif() 354endif() 355 356zephyr_cc_option_ifdef(CONFIG_STACK_USAGE -fstack-usage) 357 358# If the compiler supports it, strip the ${ZEPHYR_BASE} prefix from the 359# __FILE__ macro used in __ASSERT*, in the 360# .noinit."/home/joe/zephyr/fu/bar.c" section names and in any 361# application code. This saves some memory, stops leaking user locations 362# in binaries, makes failure logs more deterministic and most 363# importantly makes builds more deterministic 364 365# If several match then the last one wins. This matters for instances 366# like tests/ and samples/: they're inside all of them! Then let's 367# strip as little as possible. 368zephyr_cc_option(-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=CMAKE_SOURCE_DIR) 369zephyr_cc_option(-fmacro-prefix-map=${ZEPHYR_BASE}=ZEPHYR_BASE) 370if(WEST_TOPDIR) 371 zephyr_cc_option(-fmacro-prefix-map=${WEST_TOPDIR}=WEST_TOPDIR) 372endif() 373 374# TODO: Archiver arguments 375# ar_option(D) 376 377# Declare MPU userspace dependencies before the linker scripts to make 378# sure the order of dependencies are met 379if(CONFIG_USERSPACE) 380 add_custom_target(app_smem) 381 set(APP_SMEM_ALIGNED_DEP app_smem_aligned_linker) 382 set(APP_SMEM_UNALIGNED_DEP app_smem_unaligned_linker) 383endif() 384 385if(CONFIG_USERSPACE) 386 set(KOBJECT_LINKER_DEP kobject_linker) 387endif() 388 389get_property(TOPT GLOBAL PROPERTY TOPT) 390set_ifndef( TOPT -Wl,-T) # clang doesn't pick -T for some reason and complains, 391 # while -Wl,-T works for both, gcc and clang 392 393if(CONFIG_HAVE_CUSTOM_LINKER_SCRIPT) 394 set(LINKER_SCRIPT ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT}) 395 if(NOT EXISTS ${LINKER_SCRIPT}) 396 set(LINKER_SCRIPT ${CONFIG_CUSTOM_LINKER_SCRIPT}) 397 assert_exists(CONFIG_CUSTOM_LINKER_SCRIPT) 398 endif() 399else() 400 # Try a board specific linker file 401 set(LINKER_SCRIPT ${BOARD_DIR}/linker.ld) 402 if(NOT EXISTS ${LINKER_SCRIPT}) 403 # If not available, try an SoC specific linker file 404 set(LINKER_SCRIPT ${SOC_DIR}/${ARCH}/${SOC_PATH}/linker.ld) 405 endif() 406endif() 407 408if(NOT EXISTS ${LINKER_SCRIPT}) 409 message(FATAL_ERROR "Could not find linker script: '${LINKER_SCRIPT}'. Corrupted configuration?") 410endif() 411 412configure_file(version.h.in ${PROJECT_BINARY_DIR}/include/generated/version.h) 413 414# Error-out when the deprecated naming convention is found (until 415# after 1.14.0 has been released) 416foreach(path 417 ${BOARD_DIR}/dts.fixup 418 ${PROJECT_SOURCE_DIR}/soc/${ARCH}/${SOC_PATH}/dts.fixup 419 ${APPLICATION_SOURCE_DIR}/dts.fixup 420 ) 421 if(EXISTS ${path}) 422 message(FATAL_ERROR 423 "A deprecated filename has been detected. Porting is required." 424 "The file '${path}' exists, but it should be named dts_fixup.h instead." 425 "See https://github.com/zephyrproject-rtos/zephyr/pull/10352 for more details" 426 ) 427 endif() 428endforeach() 429 430set_ifndef( DTS_BOARD_FIXUP_FILE ${BOARD_DIR}/dts_fixup.h) 431set_ifndef( DTS_SOC_FIXUP_FILE ${SOC_DIR}/${ARCH}/${SOC_PATH}/dts_fixup.h) 432set( DTS_APP_FIXUP_FILE ${APPLICATION_SOURCE_DIR}/dts_fixup.h) 433 434set_ifndef(DTS_CAT_OF_FIXUP_FILES ${ZEPHYR_BINARY_DIR}/include/generated/devicetree_fixups.h) 435 436# Concatenate the fixups into a single header file for easy 437# #include'ing 438file(WRITE ${DTS_CAT_OF_FIXUP_FILES} "/* May only be included by devicetree.h */\n\n") 439set(DISCOVERED_FIXUP_FILES) 440foreach(fixup_file 441 ${DTS_BOARD_FIXUP_FILE} 442 ${DTS_SOC_FIXUP_FILE} 443 ${DTS_APP_FIXUP_FILE} 444 ${shield_dts_fixups} 445 ) 446 if(EXISTS ${fixup_file}) 447 file(READ ${fixup_file} contents) 448 file(APPEND ${DTS_CAT_OF_FIXUP_FILES} "${contents}") 449 string(APPEND DISCOVERED_FIXUP_FILES "- ${fixup_file}\n") 450 endif() 451endforeach() 452 453if (DISCOVERED_FIXUP_FILES) 454 message(WARNING "One or more dts_fixup.h files detected:\n${DISCOVERED_FIXUP_FILES}Use of these files is deprecated; use the devicetree.h API instead.") 455endif() 456 457# Unfortunately, the order in which CMakeLists.txt code is processed 458# matters so we need to be careful about how we order the processing 459# of subdirectories. One example is "Compiler flags added late in the 460# build are not exported to external build systems #5605"; when we 461# integrate with an external build system we read out all compiler 462# flags when the external project is created. So an external project 463# defined in subsys or ext will not get global flags added by drivers/ 464# or tests/ as the subdirectories are ordered now. 465# 466# Another example of when the order matters is the reading and writing 467# of global properties such as ZEPHYR_LIBS or 468# GENERATED_KERNEL_OBJECT_FILES. 469# 470# Arch is placed early because it defines important compiler flags 471# that must be exported to external build systems defined in 472# e.g. subsys/. 473add_subdirectory(arch) 474add_subdirectory(lib) 475# We use include instead of add_subdirectory to avoid creating a new directory scope. 476# This is because source file properties are directory scoped, including the GENERATED 477# property which is set implicitly for custom command outputs 478include(misc/generated/CMakeLists.txt) 479 480if(EXISTS ${SOC_DIR}/${ARCH}/CMakeLists.txt) 481 add_subdirectory(${SOC_DIR}/${ARCH} soc/${ARCH}) 482else() 483 add_subdirectory(${SOC_DIR}/${ARCH}/${SOC_PATH} soc/${ARCH}/${SOC_PATH}) 484endif() 485 486add_subdirectory(boards) 487add_subdirectory(subsys) 488add_subdirectory(drivers) 489 490# Include zephyr modules generated CMake file. 491foreach(module_name ${ZEPHYR_MODULE_NAMES}) 492 # Note the second, binary_dir parameter requires the added 493 # subdirectory to have its own, local cmake target(s). If not then 494 # this binary_dir is created but stays empty. Object files land in 495 # the main binary dir instead. 496 # https://cmake.org/pipermail/cmake/2019-June/069547.html 497 zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name}) 498 if(NOT ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR} STREQUAL "") 499 set(ZEPHYR_CURRENT_MODULE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}) 500 set(ZEPHYR_CURRENT_CMAKE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR}) 501 add_subdirectory(${ZEPHYR_CURRENT_CMAKE_DIR} ${CMAKE_BINARY_DIR}/modules/${module_name}) 502 endif() 503endforeach() 504# Done processing modules, clear ZEPHYR_CURRENT_MODULE_DIR and ZEPHYR_CURRENT_CMAKE_DIR. 505set(ZEPHYR_CURRENT_MODULE_DIR) 506set(ZEPHYR_CURRENT_CMAKE_DIR) 507 508set(syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscall_list.h) 509set(syscalls_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls.json) 510set(struct_tags_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/struct_tags.json) 511 512# The syscalls subdirs txt file is constructed by python containing a list of folders to use for 513# dependency handling, including empty folders. 514# Windows: The list is used to specify DIRECTORY list with CMAKE_CONFIGURE_DEPENDS attribute. 515# Other OS: The list will update whenever a file is added/removed/modified and ensure a re-build. 516set(syscalls_subdirs_txt ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_subdirs.txt) 517 518# As syscalls_subdirs_txt is updated whenever a file is modified, this file can not be used for 519# monitoring of added / removed folders. A trigger file is thus used for correct dependency 520# handling. The trigger file will update when a folder is added / removed. 521set(syscalls_subdirs_trigger ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_subdirs.trigger) 522 523if(NOT (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows)) 524 set(syscalls_links --create-links ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_links) 525endif() 526 527# When running CMake it must be ensured that all dependencies are correctly acquired. 528execute_process( 529 COMMAND 530 ${PYTHON_EXECUTABLE} 531 ${ZEPHYR_BASE}/scripts/subfolder_list.py 532 --directory ${ZEPHYR_BASE}/include # Walk this directory 533 --out-file ${syscalls_subdirs_txt} # Write file with discovered folder 534 --trigger ${syscalls_subdirs_trigger} # Trigger file that is used for json generation 535 ${syscalls_links} # If defined, create symlinks for dependencies 536) 537file(STRINGS ${syscalls_subdirs_txt} PARSE_SYSCALLS_PATHS_DEPENDS ENCODING UTF-8) 538 539if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) 540 # On windows only adding/removing files or folders will be reflected in depends. 541 # Hence adding a file requires CMake to re-run to add this file to the file list. 542 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PARSE_SYSCALLS_PATHS_DEPENDS}) 543 544 # Also On Windows each header file must be monitored as file modifications are not reflected 545 # on directory level. 546 file(GLOB_RECURSE PARSE_SYSCALLS_HEADER_DEPENDS ${ZEPHYR_BASE}/include/*.h) 547else() 548 # The syscall parsing depends on the folders in order to detect add/removed/modified files. 549 # When a folder is removed, CMake will try to find a target that creates that dependency. 550 # This command sets up the target for CMake to find. 551 # Without this code, CMake will fail with the following error: 552 # <folder> needed by '<target>', missing and no known rule to make it 553 # when a folder is removed. 554 add_custom_command(OUTPUT ${PARSE_SYSCALLS_PATHS_DEPENDS} 555 COMMAND ${CMAKE_COMMAND} -E echo "" 556 COMMENT "Preparing syscall dependency handling" 557 ) 558 559 add_custom_command( 560 OUTPUT 561 ${syscalls_subdirs_trigger} 562 COMMAND 563 ${PYTHON_EXECUTABLE} 564 ${ZEPHYR_BASE}/scripts/subfolder_list.py 565 --directory ${ZEPHYR_BASE}/include # Walk this directory 566 --out-file ${syscalls_subdirs_txt} # Write file with discovered folder 567 --trigger ${syscalls_subdirs_trigger} # Trigger file that is used for json generation 568 ${syscalls_links} # If defined, create symlinks for dependencies 569 DEPENDS ${PARSE_SYSCALLS_PATHS_DEPENDS} 570 ) 571 572 # Ensure subdir file always exists when specifying CMake dependency. 573 if(NOT EXISTS ${syscalls_subdirs_txt}) 574 file(WRITE ${syscalls_subdirs_txt} "") 575 endif() 576 577 # On other OS'es, modifying a file is reflected on the folder timestamp and hence detected 578 # when using depend on directory level. 579 # Thus CMake only needs to re-run when sub-directories are added / removed, which is indicated 580 # using a trigger file. 581 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${syscalls_subdirs_txt}) 582endif() 583 584# syscall declarations are searched for in the SYSCALL_INCLUDE_DIRS 585if(CONFIG_APPLICATION_DEFINED_SYSCALL) 586 list(APPEND SYSCALL_INCLUDE_DIRS ${APPLICATION_SOURCE_DIR}) 587endif() 588 589if(CONFIG_ZTEST) 590 list(APPEND SYSCALL_INCLUDE_DIRS ${ZEPHYR_BASE}/subsys/testsuite/ztest/include) 591endif() 592 593foreach(d ${SYSCALL_INCLUDE_DIRS}) 594 list(APPEND parse_syscalls_include_args 595 --include ${d} 596 ) 597endforeach() 598 599add_custom_command( 600 OUTPUT 601 ${syscalls_json} 602 ${struct_tags_json} 603 COMMAND 604 ${PYTHON_EXECUTABLE} 605 ${ZEPHYR_BASE}/scripts/parse_syscalls.py 606 --include ${ZEPHYR_BASE}/include # Read files from this dir 607 --include ${ZEPHYR_BASE}/drivers # For net sockets 608 --include ${ZEPHYR_BASE}/subsys/net # More net sockets 609 ${parse_syscalls_include_args} # Read files from these dirs also 610 --json-file ${syscalls_json} # Write this file 611 --tag-struct-file ${struct_tags_json} # Write subsystem list to this file 612 DEPENDS ${syscalls_subdirs_trigger} ${PARSE_SYSCALLS_HEADER_DEPENDS} 613 ) 614 615add_custom_target(${SYSCALL_LIST_H_TARGET} DEPENDS ${syscall_list_h}) 616 617set_property(TARGET ${SYSCALL_LIST_H_TARGET} 618 APPEND PROPERTY 619 ADDITIONAL_CLEAN_FILES 620 ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscalls 621) 622 623add_custom_target(${PARSE_SYSCALLS_TARGET} 624 DEPENDS 625 ${syscalls_json} 626 ${struct_tags_json} 627 ) 628 629# 64-bit systems do not require special handling of 64-bit system call 630# parameters or return values, indicate this to the system call boilerplate 631# generation script. 632if(CONFIG_64BIT) 633 set(SYSCALL_LONG_REGISTERS_ARG --long-registers) 634endif() 635 636if(CONFIG_TIMEOUT_64BIT) 637 set(SYSCALL_SPLIT_TIMEOUT_ARG --split-type k_timeout_t --split-type k_ticks_t) 638endif() 639 640add_custom_command(OUTPUT include/generated/syscall_dispatch.c ${syscall_list_h} 641 # Also, some files are written to include/generated/syscalls/ 642 COMMAND 643 ${PYTHON_EXECUTABLE} 644 ${ZEPHYR_BASE}/scripts/gen_syscalls.py 645 --json-file ${syscalls_json} # Read this file 646 --base-output include/generated/syscalls # Write to this dir 647 --syscall-dispatch include/generated/syscall_dispatch.c # Write this file 648 --syscall-list ${syscall_list_h} 649 ${SYSCALL_LONG_REGISTERS_ARG} 650 ${SYSCALL_SPLIT_TIMEOUT_ARG} 651 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 652 DEPENDS ${PARSE_SYSCALLS_TARGET} 653 ) 654 655# This is passed into all calls to the gen_kobject_list.py script. 656set(gen_kobject_list_include_args --include ${struct_tags_json}) 657 658set(DRV_VALIDATION ${PROJECT_BINARY_DIR}/include/generated/driver-validation.h) 659add_custom_command( 660 OUTPUT ${DRV_VALIDATION} 661 COMMAND 662 ${PYTHON_EXECUTABLE} 663 ${ZEPHYR_BASE}/scripts/gen_kobject_list.py 664 --validation-output ${DRV_VALIDATION} 665 ${gen_kobject_list_include_args} 666 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 667 DEPENDS 668 ${ZEPHYR_BASE}/scripts/gen_kobject_list.py 669 ${PARSE_SYSCALLS_TARGET} 670 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 671 ) 672add_custom_target(${DRIVER_VALIDATION_H_TARGET} DEPENDS ${DRV_VALIDATION}) 673 674include(${ZEPHYR_BASE}/cmake/kobj.cmake) 675gen_kobj(KOBJ_INCLUDE_PATH) 676 677# Add a pseudo-target that is up-to-date when all generated headers 678# are up-to-date. 679 680add_custom_target(zephyr_generated_headers) 681add_dependencies(zephyr_generated_headers 682 offsets_h 683 ) 684 685# Generate offsets.c.obj from offsets.c 686# Generate offsets.h from offsets.c.obj 687 688set(OFFSETS_LIB offsets) 689 690set(OFFSETS_C_PATH ${ARCH_DIR}/${ARCH}/core/offsets/offsets.c) 691set(OFFSETS_H_PATH ${PROJECT_BINARY_DIR}/include/generated/offsets.h) 692 693add_library( ${OFFSETS_LIB} OBJECT ${OFFSETS_C_PATH}) 694target_include_directories(${OFFSETS_LIB} PRIVATE 695 kernel/include 696 ${ARCH_DIR}/${ARCH}/include 697 ) 698target_link_libraries(${OFFSETS_LIB} zephyr_interface) 699add_dependencies(zephyr_interface 700 ${SYSCALL_LIST_H_TARGET} 701 ${DRIVER_VALIDATION_H_TARGET} 702 ${KOBJ_TYPES_H_TARGET} 703 ) 704 705add_custom_command( 706 OUTPUT ${OFFSETS_H_PATH} 707 COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/gen_offset_header.py 708 -i $<TARGET_OBJECTS:${OFFSETS_LIB}> 709 -o ${OFFSETS_H_PATH} 710 DEPENDS 711 ${OFFSETS_LIB} 712 $<TARGET_OBJECTS:${OFFSETS_LIB}> 713) 714add_custom_target(${OFFSETS_H_TARGET} DEPENDS ${OFFSETS_H_PATH}) 715 716zephyr_get_include_directories_for_lang(C ZEPHYR_INCLUDES) 717 718add_subdirectory(kernel) 719 720# Read list content 721get_property(ZEPHYR_LIBS_PROPERTY GLOBAL PROPERTY ZEPHYR_LIBS) 722 723foreach(zephyr_lib ${ZEPHYR_LIBS_PROPERTY}) 724 get_property(lib_type TARGET ${zephyr_lib} PROPERTY TYPE) 725 # To prevent CMake failure when a driver is enabled, for example: REGULATOR=y 726 # we disable any Zephyr libraries without sources and adds the `empty_file.c`. 727 if(${lib_type} STREQUAL STATIC_LIBRARY 728 AND NOT ${zephyr_lib} STREQUAL app 729 ) 730 get_property(source_list TARGET ${zephyr_lib} PROPERTY SOURCES) 731 get_property(lib_imported TARGET ${zephyr_lib} PROPERTY IMPORTED) 732 if(NOT source_list 733 AND NOT ${lib_imported} 734 ) 735 get_property(allow_empty TARGET ${zephyr_lib} PROPERTY ALLOW_EMPTY) 736 if(NOT "${allow_empty}") 737 message(WARNING 738 "No SOURCES given to Zephyr library: ${zephyr_lib}\nExcluding target from build." 739 ) 740 endif() 741 target_sources(${zephyr_lib} PRIVATE ${ZEPHYR_BASE}/misc/empty_file.c) 742 set_property(TARGET ${zephyr_lib} PROPERTY EXCLUDE_FROM_ALL TRUE) 743 list(REMOVE_ITEM ZEPHYR_LIBS_PROPERTY ${zephyr_lib}) 744 continue() 745 endif() 746 endif() 747 748 # TODO: Could this become an INTERFACE property of zephyr_interface? 749 add_dependencies(${zephyr_lib} zephyr_generated_headers) 750endforeach() 751 752get_property(OUTPUT_FORMAT GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT) 753 754if (CONFIG_CODE_DATA_RELOCATION) 755 set(CODE_RELOCATION_DEP code_relocation_source_lib) 756endif() # CONFIG_CODE_DATA_RELOCATION 757 758# Give the linker script targets all of the include directories so 759# that cmake can successfully find the linker scripts' header 760# dependencies. 761zephyr_get_include_directories_for_lang(C 762 ZEPHYR_INCLUDE_DIRS 763 STRIP_PREFIX # Don't use a -I prefix 764 ) 765 766if(CONFIG_GEN_ISR_TABLES) 767 if(CONFIG_GEN_SW_ISR_TABLE) 768 list(APPEND GEN_ISR_TABLE_EXTRA_ARG --sw-isr-table) 769 endif() 770 771 if(CONFIG_GEN_IRQ_VECTOR_TABLE) 772 list(APPEND GEN_ISR_TABLE_EXTRA_ARG --vector-table) 773 endif() 774 775 # isr_tables.c is generated from ${ZEPHYR_PREBUILT_EXECUTABLE} by 776 # gen_isr_tables.py 777 add_custom_command( 778 OUTPUT isr_tables.c isrList.bin 779 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 780 $<TARGET_PROPERTY:bintools,elfconvert_flag> 781 $<TARGET_PROPERTY:bintools,elfconvert_flag_intarget>${OUTPUT_FORMAT} 782 $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>binary 783 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_only>.intList 784 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>$<TARGET_FILE:${ZEPHYR_PREBUILT_EXECUTABLE}> 785 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>isrList.bin 786 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 787 COMMAND ${PYTHON_EXECUTABLE} 788 ${ZEPHYR_BASE}/arch/common/gen_isr_tables.py 789 --output-source isr_tables.c 790 --kernel $<TARGET_FILE:${ZEPHYR_PREBUILT_EXECUTABLE}> 791 --intlist isrList.bin 792 $<$<BOOL:${CONFIG_BIG_ENDIAN}>:--big-endian> 793 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--debug> 794 ${GEN_ISR_TABLE_EXTRA_ARG} 795 DEPENDS ${ZEPHYR_PREBUILT_EXECUTABLE} 796 COMMAND_EXPAND_LISTS 797 ) 798 set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES isr_tables.c) 799endif() 800 801if(CONFIG_HAS_DTS) 802 # dev_handles.c is generated from ${ZEPHYR_PREBUILT_EXECUTABLE} by 803 # gen_handles.py 804 add_custom_command( 805 OUTPUT dev_handles.c 806 COMMAND 807 ${PYTHON_EXECUTABLE} 808 ${ZEPHYR_BASE}/scripts/gen_handles.py 809 --output-source dev_handles.c 810 --kernel $<TARGET_FILE:${ZEPHYR_PREBUILT_EXECUTABLE}> 811 --zephyr-base ${ZEPHYR_BASE} 812 --start-symbol "$<TARGET_PROPERTY:linker,devices_start_symbol>" 813 DEPENDS ${ZEPHYR_PREBUILT_EXECUTABLE} 814 ) 815 set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES dev_handles.c) 816endif() 817 818if(CONFIG_CODE_DATA_RELOCATION) 819 # @Intent: Linker script to relocate .text, data and .bss sections 820 toolchain_ld_relocation() 821endif() 822 823if(CONFIG_USERSPACE) 824 zephyr_get_compile_options_for_lang_as_string(C compiler_flags_priv) 825 string(REPLACE "$<TARGET_PROPERTY:compiler,coverage>" "" 826 NO_COVERAGE_FLAGS "${compiler_flags_priv}" 827 ) 828 829 get_property(include_dir_in_interface TARGET zephyr_interface 830 PROPERTY INTERFACE_INCLUDE_DIRECTORIES) 831 832 get_property(sys_include_dir_in_interface TARGET zephyr_interface 833 PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) 834 835 get_property(compile_definitions_interface TARGET zephyr_interface 836 PROPERTY INTERFACE_COMPILE_DEFINITIONS) 837 838 set(GEN_KOBJ_LIST ${ZEPHYR_BASE}/scripts/gen_kobject_list.py) 839 set(PROCESS_GPERF ${ZEPHYR_BASE}/scripts/process_gperf.py) 840 841 set(KOBJECT_HASH_LIST kobject_hash.gperf) 842 set(KOBJECT_HASH_OUTPUT_SRC_PRE kobject_hash_preprocessed.c) 843 set(KOBJECT_HASH_OUTPUT_SRC kobject_hash.c) 844 set(KOBJECT_HASH_OUTPUT_OBJ kobject_hash.c.obj) 845 set(KOBJECT_HASH_OUTPUT_OBJ_RENAMED kobject_hash_renamed.o) 846 847 # Essentially what we are doing here is extracting some information 848 # out of the nearly finished elf file, generating the source code 849 # for a hash table based on that information, and then compiling and 850 # linking the hash table back into a now even more nearly finished 851 # elf file. More information in gen_kobject_list.py --help. 852 853 # Use the script GEN_KOBJ_LIST to scan the kernel binary's 854 # (${ZEPHYR_PREBUILT_EXECUTABLE}) DWARF information to produce a table of kernel 855 # objects (KOBJECT_HASH_LIST) which we will then pass to gperf 856 add_custom_command( 857 OUTPUT ${KOBJECT_HASH_LIST} 858 COMMAND 859 ${PYTHON_EXECUTABLE} 860 ${GEN_KOBJ_LIST} 861 --kernel $<TARGET_FILE:${ZEPHYR_PREBUILT_EXECUTABLE}> 862 --gperf-output ${KOBJECT_HASH_LIST} 863 ${gen_kobject_list_include_args} 864 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 865 DEPENDS 866 ${ZEPHYR_PREBUILT_EXECUTABLE} 867 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 868 ) 869 add_custom_target( 870 kobj_hash_list 871 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_LIST} 872 ) 873 874 # Use gperf to generate C code (KOBJECT_HASH_OUTPUT_SRC_PRE) which implements a 875 # perfect hashtable based on KOBJECT_HASH_LIST 876 add_custom_command( 877 OUTPUT ${KOBJECT_HASH_OUTPUT_SRC_PRE} 878 COMMAND 879 ${GPERF} 880 --output-file ${KOBJECT_HASH_OUTPUT_SRC_PRE} 881 --multiple-iterations 10 882 ${KOBJECT_HASH_LIST} 883 DEPENDS kobj_hash_list ${KOBJECT_HASH_LIST} 884 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 885 ) 886 add_custom_target( 887 kobj_hash_output_src_pre 888 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC_PRE} 889 ) 890 891 # For our purposes the code/data generated by gperf is not optimal. 892 # 893 # The script PROCESS_GPERF creates a new c file KOBJECT_HASH_OUTPUT_SRC based on 894 # KOBJECT_HASH_OUTPUT_SRC_PRE to greatly reduce the amount of code/data generated 895 # since we know we are always working with pointer values 896 add_custom_command( 897 OUTPUT ${KOBJECT_HASH_OUTPUT_SRC} 898 COMMAND 899 ${PYTHON_EXECUTABLE} 900 ${PROCESS_GPERF} 901 -i ${KOBJECT_HASH_OUTPUT_SRC_PRE} 902 -o ${KOBJECT_HASH_OUTPUT_SRC} 903 -p "struct z_object" 904 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 905 DEPENDS kobj_hash_output_src_pre ${KOBJECT_HASH_OUTPUT_SRC_PRE} 906 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 907 ) 908 add_custom_target( 909 kobj_hash_output_src 910 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC} 911 ) 912 913 # We need precise control of where generated text/data ends up in the final 914 # kernel image. Disable function/data sections and use objcopy to move 915 # generated data into special section names 916 add_library( 917 kobj_hash_output_lib 918 STATIC ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_SRC} 919 ) 920 921 set_source_files_properties(${KOBJECT_HASH_OUTPUT_SRC} 922 PROPERTIES COMPILE_FLAGS 923 "${NO_COVERAGE_FLAGS} -fno-function-sections -fno-data-sections") 924 925 set_source_files_properties(${KOBJECT_HASH_OUTPUT_SRC} 926 PROPERTIES COMPILE_DEFINITIONS "${compile_definitions_interface}") 927 928 # Turn off -ffunction-sections, etc. 929 # NB: Using a library instead of target_compile_options(kobj_hash_output_lib 930 # [...]) because a library's options have precedence 931 add_library(kobj_hash_output_lib_interface INTERFACE) 932 933 target_link_libraries(kobj_hash_output_lib kobj_hash_output_lib_interface) 934 935 foreach(incl ${include_dir_in_interface}) 936 target_include_directories(kobj_hash_output_lib_interface INTERFACE ${incl}) 937 endforeach() 938 939 foreach(incl ${sys_include_dir_in_interface}) 940 target_include_directories(kobj_hash_output_lib_interface SYSTEM INTERFACE ${incl}) 941 endforeach() 942 943 set( 944 KOBJECT_HASH_OUTPUT_OBJ_PATH 945 ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/kobj_hash_output_lib.dir/${KOBJECT_HASH_OUTPUT_OBJ} 946 ) 947 948 add_custom_command( 949 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 950 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 951 $<TARGET_PROPERTY:bintools,elfconvert_flag> 952 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.data=.kobject_data.data 953 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.sdata=.kobject_data.sdata 954 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.text=.kobject_data.text 955 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_rename>.rodata=.kobject_data.rodata 956 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KOBJECT_HASH_OUTPUT_OBJ_PATH} 957 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 958 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 959 DEPENDS kobj_hash_output_lib 960 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 961 COMMAND_EXPAND_LISTS 962 ) 963 add_custom_target( 964 kobj_hash_output_obj_renamed 965 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 966 ) 967 968 add_library(kobj_hash_output_obj_renamed_lib STATIC IMPORTED GLOBAL) 969 set_property( 970 TARGET kobj_hash_output_obj_renamed_lib 971 PROPERTY 972 IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_OUTPUT_OBJ_RENAMED} 973 ) 974 add_dependencies( 975 kobj_hash_output_obj_renamed_lib 976 kobj_hash_output_obj_renamed 977 ) 978 979 set_property( 980 GLOBAL APPEND PROPERTY 981 GENERATED_KERNEL_OBJECT_FILES kobj_hash_output_obj_renamed_lib 982 ) 983endif() 984 985# Read global variables into local variables 986get_property(GKOF GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES) 987get_property(GKSF GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES) 988 989 990get_property(CSTD GLOBAL PROPERTY CSTD) 991set_ifndef(CSTD c99) 992 993# @Intent: Obtain compiler specific flag for specifying the c standard 994zephyr_compile_options( 995 $<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,cstd>${CSTD}> 996) 997set(CMAKE_C_COMPILE_FEATURES ${compile_features_${CSTD}} PARENT_SCOPE) 998 999# @Intent: Configure linker scripts, i.e. generate linker scripts with variables substituted 1000toolchain_ld_configure_files() 1001 1002if(CONFIG_USERSPACE) 1003 set(APP_SMEM_ALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld") 1004 set(APP_SMEM_UNALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld") 1005 1006 if(CONFIG_LINKER_USE_PINNED_SECTION) 1007 set(APP_SMEM_PINNED_ALIGNED_LD 1008 "${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_aligned.ld") 1009 set(APP_SMEM_PINNED_UNALIGNED_LD 1010 "${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_unaligned.ld") 1011 1012 if(NOT CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT) 1013 # The libc partition may hold symbols that are required during boot process, 1014 # for example, stack guard (if enabled). So the libc partition must be pinned 1015 # if not sections are in physical memory at boot, as the paging mechanism is 1016 # only initialized post-kernel. 1017 set_property(TARGET app_smem APPEND PROPERTY pinned_partitions "z_libc_partition") 1018 endif() 1019 1020 get_property(APP_SMEM_PINNED_PARTITION_LIST TARGET app_smem PROPERTY pinned_partitions) 1021 if(APP_SMEM_PINNED_PARTITION_LIST) 1022 list(JOIN APP_SMEM_PINNED_PARTITION_LIST "," APP_SMEM_PINNED_PARTITION_LIST_ARG_CSL) 1023 set(APP_SMEM_PINNED_PARTITION_LIST_ARG "--pinpartitions=${APP_SMEM_PINNED_PARTITION_LIST_ARG_CSL}") 1024 endif() 1025 endif() 1026 1027 set(OBJ_FILE_DIR "${PROJECT_BINARY_DIR}/../") 1028 1029 add_custom_target( 1030 ${APP_SMEM_ALIGNED_DEP} 1031 DEPENDS 1032 ${APP_SMEM_ALIGNED_LD} 1033 ${APP_SMEM_PINNED_ALIGNED_LD} 1034 ) 1035 1036 add_custom_target( 1037 ${APP_SMEM_UNALIGNED_DEP} 1038 DEPENDS 1039 ${APP_SMEM_UNALIGNED_LD} 1040 ${APP_SMEM_PINNED_UNALIGNED_LD} 1041 ) 1042 1043 if(CONFIG_NEWLIB_LIBC) 1044 set(NEWLIB_PART -l libc.a z_libc_partition) 1045 endif() 1046 if(CONFIG_NEWLIB_LIBC_NANO) 1047 set(NEWLIB_PART -l libc_nano.a z_libc_partition) 1048 endif() 1049 1050 add_custom_command( 1051 OUTPUT ${APP_SMEM_UNALIGNED_LD} ${APP_SMEM_PINNED_UNALIGNED_LD} 1052 COMMAND ${PYTHON_EXECUTABLE} 1053 ${ZEPHYR_BASE}/scripts/gen_app_partitions.py 1054 -f ${CMAKE_BINARY_DIR}/compile_commands.json 1055 -o ${APP_SMEM_UNALIGNED_LD} 1056 $<$<BOOL:${APP_SMEM_PINNED_UNALIGNED_LD}>:--pinoutput=${APP_SMEM_PINNED_UNALIGNED_LD}> 1057 ${APP_SMEM_PINNED_PARTITION_LIST_ARG} 1058 ${NEWLIB_PART} 1059 $<TARGET_PROPERTY:zephyr_property_target,COMPILE_OPTIONS> 1060 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1061 DEPENDS 1062 kernel 1063 ${ZEPHYR_LIBS_PROPERTY} 1064 WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/ 1065 COMMAND_EXPAND_LISTS 1066 COMMENT "Generating app_smem_unaligned linker section" 1067 ) 1068 1069 configure_linker_script( 1070 linker_app_smem_unaligned.cmd 1071 "-DLINKER_APP_SMEM_UNALIGNED" 1072 ${CODE_RELOCATION_DEP} 1073 ${APP_SMEM_UNALIGNED_DEP} 1074 ${APP_SMEM_UNALIGNED_LD} 1075 ${APP_SMEM_PINNED_UNALIGNED_LD} 1076 zephyr_generated_headers 1077 ) 1078 1079 add_custom_target( 1080 linker_app_smem_unaligned_script 1081 DEPENDS 1082 linker_app_smem_unaligned.cmd 1083 ) 1084 1085 set_property(TARGET 1086 linker_app_smem_unaligned_script 1087 PROPERTY INCLUDE_DIRECTORIES 1088 ${ZEPHYR_INCLUDE_DIRS} 1089 ) 1090 1091 set(APP_SMEM_UNALIGNED_LIB app_smem_unaligned_output_obj_renamed_lib) 1092 add_executable( app_smem_unaligned_prebuilt misc/empty_file.c) 1093 toolchain_ld_link_elf( 1094 TARGET_ELF app_smem_unaligned_prebuilt 1095 OUTPUT_MAP ${PROJECT_BINARY_DIR}/app_smem_unaligned_prebuilt.map 1096 LIBRARIES_PRE_SCRIPT "" 1097 LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker_app_smem_unaligned.cmd 1098 LIBRARIES_POST_SCRIPT "" 1099 DEPENDENCIES ${CODE_RELOCATION_DEP} 1100 ) 1101 target_byproducts(TARGET app_smem_unaligned_prebuilt 1102 BYPRODUCTS ${PROJECT_BINARY_DIR}/app_smem_unaligned_prebuilt.map 1103 ) 1104 set_property(TARGET app_smem_unaligned_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_app_smem_unaligned.cmd) 1105 add_dependencies( app_smem_unaligned_prebuilt linker_app_smem_unaligned_script ${OFFSETS_LIB}) 1106 1107 add_custom_command( 1108 OUTPUT ${APP_SMEM_ALIGNED_LD} ${APP_SMEM_PINNED_ALIGNED_LD} 1109 COMMAND ${PYTHON_EXECUTABLE} 1110 ${ZEPHYR_BASE}/scripts/gen_app_partitions.py 1111 -e $<TARGET_FILE:app_smem_unaligned_prebuilt> 1112 -o ${APP_SMEM_ALIGNED_LD} 1113 $<$<BOOL:${APP_SMEM_PINNED_ALIGNED_LD}>:--pinoutput=${APP_SMEM_PINNED_ALIGNED_LD}> 1114 ${APP_SMEM_PINNED_PARTITION_LIST_ARG} 1115 ${NEWLIB_PART} 1116 $<TARGET_PROPERTY:zephyr_property_target,COMPILE_OPTIONS> 1117 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1118 DEPENDS 1119 kernel 1120 ${ZEPHYR_LIBS_PROPERTY} 1121 app_smem_unaligned_prebuilt 1122 WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/ 1123 COMMAND_EXPAND_LISTS 1124 COMMENT "Generating app_smem_aligned linker section" 1125 ) 1126endif() 1127 1128if(CONFIG_USERSPACE) 1129 # This CONFIG_USERSPACE block is to create place holders to reserve space 1130 # for the gperf generated structures for zephyr_prebuilt.elf. 1131 # These place holders are there so that the placement of kobjects would be 1132 # the same between linking zephyr_prebuilt.elf and zephyr.elf, as 1133 # the gperf hash table is hashed on the addresses of kobjects. 1134 # The placeholders are generated from app_smem_unaligned_prebuilt.elf. 1135 1136 set(KOBJECT_PREBUILT_HASH_LIST kobject_prebuilt_hash.gperf) 1137 set(KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE kobject_prebuilt_hash_preprocessed.c) 1138 set(KOBJECT_PREBUILT_HASH_OUTPUT_SRC kobject_prebuilt_hash.c) 1139 set(KOBJECT_PREBUILT_HASH_OUTPUT_OBJ kobject_prebuilt_hash.c.obj) 1140 1141 add_custom_command( 1142 OUTPUT ${KOBJECT_PREBUILT_HASH_LIST} 1143 COMMAND 1144 ${PYTHON_EXECUTABLE} 1145 ${GEN_KOBJ_LIST} 1146 --kernel $<TARGET_FILE:app_smem_unaligned_prebuilt> 1147 --gperf-output ${KOBJECT_PREBUILT_HASH_LIST} 1148 ${gen_kobject_list_include_args} 1149 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1150 DEPENDS 1151 app_smem_unaligned_prebuilt 1152 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1153 ) 1154 add_custom_target( 1155 kobj_prebuilt_hash_list 1156 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_LIST} 1157 ) 1158 1159 add_custom_command( 1160 OUTPUT ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1161 COMMAND 1162 ${GPERF} 1163 --output-file ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1164 --multiple-iterations 10 1165 ${KOBJECT_PREBUILT_HASH_LIST} 1166 DEPENDS kobj_prebuilt_hash_list ${KOBJECT_PREBUILT_HASH_LIST} 1167 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1168 ) 1169 add_custom_target( 1170 kobj_prebuilt_hash_output_src_pre 1171 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1172 ) 1173 1174 add_custom_command( 1175 OUTPUT ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1176 COMMAND 1177 ${PYTHON_EXECUTABLE} 1178 ${PROCESS_GPERF} 1179 -i ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1180 -o ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1181 -p "struct z_object" 1182 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1183 DEPENDS kobj_prebuilt_hash_output_src_pre ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} 1184 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1185 ) 1186 add_custom_target( 1187 kobj_prebuilt_hash_output_src 1188 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1189 ) 1190 1191 add_library( 1192 kobj_prebuilt_hash_output_lib 1193 STATIC ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1194 ) 1195 1196 set_source_files_properties(${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1197 PROPERTIES COMPILE_FLAGS 1198 "${NO_COVERAGE_FLAGS} -fno-function-sections -fno-data-sections") 1199 1200 set_source_files_properties(${KOBJECT_PREBUILT_HASH_OUTPUT_SRC} 1201 PROPERTIES COMPILE_DEFINITIONS "${compile_definitions_interface}") 1202 1203 add_library(kobj_prebuilt_hash_output_lib_interface INTERFACE) 1204 1205 target_link_libraries( 1206 kobj_prebuilt_hash_output_lib 1207 kobj_prebuilt_hash_output_lib_interface 1208 ) 1209 1210 foreach(incl ${include_dir_in_interface}) 1211 target_include_directories( 1212 kobj_prebuilt_hash_output_lib_interface 1213 INTERFACE ${incl} 1214 ) 1215 endforeach() 1216 1217 foreach(incl ${sys_include_dir_in_interface}) 1218 target_include_directories( 1219 kobj_prebuilt_hash_output_lib_interface 1220 SYSTEM INTERFACE ${incl} 1221 ) 1222 endforeach() 1223 1224 set( 1225 KOBJECT_PREBUILT_HASH_OUTPUT_OBJ_PATH 1226 ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/kobj_prebuilt_hash_output_lib.dir/${KOBJECT_PREBUILT_HASH_OUTPUT_OBJ} 1227 ) 1228 1229 set(KOBJECT_LINKER_HEADER_DATA "${PROJECT_BINARY_DIR}/include/generated/linker-kobject-prebuilt-data.h") 1230 1231 add_custom_command( 1232 OUTPUT ${KOBJECT_LINKER_HEADER_DATA} 1233 COMMAND 1234 ${PYTHON_EXECUTABLE} 1235 ${ZEPHYR_BASE}/scripts/gen_kobject_placeholders.py 1236 --object ${KOBJECT_PREBUILT_HASH_OUTPUT_OBJ_PATH} 1237 --outdir ${PROJECT_BINARY_DIR}/include/generated 1238 --datapct ${CONFIG_KOBJECT_DATA_AREA_RESERVE_EXTRA_PERCENT} 1239 --rodata ${CONFIG_KOBJECT_RODATA_AREA_EXTRA_BYTES} 1240 $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose> 1241 DEPENDS 1242 kobj_prebuilt_hash_output_lib 1243 ${KOBJECT_PREBUILT_HASH_OUTPUT_OBJ_PATH} 1244 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 1245 ) 1246 1247 add_custom_target( 1248 ${KOBJECT_LINKER_DEP} 1249 DEPENDS 1250 ${KOBJECT_LINKER_HEADER_DATA} 1251 ) 1252endif() 1253 1254configure_linker_script( 1255 linker_zephyr_prebuilt.cmd 1256 "-DLINKER_ZEPHYR_PREBUILT" 1257 ${APP_SMEM_ALIGNED_DEP} 1258 ${KOBJECT_LINKER_DEP} 1259 ${CODE_RELOCATION_DEP} 1260 zephyr_generated_headers 1261 ) 1262 1263add_custom_target( 1264 linker_zephyr_prebuilt_script_target 1265 DEPENDS 1266 linker_zephyr_prebuilt.cmd 1267 ) 1268 1269set_property(TARGET 1270 linker_zephyr_prebuilt_script_target 1271 PROPERTY INCLUDE_DIRECTORIES 1272 ${ZEPHYR_INCLUDE_DIRS} 1273 ) 1274 1275# FIXME: Is there any way to get rid of empty_file.c? 1276add_executable( ${ZEPHYR_PREBUILT_EXECUTABLE} misc/empty_file.c) 1277toolchain_ld_link_elf( 1278 TARGET_ELF ${ZEPHYR_PREBUILT_EXECUTABLE} 1279 OUTPUT_MAP ${PROJECT_BINARY_DIR}/${ZEPHYR_PREBUILT_EXECUTABLE}.map 1280 LIBRARIES_PRE_SCRIPT "" 1281 LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker_zephyr_prebuilt.cmd 1282 DEPENDENCIES ${CODE_RELOCATION_DEP} 1283) 1284target_byproducts(TARGET ${ZEPHYR_PREBUILT_EXECUTABLE} 1285 BYPRODUCTS ${PROJECT_BINARY_DIR}/${ZEPHYR_PREBUILT_EXECUTABLE}.map 1286) 1287set_property(TARGET 1288 ${ZEPHYR_PREBUILT_EXECUTABLE} 1289 PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_zephyr_prebuilt.cmd 1290 ) 1291add_dependencies( 1292 ${ZEPHYR_PREBUILT_EXECUTABLE} 1293 linker_zephyr_prebuilt_script_target 1294 ${OFFSETS_LIB} 1295 ) 1296 1297set(generated_kernel_files ${GKSF} ${GKOF}) 1298if(NOT generated_kernel_files) 1299 # Use the prebuilt elf as the final elf since we don't have a 1300 # generation stage. 1301 set(logical_target_for_zephyr_elf ${ZEPHYR_PREBUILT_EXECUTABLE}) 1302else() 1303 # The final linker pass uses the same source linker script of the 1304 # previous passes, but this time with a different output 1305 # file and preprocessed with the define LINKER_ZEPHYR_FINAL. 1306 # 1307 # LINKER_PASS2 is deprecated but being kept to avoid breaking 1308 # external projects. It will be removed in the future. 1309 configure_linker_script( 1310 linker.cmd 1311 "-DLINKER_ZEPHYR_FINAL;-DLINKER_PASS2" 1312 ${CODE_RELOCATION_DEP} 1313 ${ZEPHYR_PREBUILT_EXECUTABLE} 1314 zephyr_generated_headers 1315 ) 1316 1317 add_custom_target( 1318 linker_zephyr_final_script_target 1319 DEPENDS 1320 linker.cmd 1321 ) 1322 set_property(TARGET 1323 linker_zephyr_final_script_target 1324 PROPERTY INCLUDE_DIRECTORIES 1325 ${ZEPHYR_INCLUDE_DIRS} 1326 ) 1327 1328 add_executable( ${ZEPHYR_FINAL_EXECUTABLE} misc/empty_file.c ${GKSF}) 1329 toolchain_ld_link_elf( 1330 TARGET_ELF ${ZEPHYR_FINAL_EXECUTABLE} 1331 OUTPUT_MAP ${PROJECT_BINARY_DIR}/${ZEPHYR_FINAL_EXECUTABLE}.map 1332 LIBRARIES_PRE_SCRIPT ${GKOF} 1333 LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker.cmd 1334 LIBRARIES_POST_SCRIPT "" 1335 DEPENDENCIES ${CODE_RELOCATION_DEP} 1336 ) 1337 set_property(TARGET ${ZEPHYR_FINAL_EXECUTABLE} PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker.cmd) 1338 add_dependencies( ${ZEPHYR_FINAL_EXECUTABLE} linker_zephyr_final_script_target) 1339 1340 # Use the pass2 elf as the final elf 1341 set(logical_target_for_zephyr_elf ${ZEPHYR_FINAL_EXECUTABLE}) 1342endif() 1343 1344# Export the variable to the application's scope to allow the 1345# application to know what the name of the final elf target is. 1346set(logical_target_for_zephyr_elf ${logical_target_for_zephyr_elf} PARENT_SCOPE) 1347 1348# Override the base name of the last, "logical" .elf output (and last .map) so: 1349# 1. it doesn't depend on the number of passes above and the 1350# post_build_commands below can always find it no matter which is it; 1351# 2. it can be defined in Kconfig 1352set_target_properties(${logical_target_for_zephyr_elf} PROPERTIES OUTPUT_NAME ${KERNEL_NAME}) 1353 1354set(post_build_commands "") 1355set(post_build_byproducts "") 1356 1357list(APPEND 1358 post_build_commands 1359 COMMAND 1360 ${CMAKE_COMMAND} -E rename ${logical_target_for_zephyr_elf}.map ${KERNEL_MAP_NAME} 1361) 1362list(APPEND post_build_byproducts ${KERNEL_MAP_NAME}) 1363 1364if(NOT CONFIG_BUILD_NO_GAP_FILL) 1365 # Use ';' as separator to get proper space in resulting command. 1366 set(GAP_FILL "$<TARGET_PROPERTY:bintools,elfconvert_flag_gapfill>0xff") 1367endif() 1368 1369if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) 1370 target_link_libraries(${logical_target_for_zephyr_elf} $<TARGET_PROPERTY:linker,memusage>) 1371 1372 get_property(memusage_build_command TARGET bintools PROPERTY memusage_command) 1373 if(memusage_build_command) 1374 # Note: The use of generator expressions allows downstream extensions to add/change the post build. 1375 # Unfortunately, the BYPRODUCTS does not allow for generator expression, so question is if we 1376 # should remove the downstream ability from start. 1377 # Or fix the output name, by the use of `get_property` 1378 list(APPEND 1379 post_build_commands 1380 COMMAND $<TARGET_PROPERTY:bintools,memusage_command> 1381 $<TARGET_PROPERTY:bintools,memusage_flag> 1382 $<TARGET_PROPERTY:bintools,memusage_infile>${KERNEL_ELF_NAME} 1383 ) 1384 1385 # For now, the byproduct can only be supported upstream on byproducts name, 1386 # cause byproduct does not support generator expressions 1387 get_property(memusage_byproducts TARGET bintools PROPERTY memusage_byproducts) 1388 list(APPEND 1389 post_build_byproducts 1390 ${memusage_byproducts} 1391 ) 1392 endif() 1393endif() 1394 1395if(NOT CONFIG_EXCEPTIONS) 1396 set(eh_frame_section ".eh_frame") 1397else() 1398 set(eh_frame_section "") 1399endif() 1400set(remove_sections_argument_list "") 1401foreach(section .comment COMMON ${eh_frame_section}) 1402 list(APPEND remove_sections_argument_list 1403 $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>${section}) 1404endforeach() 1405 1406if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd) 1407 get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) 1408 if(ihex IN_LIST elfconvert_formats) 1409 list(APPEND 1410 post_build_commands 1411 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1412 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1413 ${GAP_FILL} 1414 $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>ihex 1415 ${remove_sections_argument_list} 1416 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1417 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_HEX_NAME} 1418 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1419 ) 1420 list(APPEND 1421 post_build_byproducts 1422 ${KERNEL_HEX_NAME} 1423 # ${out_hex_byprod} # Is this needed ? 1424 ) 1425 endif() 1426endif() 1427 1428if(CONFIG_BUILD_OUTPUT_BIN) 1429 get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) 1430 if(binary IN_LIST elfconvert_formats) 1431 list(APPEND 1432 post_build_commands 1433 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1434 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1435 ${GAP_FILL} 1436 $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>binary 1437 ${remove_sections_argument_list} 1438 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1439 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_BIN_NAME} 1440 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1441 ) 1442 list(APPEND 1443 post_build_byproducts 1444 ${KERNEL_BIN_NAME} 1445 # ${out_hex_byprod} # Is this needed ? 1446 ) 1447 endif() 1448endif() 1449 1450if(CONFIG_BUILD_OUTPUT_BIN AND CONFIG_BUILD_OUTPUT_UF2) 1451 list(APPEND 1452 post_build_commands 1453 COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/uf2conv.py 1454 -c 1455 -f ${CONFIG_BUILD_OUTPUT_UF2_FAMILY_ID} 1456 -b ${CONFIG_FLASH_LOAD_OFFSET} 1457 -o ${KERNEL_UF2_NAME} 1458 ${KERNEL_BIN_NAME} 1459 ) 1460 list(APPEND 1461 post_build_byproducts 1462 ${KERNEL_UF2_NAME} 1463 ) 1464endif() 1465 1466# Cleanup intermediate files 1467if(CONFIG_CLEANUP_INTERMEDIATE_FILES) 1468 list(APPEND 1469 post_build_commands 1470 COMMAND 1471 # This file can be very large in some cases, delete it as we do not need it. 1472 ${CMAKE_COMMAND} -E remove ${ZEPHYR_PREBUILT_EXECUTABLE}.elf 1473 ) 1474endif() 1475 1476if(CONFIG_BUILD_OUTPUT_S19) 1477 get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) 1478 if(srec IN_LIST elfconvert_formats) 1479 # Should we print a warning if case the tools does not support converting to s19 ? 1480 list(APPEND 1481 post_build_commands 1482 COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command> 1483 $<TARGET_PROPERTY:bintools,elfconvert_flag> 1484 ${GAP_FILL} 1485 $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>srec 1486 $<TARGET_PROPERTY:bintools,elfconvert_flag_srec_len>1 1487 $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME} 1488 $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_S19_NAME} 1489 $<TARGET_PROPERTY:bintools,elfconvert_flag_final> 1490 ) 1491 list(APPEND 1492 post_build_byproducts 1493 ${KERNEL_S19_NAME} 1494 # ${out_S19_byprod} # Is this needed ? 1495 1496 ) 1497 endif() 1498endif() 1499 1500if(CONFIG_OUTPUT_DISASSEMBLY) 1501if(CONFIG_OUTPUT_DISASSEMBLE_ALL) 1502 set(disassembly_type "$<TARGET_PROPERTY:bintools,disassembly_flag_all>") 1503 else() 1504 set(disassembly_type "$<TARGET_PROPERTY:bintools,disassembly_flag_inline_source>") 1505 endif() 1506 list(APPEND 1507 post_build_commands 1508 COMMAND $<TARGET_PROPERTY:bintools,disassembly_command> 1509 $<TARGET_PROPERTY:bintools,disassembly_flag> 1510 ${disassembly_type} 1511 $<TARGET_PROPERTY:bintools,disassembly_flag_infile>${KERNEL_ELF_NAME} 1512 $<TARGET_PROPERTY:bintools,disassembly_flag_outfile>${KERNEL_LST_NAME} 1513 $<TARGET_PROPERTY:bintools,disassembly_flag_final> 1514 ) 1515 list(APPEND 1516 post_build_byproducts 1517 ${KERNEL_LST_NAME} 1518# ${out_disassembly_byprod} # Needed ?? 1519 ) 1520endif() 1521 1522if(CONFIG_OUTPUT_STAT) 1523# zephyr_post_build(TOOLS bintools COMMAND readelf FLAGS headers INFILE file OUTFILE outfile) 1524 list(APPEND 1525 post_build_commands 1526 COMMAND $<TARGET_PROPERTY:bintools,readelf_command> 1527 $<TARGET_PROPERTY:bintools,readelf_flag> 1528 $<TARGET_PROPERTY:bintools,readelf_flag_headers> 1529 $<TARGET_PROPERTY:bintools,readelf_flag_infile>${KERNEL_ELF_NAME} 1530 $<TARGET_PROPERTY:bintools,readelf_flag_outfile>${KERNEL_STAT_NAME} 1531 $<TARGET_PROPERTY:bintools,readelf_flag_final> 1532 ) 1533 list(APPEND 1534 post_build_byproducts 1535 ${KERNEL_STAT_NAME} 1536 ) 1537endif() 1538 1539if(CONFIG_BUILD_OUTPUT_STRIPPED) 1540 list(APPEND 1541 post_build_commands 1542 COMMAND $<TARGET_PROPERTY:bintools,strip_command> 1543 $<TARGET_PROPERTY:bintools,strip_flag> 1544 $<TARGET_PROPERTY:bintools,strip_flag_all> 1545 $<TARGET_PROPERTY:bintools,strip_flag_infile>${KERNEL_ELF_NAME} 1546 $<TARGET_PROPERTY:bintools,strip_flag_outfile>${KERNEL_STRIP_NAME} 1547 $<TARGET_PROPERTY:bintools,strip_flag_final> 1548 ) 1549 list(APPEND 1550 post_build_byproducts 1551 ${KERNEL_STRIP_NAME} 1552 ) 1553endif() 1554 1555if(CONFIG_BUILD_OUTPUT_EXE) 1556 list(APPEND 1557 post_build_commands 1558 COMMAND 1559 ${CMAKE_COMMAND} -E copy ${KERNEL_ELF_NAME} ${KERNEL_EXE_NAME} 1560 ) 1561 list(APPEND 1562 post_build_byproducts 1563 ${KERNEL_EXE_NAME} 1564 ) 1565endif() 1566 1567# Generate and use MCUboot related artifacts as needed. 1568if(CONFIG_BOOTLOADER_MCUBOOT) 1569 include(${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake) 1570endif() 1571 1572get_property(extra_post_build_commands 1573 GLOBAL PROPERTY 1574 extra_post_build_commands 1575 ) 1576 1577list(APPEND 1578 post_build_commands 1579 ${extra_post_build_commands} 1580 ) 1581 1582get_property(extra_post_build_byproducts 1583 GLOBAL PROPERTY 1584 extra_post_build_byproducts 1585 ) 1586 1587list(APPEND 1588 post_build_byproducts 1589 ${extra_post_build_byproducts} 1590 ) 1591 1592if(CONFIG_LOG_DICTIONARY_SUPPORT) 1593 set(LOG_DICT_DB_NAME ${PROJECT_BINARY_DIR}/log_dictionary.json) 1594 1595 list(APPEND 1596 post_build_commands 1597 COMMAND 1598 ${PYTHON_EXECUTABLE} 1599 ${ZEPHYR_BASE}/scripts/logging/dictionary/database_gen.py 1600 ${KERNEL_ELF_NAME} 1601 ${LOG_DICT_DB_NAME} 1602 --build ${BUILD_VERSION} 1603 ) 1604 list(APPEND 1605 post_build_byproducts 1606 ${LOG_DICT_DB_NAME} 1607 ) 1608endif() 1609 1610# Add post_build_commands to post-process the final .elf file produced by 1611# either the ZEPHYR_PREBUILT_EXECUTABLE or the KERNEL_ELF executable 1612# targets above. 1613add_custom_command( 1614 TARGET ${logical_target_for_zephyr_elf} 1615 POST_BUILD 1616 ${post_build_commands} 1617 BYPRODUCTS 1618 ${post_build_byproducts} 1619 COMMENT "Generating files from ${KERNEL_ELF_NAME} for board: ${BOARD}" 1620 COMMAND_EXPAND_LISTS 1621 # NB: COMMENT only works for some CMake-Generators 1622 ) 1623 1624# To populate with hex files to merge, do the following: 1625# set_property(GLOBAL APPEND PROPERTY HEX_FILES_TO_MERGE ${my_local_list}) 1626# Note that the zephyr.hex file will not be included automatically. 1627get_property(HEX_FILES_TO_MERGE GLOBAL PROPERTY HEX_FILES_TO_MERGE) 1628if(HEX_FILES_TO_MERGE) 1629 # Merge in out-of-tree hex files. 1630 set(MERGED_HEX_NAME merged.hex) 1631 1632 add_custom_command( 1633 OUTPUT ${MERGED_HEX_NAME} 1634 COMMAND 1635 ${PYTHON_EXECUTABLE} 1636 ${ZEPHYR_BASE}/scripts/mergehex.py 1637 -o ${MERGED_HEX_NAME} 1638 ${HEX_FILES_TO_MERGE} 1639 DEPENDS ${HEX_FILES_TO_MERGE} ${logical_target_for_zephyr_elf} 1640 ) 1641 1642 add_custom_target(mergehex ALL DEPENDS ${MERGED_HEX_NAME}) 1643 list(APPEND RUNNERS_DEPS mergehex) 1644 1645 message(VERBOSE "Merging hex files: ${HEX_FILES_TO_MERGE}") 1646endif() 1647 1648if(EMU_PLATFORM) 1649 include(${ZEPHYR_BASE}/cmake/emu/${EMU_PLATFORM}.cmake) 1650else() 1651 add_custom_target(run 1652 COMMAND 1653 ${CMAKE_COMMAND} -E echo 1654 "===================================================" 1655 "Emulation/Simulation not supported with this board." 1656 "===================================================" 1657 ) 1658endif() 1659 1660add_subdirectory(cmake/flash) 1661add_subdirectory(cmake/usage) 1662add_subdirectory(cmake/reports) 1663 1664if(NOT CONFIG_TEST) 1665if(CONFIG_ASSERT AND (NOT CONFIG_FORCE_NO_ASSERT)) 1666 message(WARNING "__ASSERT() statements are globally ENABLED") 1667endif() 1668endif() 1669 1670if(CONFIG_BOARD_DEPRECATED_RELEASE) 1671 message(WARNING " 1672 WARNING: The board '${BOARD}' is deprecated and will be 1673 removed in version ${CONFIG_BOARD_DEPRECATED_RELEASE}" 1674 ) 1675endif() 1676 1677if(CONFIG_SOC_DEPRECATED_RELEASE) 1678 message(WARNING " 1679 WARNING: The SoC '${SOC_NAME}' is deprecated and will be 1680 removed in version ${CONFIG_SOC_DEPRECATED_RELEASE}" 1681 ) 1682endif() 1683 1684# In CMake projects, 'CMAKE_BUILD_TYPE' usually determines the 1685# optimization flag, but in Zephyr it is determined through 1686# Kconfig. Here we give a warning when there is a mismatch between the 1687# two in case the user is not aware of this. 1688set(build_types None Debug Release RelWithDebInfo MinSizeRel) 1689 1690if((CMAKE_BUILD_TYPE IN_LIST build_types) AND (NOT NO_BUILD_TYPE_WARNING)) 1691 string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_uppercase) 1692 1693 if(NOT (${OPTIMIZATION_FLAG} IN_LIST CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_uppercase})) 1694 message(WARNING " 1695 The CMake build type was set to '${CMAKE_BUILD_TYPE}', but the optimization flag was set to '${OPTIMIZATION_FLAG}'. 1696 This may be intentional and the warning can be turned off by setting the CMake variable 'NO_BUILD_TYPE_WARNING'" 1697 ) 1698 endif() 1699endif() 1700 1701# @Intent: Set compiler specific flags for standard C/C++ includes 1702# Done at the very end, so any other system includes which may 1703# be added by Zephyr components were first in list. 1704# Note, the compile flags are moved, but the system include is still present here. 1705zephyr_compile_options($<TARGET_PROPERTY:compiler,nostdinc>) 1706target_include_directories(zephyr_interface SYSTEM INTERFACE $<TARGET_PROPERTY:compiler,nostdinc_include>) 1707 1708if(NOT CONFIG_LIB_CPLUSPLUS) 1709 zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,nostdincxx>>) 1710endif() 1711 1712# Finally export all build flags from Zephyr 1713add_subdirectory_ifdef( 1714 CONFIG_MAKEFILE_EXPORTS 1715 cmake/makefile_exports 1716 ) 1717