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/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 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