yang.li | d6fe624 | 2022-01-13 14:44:24 +0800 | [diff] [blame] | 1 | # Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved. |
| 2 | |
| 3 | # SPDX-License-Identifier: MIT |
| 4 | |
bin.chen | 1a426d3 | 2021-10-13 10:52:36 +0800 | [diff] [blame] | 5 | # SPDX-License-Identifier: Apache-2.0 |
| 6 | |
| 7 | # Folders needed for conf/mconf files (kconfig has no method of redirecting all output files). |
| 8 | # conf/mconf needs to be run from a different directory because of: GH-3408 |
| 9 | file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/generated) |
| 10 | file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/config) |
| 11 | |
| 12 | if(KCONFIG_ROOT) |
| 13 | # KCONFIG_ROOT has either been specified as a CMake variable or is |
| 14 | # already in the CMakeCache.txt. This has precedence. |
| 15 | elseif(EXISTS ${APPLICATION_SOURCE_DIR}/Kconfig) |
| 16 | set(KCONFIG_ROOT ${APPLICATION_SOURCE_DIR}/Kconfig) |
| 17 | else() |
| 18 | set(KCONFIG_ROOT ${SDK_BASE}/Kconfig) |
| 19 | endif() |
| 20 | |
xiaohu.huang | 9f57610 | 2024-10-30 15:00:08 +0800 | [diff] [blame] | 21 | if(NOT DEFINED ENV{BOARD_SPEC_CONFIG} AND NOT DEFINED DEFCONFIG_NAME) |
xiaohu.huang | 330893f | 2024-10-18 11:28:10 +0800 | [diff] [blame] | 22 | message(STATUS "Use default config file:defconfig.") |
| 23 | set(BOARD_DEFCONFIG ${BOARD_DIR}/defconfig) |
| 24 | else() |
xiaohu.huang | 9f57610 | 2024-10-30 15:00:08 +0800 | [diff] [blame] | 25 | if (NOT "$ENV{BOARD_SPEC_CONFIG}" STREQUAL "") |
| 26 | set(DEFCONFIG_NAME $ENV{BOARD_SPEC_CONFIG} CACHE STRING "save defconfig file name" FORCE) |
| 27 | else() |
| 28 | set(ENV{BOARD_SPEC_CONFIG} ${DEFCONFIG_NAME}) |
| 29 | endif() |
xiaohu.huang | 330893f | 2024-10-18 11:28:10 +0800 | [diff] [blame] | 30 | set(BOARD_DEFCONFIG ${BOARD_DIR}/$ENV{BOARD_SPEC_CONFIG}) |
xiaohu.huang | 9f57610 | 2024-10-30 15:00:08 +0800 | [diff] [blame] | 31 | message(STATUS "Use config file $ENV{BOARD_SPEC_CONFIG}.") |
xiaohu.huang | 330893f | 2024-10-18 11:28:10 +0800 | [diff] [blame] | 32 | endif() |
| 33 | |
bin.chen | 1a426d3 | 2021-10-13 10:52:36 +0800 | [diff] [blame] | 34 | set(DOTCONFIG ${PROJECT_BINARY_DIR}/.config) |
| 35 | set(PARSED_KCONFIG_SOURCES_TXT ${PROJECT_BINARY_DIR}/kconfig/sources.txt) |
| 36 | set(AUTOCONF_H ${PROJECT_BINARY_DIR}/autoconf.h) |
| 37 | set(GENERATED_DTS_BOARD_CONF .config) |
| 38 | set(SCRIPTS ${SDK_BASE}/scripts) |
| 39 | |
| 40 | if(CONF_FILE) |
| 41 | string(REPLACE " " ";" CONF_FILE_AS_LIST "${CONF_FILE}") |
| 42 | endif() |
| 43 | |
| 44 | if(OVERLAY_CONFIG) |
| 45 | string(REPLACE " " ";" OVERLAY_CONFIG_AS_LIST "${OVERLAY_CONFIG}") |
| 46 | endif() |
| 47 | |
| 48 | set(ENV{srctree} ${SDK_BASE}) |
| 49 | set(ENV{KERNELVERSION} ${KERNELVERSION}) |
| 50 | set(ENV{KCONFIG_CONFIG} ${DOTCONFIG}) |
| 51 | set(ENV{PYTHON_EXECUTABLE} ${PYTHON_EXECUTABLE}) |
| 52 | |
| 53 | # Set environment variables so that Kconfig can prune Kconfig source |
| 54 | # files for other architectures |
| 55 | set(ENV{ARCH} ${ARCH}) |
| 56 | set(ENV{BOARD_DIR} ${BOARD_DIR}) |
| 57 | set(ENV{SOC_DIR} ${SOC_DIR}) |
| 58 | set(ENV{CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}) |
| 59 | set(ENV{ARCH_DIR} ${ARCH_DIR}) |
| 60 | set(ENV{GENERATED_DTS_BOARD_CONF} ${GENERATED_DTS_BOARD_CONF}) |
| 61 | |
| 62 | # Allow out-of-tree users to add their own Kconfig python frontend |
| 63 | # targets by appending targets to the CMake list |
| 64 | # 'EXTRA_KCONFIG_TARGETS' and setting variables named |
| 65 | # 'EXTRA_KCONFIG_TARGET_COMMAND_FOR_<target>' |
| 66 | # |
| 67 | # e.g. |
| 68 | # cmake -DEXTRA_KCONFIG_TARGETS=cli |
| 69 | # -DEXTRA_KCONFIG_TARGET_COMMAND_FOR_cli=cli_kconfig_frontend.py |
| 70 | |
| 71 | set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_menuconfig |
| 72 | ${SCRIPTS}/kconfig/menuconfig.py |
| 73 | ) |
| 74 | |
| 75 | foreach(kconfig_target |
| 76 | menuconfig |
| 77 | guiconfig |
| 78 | hardenconfig |
| 79 | ${EXTRA_KCONFIG_TARGETS} |
| 80 | ) |
| 81 | add_custom_target( |
| 82 | ${kconfig_target} |
| 83 | ${CMAKE_COMMAND} -E env |
| 84 | PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} |
| 85 | srctree=${SDK_BASE} |
| 86 | KERNELVERSION=${KERNELVERSION} |
| 87 | KCONFIG_CONFIG=${DOTCONFIG} |
| 88 | ARCH=$ENV{ARCH} |
| 89 | BOARD_DIR=$ENV{BOARD_DIR} |
| 90 | SOC_DIR=$ENV{SOC_DIR} |
| 91 | SDK_BASE=$ENV{SDK_BASE} |
| 92 | CMAKE_BINARY_DIR=$ENV{CMAKE_BINARY_DIR} |
| 93 | ARCH_DIR=$ENV{ARCH_DIR} |
| 94 | GENERATED_DTS_BOARD_CONF=${GENERATED_DTS_BOARD_CONF} |
| 95 | ${PYTHON_EXECUTABLE} |
| 96 | ${EXTRA_KCONFIG_TARGET_COMMAND_FOR_${kconfig_target}} |
| 97 | ${KCONFIG_ROOT} |
| 98 | WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig |
| 99 | USES_TERMINAL |
| 100 | ) |
| 101 | endforeach() |
| 102 | |
| 103 | # Support assigning Kconfig symbols on the command-line with CMake |
| 104 | # cache variables prefixed with 'CONFIG_'. This feature is |
| 105 | # experimental and undocumented until it has undergone more |
| 106 | # user-testing. |
| 107 | unset(EXTRA_KCONFIG_OPTIONS) |
| 108 | get_cmake_property(cache_variable_names CACHE_VARIABLES) |
| 109 | foreach (name ${cache_variable_names}) |
| 110 | if("${name}" MATCHES "^CONFIG_") |
| 111 | # When a cache variable starts with 'CONFIG_', it is assumed to be |
| 112 | # a CLI Kconfig symbol assignment. |
| 113 | set(EXTRA_KCONFIG_OPTIONS |
| 114 | "${EXTRA_KCONFIG_OPTIONS}\n${name}=${${name}}" |
| 115 | ) |
| 116 | endif() |
| 117 | endforeach() |
| 118 | |
| 119 | if(EXTRA_KCONFIG_OPTIONS) |
| 120 | set(EXTRA_KCONFIG_OPTIONS_FILE ${PROJECT_BINARY_DIR}/misc/generated/extra_kconfig_options.conf) |
| 121 | file(WRITE |
| 122 | ${EXTRA_KCONFIG_OPTIONS_FILE} |
| 123 | ${EXTRA_KCONFIG_OPTIONS} |
| 124 | ) |
| 125 | endif() |
| 126 | |
| 127 | # Bring in extra configuration files dropped in by the user or anyone else; |
| 128 | # make sure they are set at the end so we can override any other setting |
| 129 | file(GLOB config_files ${APPLICATION_BINARY_DIR}/*.conf) |
| 130 | list(SORT config_files) |
| 131 | set( |
| 132 | merge_config_files |
| 133 | ${BOARD_DEFCONFIG} |
| 134 | ${CONF_FILE_AS_LIST} |
| 135 | ${OVERLAY_CONFIG_AS_LIST} |
| 136 | ${EXTRA_KCONFIG_OPTIONS_FILE} |
| 137 | ${config_files} |
| 138 | ) |
| 139 | |
| 140 | # Create a list of absolute paths to the .config sources from |
| 141 | # merge_config_files, which is a mix of absolute and relative paths. |
| 142 | set(merge_config_files_with_absolute_paths "") |
| 143 | foreach(f ${merge_config_files}) |
| 144 | if(IS_ABSOLUTE ${f}) |
| 145 | set(path ${f}) |
| 146 | else() |
| 147 | set(path ${APPLICATION_SOURCE_DIR}/${f}) |
| 148 | endif() |
| 149 | |
| 150 | list(APPEND merge_config_files_with_absolute_paths ${path}) |
| 151 | endforeach() |
| 152 | |
| 153 | foreach(f ${merge_config_files_with_absolute_paths}) |
| 154 | if(NOT EXISTS ${f} OR IS_DIRECTORY ${f}) |
| 155 | message(FATAL_ERROR "File not found: ${f}") |
| 156 | endif() |
| 157 | endforeach() |
| 158 | |
| 159 | # Calculate a checksum of merge_config_files to determine if we need |
| 160 | # to re-generate .config |
| 161 | set(merge_config_files_checksum "") |
| 162 | foreach(f ${merge_config_files_with_absolute_paths}) |
| 163 | file(MD5 ${f} checksum) |
| 164 | set(merge_config_files_checksum "${merge_config_files_checksum}${checksum}") |
| 165 | endforeach() |
| 166 | |
| 167 | # Create a new .config if it does not exists, or if the checksum of |
| 168 | # the dependencies has changed |
| 169 | set(merge_config_files_checksum_file ${PROJECT_BINARY_DIR}/.cmake.dotconfig.checksum) |
| 170 | set(CREATE_NEW_DOTCONFIG 1) |
| 171 | # Check if the checksum file exists too before trying to open it, though it |
| 172 | # should under normal circumstances |
| 173 | if(EXISTS ${DOTCONFIG} AND EXISTS ${merge_config_files_checksum_file}) |
| 174 | # Read out what the checksum was previously |
| 175 | file(READ |
| 176 | ${merge_config_files_checksum_file} |
| 177 | merge_config_files_checksum_prev |
| 178 | ) |
| 179 | if( |
| 180 | ${merge_config_files_checksum} STREQUAL |
| 181 | ${merge_config_files_checksum_prev} |
| 182 | ) |
| 183 | # Checksum is the same as before |
| 184 | set(CREATE_NEW_DOTCONFIG 0) |
| 185 | endif() |
| 186 | endif() |
| 187 | |
| 188 | if(CREATE_NEW_DOTCONFIG) |
| 189 | file(WRITE |
| 190 | ${merge_config_files_checksum_file} |
| 191 | ${merge_config_files_checksum} |
| 192 | ) |
| 193 | |
| 194 | set(merge_fragments ${merge_config_files}) |
| 195 | else() |
| 196 | set(merge_fragments ${DOTCONFIG}) |
| 197 | endif() |
| 198 | |
| 199 | message(STATUS KCONFIG_ROOT: ${KCONFIG_ROOT}) |
| 200 | message(STATUS DOTCONFIG: ${DOTCONFIG}) |
| 201 | message(STATUS AUTOCONF_H: ${AUTOCONF_H}) |
| 202 | message(STATUS PARSED_KCONFIG_SOURCES_TXT: ${PARSED_KCONFIG_SOURCES_TXT}) |
| 203 | message(STATUS merge_fragments: ${merge_fragments}) |
| 204 | |
| 205 | include_directories( |
| 206 | PUBLIC |
| 207 | ${PROJECT_BINARY_DIR} |
| 208 | ) |
| 209 | |
| 210 | execute_process( |
| 211 | COMMAND |
| 212 | ${PYTHON_EXECUTABLE} |
| 213 | ${SCRIPTS}/kconfig/kconfig.py |
| 214 | ${KCONFIG_ROOT} |
| 215 | ${DOTCONFIG} |
| 216 | ${AUTOCONF_H} |
| 217 | ${PARSED_KCONFIG_SOURCES_TXT} |
| 218 | ${merge_fragments} |
| 219 | WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} |
| 220 | # The working directory is set to the app dir such that the user |
| 221 | # can use relative paths in CONF_FILE, e.g. CONF_FILE=nrf5.conf |
| 222 | RESULT_VARIABLE ret |
| 223 | ) |
| 224 | if(NOT "${ret}" STREQUAL "0") |
| 225 | message(FATAL_ERROR "command failed with return code: ${ret}") |
| 226 | endif() |
| 227 | |
| 228 | # Read out the list of 'Kconfig' sources that were used by the engine. |
| 229 | file(STRINGS ${PARSED_KCONFIG_SOURCES_TXT} PARSED_KCONFIG_SOURCES_LIST) |
| 230 | |
| 231 | # Force CMAKE configure when the Kconfig sources or configuration files changes. |
| 232 | foreach(kconfig_input |
| 233 | ${merge_config_files} |
| 234 | ${DOTCONFIG} |
| 235 | ${PARSED_KCONFIG_SOURCES_LIST} |
| 236 | ) |
| 237 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig_input}) |
| 238 | endforeach() |
| 239 | |
| 240 | add_custom_target(config-sanitycheck DEPENDS ${DOTCONFIG}) |
| 241 | |
| 242 | # Remove the CLI Kconfig symbols from the namespace and |
| 243 | # CMakeCache.txt. If the symbols end up in DOTCONFIG they will be |
| 244 | # re-introduced to the namespace through 'import_kconfig'. |
| 245 | foreach (name ${cache_variable_names}) |
| 246 | if("${name}" MATCHES "^CONFIG_") |
| 247 | unset(${name}) |
| 248 | unset(${name} CACHE) |
| 249 | endif() |
| 250 | endforeach() |
| 251 | |
| 252 | # Parse the lines prefixed with CONFIG_ in the .config file from Kconfig |
| 253 | import_kconfig(CONFIG_ ${DOTCONFIG}) |
| 254 | |
| 255 | # Re-introduce the CLI Kconfig symbols that survived |
| 256 | foreach (name ${cache_variable_names}) |
| 257 | if("${name}" MATCHES "^CONFIG_") |
| 258 | if(DEFINED ${name}) |
| 259 | set(${name} ${${name}} CACHE STRING "") |
| 260 | endif() |
| 261 | endif() |
| 262 | endforeach() |