blob: c9c86030693e54c663cef7567d160000a50e9ff0 [file] [log] [blame]
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2021, Nordic Semiconductor ASA
# Validate board and setup boards target.
#
# This CMake module will validate the BOARD argument as well as splitting the
# BOARD argument into <BOARD> and <BOARD_REVISION>.
#
# If a board implementation is not found for the specified board an error will
# be raised and list of valid boards will be printed.
#
# If user provided board is a board alias, the board will be adjusted to real
# board name.
#
# If board name is deprecated, then board will be adjusted to new board name and
# a deprecation warning will be printed to the user.
#
# Outcome:
# The following variables will be defined when this CMake module completes:
#
# - BOARD: Board, without revision field.
# - BOARD_REVISION: Board revision
# - BOARD_DIR: Board directory with the implementation for selected board
# - ARCH_DIR: Arch dir for extracted from selected board
# - BOARD_ROOT: BOARD_ROOT with ZEPHYR_BASE appended
#
# The following targets will be defined when this CMake module completes:
# - board: when invoked, a list of valid boards will be printed
#
# Required variables:
# - BOARD: Board name, including any optional revision field, for example: `foo` or `foo@1.0.0`
#
# Optional variables:
# - BOARD_ROOT: CMake list of board roots containing board implementations
# - ARCH_ROOT: CMake list of arch roots containing arch implementations
#
# Optional environment variables:
# - ZEPHYR_BOARD_ALIASES: Environment setting pointing to a CMake file
# containing board aliases.
#
# 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(python)
include(extensions)
# Check that BOARD has been provided, and that it has not changed.
# If user tries to change the BOARD, the BOARD value is reset to the BOARD_CACHED value.
zephyr_check_cache(BOARD REQUIRED)
# 'BOARD_ROOT' is a prioritized list of directories where boards may
# be found. It always includes ${ZEPHYR_BASE} at the lowest priority (except for unittesting).
if(NOT unittest IN_LIST Zephyr_FIND_COMPONENTS)
list(APPEND BOARD_ROOT ${ZEPHYR_BASE})
endif()
string(FIND "${BOARD}" "@" REVISION_SEPARATOR_INDEX)
if(NOT (REVISION_SEPARATOR_INDEX EQUAL -1))
math(EXPR BOARD_REVISION_INDEX "${REVISION_SEPARATOR_INDEX} + 1")
string(SUBSTRING ${BOARD} ${BOARD_REVISION_INDEX} -1 BOARD_REVISION)
string(SUBSTRING ${BOARD} 0 ${REVISION_SEPARATOR_INDEX} BOARD)
endif()
zephyr_get(ZEPHYR_BOARD_ALIASES)
if(DEFINED ZEPHYR_BOARD_ALIASES)
include(${ZEPHYR_BOARD_ALIASES})
if(${BOARD}_BOARD_ALIAS)
set(BOARD_ALIAS ${BOARD} CACHE STRING "Board alias, provided by user")
set(BOARD ${${BOARD}_BOARD_ALIAS})
message(STATUS "Aliased BOARD=${BOARD_ALIAS} changed to ${BOARD}")
endif()
endif()
include(${ZEPHYR_BASE}/boards/deprecated.cmake)
if(${BOARD}_DEPRECATED)
set(BOARD_DEPRECATED ${BOARD} CACHE STRING "Deprecated board name, provided by user")
set(BOARD ${${BOARD}_DEPRECATED})
message(WARNING "Deprecated BOARD=${BOARD_DEPRECATED} name specified, board automatically changed to: ${BOARD}.")
endif()
zephyr_boilerplate_watch(BOARD)
foreach(root ${BOARD_ROOT})
# Check that the board root looks reasonable.
if(NOT IS_DIRECTORY "${root}/boards")
message(WARNING "BOARD_ROOT element without a 'boards' subdirectory:
${root}
Hints:
- if your board directory is '/foo/bar/boards/<ARCH>/my_board' then add '/foo/bar' to BOARD_ROOT, not the entire board directory
- if in doubt, use absolute paths")
endif()
# NB: find_path will return immediately if the output variable is
# already set
if (BOARD_ALIAS)
find_path(BOARD_HIDDEN_DIR
NAMES ${BOARD_ALIAS}_defconfig
PATHS ${root}/boards/*/*
NO_DEFAULT_PATH
)
if(BOARD_HIDDEN_DIR)
message("Board alias ${BOARD_ALIAS} is hiding the real board of same name")
endif()
endif()
if(BOARD_DIR AND NOT EXISTS ${BOARD_DIR}/${BOARD}_defconfig)
message(WARNING "BOARD_DIR: ${BOARD_DIR} has been moved or deleted. "
"Trying to find new location."
)
set(BOARD_DIR BOARD_DIR-NOTFOUND CACHE PATH "Path to a file." FORCE)
endif()
find_path(BOARD_DIR
NAMES ${BOARD}_defconfig
PATHS ${root}/boards/*/*
NO_DEFAULT_PATH
)
if(BOARD_DIR AND NOT (${root} STREQUAL ${ZEPHYR_BASE}))
set(USING_OUT_OF_TREE_BOARD 1)
endif()
endforeach()
if(EXISTS ${BOARD_DIR}/revision.cmake)
# Board provides revision handling.
include(${BOARD_DIR}/revision.cmake)
elseif(BOARD_REVISION)
message(WARNING "Board revision ${BOARD_REVISION} specified for ${BOARD}, \
but board has no revision so revision will be ignored.")
endif()
set(board_message "Board: ${BOARD}")
if(DEFINED BOARD_REVISION)
set(board_message "${board_message}, Revision: ${BOARD_REVISION}")
if(DEFINED ACTIVE_BOARD_REVISION)
set(board_message "${board_message} (Active: ${ACTIVE_BOARD_REVISION})")
set(BOARD_REVISION ${ACTIVE_BOARD_REVISION})
endif()
string(REPLACE "." "_" BOARD_REVISION_STRING ${BOARD_REVISION})
endif()
message(STATUS "${board_message}")
# Prepare boards usage command printing.
# This command prints all boards in the system in the following cases:
# - User specifies an invalid BOARD
# - User invokes '<build-command> boards' target
list(TRANSFORM ARCH_ROOT PREPEND "--arch-root=" OUTPUT_VARIABLE arch_root_args)
list(TRANSFORM BOARD_ROOT PREPEND "--board-root=" OUTPUT_VARIABLE board_root_args)
set(list_boards_commands
COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/list_boards.py
${arch_root_args} ${board_root_args} --arch-root=${ZEPHYR_BASE}
)
if(NOT BOARD_DIR)
message("No board named '${BOARD}' found.\n\n"
"Please choose one of the following boards:\n"
)
execute_process(${list_boards_commands})
unset(CACHED_BOARD CACHE)
message(FATAL_ERROR "Invalid BOARD; see above.")
endif()
add_custom_target(boards ${list_boards_commands} USES_TERMINAL)