| # SPDX-License-Identifier: Apache-2.0 |
| |
| include_guard(GLOBAL) |
| |
| include(extensions) |
| include(python) |
| |
| # This cmake file provides functionality to import CMakeLists.txt and Kconfig |
| # files for Zephyr modules into Zephyr build system. |
| # |
| # CMakeLists.txt and Kconfig files can reside directly in the Zephyr module or |
| # in a MODULE_EXT_ROOT. |
| # The `<module>/zephyr/module.yml` file specifies whether the build files are |
| # located in the Zephyr module or in a MODULE_EXT_ROOT. |
| # |
| # A list of Zephyr modules can be provided to the build system using: |
| # -DZEPHYR_MODULES=<module-path>[;<additional-module(s)-path>] |
| # |
| # It looks for: <module>/zephyr/module.yml or |
| # <module>/zephyr/CMakeLists.txt |
| # to load the Zephyr module into Zephyr build system. |
| # If west is installed, it uses west's APIs to obtain a list of projects to |
| # search for zephyr/module.yml from the current workspace's manifest. |
| # |
| # If the module.yml file specifies that build files are located in a |
| # MODULE_EXT_ROOT then the variables: |
| # - `ZEPHYR_<MODULE_NAME>_CMAKE_DIR` is used for inclusion of the CMakeLists.txt |
| # - `ZEPHYR_<MODULE_NAME>_KCONFIG` is used for inclusion of the Kconfig |
| # files into the build system. |
| |
| # Settings used by Zephyr module but where systems may define an alternative value. |
| set_ifndef(KCONFIG_BINARY_DIR ${CMAKE_BINARY_DIR}/Kconfig) |
| |
| zephyr_get(ZEPHYR_MODULES) |
| if(ZEPHYR_MODULES) |
| set(ZEPHYR_MODULES_ARG "--modules" ${ZEPHYR_MODULES}) |
| endif() |
| |
| zephyr_get(EXTRA_ZEPHYR_MODULES VAR EXTRA_ZEPHYR_MODULES ZEPHYR_EXTRA_MODULES) |
| if(EXTRA_ZEPHYR_MODULES) |
| set(EXTRA_ZEPHYR_MODULES_ARG "--extra-modules" ${EXTRA_ZEPHYR_MODULES}) |
| endif() |
| |
| file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}) |
| set(kconfig_modules_file ${KCONFIG_BINARY_DIR}/Kconfig.modules) |
| set(kconfig_sysbuild_file ${KCONFIG_BINARY_DIR}/Kconfig.sysbuild.modules) |
| set(cmake_modules_file ${CMAKE_BINARY_DIR}/zephyr_modules.txt) |
| set(cmake_sysbuild_file ${CMAKE_BINARY_DIR}/sysbuild_modules.txt) |
| set(zephyr_settings_file ${CMAKE_BINARY_DIR}/zephyr_settings.txt) |
| |
| if(WEST) |
| set(west_arg "--zephyr-base" ${ZEPHYR_BASE}) |
| endif() |
| |
| if(WEST OR ZEPHYR_MODULES) |
| # Zephyr module uses west, so only call it if west is installed or |
| # ZEPHYR_MODULES was provided as argument to CMake. |
| execute_process( |
| COMMAND |
| ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/zephyr_module.py |
| ${west_arg} |
| ${ZEPHYR_MODULES_ARG} |
| ${EXTRA_ZEPHYR_MODULES_ARG} |
| --kconfig-out ${kconfig_modules_file} |
| --cmake-out ${cmake_modules_file} |
| --sysbuild-kconfig-out ${kconfig_sysbuild_file} |
| --sysbuild-cmake-out ${cmake_sysbuild_file} |
| --settings-out ${zephyr_settings_file} |
| WORKING_DIRECTORY ${ZEPHYR_BASE} |
| ERROR_VARIABLE |
| zephyr_module_error_text |
| RESULT_VARIABLE |
| zephyr_module_return |
| ) |
| |
| if(${zephyr_module_return}) |
| message(FATAL_ERROR "${zephyr_module_error_text}") |
| endif() |
| |
| if(EXISTS ${zephyr_settings_file}) |
| file(STRINGS ${zephyr_settings_file} zephyr_settings_txt ENCODING UTF-8 REGEX "^[^#]") |
| foreach(setting ${zephyr_settings_txt}) |
| # Match <key>:<value> for each line of file, each corresponding to |
| # a setting. The use of quotes is required due to CMake not supporting |
| # lazy regexes (it supports greedy only). |
| string(REGEX REPLACE "\"(.*)\":\".*\"" "\\1" key ${setting}) |
| string(REGEX REPLACE "\".*\":\"(.*)\"" "\\1" value ${setting}) |
| list(APPEND ${key} ${value}) |
| endforeach() |
| endif() |
| |
| # Append ZEPHYR_BASE as a default ext root at lowest priority |
| list(APPEND MODULE_EXT_ROOT ${ZEPHYR_BASE}) |
| |
| if(EXISTS ${cmake_modules_file}) |
| file(STRINGS ${cmake_modules_file} zephyr_modules_txt ENCODING UTF-8) |
| endif() |
| |
| set(ZEPHYR_MODULE_NAMES) |
| foreach(module ${zephyr_modules_txt}) |
| # Match "<name>":"<path>" for each line of file, each corresponding to |
| # one module. The use of quotes is required due to CMake not supporting |
| # lazy regexes (it supports greedy only). |
| string(REGEX REPLACE "\"(.*)\":\".*\":\".*\"" "\\1" module_name ${module}) |
| list(APPEND ZEPHYR_MODULE_NAMES ${module_name}) |
| endforeach() |
| |
| if(EXISTS ${cmake_sysbuild_file}) |
| file(STRINGS ${cmake_sysbuild_file} sysbuild_modules_txt ENCODING UTF-8) |
| endif() |
| |
| set(SYSBUILD_MODULE_NAMES) |
| foreach(module ${sysbuild_modules_txt}) |
| # Match "<name>":"<path>" for each line of file, each corresponding to |
| # one module. The use of quotes is required due to CMake not supporting |
| # lazy regexes (it supports greedy only). |
| string(REGEX REPLACE "\"(.*)\":\".*\":\".*\"" "\\1" module_name ${module}) |
| list(APPEND SYSBUILD_MODULE_NAMES ${module_name}) |
| endforeach() |
| |
| # MODULE_EXT_ROOT is process order which means Zephyr module roots processed |
| # later wins. therefore we reverse the list before processing. |
| list(REVERSE MODULE_EXT_ROOT) |
| foreach(root ${MODULE_EXT_ROOT}) |
| set(module_cmake_file_path modules/modules.cmake) |
| if(NOT EXISTS ${root}/${module_cmake_file_path}) |
| message(FATAL_ERROR "No `${module_cmake_file_path}` found in module root `${root}`.") |
| endif() |
| |
| include(${root}/${module_cmake_file_path}) |
| endforeach() |
| |
| foreach(module ${zephyr_modules_txt}) |
| # Match "<name>":"<path>" for each line of file, each corresponding to |
| # one Zephyr module. The use of quotes is required due to CMake not |
| # supporting lazy regexes (it supports greedy only). |
| string(CONFIGURE ${module} module) |
| string(REGEX REPLACE "\"(.*)\":\".*\":\".*\"" "\\1" module_name ${module}) |
| string(REGEX REPLACE "\".*\":\"(.*)\":\".*\"" "\\1" module_path ${module}) |
| string(REGEX REPLACE "\".*\":\".*\":\"(.*)\"" "\\1" cmake_path ${module}) |
| |
| zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name}) |
| if(NOT ${MODULE_NAME_UPPER} STREQUAL CURRENT) |
| set(ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR ${module_path}) |
| set(ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR ${cmake_path}) |
| else() |
| message(FATAL_ERROR "Found Zephyr module named: ${module_name}\n\ |
| ${MODULE_NAME_UPPER} is a restricted name for Zephyr modules as it is used for \ |
| \${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR} CMake variable.") |
| endif() |
| endforeach() |
| |
| foreach(module ${sysbuild_modules_txt}) |
| # Match "<name>":"<path>" for each line of file, each corresponding to |
| # one Zephyr module. The use of quotes is required due to CMake not |
| # supporting lazy regexes (it supports greedy only). |
| string(CONFIGURE ${module} module) |
| string(REGEX REPLACE "\"(.*)\":\".*\":\".*\"" "\\1" module_name ${module}) |
| string(REGEX REPLACE "\".*\":\"(.*)\":\".*\"" "\\1" module_path ${module}) |
| string(REGEX REPLACE "\".*\":\".*\":\"(.*)\"" "\\1" cmake_path ${module}) |
| |
| zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name}) |
| if(NOT ${MODULE_NAME_UPPER} STREQUAL CURRENT) |
| set(SYSBUILD_${MODULE_NAME_UPPER}_MODULE_DIR ${module_path}) |
| set(SYSBUILD_${MODULE_NAME_UPPER}_CMAKE_DIR ${cmake_path}) |
| else() |
| message(FATAL_ERROR "Found Zephyr module named: ${module_name}\n\ |
| ${MODULE_NAME_UPPER} is a restricted name for Zephyr modules as it is used for \ |
| \${SYSBUILD_${MODULE_NAME_UPPER}_MODULE_DIR} CMake variable.") |
| endif() |
| endforeach() |
| else() |
| |
| file(WRITE ${kconfig_modules_file} |
| "# No west and no Zephyr modules\n" |
| ) |
| |
| file(WRITE ${kconfig_sysbuild_file} |
| "# No west and no Zephyr modules\n" |
| ) |
| |
| endif() |