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