From 68e44f4a5a96a510de2974af1e5eefe5d4069708 Mon Sep 17 00:00:00 2001 From: ppannuto-claude Date: Fri, 28 Aug 2026 09:12:25 -0700 Subject: [PATCH 1/2] qemu_i486_q35: use [unstable] json-target-spec instead of -Zjson-target-spec qemu_i486_q35's target is a bare JSON filename, not a path, which cargo only resolves as a custom target spec (rather than requiring a builtin triple name) via the unstable json-target-spec mechanism. Previously this was passed as a `-Zjson-target-spec` CLI flag baked into the board's own Makefile (`CARGO = cargo -Zjson-target-spec`), the only board doing so. Set it instead via `[unstable] json-target-spec = true` in the board's own .cargo/config.toml -- the same persistent-config mechanism ../cargo/riscv_flags.toml already uses for the RISC-V boards' JSON specs (those are referenced by relative path instead, so didn't need it spelled out explicitly). That makes a plain `cargo clippy`/`cargo check`/`cargo build` all work with no special-casing in the board Makefile, so the now-redundant CARGO override is dropped. Also removed a stale `[env] RUST_TARGET_PATH` + TODO comment that predated the current include-based config layout. Verified: a full `make -C boards/qemu_i486_q35` build still produces a working kernel binary with the CARGO override removed. Co-Authored-By: Claude Sonnet 5 --- boards/qemu_i486_q35/.cargo/config.toml | 13 ++++++++----- boards/qemu_i486_q35/Makefile | 4 ---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/boards/qemu_i486_q35/.cargo/config.toml b/boards/qemu_i486_q35/.cargo/config.toml index 053c8ea2905..a77c953ce57 100644 --- a/boards/qemu_i486_q35/.cargo/config.toml +++ b/boards/qemu_i486_q35/.cargo/config.toml @@ -7,13 +7,16 @@ include = [ "../../cargo/unstable_flags.toml", ] -[env] -# Relative to crate root, not this file -# TODO: where is the best place to store this config file? -RUST_TARGET_PATH = "." - [build] target = "i486-unknown-none.json" [target.i486-unknown-none] runner = "qemu-system-i386 -cpu 486 -machine q35 -net none -device isa-debug-exit,iobase=0xf4,iosize=0x04 -device virtio-rng-pci,disable-legacy=on -serial stdio -kernel" + +# `target` above is a bare filename, not a path -- cargo only resolves that +# as a custom target spec (rather than requiring a builtin triple name) with +# this enabled. Same mechanism ../../cargo/riscv_flags.toml uses for the +# RISC-V boards' JSON specs, just needed explicitly here since those are +# referenced by relative path instead. +[unstable] +json-target-spec = true diff --git a/boards/qemu_i486_q35/Makefile b/boards/qemu_i486_q35/Makefile index 6ca8ce21842..74fc04fff9a 100644 --- a/boards/qemu_i486_q35/Makefile +++ b/boards/qemu_i486_q35/Makefile @@ -8,10 +8,6 @@ # Skip auto-installing targets with rustup, since we are using a custom target NO_RUSTUP := 1 -# Because we use a custom target with a .json file, we must pass -# `-Zjson-target-spec` to cargo as of roughly January 2026. -CARGO = cargo -Zjson-target-spec - include ../Makefile.common QEMU_CMD := qemu-system-i386 From b12efe4ab2d3c0c5eb71590a2093cdcef318a646 Mon Sep 17 00:00:00 2001 From: ppannuto-claude Date: Fri, 28 Aug 2026 09:12:40 -0700 Subject: [PATCH 2/2] Make ci-job-clippy's board selection cover all archs, dynamically The hand-picked board list (nrf52840dk, raspberry_pi_pico, hifive1, qemu_i486_q35) silently missed arch/* crates with no board maintaining the list ever noticed: cortexm7, cortexm33, and rv64i had no clippy coverage with a real target. tools/build/list_arch_boards.sh picks one board per arch/* crate, so the set self-updates as boards and archs are added or removed instead of drifting stale. It iterates tools/build/list_archs.sh's small, already-existing arch list on the outside and boards on the inside, stopping at the first (alphabetically, since boards are sorted first) match per arch -- rather than scanning every board regardless of whether a match was already found. Every chip that depends on an arch crate does so directly (one hop; verified against every chips/*/Cargo.toml), and a few board crates also depend on an arch crate directly alongside their chip (e.g. hail, the apollo3 boards) -- so for each candidate board, check both its own Cargo.toml and its chip's for an arch/ path dependency. An arch crate with no board using it directly is only an error if no *other* arch crate depends on it either (checked with one more grep over arch/*/Cargo.toml): e.g. cortex-v7m, cortex-m, cortex-m0, and riscv all have zero boards depending on them directly today, but each is a sibling dependency of some other arch crate that a board does use directly (cortex-m4f -> cortex-v7m -> cortex-m, rv32i -> riscv, etc.), so building that board compiles -- and so checks -- them too as a side effect, with no separate pick needed. cortex-m3 is currently the only arch crate genuinely unreachable either way; the script correctly hard-fails on it (verified: `make ci-job-clippy` now fails specifically and only on cortex-m3, everything else still resolves to the same 7 boards as before). This should self-resolve once a board using cortex-m3 lands. Results are collected into a variable and only printed after the full loop succeeds, rather than printed as each arch resolves: a failure partway through then leaves stdout completely empty instead of an incomplete board list, which matters because a `$(shell ...)`-based caller (as opposed to a direct invocation checked with `|| exit 1`) can only observe empty-vs-nonempty output, not the exit status. An earlier version used `cargo metadata` to compute each board's whole transitive dependency graph, which turned out to be solving a problem that doesn't exist here -- the codebase just doesn't have deep chip->chip->arch chains that would need it. A cold-context review caught a real bug in the regex: `path = "..."` requires exact spacing around `=`, but two chips (psoc62xa, rp2040) write `path="..."` with none, so their arch dependency silently didn't match. Harmless today only by coincidence -- both boards using those chips also happen to redeclare the same arch crate directly, so the board-level lookup covered for it -- but a future cleanup removing that "redundant" direct dependency would silently drop cortex-m0p from clippy coverage with nothing to flag it. Loosened the regex to tolerate any whitespace around `=`. Verified: `make prepush` passes except for ci-job-clippy, which fails specifically and only on the cortex-m3 gap described above; output for every other arch is identical to the earlier board-first version's. Co-Authored-By: Claude Sonnet 5 --- Makefile | 17 +++------ tools/build/list_arch_boards.sh | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 11 deletions(-) create mode 100755 tools/build/list_arch_boards.sh diff --git a/Makefile b/Makefile index c9113b29180..53e78cbbebd 100644 --- a/Makefile +++ b/Makefile @@ -405,17 +405,12 @@ ci-job-readme-check: ci-job-clippy: $(call banner,CI-Job: Clippy) @cargo clippy -- -D warnings - # Run `cargo clippy` in select boards so we run clippy with targets that - # actually check the arch-specific functions. - # - # - nrf52840dk: cortex-m4 - # - raspberry_pi_pico: cortex-m0 - # - hifive1: riscv - # - qemu_i486_q35: x86 - @cd boards/nordic/nrf52840dk && cargo clippy -- -D warnings - @cd boards/raspberry_pi_pico && cargo clippy -- -D warnings - @cd boards/hifive1 && cargo clippy -- -D warnings - @cd boards/qemu_i486_q35 && cargo clippy -Zjson-target-spec -- -D warnings + # One board per `arch/*` crate (tools/build/list_arch_boards.sh). + @arch_boards="`./tools/build/list_arch_boards.sh`" || exit 1;\ + for b in $$arch_boards;\ + do echo "$$(tput bold)Clippy $$b$$(tput sgr0)";\ + (cd boards/$$b && cargo clippy -- -D warnings) || exit 1;\ + done diff --git a/tools/build/list_arch_boards.sh b/tools/build/list_arch_boards.sh new file mode 100755 index 00000000000..d3dc6d7844d --- /dev/null +++ b/tools/build/list_arch_boards.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2026. + +# For each arch/* crate, print one representative board: the +# alphabetically-first board that depends on it, directly or via its chip. +# +# Reasonably aware of arch dependencies (i.e., `cortexm` picked up by `cortexm7`), and +# avoids duplicates where unneeded (but, e.g., `cortexm4` also necessarily repeats `cortexm`). +# +# Variants of another board (extra feature/policy configs, tutorial +# copies) are skipped, same as boards/README.md's own tooling, since +# they're not independent ports and would just be redundant picks. +# Sorted once so the loop below can stop at the first (alphabetical) match. +boards=($(./tools/build/list_boards.sh | sort | grep -vE '^(configurations|tutorials)/')) + +# True if $board depends on arch/$arch, directly or via its chip. +board_depends_on_arch() { + local board="$1" arch="$2" + local board_toml="boards/$board/Cargo.toml" + # Matches a `path = "…/arch/$arch"` dependency line; some Cargo.toml + # files omit the whitespace around `=`. + local pattern="path[[:space:]]*=[[:space:]]*\"[^\"]*/arch/$arch\"" + + grep -qE "$pattern" "$board_toml" && return 0 + + local chip_path chip_toml + # Pulls the path out of each `chips/*` dependency the board declares. + for chip_path in $(grep -oE 'path[[:space:]]*=[[:space:]]*"[^"]*/chips/[^"]*"' "$board_toml" | sed -E 's/.*"(.*)"/\1/'); do + chip_toml="boards/$board/$chip_path/Cargo.toml" + [ -f "$chip_toml" ] && grep -qE "$pattern" "$chip_toml" && return 0 + done + return 1 +} + +# Collected rather than printed as we go, so a failure partway through +# (see below) leaves nothing on stdout instead of an incomplete board list +# -- callers using `$(shell ...)` can't see a nonzero exit status, only +# empty-vs-nonempty output. +found_boards="" + +for arch in $(./tools/build/list_archs.sh); do + found="" + for board in "${boards[@]}"; do + if board_depends_on_arch "$board" "$arch"; then + found="$board" + break + fi + done + if [ -n "$found" ]; then + found_boards="$found_boards$found +" + continue + fi + + # No board uses this arch directly -- fine if another arch crate does + # (e.g. cortex-m, picked up by cortex-m4), since it then gets compiled, + # and so checked, as a side effect of building that arch's own board. + grep -qE "path[[:space:]]*=[[:space:]]*\"\.\./$arch\"" arch/*/Cargo.toml 2>/dev/null && continue + + echo "error: no board or arch crate depends on arch/$arch" >&2 + exit 1 +done + +printf '%s' "$found_boards" | sort -u