From 50f12c84bb2a6bed0c5892eb8785c105861a0543 Mon Sep 17 00:00:00 2001 From: Yinan Xu Date: Fri, 8 May 2026 15:59:17 +0800 Subject: [PATCH] fix(spec2006): install SPEC workspace from ISO Require SPEC2006_ISO and prepare build/linux-workloads/spec2006/spec-src by extracting the ISO into a temporary local staging tree, running the vendor installer there, and copying the installed workspace into the repository build directory. Relocate the copied tool tree in place and keep the prepare stamp reusable so later SPEC targets do not reinstall the workspace unless the ISO or the prepare script changes. --- workloads/linux/spec2006/README.md | 53 +++++++++--------- .../linux/spec2006/prepare-spec-workspace.sh | 54 ++++++++++++++++++ workloads/linux/spec2006/rules.mk | 56 ++++++++++--------- 3 files changed, 113 insertions(+), 50 deletions(-) create mode 100755 workloads/linux/spec2006/prepare-spec-workspace.sh diff --git a/workloads/linux/spec2006/README.md b/workloads/linux/spec2006/README.md index e140e44..ca60c88 100644 --- a/workloads/linux/spec2006/README.md +++ b/workloads/linux/spec2006/README.md @@ -1,35 +1,31 @@ # SPEC CPU2006 Linux workload `workloads/linux/spec2006` now builds SPEC CPU2006 workloads with the original -SPEC tools (`runspec`) against an external SPEC installation. +SPEC tools (`runspec`) from a prepared workspace installed from a SPEC ISO. ## Build one case -Either point `SPEC` at the SPEC tree: +Point `SPEC2006_ISO` at the SPEC ISO: ```sh -make linux/spec2006 BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN -``` - -or pass `SPEC2006` explicitly: - -```sh -make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006=/path/to/cpu2006 -jN +make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN ``` `BENCH` may also be a full case name from `spec06.json`: ```sh -make linux/spec2006 BENCH=astar_biglakes SPEC=/path/to/cpu2006 -jN +make linux/spec2006 BENCH=astar_biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN ``` The build flow is: -1. Generate a build-local SPEC cfg copy under the case build directory. -2. Inject `output_root` into that cfg so SPEC build artifacts stay under this - repository instead of modifying the original SPEC installation. -3. Run `runspec --action build`. -4. Export the built SPEC ELF, package the benchmark plus input files into the +1. Run `make spec2006-prepare SPEC2006_ISO=/path/to/cpu2006.iso` to install a build-local + writable SPEC workspace under `build/linux-workloads/spec2006/spec-src`. +2. Generate a build-local SPEC cfg copy under the case build directory. +3. Inject `output_root` into that cfg so SPEC build artifacts stay under this + repository instead of modifying the prepared SPEC workspace. +4. Run `runspec --action build` inside the prepared workspace. +5. Export the built SPEC ELF, package the benchmark plus input files into the Linux rootfs, and produce: ```text @@ -41,15 +37,15 @@ build/linux-workloads/spec2006//fw_payload.bin Export all selected cases to `build/images/spec2006`: ```sh -make spec2006-images SPEC=/path/to/cpu2006 -jN +make spec2006-images SPEC2006_ISO=/path/to/cpu2006.iso -jN ``` By default, export builds only `ref` cases. Select another input set with `SPEC2006_INPUT`; use `all` to export every configured case: ```sh -make spec2006-images SPEC=/path/to/cpu2006 SPEC2006_INPUT=test -jN -make spec2006-images SPEC=/path/to/cpu2006 SPEC2006_INPUT=all -jN +make spec2006-images SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=test -jN +make spec2006-images SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=all -jN ``` Selected SPEC cases are built one by one to avoid concurrent `runspec` @@ -76,7 +72,7 @@ Override the destination with `SPEC2006_IMAGE_DIR=/path/to/image`. Build one case without packaging it into the Linux rootfs: ```sh -make spec2006-elf BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN +make spec2006-elf BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN ``` This writes: @@ -88,8 +84,8 @@ build/linux-workloads/spec2006//elf/.elf Build every selected case as ELF only: ```sh -make spec2006-elfs SPEC=/path/to/cpu2006 SPEC2006_INPUT=ref -jN -make spec2006-elfs SPEC=/path/to/cpu2006 SPEC2006_INPUT=all -jN +make spec2006-elfs SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=ref -jN +make spec2006-elfs SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=all -jN ``` If you only want the standalone ELF build flow, you can run it from this @@ -97,8 +93,8 @@ directory without the top-level Makefile: ```sh cd workloads/linux/spec2006 -make -f rules.mk spec2006-elf BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN -make -f rules.mk spec2006-elfs SPEC=/path/to/cpu2006 SPEC2006_INPUT=all -jN +make -f rules.mk spec2006-elf BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN +make -f rules.mk spec2006-elfs SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=all -jN ``` ## Configuration @@ -113,7 +109,7 @@ Override it with: ```sh make linux/spec2006 BENCH=bzip2_source \ - SPEC=/path/to/cpu2006 \ + SPEC2006_ISO=/path/to/cpu2006.iso \ SPEC2006_CFG=/path/to/other.cfg \ -jN ``` @@ -170,7 +166,14 @@ SPEC2006 builds keep console output concise. Detailed logs are written to: ## Notes -- The original SPEC tree is used read-only for sources and input data. +- The original SPEC ISO is used read-only as installation media. +- `runspec` is never executed against the original ISO contents; it only sees the + prepared workspace under `build/linux-workloads/spec2006/spec-src`. +- The prepared workspace is installed into a writable build directory before + any SPEC tools are executed. +- Installation staging uses a temporary local filesystem; override + `SPEC2006_PREPARE_TMPDIR` if `/tmp` is not suitable. +- `xorriso` is required to extract the SPEC ISO during `spec2006-prepare`. - Build logs, copied cfg files, build directories, and built executables are redirected into the case-local `runspec-output` directory via `output_root`. - The source cfg in this repository is never passed to `runspec` directly; diff --git a/workloads/linux/spec2006/prepare-spec-workspace.sh b/workloads/linux/spec2006/prepare-spec-workspace.sh new file mode 100755 index 0000000..4820b99 --- /dev/null +++ b/workloads/linux/spec2006/prepare-spec-workspace.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +set -euo pipefail + +source_spec_iso="$(realpath "$1")" +prepared_spec_root="$(realpath -m "$2")" + +prepare_dir="$(dirname "$prepared_spec_root")" +mkdir -p "$prepare_dir" +chmod -R u+rwX "$prepared_spec_root" 2>/dev/null || true +rm -rf "$prepared_spec_root" + +temp_root="" +cleanup() { + if [ -n "$temp_root" ]; then + chmod -R u+rwX "$temp_root" 2>/dev/null || true + rm -rf "$temp_root" 2>/dev/null || true + fi +} +trap cleanup EXIT + +if ! command -v xorriso >/dev/null 2>&1; then + echo "xorriso is required to extract $source_spec_iso" >&2 + exit 1 +fi + +tmp_parent="${SPEC2006_PREPARE_TMPDIR:-${TMPDIR:-/tmp}}" +mkdir -p "$tmp_parent" +temp_root="$(mktemp -d "$tmp_parent/spec-prepare.XXXXXX")" + +media_root="$temp_root/media" +staged_spec_root="$temp_root/spec-src" +mkdir -p "$media_root" + +xorriso -osirrox on -indev "$source_spec_iso" -extract / "$media_root" >/dev/null + +if ! [ -f "$media_root/install.sh" ]; then + echo "install.sh not found in $source_spec_iso" >&2 + exit 1 +fi + +( + cd "$media_root" + env -u SPEC sh ./install.sh -f -d "$staged_spec_root" +) + +mkdir -p "$prepared_spec_root" +cp -R "$staged_spec_root"/. "$prepared_spec_root"/ +chmod -R u+rwX "$prepared_spec_root" + +( + cd "$prepared_spec_root" + . ./shrc >/dev/null + bin/relocate >/dev/null +) diff --git a/workloads/linux/spec2006/rules.mk b/workloads/linux/spec2006/rules.mk index baf7c29..4b8c163 100644 --- a/workloads/linux/spec2006/rules.mk +++ b/workloads/linux/spec2006/rules.mk @@ -10,7 +10,11 @@ SPEC2006_CASE_CONFIG := $(SPEC2006_WORKLOAD_DIR)/spec06.json SPEC2006_CFG ?= $(SPEC2006_WORKLOAD_DIR)/riscv_gcc15_base.cfg SPEC2006_HELPER := $(SPEC2006_WORKLOAD_DIR)/spec2006-package.py SPEC2006_IMAGE_DIR ?= $(SPEC2006_REPO_ROOT)/build/images/spec2006 -SPEC2006_SPEC_ROOT := $(if $(SPEC2006),$(SPEC2006),$(SPEC)) +SPEC2006_SOURCE_SPEC_ISO := $(SPEC2006_ISO) +SPEC2006_PREPARED_SPEC_ROOT := $(SPEC2006_BUILD_DIR)/spec-src +SPEC2006_SOURCE_SPEC_HASH := $(shell printf '%s\n' "$(SPEC2006_SOURCE_SPEC_ISO)" | sha256sum | cut -d ' ' -f 1) +SPEC2006_PREPARE_STAMP := $(SPEC2006_BUILD_DIR)/spec-src.$(SPEC2006_SOURCE_SPEC_HASH).prepared +SPEC2006_PREPARE_SCRIPT := $(SPEC2006_WORKLOAD_DIR)/prepare-spec-workspace.sh SPEC2006_CROSS_COMPILE ?= riscv64-unknown-linux-gnu- SPEC2006_COMPILER_ROOT ?= SPEC2006_GNU_TOOLCHAIN_ROOT ?= @@ -40,19 +44,14 @@ SPEC2006_DEFAULT_DTB_STAMP := $(SPEC2006_BUILD_DIR)/dtb.$(shell printf '%s\n' "$ WORKLOAD_DIRS += $(SPEC2006_BUILD_DIR) -spec2006-check-spec-dir: - @if [ -z "$(SPEC2006_SPEC_ROOT)" ]; then \ - echo "SPEC or SPEC2006 is required, for example:"; \ - echo " make linux/spec2006 BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN"; \ - echo " make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006=/path/to/cpu2006 -jN"; \ +spec2006-check-spec-iso: + @if [ -z "$(SPEC2006_SOURCE_SPEC_ISO)" ]; then \ + echo "SPEC2006_ISO is required, for example:"; \ + echo " make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \ exit 1; \ fi; \ - if ! [ -d "$(SPEC2006_SPEC_ROOT)" ]; then \ - echo "SPEC path does not exist or is not a directory: $(SPEC2006_SPEC_ROOT)"; \ - exit 1; \ - fi; \ - if ! [ -x "$(SPEC2006_SPEC_ROOT)/bin/runspec" ]; then \ - echo "runspec not found under $(SPEC2006_SPEC_ROOT)/bin/runspec"; \ + if ! [ -f "$(SPEC2006_SOURCE_SPEC_ISO)" ]; then \ + echo "SPEC ISO path does not exist: $(SPEC2006_SOURCE_SPEC_ISO)"; \ exit 1; \ fi; \ if ! [ -f "$(SPEC2006_CFG)" ]; then \ @@ -68,6 +67,13 @@ spec2006-check-spec-dir: *) echo "SPEC2006_INPUT must be one of: ref, train, test, all"; exit 1 ;; \ esac +spec2006-prepare: $(SPEC2006_PREPARE_STAMP) + +$(SPEC2006_PREPARE_STAMP): $(SPEC2006_PREPARE_SCRIPT) $(SPEC2006_SOURCE_SPEC_ISO) | spec2006-check-spec-iso + @printf '$(SPEC2006_PROGRESS_PREFIX) Preparing SPEC workspace at $(SPEC2006_PREPARED_SPEC_ROOT)\n' + @bash "$(SPEC2006_PREPARE_SCRIPT)" "$(SPEC2006_SOURCE_SPEC_ISO)" "$(SPEC2006_PREPARED_SPEC_ROOT)" + @touch "$@" + $(SPEC2006_DEFAULT_DTB_STAMP): @mkdir -p "$(@D)" @rm -f "$(SPEC2006_BUILD_DIR)"/dtb.* @@ -78,7 +84,7 @@ $(SPEC2006_BUILD_DIR)/$(1)/download/sentinel: @mkdir -p $$(@D) @touch $$@ -$(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: spec2006-check-spec-dir $$(SPEC2006_HELPER) $$(SPEC2006_WORKLOAD_DIR)/build.sh $$(SPEC2006_CASE_CONFIG) $$(SPEC2006_CFG) +$(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: $(SPEC2006_PREPARE_STAMP) $$(SPEC2006_HELPER) $$(SPEC2006_WORKLOAD_DIR)/build.sh $$(SPEC2006_CASE_CONFIG) $$(SPEC2006_CFG) @mkdir -p "$$(dir $$@)" @WORKLOAD_DIR="$$(abspath $$(SPEC2006_WORKLOAD_DIR))" \ WORKLOAD_BUILD_DIR="$$(abspath $(SPEC2006_BUILD_DIR)/$(1))" \ @@ -87,7 +93,7 @@ $(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: spec2006-check-spec-dir $$(SPEC2006_HEL SPEC2006_PROGRESS_K="$$(SPEC2006_PROGRESS_K)" \ SPEC2006_PROGRESS_N="$$(SPEC2006_PROGRESS_N)" \ SPEC2006_CASE="$(1)" \ - SPEC2006="$$(SPEC2006_SPEC_ROOT)" \ + SPEC2006="$$(SPEC2006_PREPARED_SPEC_ROOT)" \ SPEC2006_CASE_CONFIG="$$(abspath $$(SPEC2006_CASE_CONFIG))" \ SPEC2006_CFG="$$(abspath $$(SPEC2006_CFG))" \ SPEC2006_COMPILER_ROOT="$$(SPEC2006_COMPILER_ROOT)" \ @@ -98,12 +104,12 @@ $(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: spec2006-check-spec-dir $$(SPEC2006_HEL SPEC2006_ELF_ONLY=1 \ bash "$$(abspath $$(SPEC2006_WORKLOAD_DIR))/build.sh" -$(SPEC2006_BUILD_DIR)/$(1)/rootfs.cpio: spec2006-check-spec-dir $$(SPEC2006_HELPER) $$(SPEC2006_WORKLOAD_DIR)/build.sh $$(SPEC2006_CASE_CONFIG) $$(SPEC2006_CFG) $(SPEC2006_BUILD_DIR)/$(1)/download/sentinel $$(SPEC2006_SCRIPTS_DIR)/build-workload-linux.sh +$(SPEC2006_BUILD_DIR)/$(1)/rootfs.cpio: $(SPEC2006_PREPARE_STAMP) $$(SPEC2006_HELPER) $$(SPEC2006_WORKLOAD_DIR)/build.sh $$(SPEC2006_CASE_CONFIG) $$(SPEC2006_CFG) $(SPEC2006_BUILD_DIR)/$(1)/download/sentinel $$(SPEC2006_SCRIPTS_DIR)/build-workload-linux.sh @CROSS_COMPILE="$$(SPEC2006_CROSS_COMPILE)" \ SPEC2006_PROGRESS_K="$$(SPEC2006_PROGRESS_K)" \ SPEC2006_PROGRESS_N="$$(SPEC2006_PROGRESS_N)" \ SPEC2006_CASE="$(1)" \ - SPEC2006="$$(SPEC2006_SPEC_ROOT)" \ + SPEC2006="$$(SPEC2006_PREPARED_SPEC_ROOT)" \ SPEC2006_CASE_CONFIG="$$(abspath $$(SPEC2006_CASE_CONFIG))" \ SPEC2006_CFG="$$(abspath $$(SPEC2006_CFG))" \ SPEC2006_COMPILER_ROOT="$$(SPEC2006_COMPILER_ROOT)" \ @@ -145,23 +151,23 @@ endef $(foreach case,$(SPEC2006_ALL_CASES),$(eval $(call add_spec2006_case,$(case)))) -linux/spec2006: spec2006-check-spec-dir +linux/spec2006: spec2006-check-spec-iso @if [ -z "$(BENCH)" ]; then \ - echo "Usage: make linux/spec2006 BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN"; \ - echo " or: make linux/spec2006 BENCH=astar_biglakes SPEC=/path/to/cpu2006 -jN"; \ + echo "Usage: make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \ + echo " or: make linux/spec2006 BENCH=astar_biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \ exit 1; \ fi @$(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" GCPT_DEFAULT_DTB="$(SPEC2006_DEFAULT_DTB)" $(SPEC2006_BUILD_DIR)/$(SPEC2006_CASE)/fw_payload.bin -spec2006-elf: spec2006-check-spec-dir +spec2006-elf: spec2006-check-spec-iso @if [ -z "$(BENCH)" ]; then \ - echo "Usage: make spec2006-elf BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN"; \ - echo " or: make spec2006-elf BENCH=astar_biglakes SPEC=/path/to/cpu2006 -jN"; \ + echo "Usage: make spec2006-elf BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \ + echo " or: make spec2006-elf BENCH=astar_biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \ exit 1; \ fi @$(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" $(SPEC2006_BUILD_DIR)/$(SPEC2006_CASE)/elf/$(SPEC2006_CASE).elf -spec2006-elfs: spec2006-check-spec-dir +spec2006-elfs: spec2006-check-spec-iso @if [ -z "$(SPEC2006_SELECTED_CASES)" ]; then \ echo "No SPEC2006 cases selected by SPEC2006_INPUT=$(SPEC2006_INPUT)"; \ exit 1; \ @@ -170,7 +176,7 @@ spec2006-elfs: spec2006-check-spec-dir $(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" "$(SPEC2006_BUILD_DIR)/$$case/elf/$$case.elf" || exit $$?; \ done -spec2006-images: spec2006-check-spec-dir +spec2006-images: spec2006-check-spec-iso @if [ -z "$(SPEC2006_IMAGE_CASES)" ]; then \ echo "No SPEC2006 cases selected by SPEC2006_INPUT=$(SPEC2006_INPUT)"; \ exit 1; \ @@ -183,4 +189,4 @@ spec2006-images: spec2006-check-spec-dir done @printf '[spec2006 %s/%s] Output written to %s\n' "$(words $(SPEC2006_IMAGE_CASES))" "$(words $(SPEC2006_IMAGE_CASES))" "$(abspath $(SPEC2006_IMAGE_DIR))" -.PHONY: linux/spec2006 spec2006-check-spec-dir spec2006-elf spec2006-elfs spec2006-images +.PHONY: linux/spec2006 spec2006-check-spec-iso spec2006-prepare spec2006-elf spec2006-elfs spec2006-images