| # SPDX-License-Identifier: Apache-2.0 |
| # |
| # Copyright (c) 2021, Nordic Semiconductor ASA |
| |
| # Validate shields and setup shields target. |
| # |
| # This module will validate the SHIELD argument. |
| # |
| # If a shield implementation is not found for one of the specified shields, an |
| # error will be raised and a list of valid shields will be printed. |
| # |
| # Outcome: |
| # The following variables will be defined when this module completes: |
| # - shield_conf_files: List of shield-specific Kconfig fragments |
| # - shield_dts_files : List of shield-specific devicetree files |
| # - SHIELD_AS_LIST : A CMake list of shields created from the SHIELD variable. |
| # - SHIELD_DIRS : A CMake list of directories which contain shield definitions |
| # |
| # The following targets will be defined when this CMake module completes: |
| # - shields: when invoked, a list of valid shields will be printed |
| # |
| # If the SHIELD variable is changed after this module completes, |
| # a warning will be printed. |
| # |
| # Optional variables: |
| # - BOARD_ROOT: CMake list of board roots containing board implementations |
| # |
| # Variables set by this module and not mentioned above are for internal |
| # use only, and may be removed, renamed, or re-purposed without prior notice. |
| |
| include_guard(GLOBAL) |
| |
| include(extensions) |
| include(python) |
| |
| # Check that SHIELD has not changed. |
| zephyr_check_cache(SHIELD WATCH) |
| |
| if(SHIELD) |
| message(STATUS "Shield(s): ${SHIELD}") |
| endif() |
| |
| if(DEFINED SHIELD) |
| string(REPLACE " " ";" SHIELD_AS_LIST "${SHIELD}") |
| endif() |
| # SHIELD-NOTFOUND is a real CMake list, from which valid shields can be popped. |
| # After processing all shields, only invalid shields will be left in this list. |
| set(SHIELD-NOTFOUND ${SHIELD_AS_LIST}) |
| |
| # Prepare list shields command. |
| # This command is used for locating the shield dir as well as printing all shields |
| # in the system in the following cases: |
| # - User specifies an invalid SHIELD |
| # - User invokes '<build-command> shields' target |
| list(TRANSFORM BOARD_ROOT PREPEND "--board-root=" OUTPUT_VARIABLE board_root_args) |
| |
| set(list_shields_commands |
| COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/list_shields.py |
| ${board_root_args} --json |
| ) |
| |
| # Get list of shields in JSON format |
| execute_process(${list_shields_commands} |
| OUTPUT_VARIABLE shields_json |
| ERROR_VARIABLE err_shields |
| RESULT_VARIABLE ret_val |
| ) |
| |
| if(ret_val) |
| message(FATAL_ERROR "Error finding shields\nError message: ${err_shields}") |
| endif() |
| |
| string(JSON shields_length LENGTH ${shields_json}) |
| |
| if(shields_length GREATER 0) |
| math(EXPR shields_length "${shields_length} - 1") |
| |
| foreach(i RANGE ${shields_length}) |
| string(JSON shield GET "${shields_json}" "${i}") |
| string(JSON shield_name GET ${shield} name) |
| string(JSON shield_dir GET ${shield} dir) |
| list(APPEND SHIELD_LIST ${shield_name}) |
| set(SHIELD_DIR_${shield_name} ${shield_dir}) |
| endforeach() |
| endif() |
| |
| # Process shields in-order |
| if(DEFINED SHIELD) |
| foreach(s ${SHIELD_AS_LIST}) |
| if(NOT ${s} IN_LIST SHIELD_LIST) |
| continue() |
| endif() |
| |
| list(REMOVE_ITEM SHIELD-NOTFOUND ${s}) |
| |
| # Add <shield>.overlay to the shield_dts_files output variable. |
| list(APPEND |
| shield_dts_files |
| ${SHIELD_DIR_${s}}/${s}.overlay |
| ) |
| |
| # Add the shield's directory to the SHIELD_DIRS output variable. |
| list(APPEND |
| SHIELD_DIRS |
| ${SHIELD_DIR_${s}} |
| ) |
| |
| include(${SHIELD_DIR_${s}}/pre_dt_shield.cmake OPTIONAL) |
| |
| # Search for shield/shield.conf file |
| if(EXISTS ${SHIELD_DIR_${s}}/${s}.conf) |
| list(APPEND |
| shield_conf_files |
| ${SHIELD_DIR_${s}}/${s}.conf |
| ) |
| endif() |
| |
| # Add board-specific .conf and .overlay files to their |
| # respective output variables. |
| zephyr_file(CONF_FILES ${SHIELD_DIR_${s}}/boards |
| DTS shield_dts_files |
| KCONF shield_conf_files |
| ) |
| zephyr_file(CONF_FILES ${SHIELD_DIR_${s}}/boards/${s} |
| DTS shield_dts_files |
| KCONF shield_conf_files |
| ) |
| endforeach() |
| endif() |
| |
| # Prepare shield usage command printing. |
| # This command prints all shields in the system in the following cases: |
| # - User specifies an invalid SHIELD |
| # - User invokes '<build-command> shields' target |
| list(SORT SHIELD_LIST) |
| |
| if(DEFINED SHIELD AND NOT (SHIELD-NOTFOUND STREQUAL "")) |
| # Convert the list to pure string with newlines for printing. |
| string(REPLACE ";" "\n" shield_string "${SHIELD_LIST}") |
| |
| foreach (s ${SHIELD-NOTFOUND}) |
| message("No shield named '${s}' found") |
| endforeach() |
| message("Please choose from among the following shields:\n" |
| "${shield_string}" |
| ) |
| unset(CACHED_SHIELD CACHE) |
| message(FATAL_ERROR "Invalid SHIELD; see above.") |
| endif() |
| |
| # Prepend each shield with COMMAND <cmake> -E echo <shield>" for printing. |
| # Each shield is printed as new command because build files are not fond of newlines. |
| list(TRANSFORM SHIELD_LIST PREPEND "COMMAND;${CMAKE_COMMAND};-E;echo;" |
| OUTPUT_VARIABLE shields_target_cmd |
| ) |
| |
| add_custom_target(shields ${shields_target_cmd} USES_TERMINAL) |