blob: eee4d320b69034fa700775c2562f144dc1f6b924 [file] [edit]
# Copyright 2026 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Incoming transition for Zephyr applications."""
load("@zephyr-bazel//:naming.bzl", "get_zc_repo_name")
load("@zephyr_index//:index.bzl", "PACKAGE_TO_BOARDS", "REPO_NAME_TO_CANONICAL")
def resolve_board_id(platform_label, pkg, pkg_boards, package_to_boards):
"""Resolves the Zephyr board ID from the platform label and context discovery index.
Args:
platform_label: The user requested platform label.
pkg: The resolved package path.
pkg_boards: Boards mapped to that package.
package_to_boards: The global boards configuration index dict.
Returns:
The resolved board_id or None.
"""
board_id = None
# Construct candidates list: (candidate_pkg, candidate_boards)
# First candidate is the current package
candidates = [(pkg, pkg_boards)]
# Add sub-packages as fallback candidates
prefix = pkg + "/"
for sub_pkg, sub_pkg_boards in package_to_boards.items():
if sub_pkg.startswith(prefix):
candidates.append((sub_pkg, sub_pkg_boards))
# Run resolution rules on candidates
for cand_pkg, cand_boards in candidates:
# Default Shortcut
if not board_id and platform_label.name == "default" and len(cand_boards) == 1:
board_id = cand_boards[0]
# Explicit Match (with default SoC resolution for HWM v2)
if not board_id and platform_label.name in cand_boards:
prefix_b = platform_label.name + "/"
qualified_variants = [b for b in cand_boards if b.startswith(prefix_b)]
if qualified_variants:
# Resolve to the first qualified variant (default SoC)
board_id = qualified_variants[0]
else:
board_id = platform_label.name
# SoC/Variant Match (e.g. :nrf52833 for board nrf52833dk)
if not board_id and cand_boards:
for b in cand_boards:
if b.endswith("/" + platform_label.name):
board_id = b
break
# Handle board/soc/variant where board == soc, simplified to board_variant (e.g. qemu_malta_be)
parts = b.split("/")
if len(parts) == 3 and parts[0] == parts[1]:
short_name = parts[0] + "_" + parts[2]
if short_name == platform_label.name:
board_id = b
break
# Fallback: if exactly one BASE board exists, assume it's board/soc
if not board_id:
base_boards = [b for b in cand_boards if "/" not in b]
if len(base_boards) == 1:
board_id = base_boards[0] + "/" + platform_label.name
if board_id:
break
return board_id
def _zephyr_transition_impl(settings, attr):
platforms = settings["//command_line_option:platforms"]
if not platforms:
return {}
platform_label = platforms[0]
# If already transitioned, do nothing.
# Check both the old zc_ pattern and the new canonical Bzlmod pattern.
if platform_label.workspace_name and ("zc_" in platform_label.workspace_name or "+zephyr_setup+" in platform_label.workspace_name):
return {}
# Resolve package path as used in PACKAGE_TO_BOARDS
pkg = str(platform_label).split(":")[0]
if pkg.startswith("//"):
pkg = "@@" + pkg
if not pkg.endswith("//"):
pkg = pkg.rstrip("/")
pkg_boards = PACKAGE_TO_BOARDS.get(pkg, None)
if pkg_boards == None:
# This platform is not in a package that contains Zephyr boards.
# Bypass the transition and let Bazel handle it.
return {}
board_id = resolve_board_id(platform_label, pkg, pkg_boards, PACKAGE_TO_BOARDS)
if not board_id:
fail("Unknown Zephyr board: %s. Valid boards in %s: %s" % (platform_label, pkg, pkg_boards))
repo_name = get_zc_repo_name(attr.app_label, board_id)
canonical_repo = REPO_NAME_TO_CANONICAL.get(repo_name)
if not canonical_repo:
fail("""
Board combination '%s' for app '%s' was filtered out by heuristics.
To fix this, you can either:
1. Add a .conf or .overlay file for this board under the 'boards/' directory of the app.
2. Add the board to the 'manual_boards' attribute of 'zephyr_setup.env' in MODULE.bazel
""" % (board_id, attr.app_label))
return {"//command_line_option:platforms": ["%s//:platform" % canonical_repo]}
zephyr_transition = transition(
implementation = _zephyr_transition_impl,
inputs = ["//command_line_option:platforms"],
outputs = ["//command_line_option:platforms"],
)