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