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