build: an SPDX SBOM with every board image, and of the source tree, by syft
make boot_image now ends by writing build/boards/<board>/<image>.spdx(.json): the image and every file copied off it, each with its SHA-256 -- the SBOM of what is on the medium. It also refreshes sbom.spdx(.json), the source SBOM: the tracked files the product is built from (kernel, v3, v4, capsules, boards, tooling, proofs), staged to build/sbom/src so nothing untracked in the working directory is swept in. Versioned as the kernel version and git describe. mk/syft.yaml turns on file cataloging with SHA-256 (a C tree has almost no packages for syft to find: the old SBOM held one file with a zero checksum). No syft: the build stops. syft 1.52.0 installed in ~/.local/bin from its GitHub release, checked against the release's published SHA-256. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f8fbc37698
commit
fcb89b0695
@@ -16,7 +16,9 @@
|
||||
# make [all] TARGET=<board> that board's boot image + its book
|
||||
# make [all] TARGET=<profile> hosted v3 build with that profile
|
||||
#
|
||||
# make boot_image TARGET=<board> only the board's boot image
|
||||
# make boot_image TARGET=<board> only the board's boot image, with its SBOM
|
||||
# (build/boards/<board>/*.spdx*) and a fresh
|
||||
# source SBOM -- needs syft
|
||||
# make boot_images every board that has a kernel port
|
||||
# make docs [TARGET=<board>] the book; a board adds its appendix
|
||||
#
|
||||
@@ -25,6 +27,7 @@
|
||||
# make clean TARGET=<profile> build/<arch>/<profile> for every arch
|
||||
# make clean-docs build/docs/
|
||||
#
|
||||
# make sbom SPDX SBOM of the source tree (sbom.spdx, sbom.spdx.json)
|
||||
# make kernel ARCH=<arch> [GOAL=g] kernel/Makefile goal (default: all)
|
||||
# make boards list boards and whether they can be built
|
||||
# make <other goal> goes to v3/Makefile (make help-hosted)
|
||||
@@ -53,7 +56,7 @@ BOARD_DIR := $(if $(TARGET),$(BOARD_DIR_$(TARGET)))
|
||||
SUBMAKE := $(MAKE) --no-print-directory
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
.PHONY: all boot_image boot_images docs clean clean-docs kernel boards help help-hosted
|
||||
.PHONY: all boot_image boot_images docs clean clean-docs kernel boards help help-hosted sbom sbom-board
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# all
|
||||
@@ -104,6 +107,9 @@ boot_image:
|
||||
@$(SUBMAKE) -f kernel/Makefile \
|
||||
BOARD=$(BOARD_DIR) ARCH=$(call board_arch,$(TARGET)) TARGET=kernel \
|
||||
STARFORTH_V4=1 V4_DEFAULT=0 boot_image
|
||||
@# Its SBOM, and the source tree's, are part of the build (2026-10-14).
|
||||
@$(SUBMAKE) sbom-board TARGET=$(TARGET)
|
||||
@$(SUBMAKE) sbom
|
||||
|
||||
boot_images:
|
||||
@for b in $(READY_BOARDS); do \
|
||||
@@ -111,6 +117,55 @@ boot_images:
|
||||
done
|
||||
@$(foreach b,$(UNREADY_BOARDS),echo "Skipped $(b): needs kernel/src/arch/$(call board_arch,$(b)), which does not exist yet";)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# SBOMs (SPDX 2.3, by syft; config mk/syft.yaml) -- part of every board build
|
||||
# ------------------------------------------------------------------------------
|
||||
# The source SBOM covers what the product is built from: the tracked files of
|
||||
# the kernel, v3, v4, capsules, boards, build tooling and proofs, each with its
|
||||
# SHA-256 -- copied to build/sbom/src first, so nothing untracked in the
|
||||
# working directory is ever swept in. Not logs, documents, experiment data or
|
||||
# the disk images. A board's SBOM covers
|
||||
# its image and every file on it, copied off the image, so the SBOM is of what
|
||||
# is on the medium, not of what was meant to be. Versioned as the kernel
|
||||
# version and the commit. No syft: the build stops, as for any missing tool.
|
||||
SYFT ?= syft
|
||||
SBOM_VERSION = $(shell sed -n 's/^LITHOS_VERSION *?= *//p' kernel/Makefile)+$(shell git describe --always --dirty 2>/dev/null)
|
||||
# What the product is built from: tracked files only, in these places (never
|
||||
# untracked or ignored files in the working directory).
|
||||
SBOM_SOURCES := kernel v3 v4 capsules boards mk tools scripts proof configs \
|
||||
Makefile Kconfig Kconfig.arch Kconfig.heartbeat Kconfig.kernel \
|
||||
Kconfig.physics Kconfig.variant LICENSE NOTICE.md
|
||||
GIT_PLAIN := git -c filter.lfs.process= -c filter.lfs.smudge=cat -c filter.lfs.required=false
|
||||
|
||||
define need_syft
|
||||
@command -v $(SYFT) >/dev/null 2>&1 || { \
|
||||
echo "Error: syft not found -- the SBOM is part of this build."; \
|
||||
echo " Install a release from https://github.com/anchore/syft/releases"; \
|
||||
echo " (verify it against the release's checksums), or SYFT=/path/to/syft."; exit 1; }
|
||||
endef
|
||||
|
||||
sbom:
|
||||
$(need_syft)
|
||||
@echo " SBOM source tree -> sbom.spdx, sbom.spdx.json ($(SBOM_VERSION))"
|
||||
@rm -rf build/sbom/src && mkdir -p build/sbom/src && \
|
||||
$(GIT_PLAIN) ls-files -z -- $(SBOM_SOURCES) | xargs -0 cp --parents -t build/sbom/src && \
|
||||
$(SYFT) -q -c mk/syft.yaml dir:build/sbom/src \
|
||||
--source-name LithosAnanke --source-version "$(SBOM_VERSION)" \
|
||||
-o spdx-json=sbom.spdx.json -o spdx=sbom.spdx
|
||||
|
||||
sbom-board:
|
||||
$(need_syft)
|
||||
@if [ -z "$(BOARD_DIR)" ]; then echo "Usage: make sbom-board TARGET=<$(subst $(space),|,$(BOARDS))>"; exit 1; fi
|
||||
@img=build/boards/$(BOARD_DIR)/$(call board_field,$(TARGET),BOARD_IMAGE); \
|
||||
if [ ! -f "$$img" ]; then echo "Error: $$img not built (make boot_image TARGET=$(TARGET))"; exit 1; fi; \
|
||||
rm -rf build/boards/$(BOARD_DIR)/contents && mkdir -p build/boards/$(BOARD_DIR)/contents && \
|
||||
mcopy -s -n -i "$$img@@1M" '::/*' build/boards/$(BOARD_DIR)/contents/ && \
|
||||
echo " SBOM $$img -> $${img%.img}.spdx, $${img%.img}.spdx.json" && \
|
||||
$(SYFT) -q -c mk/syft.yaml dir:build/boards/$(BOARD_DIR) \
|
||||
--exclude './*.spdx' --exclude './*.spdx.json' \
|
||||
--source-name "LithosAnanke-$(BOARD_DIR)" --source-version "$(SBOM_VERSION)" \
|
||||
-o spdx-json=$${img%.img}.spdx.json -o spdx=$${img%.img}.spdx
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# docs
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# syft configuration for this repository's SBOMs (make sbom, make boot_image).
|
||||
# A C kernel has almost no "packages" for syft's catalogers to find, so the
|
||||
# SBOM's substance is the file list: every file in scope, with its SHA-256
|
||||
# (2026-10-14; until then the SBOM held one file, with a zero checksum).
|
||||
file:
|
||||
metadata:
|
||||
selection: all
|
||||
digests:
|
||||
- sha256
|
||||
Reference in New Issue
Block a user