cmake: modules: boards: Enhance board aliases for HWMv2

To address concerns about lengthy board identifiers in HWMv2, the
proposal is to apply the existing BOARD_ALIAS feature, like so:

   set(<alias>_BOARD_ALIAS <board>/<soc>)

It should then be possible to build with either:

   -DBOARD=<alias>            # expands to <board>/<soc>
   -DBOARD=<alias>/<variant>  # expands to <board>/<soc>/<variant>

However, this wouldn't work out of the box. A board alias can only be
expanded to a board name, without revision or identifier, because the
alias substitution happens after having parsed BOARD as user input -
namely, into BOARD (name), BOARD_REVISION, and BOARD_IDENTIFIER.

Furthermore, this means that in the legacy model, it was possible to
build with `-DBOARD=<alias>@<revision>`, and it would resolve to the
actual board name + revision.

To support both the old and new use cases, we can parse the alias just
like BOARD itself, then concatenate their identifiers as shown above.
Adding a revision works as before, but now it is also possible for the
alias to set its own revision. In this example:

   set(<alias>_BOARD_ALIAS <board>@<rev-A>/<soc>/<variant>)

`<rev-A>` is treated as the default revision, and it can be overridden:

   -DBOARD=<alias>          # expands to <board>@<rev-A>/<soc>/<variant>
   -DBOARD=<alias>@<rev-B>  # expands to <board>@<rev-B>/<soc>/<variant>

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
This commit is contained in:
Grzegorz Swiderski
2024-02-13 16:06:53 +01:00
committed by Carles Cufi
parent fc314e8e3f
commit dca54e000a

View File

@@ -61,37 +61,35 @@ if(NOT unittest IN_LIST Zephyr_FIND_COMPONENTS)
list(APPEND BOARD_ROOT ${ZEPHYR_BASE})
endif()
string(FIND "${BOARD}" "@" REVISION_SEPARATOR_INDEX)
string(FIND "${BOARD}" "/" IDENTIFIER_SEPARATOR_INDEX)
if(NOT (REVISION_SEPARATOR_INDEX EQUAL -1 OR IDENTIFIER_SEPARATOR_INDEX EQUAL -1))
if(REVISION_SEPARATOR_INDEX GREATER IDENTIFIER_SEPARATOR_INDEX)
message(FATAL_ERROR "Invalid revision / identifier format, format is: "
"<board>@<revision>/<identifier>"
# Helper function for parsing a board's name, revision, and identifier,
# from one input variable to three separate output variables.
function(parse_board_components board_in name_out revision_out identifier_out)
if(NOT "${${board_in}}" MATCHES "^([^@/]+)(@[^@/]+)?(/[^@]+)?$")
message(FATAL_ERROR
"Invalid revision / identifier format for ${board_in} (${${board_in}}). "
"Valid format is: <board>@<revision>/<identifier>"
)
endif()
endif()
string(REPLACE "@" "" board_revision "${CMAKE_MATCH_2}")
if(NOT (IDENTIFIER_SEPARATOR_INDEX EQUAL -1))
if(NOT DEFINED CACHE{BOARD_IDENTIFIER})
string(SUBSTRING ${BOARD} ${IDENTIFIER_SEPARATOR_INDEX} -1 BOARD_IDENTIFIER)
endif()
string(SUBSTRING ${BOARD} 0 ${IDENTIFIER_SEPARATOR_INDEX} BOARD)
endif()
set(${name_out} ${CMAKE_MATCH_1} PARENT_SCOPE)
set(${revision_out} ${board_revision} PARENT_SCOPE)
set(${identifier_out} ${CMAKE_MATCH_3} PARENT_SCOPE)
endfunction()
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()
parse_board_components(BOARD BOARD BOARD_REVISION BOARD_IDENTIFIER)
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})
parse_board_components(${BOARD}_BOARD_ALIAS BOARD BOARD_ALIAS_REVISION BOARD_ALIAS_IDENTIFIER)
message(STATUS "Aliased BOARD=${BOARD_ALIAS} changed to ${BOARD}")
if(NOT DEFINED BOARD_REVISION)
set(BOARD_REVISION ${BOARD_ALIAS_REVISION})
endif()
set(BOARD_IDENTIFIER ${BOARD_ALIAS_IDENTIFIER}${BOARD_IDENTIFIER})
endif()
endif()
include(${ZEPHYR_BASE}/boards/deprecated.cmake)