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