summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-08-21 14:23:40 +0700
committerhathach <[email protected]>2026-08-21 14:23:40 +0700
commita408a8e9af4a043202f79a2b8e20d229093148e5 (patch)
treeb2a122bfaf08e7e16f3a6315fe54e1d08a0f86ce
parente13eff8d4e757ebe7709a58fce44017b8be5a84d (diff)
hil: express a board's always-on defines as a variant, dropping build.args
The roster had two ways to pass a cmake -D to a board's build: `build.args`, applied to every variant, and `variant[].defines`, applied to one. They did the same thing, and only metro_m4_express used the first - for MAX3421_HOST=1, which is what makes it the one rig board that compiles hcd_max3421.c. A board whose define is always on now carries a single variant named after itself, which is exactly the shape `board.get('variant') or [{'name': name, 'flags': ''}]` already synthesises everywhere - so the build dir, the HIL report row and the variant-boundary handling are unchanged. raspberry_pi_pico has used that shape for its flags all along. Removes the BuildCfg type and the parallel code path from all four consumers: hil_test.build_board, hil_pool_check's two builders, hil_ci_set_matrix and ci_select.board_options. Verified: the hil-build matrix entry is byte-identical (`-b metro_m4_express -DMAX3421_HOST=1`), hil_test's build command is unchanged, ci_select still selects the board for a max3421 diff with MAX3421_HOST in its options, and a real build of dual/host_info_to_device_cdc and host/cdc_msc_hid on that board still compiles hcd_max3421.c.
-rw-r--r--.github/scripts/hil_ci_set_matrix.py2
-rw-r--r--test/hil/helper/hil_pool_check.py4
-rwxr-xr-xtest/hil/hil_test.py14
-rw-r--r--test/hil/test/test_ci_select.py10
-rw-r--r--test/hil/tinyusb.json13
-rwxr-xr-xtools/ci_select.py10
6 files changed, 24 insertions, 29 deletions
diff --git a/.github/scripts/hil_ci_set_matrix.py b/.github/scripts/hil_ci_set_matrix.py
index 396c4175a..bf50061dd 100644
--- a/.github/scripts/hil_ci_set_matrix.py
+++ b/.github/scripts/hil_ci_set_matrix.py
@@ -103,8 +103,6 @@ def main():
f'hil-build-esp jobs in .github/workflows/build.yml')
build_board = f'-b {name}'
- if 'build' in board and 'args' in board['build']:
- build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args'])
# PR selection: build only the examples this board will run (its test
# list plus device/board_test, the parking firmware) - tools/build.py -e.
diff --git a/test/hil/helper/hil_pool_check.py b/test/hil/helper/hil_pool_check.py
index d926bbe3d..179a417ed 100644
--- a/test/hil/helper/hil_pool_check.py
+++ b/test/hil/helper/hil_pool_check.py
@@ -433,7 +433,7 @@ def build_example(board: dict, variant: str, example: str) -> int:
cmd = ['idf.py', '-C', f'examples/{example}',
'-B', f'cmake-build/cmake-build-{vcfg["name"]}/{example}',
'-G', 'Ninja', f'-DBOARD={name}', 'build']
- for d in board.get('build', {}).get('args', []) + vcfg.get('defines', []):
+ for d in vcfg.get('defines', []):
cmd.insert(-1, f'-D{d}')
if vcfg.get('flags'):
cmd.insert(-1, f'-DCFLAGS_CLI={vcfg["flags"]}')
@@ -446,8 +446,6 @@ def build_example(board: dict, variant: str, example: str) -> int:
cmd = [sys.executable, str(hil_util.TINYUSB_ROOT / 'tools' / 'build.py'),
'-b', name, '-T', Path(example).name,
'-j', str(max(1, (os.cpu_count() or _jobs) // _jobs))]
- for d in board.get('build', {}).get('args', []):
- cmd += ['-D', d]
if vcfg['name'] != name:
cmd += ['--build-name', vcfg['name']]
for d in vcfg.get('defines', []):
diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py
index 174251343..fcd7c7e6f 100755
--- a/test/hil/hil_test.py
+++ b/test/hil/hil_test.py
@@ -194,10 +194,6 @@ class TestsCfg(TypedDict, total=False):
dev_attached: list[AttachedDevCfg]
-class BuildCfg(TypedDict, total=False):
- args: list[str]
-
-
class VariantCfg(TypedDict, total=False):
name: str # build dir (cmake-build-<name>) and HIL report row
flags: str # raw CFLAGS, e.g. "-DCFG_TUD_DWC2_DMA_ENABLE=1"
@@ -209,7 +205,9 @@ class Board(TypedDict):
uid: str
tests: TestsCfg
flasher: FlasherCfg
- build: NotRequired[BuildCfg]
+ # every build knob lives here, including a board's always-on defines: a board that
+ # needs one carries a single variant named after itself (metro_m4_express /
+ # MAX3421_HOST=1), which is exactly what the `or [...]` default below synthesises
variant: NotRequired[list[VariantCfg]]
toolchain: NotRequired[str] # CI build bucket override, e.g. "riscv-gcc" (consumed by hil_ci_set_matrix.py)
@@ -1670,21 +1668,17 @@ def test_example(board: Board, variant: str, example: str) -> tuple[int, str, st
def build_board(board: Board) -> tuple[str, int]:
"""Build firmware for this board via tools/build.py.
- Honors board config's variant list and build.args defines.
+ Honors board config's variant list (name, defines, flags).
Output goes to cmake-build/cmake-build-<variant>/ (tools/build.py layout).
Unbounded on purpose: --build is a local convenience (no CI workflow passes it), so
the developer watching the build is the timeout."""
name = board['name']
- bcfg = cast(BuildCfg, board.get('build', {}))
- extra_defs = bcfg.get('args', [])
variants = board.get('variant') or [{'name': name, 'flags': ''}]
failed = 0
for v in variants:
cmd = [sys.executable, str(hil_util.TINYUSB_ROOT / 'tools' / 'build.py'), '-b', name]
- for d in extra_defs:
- cmd += ['-D', d]
if v['name'] != name:
cmd += ['--build-name', v['name']]
for d in v.get('defines', []):
diff --git a/test/hil/test/test_ci_select.py b/test/hil/test/test_ci_select.py
index 031e8e287..f5c64ac1c 100644
--- a/test/hil/test/test_ci_select.py
+++ b/test/hil/test/test_ci_select.py
@@ -329,7 +329,7 @@ class TestOptionGatedPort(unittest.TestCase):
# host-side option board (max3421 as host controller), off any max3421 family
OPT_ROSTER = [('test/hil/opt.json', [
{'name': 'fake_dual_board', 'uid': 'o1', 'flasher': {'name': 'jlink'},
- 'build': {'args': ['MAX3421_HOST=1']},
+ 'variant': [{'name': 'fake_dual_board', 'defines': ['MAX3421_HOST=1']}],
'tests': {'device': True, 'host': False, 'dual': True}},
{'name': 'fake_host_board', 'uid': 'o2', 'flasher': {'name': 'jlink'},
'variant': [{'name': 'fake_host_board', 'flags': '-DMAX3421_HOST=1'}],
@@ -346,10 +346,10 @@ class TestOptionGatedPort(unittest.TestCase):
for board in boards:
self.assertIn(board, s['boards'])
- def test_option_selects_via_args_defines_and_flags(self):
+ def test_option_selects_via_defines_and_flags(self):
s = ci_select.classify(['src/portable/analog/max3421/hcd_max3421.c'], REPO, self.OPT_ROSTER)
self.assertFalse(s['full'])
- self.assertIn('fake_dual_board', s['boards']) # build.args
+ self.assertIn('fake_dual_board', s['boards']) # variant defines
self.assertIn('fake_host_board', s['boards']) # variant flags
self.assertNotIn('fake_off_board', s['boards']) # variant defines, but =0
@@ -1762,7 +1762,7 @@ class TestBuildPyExampleFilter(unittest.TestCase):
{'tinyusb_metrics', 'cdc_msc', 'cdc_msc-membrowse-upload'})
def test_build_defines_reach_the_example_filter(self):
- # metro_m4_express gets MAX3421_HOST=1 from the roster build args, never
+ # metro_m4_express gets MAX3421_HOST=1 from its roster variant, never
# from its BSP: without threading them through, -e drops the rig's only
# MAX3421 dual firmware that --target all used to build
self.assertIsNone(self.build.resolve_example_target_groups(
@@ -1934,7 +1934,7 @@ class TestSkipExampleMirrorsFamilyFilter(unittest.TestCase):
def test_build_define_enables_max3421_only_list(self):
# family_support.cmake:940 appends MAX3421 to FAMILY_MCUS when
# MAX3421_HOST=1; on metro_m4_express that define comes from the roster
- # build args, so skip_example has to be told about it
+ # variant defines, so skip_example has to be told about it
ex = 'dual/host_info_to_device_cdc'
self.assertTrue(self.build_utils.skip_example(ex, 'metro_m4_express'))
self.assertFalse(self.build_utils.skip_example(ex, 'metro_m4_express',
diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json
index 6f552f126..8fd4683a4 100644
--- a/test/hil/tinyusb.json
+++ b/test/hil/tinyusb.json
@@ -157,11 +157,14 @@
{
"name": "metro_m4_express",
"uid": "9995AD485337433231202020FF100A34",
- "build": {
- "args": [
- "MAX3421_HOST=1"
- ]
- },
+ "variant": [
+ {
+ "name": "metro_m4_express",
+ "defines": [
+ "MAX3421_HOST=1"
+ ]
+ }
+ ],
"tests": {
"device": true,
"host": false,
diff --git a/tools/ci_select.py b/tools/ci_select.py
index cd63899c1..ced3bbbc0 100755
--- a/tools/ci_select.py
+++ b/tools/ci_select.py
@@ -188,10 +188,12 @@ def bsp_board_options(board_name: str, repo_root: str) -> frozenset:
def board_options(board: dict, repo_root: str) -> set:
- """Build options a board has truthy: the roster entry's build.args plus each
- variant's defines (NAME=VALUE) and raw CFLAGS (-DNAME=VALUE), plus whatever its
- own board.cmake sets (a board can enable a gated port without the roster saying so)."""
- toks = list(board.get('build', {}).get('args', []))
+ """Build options a board has truthy: each variant's defines (NAME=VALUE) and raw
+ CFLAGS (-DNAME=VALUE), plus whatever its own board.cmake sets (a board can enable a
+ gated port without the roster saying so). A board whose option is always on carries
+ a single variant named after itself - metro_m4_express and MAX3421_HOST=1, which is
+ what makes it the one rig board that compiles hcd_max3421.c."""
+ toks = []
for v in board.get('variant', []):
toks += list(v.get('defines', []))
toks += v.get('flags', '').split()