| # SPDX-License-Identifier: Apache-2.0 | 
 |  | 
 | include_guard(GLOBAL) | 
 |  | 
 | include(extensions) | 
 | include(python) | 
 |  | 
 | # autoconf.h is generated by Kconfig and placed in <build>/zephyr/include/generated/autoconf.h. | 
 | # A project may request a custom location by setting AUTOCONF_H explicitly before | 
 | # calling 'find_package(Zephyr)' or loading this module. | 
 | set_ifndef(AUTOCONF_H ${PROJECT_BINARY_DIR}/include/generated/autoconf.h) | 
 | # Re-configure (Re-execute all CMakeLists.txt code) when autoconf.h changes | 
 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${AUTOCONF_H}) | 
 |  | 
 | # Folders needed for conf/mconf files (kconfig has no method of redirecting all output files). | 
 | # conf/mconf needs to be run from a different directory because of: GH-3408 | 
 | file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/generated) | 
 | file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/config) | 
 |  | 
 | set_ifndef(KCONFIG_NAMESPACE "CONFIG") | 
 |  | 
 | set_ifndef(KCONFIG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/Kconfig) | 
 | file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}) | 
 |  | 
 | # Support multiple SOC_ROOT, remove ZEPHYR_BASE as that is always sourced. | 
 | set(kconfig_soc_root ${SOC_ROOT}) | 
 | list(REMOVE_ITEM kconfig_soc_root ${ZEPHYR_BASE}) | 
 | set(OPERATION WRITE) | 
 | foreach(root ${kconfig_soc_root}) | 
 |   file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc.defconfig | 
 |        "osource \"${root}/soc/$(ARCH)/*/Kconfig.defconfig\"\n" | 
 |   ) | 
 |   file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc | 
 |        "osource \"${root}/soc/$(ARCH)/*/Kconfig.soc\"\n" | 
 |   ) | 
 |   file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc.arch | 
 |        "osource \"${root}/soc/$(ARCH)/Kconfig\"\n" | 
 |        "osource \"${root}/soc/$(ARCH)/*/Kconfig\"\n" | 
 |   ) | 
 |   set(OPERATION APPEND) | 
 | endforeach() | 
 |  | 
 | # Support multiple shields in BOARD_ROOT, remove ZEPHYR_BASE as that is always sourced. | 
 | set(kconfig_board_root ${BOARD_ROOT}) | 
 | list(REMOVE_ITEM kconfig_board_root ${ZEPHYR_BASE}) | 
 | set(OPERATION WRITE) | 
 | foreach(root ${kconfig_board_root}) | 
 |   file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.shield.defconfig | 
 |        "osource \"${root}/boards/shields/*/Kconfig.defconfig\"\n" | 
 |   ) | 
 |   file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.shield | 
 |        "osource \"${root}/boards/shields/*/Kconfig.shield\"\n" | 
 |   ) | 
 |   set(OPERATION APPEND) | 
 | endforeach() | 
 |  | 
 | if(KCONFIG_ROOT) | 
 |   zephyr_file(APPLICATION_ROOT KCONFIG_ROOT) | 
 |   # KCONFIG_ROOT has either been specified as a CMake variable or is | 
 |   # already in the CMakeCache.txt. This has precedence. | 
 | elseif(EXISTS   ${APPLICATION_SOURCE_DIR}/Kconfig) | 
 |   set(KCONFIG_ROOT ${APPLICATION_SOURCE_DIR}/Kconfig) | 
 | else() | 
 |   set(KCONFIG_ROOT ${ZEPHYR_BASE}/Kconfig) | 
 | endif() | 
 |  | 
 | set_ifndef(BOARD_DEFCONFIG ${BOARD_DIR}/${BOARD}_defconfig) | 
 | set(DOTCONFIG                  ${PROJECT_BINARY_DIR}/.config) | 
 | set(PARSED_KCONFIG_SOURCES_TXT ${PROJECT_BINARY_DIR}/kconfig/sources.txt) | 
 |  | 
 | if(CONF_FILE) | 
 | string(REPLACE " " ";" CONF_FILE_AS_LIST "${CONF_FILE}") | 
 | endif() | 
 |  | 
 | zephyr_get(OVERLAY_CONFIG SYSBUILD LOCAL) | 
 | if(OVERLAY_CONFIG) | 
 |   string(REPLACE " " ";" OVERLAY_CONFIG_AS_LIST "${OVERLAY_CONFIG}") | 
 | endif() | 
 |  | 
 | if((DEFINED BOARD_REVISION) AND EXISTS ${BOARD_DIR}/${BOARD}_${BOARD_REVISION_STRING}.conf) | 
 |   list(INSERT CONF_FILE_AS_LIST 0 ${BOARD_DIR}/${BOARD}_${BOARD_REVISION_STRING}.conf) | 
 | endif() | 
 |  | 
 | # DTS_ROOT_BINDINGS is a semicolon separated list, this causes | 
 | # problems when invoking kconfig_target since semicolon is a special | 
 | # character in the C shell, so we make it into a question-mark | 
 | # separated list instead. | 
 | string(REPLACE ";" "?" DTS_ROOT_BINDINGS "${DTS_ROOT_BINDINGS}") | 
 |  | 
 | # Export each `ZEPHYR_<module>_MODULE_DIR` to Kconfig. | 
 | # This allows Kconfig files to refer relative from a modules root as: | 
 | # source "$(ZEPHYR_FOO_MODULE_DIR)/Kconfig" | 
 | foreach(module_name ${ZEPHYR_MODULE_NAMES}) | 
 |   zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name}) | 
 |   list(APPEND | 
 |        ZEPHYR_KCONFIG_MODULES_DIR | 
 |        "ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR=${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}" | 
 |   ) | 
 |  | 
 |   if(ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG) | 
 |     list(APPEND | 
 |          ZEPHYR_KCONFIG_MODULES_DIR | 
 |          "ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG=${ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG}" | 
 |   ) | 
 |   endif() | 
 | endforeach() | 
 |  | 
 | # A list of common environment settings used when invoking Kconfig during CMake | 
 | # configure time or menuconfig and related build target. | 
 | string(REPLACE ";" "\\\;" SHIELD_AS_LIST_ESCAPED "${SHIELD_AS_LIST}") | 
 | # cmake commands are escaped differently | 
 | string(REPLACE ";" "\\;" SHIELD_AS_LIST_ESCAPED_COMMAND "${SHIELD_AS_LIST}") | 
 |  | 
 | set(COMMON_KCONFIG_ENV_SETTINGS | 
 |   PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} | 
 |   srctree=${ZEPHYR_BASE} | 
 |   KERNELVERSION=${KERNELVERSION} | 
 |   CONFIG_=${KCONFIG_NAMESPACE}_ | 
 |   KCONFIG_CONFIG=${DOTCONFIG} | 
 |   # Set environment variables so that Kconfig can prune Kconfig source | 
 |   # files for other architectures | 
 |   ARCH=${ARCH} | 
 |   ARCH_DIR=${ARCH_DIR} | 
 |   BOARD_DIR=${BOARD_DIR} | 
 |   BOARD_REVISION=${BOARD_REVISION} | 
 |   KCONFIG_BINARY_DIR=${KCONFIG_BINARY_DIR} | 
 |   ZEPHYR_TOOLCHAIN_VARIANT=${ZEPHYR_TOOLCHAIN_VARIANT} | 
 |   TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} | 
 |   TOOLCHAIN_HAS_NEWLIB=$<IF:$<BOOL:${TOOLCHAIN_HAS_NEWLIB}>,y,n> | 
 |   EDT_PICKLE=${EDT_PICKLE} | 
 |   # Export all Zephyr modules to Kconfig | 
 |   ${ZEPHYR_KCONFIG_MODULES_DIR} | 
 | ) | 
 |  | 
 | # Allow out-of-tree users to add their own Kconfig python frontend | 
 | # targets by appending targets to the CMake list | 
 | # 'EXTRA_KCONFIG_TARGETS' and setting variables named | 
 | # 'EXTRA_KCONFIG_TARGET_COMMAND_FOR_<target>' | 
 | # | 
 | # e.g. | 
 | # cmake -DEXTRA_KCONFIG_TARGETS=cli | 
 | # -DEXTRA_KCONFIG_TARGET_COMMAND_FOR_cli=cli_kconfig_frontend.py | 
 |  | 
 | set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_menuconfig | 
 |   ${ZEPHYR_BASE}/scripts/kconfig/menuconfig.py | 
 |   ) | 
 |  | 
 | set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_guiconfig | 
 |   ${ZEPHYR_BASE}/scripts/kconfig/guiconfig.py | 
 |   ) | 
 |  | 
 | set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_hardenconfig | 
 |   ${ZEPHYR_BASE}/scripts/kconfig/hardenconfig.py | 
 |   ) | 
 |  | 
 | set_ifndef(KCONFIG_TARGETS menuconfig guiconfig hardenconfig) | 
 |  | 
 | foreach(kconfig_target | 
 |     ${KCONFIG_TARGETS} | 
 |     ${EXTRA_KCONFIG_TARGETS} | 
 |     ) | 
 |   add_custom_target( | 
 |     ${kconfig_target} | 
 |     ${CMAKE_COMMAND} -E env | 
 |     ZEPHYR_BASE=${ZEPHYR_BASE} | 
 |     ${COMMON_KCONFIG_ENV_SETTINGS} | 
 |     "SHIELD_AS_LIST=${SHIELD_AS_LIST_ESCAPED}" | 
 |     DTS_POST_CPP=${DTS_POST_CPP} | 
 |     DTS_ROOT_BINDINGS=${DTS_ROOT_BINDINGS} | 
 |     ${PYTHON_EXECUTABLE} | 
 |     ${EXTRA_KCONFIG_TARGET_COMMAND_FOR_${kconfig_target}} | 
 |     ${KCONFIG_ROOT} | 
 |     WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig | 
 |     USES_TERMINAL | 
 |     COMMAND_EXPAND_LISTS | 
 |     ) | 
 | endforeach() | 
 |  | 
 | # Support assigning Kconfig symbols on the command-line with CMake | 
 | # cache variables prefixed according to the Kconfig namespace. | 
 | # This feature is experimental and undocumented until it has undergone more | 
 | # user-testing. | 
 | unset(EXTRA_KCONFIG_OPTIONS) | 
 | if(SYSBUILD) | 
 |   get_property(sysbuild_variable_names TARGET sysbuild_cache PROPERTY "SYSBUILD_CACHE:VARIABLES") | 
 |   zephyr_get(SYSBUILD_MAIN_APP) | 
 |   zephyr_get(SYSBUILD_NAME) | 
 |  | 
 |   foreach (name ${sysbuild_variable_names}) | 
 |     if("${name}" MATCHES "^${SYSBUILD_NAME}_${KCONFIG_NAMESPACE}_") | 
 |       string(REGEX REPLACE "^${SYSBUILD_NAME}_" "" org_name ${name}) | 
 |       get_property(${org_name} TARGET sysbuild_cache PROPERTY ${name}) | 
 |       list(APPEND cache_variable_names ${org_name}) | 
 |     elseif(SYSBUILD_MAIN_APP AND "${name}" MATCHES "^${KCONFIG_NAMESPACE}_") | 
 |       get_property(${name} TARGET sysbuild_cache PROPERTY ${name}) | 
 |       list(APPEND cache_variable_names ${name}) | 
 |     endif() | 
 |   endforeach() | 
 | else() | 
 |   get_cmake_property(cache_variable_names CACHE_VARIABLES) | 
 | endif() | 
 |  | 
 | foreach (name ${cache_variable_names}) | 
 |   if("${name}" MATCHES "^CLI_${KCONFIG_NAMESPACE}_") | 
 |     # Variable was set by user in earlier invocation, let's append to extra | 
 |     # config unless a new value has been given. | 
 |     string(REGEX REPLACE "^CLI_" "" org_name ${name}) | 
 |     if(NOT DEFINED ${org_name}) | 
 |       set(EXTRA_KCONFIG_OPTIONS | 
 |         "${EXTRA_KCONFIG_OPTIONS}\n${org_name}=${${name}}" | 
 |       ) | 
 |     endif() | 
 |   elseif("${name}" MATCHES "^${KCONFIG_NAMESPACE}_") | 
 |     # When a cache variable starts with the 'KCONFIG_NAMESPACE' value, it is | 
 |     # assumed to be a Kconfig symbol assignment from the CMake command line. | 
 |     set(EXTRA_KCONFIG_OPTIONS | 
 |       "${EXTRA_KCONFIG_OPTIONS}\n${name}=${${name}}" | 
 |       ) | 
 |     set(CLI_${name} "${${name}}") | 
 |     list(APPEND cli_config_list ${name}) | 
 |   endif() | 
 | endforeach() | 
 |  | 
 | if(EXTRA_KCONFIG_OPTIONS) | 
 |   set(EXTRA_KCONFIG_OPTIONS_FILE ${PROJECT_BINARY_DIR}/misc/generated/extra_kconfig_options.conf) | 
 |   file(WRITE | 
 |     ${EXTRA_KCONFIG_OPTIONS_FILE} | 
 |     ${EXTRA_KCONFIG_OPTIONS} | 
 |     ) | 
 | endif() | 
 |  | 
 | # Bring in extra configuration files dropped in by the user or anyone else; | 
 | # make sure they are set at the end so we can override any other setting | 
 | file(GLOB config_files ${APPLICATION_BINARY_DIR}/*.conf) | 
 | list(SORT config_files) | 
 | set( | 
 |   merge_config_files | 
 |   ${BOARD_DEFCONFIG} | 
 |   ${CONF_FILE_AS_LIST} | 
 |   ${shield_conf_files} | 
 |   ${OVERLAY_CONFIG_AS_LIST} | 
 |   ${EXTRA_KCONFIG_OPTIONS_FILE} | 
 |   ${config_files} | 
 | ) | 
 |  | 
 | # Create a list of absolute paths to the .config sources from | 
 | # merge_config_files, which is a mix of absolute and relative paths. | 
 | set(merge_config_files_with_absolute_paths "") | 
 | foreach(f ${merge_config_files}) | 
 |   if(IS_ABSOLUTE ${f}) | 
 |     set(path ${f}) | 
 |   else() | 
 |     set(path ${APPLICATION_CONFIG_DIR}/${f}) | 
 |   endif() | 
 |  | 
 |   list(APPEND merge_config_files_with_absolute_paths ${path}) | 
 | endforeach() | 
 | set(merge_config_files ${merge_config_files_with_absolute_paths}) | 
 |  | 
 | foreach(f ${merge_config_files}) | 
 |   if(NOT EXISTS ${f} OR IS_DIRECTORY ${f}) | 
 |     message(FATAL_ERROR "File not found: ${f}") | 
 |   endif() | 
 | endforeach() | 
 |  | 
 | # Calculate a checksum of merge_config_files to determine if we need | 
 | # to re-generate .config | 
 | set(merge_config_files_checksum "") | 
 | foreach(f ${merge_config_files}) | 
 |   file(MD5 ${f} checksum) | 
 |   set(merge_config_files_checksum "${merge_config_files_checksum}${checksum}") | 
 | endforeach() | 
 |  | 
 | # Create a new .config if it does not exists, or if the checksum of | 
 | # the dependencies has changed | 
 | set(merge_config_files_checksum_file ${PROJECT_BINARY_DIR}/.cmake.dotconfig.checksum) | 
 | set(CREATE_NEW_DOTCONFIG 1) | 
 | # Check if the checksum file exists too before trying to open it, though it | 
 | # should under normal circumstances | 
 | if(EXISTS ${DOTCONFIG} AND EXISTS ${merge_config_files_checksum_file}) | 
 |   # Read out what the checksum was previously | 
 |   file(READ | 
 |     ${merge_config_files_checksum_file} | 
 |     merge_config_files_checksum_prev | 
 |     ) | 
 |   if( | 
 |       ${merge_config_files_checksum} STREQUAL | 
 |       ${merge_config_files_checksum_prev} | 
 |       ) | 
 |     # Checksum is the same as before | 
 |     set(CREATE_NEW_DOTCONFIG 0) | 
 |   endif() | 
 | endif() | 
 |  | 
 | if(CREATE_NEW_DOTCONFIG) | 
 |   set(input_configs_are_handwritten --handwritten-input-configs) | 
 |   set(input_configs ${merge_config_files}) | 
 | else() | 
 |   set(input_configs ${DOTCONFIG}) | 
 | endif() | 
 |  | 
 | cmake_path(GET AUTOCONF_H PARENT_PATH autoconf_h_path) | 
 | if(NOT EXISTS ${autoconf_h_path}) | 
 |   file(MAKE_DIRECTORY ${autoconf_h_path}) | 
 | endif() | 
 |  | 
 | execute_process( | 
 |   COMMAND ${CMAKE_COMMAND} -E env | 
 |   ${COMMON_KCONFIG_ENV_SETTINGS} | 
 |   SHIELD_AS_LIST=${SHIELD_AS_LIST_ESCAPED_COMMAND} | 
 |   ${PYTHON_EXECUTABLE} | 
 |   ${ZEPHYR_BASE}/scripts/kconfig/kconfig.py | 
 |   --zephyr-base=${ZEPHYR_BASE} | 
 |   ${input_configs_are_handwritten} | 
 |   ${KCONFIG_ROOT} | 
 |   ${DOTCONFIG} | 
 |   ${AUTOCONF_H} | 
 |   ${PARSED_KCONFIG_SOURCES_TXT} | 
 |   ${input_configs} | 
 |   WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} | 
 |   # The working directory is set to the app dir such that the user | 
 |   # can use relative paths in CONF_FILE, e.g. CONF_FILE=nrf5.conf | 
 |   RESULT_VARIABLE ret | 
 |   ) | 
 | if(NOT "${ret}" STREQUAL "0") | 
 |   message(FATAL_ERROR "command failed with return code: ${ret}") | 
 | endif() | 
 |  | 
 | if(CREATE_NEW_DOTCONFIG) | 
 |   # Write the new configuration fragment checksum. Only do this if kconfig.py | 
 |   # succeeds, to avoid marking zephyr/.config as up-to-date when it hasn't been | 
 |   # regenerated. | 
 |   file(WRITE ${merge_config_files_checksum_file} | 
 |              ${merge_config_files_checksum}) | 
 | endif() | 
 |  | 
 | # Read out the list of 'Kconfig' sources that were used by the engine. | 
 | file(STRINGS ${PARSED_KCONFIG_SOURCES_TXT} PARSED_KCONFIG_SOURCES_LIST) | 
 |  | 
 | # Force CMAKE configure when the Kconfig sources or configuration files changes. | 
 | foreach(kconfig_input | 
 |     ${merge_config_files} | 
 |     ${DOTCONFIG} | 
 |     ${PARSED_KCONFIG_SOURCES_LIST} | 
 |     ) | 
 |   set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig_input}) | 
 | endforeach() | 
 |  | 
 | add_custom_target(config-twister DEPENDS ${DOTCONFIG}) | 
 |  | 
 | # Remove the CLI Kconfig symbols from the namespace and | 
 | # CMakeCache.txt. If the symbols end up in DOTCONFIG they will be | 
 | # re-introduced to the namespace through 'import_kconfig'. | 
 | foreach (name ${cli_config_list}) | 
 |   unset(${name}) | 
 |   unset(${name} CACHE) | 
 | endforeach() | 
 |  | 
 | # Import the .config file and make all settings available in CMake processing. | 
 | import_kconfig(${KCONFIG_NAMESPACE} ${DOTCONFIG}) | 
 |  | 
 | # Cache the CLI Kconfig symbols that survived through Kconfig, prefixed with CLI_. | 
 | # Remove those who might have changed compared to earlier runs, if they no longer appears. | 
 | foreach (name ${cli_config_list}) | 
 |   if(DEFINED ${name}) | 
 |     set(CLI_${name} ${CLI_${name}} CACHE INTERNAL "") | 
 |   else() | 
 |     unset(CLI_${name} CACHE) | 
 |   endif() | 
 | endforeach() |