zephyr/cmake/kconfig.cmake

262 lines
8.3 KiB
CMake
Raw Permalink Normal View History

# SPDX-License-Identifier: Apache-2.0
# 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)
if(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(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()
if(OVERLAY_CONFIG)
string(REPLACE " " ";" OVERLAY_CONFIG_AS_LIST "${OVERLAY_CONFIG}")
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}")
set(ENV{srctree} ${ZEPHYR_BASE})
set(ENV{KERNELVERSION} ${KERNELVERSION})
set(ENV{KCONFIG_CONFIG} ${DOTCONFIG})
set(ENV{PYTHON_EXECUTABLE} ${PYTHON_EXECUTABLE})
# Set environment variables so that Kconfig can prune Kconfig source
# files for other architectures
set(ENV{ARCH} ${ARCH})
set(ENV{BOARD_DIR} ${BOARD_DIR})
set(ENV{SOC_DIR} ${SOC_DIR})
set(ENV{SHIELD_AS_LIST} "${SHIELD_AS_LIST}")
set(ENV{CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR})
set(ENV{ARCH_DIR} ${ARCH_DIR})
set(ENV{TOOLCHAIN_KCONFIG_DIR} "${TOOLCHAIN_KCONFIG_DIR}")
set(ENV{EDT_PICKLE} ${EDT_PICKLE})
# 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
)
foreach(kconfig_target
menuconfig
guiconfig
hardenconfig
${EXTRA_KCONFIG_TARGETS}
)
add_custom_target(
${kconfig_target}
${CMAKE_COMMAND} -E env
PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
srctree=${ZEPHYR_BASE}
KERNELVERSION=${KERNELVERSION}
ZEPHYR_BASE=${ZEPHYR_BASE}
KCONFIG_CONFIG=${DOTCONFIG}
ARCH=$ENV{ARCH}
BOARD_DIR=$ENV{BOARD_DIR}
SOC_DIR=$ENV{SOC_DIR}
SHIELD_AS_LIST=$ENV{SHIELD_AS_LIST}
CMAKE_BINARY_DIR=$ENV{CMAKE_BINARY_DIR}
ZEPHYR_TOOLCHAIN_VARIANT=${ZEPHYR_TOOLCHAIN_VARIANT}
TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR}
ARCH_DIR=$ENV{ARCH_DIR}
EXTRA_DTC_FLAGS=${EXTRA_DTC_FLAGS}
DTS_POST_CPP=${DTS_POST_CPP}
DTS_ROOT_BINDINGS=${DTS_ROOT_BINDINGS}
EDT_PICKLE=${EDT_PICKLE}
${PYTHON_EXECUTABLE}
${EXTRA_KCONFIG_TARGET_COMMAND_FOR_${kconfig_target}}
${KCONFIG_ROOT}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig
USES_TERMINAL
)
endforeach()
# Support assigning Kconfig symbols on the command-line with CMake
# cache variables prefixed with 'CONFIG_'. This feature is
# experimental and undocumented until it has undergone more
# user-testing.
unset(EXTRA_KCONFIG_OPTIONS)
get_cmake_property(cache_variable_names CACHE_VARIABLES)
foreach (name ${cache_variable_names})
if("${name}" MATCHES "^CONFIG_")
# When a cache variable starts with 'CONFIG_', it is assumed to be
sanitycheck: fix priority of --extra-args=CONFIG_ over testcase.yaml sanitycheck takes any "extra_config" list found in the testcase.yaml file and generates an "overlay" file from it. This file is placed in the per-test build directory and passed to cmake/kconfig.cmake through a -DOVERLAY_CONF= option set in the (also) generated sanity-out/Makefile. This commit moves this generated config overlay to a subdirectory one level down from the build directory, otherwise kconfig.cmake picks it up *twice*: once from the -DOVERLAY_CONF= option already mentioned above and a second time because kconfig.cmake scans the build directory and blindly picks up ALL files ending with .conf[*]. The second pickup is problematic because kconfig.cmake currently gives it the top precedence, even higher than anything the user espressed with --extra-args=CONFIG_* Here's a quick and simple demonstration of the issue fixed by this commit: cd $ZEPHYR_BASE/samples/net/sockets/net_mgmt/ sanitycheck -T. -p qemu_x86 -b -v # --extra-args=CONFIG_USERSPACE=y|n grep CONFIG_USERSPACE $(find sanity-out/ -name .config) .net_mgmt.kernelmode/zephyr/.config: # CONFIG_USERSPACE is not set .net_mgmt.usermode/zephyr/.config: CONFIG_USERSPACE=y grep 'Merged configuration' $(find sanity-out/ -name build.log) Without this commit, attemps to override anything with --extra-args=CONFIG_ are silently dropped on the floor. For more background this issue was found while using the recipe in commit message 4afcc0f8af2b [*] picking up all .conf files is debatable but a much bigger debate with backward compatibility implications. This small fix makes absolutely zero difference to anyone or anything not using sanitycheck. Signed-off-by: Marc Herbert <marc.herbert@intel.com>
2019-07-07 00:52:31 +02:00
# a Kconfig symbol assignment from the CMake command line.
set(EXTRA_KCONFIG_OPTIONS
"${EXTRA_KCONFIG_OPTIONS}\n${name}=${${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_SOURCE_DIR}/${f})
endif()
list(APPEND merge_config_files_with_absolute_paths ${path})
endforeach()
foreach(f ${merge_config_files_with_absolute_paths})
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_with_absolute_paths})
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)
kconfig/cmake: Improve reconfiguration behavior There are some issues with the behavior when rerunning CMake in an already initialized build directory: 1. The check for assignments to promptless symbols in configuration fragments isn't run when reconfiguring, because it only runs if zephyr/.config doesn't exist 2. As outlined in https://github.com/zephyrproject-rtos/zephyr/issues/9573, you can get into situations where zephyr/.config is invalid (e.g. due to being outdated), but menuconfig/guiconfig can't be run to fix it 3. If kconfig.py fails while merging fragments during reconfiguration, it will ignore the fragments during the next reconfiguration and use the existing zephyr/.config instead, because the fragment checksum is calculated and saved before running kconfig.py (Footnote: The input configuration file(s) to kconfig.py can be either a list of configuration fragments, when merging fragments, or just zephyr/.config, if the merged configuration is up-to-date. The output configuration file is always zephyr/.config.) To fix the first two issues, explicitly tell kconfig.py when it's dealing with handwritten configuration input (fragments), via a new --handwritten-input-configs flag. This is more robust than checking whether zephyr/.config exists, which was the old logic. When dealing with handwritten input, there should be no assignments to promptless symbols. Assignments to promptless symbols is expected in zephyr/.config however, because it doubles as configuration output. When running menuconfig/guiconfig, the input configuration is zephyr/.config rather than configuration fragments, so this change also makes sure that menuconfig can always be run as long as zephyr/.config exists and is up-to-date. To fix the last issue, only write the checksum for the configuration fragments if kconfig.py succeeds (which means it wrote a zephyr/.config). Also improve naming a bit, add help texts for the command-line parameters to kconfig.py, and simplify write_kconfig_filenames() by moving logic into it. Partial fix for https://github.com/zephyrproject-rtos/zephyr/issues/9573, without the part in #issuecomment-469701831. Can still run into issues when e.g. when CMake files can't make sense of settings. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2020-01-20 11:25:13 +01:00
set(input_configs_are_handwritten --handwritten-input-configs)
set(input_configs ${merge_config_files})
else()
kconfig/cmake: Improve reconfiguration behavior There are some issues with the behavior when rerunning CMake in an already initialized build directory: 1. The check for assignments to promptless symbols in configuration fragments isn't run when reconfiguring, because it only runs if zephyr/.config doesn't exist 2. As outlined in https://github.com/zephyrproject-rtos/zephyr/issues/9573, you can get into situations where zephyr/.config is invalid (e.g. due to being outdated), but menuconfig/guiconfig can't be run to fix it 3. If kconfig.py fails while merging fragments during reconfiguration, it will ignore the fragments during the next reconfiguration and use the existing zephyr/.config instead, because the fragment checksum is calculated and saved before running kconfig.py (Footnote: The input configuration file(s) to kconfig.py can be either a list of configuration fragments, when merging fragments, or just zephyr/.config, if the merged configuration is up-to-date. The output configuration file is always zephyr/.config.) To fix the first two issues, explicitly tell kconfig.py when it's dealing with handwritten configuration input (fragments), via a new --handwritten-input-configs flag. This is more robust than checking whether zephyr/.config exists, which was the old logic. When dealing with handwritten input, there should be no assignments to promptless symbols. Assignments to promptless symbols is expected in zephyr/.config however, because it doubles as configuration output. When running menuconfig/guiconfig, the input configuration is zephyr/.config rather than configuration fragments, so this change also makes sure that menuconfig can always be run as long as zephyr/.config exists and is up-to-date. To fix the last issue, only write the checksum for the configuration fragments if kconfig.py succeeds (which means it wrote a zephyr/.config). Also improve naming a bit, add help texts for the command-line parameters to kconfig.py, and simplify write_kconfig_filenames() by moving logic into it. Partial fix for https://github.com/zephyrproject-rtos/zephyr/issues/9573, without the part in #issuecomment-469701831. Can still run into issues when e.g. when CMake files can't make sense of settings. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2020-01-20 11:25:13 +01:00
set(input_configs ${DOTCONFIG})
endif()
execute_process(
COMMAND
${PYTHON_EXECUTABLE}
${ZEPHYR_BASE}/scripts/kconfig/kconfig.py
--zephyr-base=${ZEPHYR_BASE}
kconfig/cmake: Improve reconfiguration behavior There are some issues with the behavior when rerunning CMake in an already initialized build directory: 1. The check for assignments to promptless symbols in configuration fragments isn't run when reconfiguring, because it only runs if zephyr/.config doesn't exist 2. As outlined in https://github.com/zephyrproject-rtos/zephyr/issues/9573, you can get into situations where zephyr/.config is invalid (e.g. due to being outdated), but menuconfig/guiconfig can't be run to fix it 3. If kconfig.py fails while merging fragments during reconfiguration, it will ignore the fragments during the next reconfiguration and use the existing zephyr/.config instead, because the fragment checksum is calculated and saved before running kconfig.py (Footnote: The input configuration file(s) to kconfig.py can be either a list of configuration fragments, when merging fragments, or just zephyr/.config, if the merged configuration is up-to-date. The output configuration file is always zephyr/.config.) To fix the first two issues, explicitly tell kconfig.py when it's dealing with handwritten configuration input (fragments), via a new --handwritten-input-configs flag. This is more robust than checking whether zephyr/.config exists, which was the old logic. When dealing with handwritten input, there should be no assignments to promptless symbols. Assignments to promptless symbols is expected in zephyr/.config however, because it doubles as configuration output. When running menuconfig/guiconfig, the input configuration is zephyr/.config rather than configuration fragments, so this change also makes sure that menuconfig can always be run as long as zephyr/.config exists and is up-to-date. To fix the last issue, only write the checksum for the configuration fragments if kconfig.py succeeds (which means it wrote a zephyr/.config). Also improve naming a bit, add help texts for the command-line parameters to kconfig.py, and simplify write_kconfig_filenames() by moving logic into it. Partial fix for https://github.com/zephyrproject-rtos/zephyr/issues/9573, without the part in #issuecomment-469701831. Can still run into issues when e.g. when CMake files can't make sense of settings. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2020-01-20 11:25:13 +01:00
${input_configs_are_handwritten}
${KCONFIG_ROOT}
${DOTCONFIG}
${AUTOCONF_H}
${PARSED_KCONFIG_SOURCES_TXT}
kconfig/cmake: Improve reconfiguration behavior There are some issues with the behavior when rerunning CMake in an already initialized build directory: 1. The check for assignments to promptless symbols in configuration fragments isn't run when reconfiguring, because it only runs if zephyr/.config doesn't exist 2. As outlined in https://github.com/zephyrproject-rtos/zephyr/issues/9573, you can get into situations where zephyr/.config is invalid (e.g. due to being outdated), but menuconfig/guiconfig can't be run to fix it 3. If kconfig.py fails while merging fragments during reconfiguration, it will ignore the fragments during the next reconfiguration and use the existing zephyr/.config instead, because the fragment checksum is calculated and saved before running kconfig.py (Footnote: The input configuration file(s) to kconfig.py can be either a list of configuration fragments, when merging fragments, or just zephyr/.config, if the merged configuration is up-to-date. The output configuration file is always zephyr/.config.) To fix the first two issues, explicitly tell kconfig.py when it's dealing with handwritten configuration input (fragments), via a new --handwritten-input-configs flag. This is more robust than checking whether zephyr/.config exists, which was the old logic. When dealing with handwritten input, there should be no assignments to promptless symbols. Assignments to promptless symbols is expected in zephyr/.config however, because it doubles as configuration output. When running menuconfig/guiconfig, the input configuration is zephyr/.config rather than configuration fragments, so this change also makes sure that menuconfig can always be run as long as zephyr/.config exists and is up-to-date. To fix the last issue, only write the checksum for the configuration fragments if kconfig.py succeeds (which means it wrote a zephyr/.config). Also improve naming a bit, add help texts for the command-line parameters to kconfig.py, and simplify write_kconfig_filenames() by moving logic into it. Partial fix for https://github.com/zephyrproject-rtos/zephyr/issues/9573, without the part in #issuecomment-469701831. Can still run into issues when e.g. when CMake files can't make sense of settings. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2020-01-20 11:25:13 +01:00
${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()
kconfig/cmake: Improve reconfiguration behavior There are some issues with the behavior when rerunning CMake in an already initialized build directory: 1. The check for assignments to promptless symbols in configuration fragments isn't run when reconfiguring, because it only runs if zephyr/.config doesn't exist 2. As outlined in https://github.com/zephyrproject-rtos/zephyr/issues/9573, you can get into situations where zephyr/.config is invalid (e.g. due to being outdated), but menuconfig/guiconfig can't be run to fix it 3. If kconfig.py fails while merging fragments during reconfiguration, it will ignore the fragments during the next reconfiguration and use the existing zephyr/.config instead, because the fragment checksum is calculated and saved before running kconfig.py (Footnote: The input configuration file(s) to kconfig.py can be either a list of configuration fragments, when merging fragments, or just zephyr/.config, if the merged configuration is up-to-date. The output configuration file is always zephyr/.config.) To fix the first two issues, explicitly tell kconfig.py when it's dealing with handwritten configuration input (fragments), via a new --handwritten-input-configs flag. This is more robust than checking whether zephyr/.config exists, which was the old logic. When dealing with handwritten input, there should be no assignments to promptless symbols. Assignments to promptless symbols is expected in zephyr/.config however, because it doubles as configuration output. When running menuconfig/guiconfig, the input configuration is zephyr/.config rather than configuration fragments, so this change also makes sure that menuconfig can always be run as long as zephyr/.config exists and is up-to-date. To fix the last issue, only write the checksum for the configuration fragments if kconfig.py succeeds (which means it wrote a zephyr/.config). Also improve naming a bit, add help texts for the command-line parameters to kconfig.py, and simplify write_kconfig_filenames() by moving logic into it. Partial fix for https://github.com/zephyrproject-rtos/zephyr/issues/9573, without the part in #issuecomment-469701831. Can still run into issues when e.g. when CMake files can't make sense of settings. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2020-01-20 11:25:13 +01:00
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-sanitycheck 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 ${cache_variable_names})
if("${name}" MATCHES "^CONFIG_")
unset(${name})
unset(${name} CACHE)
endif()
endforeach()
# Parse the lines prefixed with CONFIG_ in the .config file from Kconfig
import_kconfig(CONFIG_ ${DOTCONFIG})
# Re-introduce the CLI Kconfig symbols that survived
foreach (name ${cache_variable_names})
if("${name}" MATCHES "^CONFIG_")
if(DEFINED ${name})
set(${name} ${${name}} CACHE STRING "")
endif()
endif()
endforeach()