build: keep test fixtures out of a no-option build
A plain `zig build` was baking all 11 /test/system/services fixtures into the production image. Split the bundle: the production set always, the userspace test fixtures only when -Dtest-case is set — which the QEMU harness passes for every scenario, exactly when the fixtures are needed on the boot volume. So `zig build` with no options now ships a clean image (no test binaries in the manifest, capsule, or FAT tree) and assumes neither -Dtest-case nor -Ddiagnose (the diagnose display-omission was already gated by the init.csv selection). Verified: a plain build has zero /test entries in the manifest; -Dtest-case=smoke includes all fixtures; the args/vfs/device-list QEMU scenarios still pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KJqSiLLchDUUCoXn5jsiwd
This commit is contained in:
@@ -773,7 +773,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
// variant that omits the display stack (so the kernel's boot transcript stays
|
// variant that omits the display stack (so the kernel's boot transcript stays
|
||||||
// on screen); both are bundled at the same /etc/init.csv path.
|
// on screen); both are bundled at the same /etc/init.csv path.
|
||||||
const init_csv_source = if (diagnose) "etc/init-diagnose.csv" else "etc/init.csv";
|
const init_csv_source = if (diagnose) "etc/init-diagnose.csv" else "etc/init.csv";
|
||||||
const bundled = [_]BundledBinary{
|
const production_bundled = [_]BundledBinary{
|
||||||
.{ .path = "system/services/init", .binary = init_exe.getEmittedBin() },
|
.{ .path = "system/services/init", .binary = init_exe.getEmittedBin() },
|
||||||
.{ .path = "system/services/fat", .binary = fat_exe.getEmittedBin() },
|
.{ .path = "system/services/fat", .binary = fat_exe.getEmittedBin() },
|
||||||
.{ .path = "system/services/display", .binary = display_exe.getEmittedBin() },
|
.{ .path = "system/services/display", .binary = display_exe.getEmittedBin() },
|
||||||
@@ -798,6 +798,13 @@ pub fn build(b: *std.Build) void {
|
|||||||
.{ .path = "system/drivers/usb-storage", .binary = usb_storage_exe.getEmittedBin() },
|
.{ .path = "system/drivers/usb-storage", .binary = usb_storage_exe.getEmittedBin() },
|
||||||
.{ .path = "system/drivers/virtio-gpu", .binary = virtio_gpu_exe.getEmittedBin() },
|
.{ .path = "system/drivers/virtio-gpu", .binary = virtio_gpu_exe.getEmittedBin() },
|
||||||
.{ .path = "system/drivers/pci-bus", .binary = pci_bus_exe.getEmittedBin() },
|
.{ .path = "system/drivers/pci-bus", .binary = pci_bus_exe.getEmittedBin() },
|
||||||
|
};
|
||||||
|
// The userspace test fixtures under /test. A plain `zig build` produces a clean
|
||||||
|
// image WITHOUT them; they are bundled only for a test build — which the QEMU
|
||||||
|
// harness signals by passing -Dtest-case=<name> for every scenario, exactly when
|
||||||
|
// these fixtures must be on the boot volume. Merely building this array never
|
||||||
|
// forces a compile: the fixture exes build only if `bundled` (below) includes them.
|
||||||
|
const test_bundled = [_]BundledBinary{
|
||||||
.{ .path = "test/system/services/vfs-test", .binary = vfstest_exe.getEmittedBin() },
|
.{ .path = "test/system/services/vfs-test", .binary = vfstest_exe.getEmittedBin() },
|
||||||
.{ .path = "test/system/services/fat-test", .binary = fat_test_exe.getEmittedBin() },
|
.{ .path = "test/system/services/fat-test", .binary = fat_test_exe.getEmittedBin() },
|
||||||
.{ .path = "test/system/services/shared-memory-server", .binary = shared_memory_server_exe.getEmittedBin() },
|
.{ .path = "test/system/services/shared-memory-server", .binary = shared_memory_server_exe.getEmittedBin() },
|
||||||
@@ -810,6 +817,13 @@ pub fn build(b: *std.Build) void {
|
|||||||
.{ .path = "test/system/services/process-test", .binary = process_test_exe.getEmittedBin() },
|
.{ .path = "test/system/services/process-test", .binary = process_test_exe.getEmittedBin() },
|
||||||
.{ .path = "test/system/services/thread-test", .binary = thread_test_exe.getEmittedBin() },
|
.{ .path = "test/system/services/thread-test", .binary = thread_test_exe.getEmittedBin() },
|
||||||
};
|
};
|
||||||
|
// A no-option build assumes neither -Dtest-case nor -Ddiagnose: it ships the
|
||||||
|
// production set only. Test fixtures join in only under -Dtest-case; the
|
||||||
|
// diagnose display-omission is already handled by init_csv_source above.
|
||||||
|
var bundled_list: std.ArrayListUnmanaged(BundledBinary) = .empty;
|
||||||
|
bundled_list.appendSlice(b.allocator, &production_bundled) catch @panic("OOM");
|
||||||
|
if (test_case != null) bundled_list.appendSlice(b.allocator, &test_bundled) catch @panic("OOM");
|
||||||
|
const bundled = bundled_list.items;
|
||||||
|
|
||||||
// The boot manifest: the FHS path of every bundled binary, one per line. The
|
// The boot manifest: the FHS path of every bundled binary, one per line. The
|
||||||
// EFI loader reads THIS by name and opens each listed path by name — FAT
|
// EFI loader reads THIS by name and opens each listed path by name — FAT
|
||||||
@@ -892,7 +906,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
// binaries at their FHS paths. QEMU presents this image as a USB mass-storage
|
// binaries at their FHS paths. QEMU presents this image as a USB mass-storage
|
||||||
// device the guest boots from (see run-x86-64 and the test harness), and the
|
// device the guest boots from (see run-x86-64 and the test harness), and the
|
||||||
// danos fat driver mounts the same image at /mnt/usb.
|
// danos fat driver mounts the same image at /mnt/usb.
|
||||||
const fat_image = addBootImage(b, exe.getEmittedBin(), efiexe.getEmittedBin(), manifest_file, capsule_img, &bundled);
|
const fat_image = addBootImage(b, exe.getEmittedBin(), efiexe.getEmittedBin(), manifest_file, capsule_img, bundled);
|
||||||
const fat_image_install = b.addInstallFile(fat_image, "danos-usb.img");
|
const fat_image_install = b.addInstallFile(fat_image, "danos-usb.img");
|
||||||
b.getInstallStep().dependOn(&fat_image_install.step);
|
b.getInstallStep().dependOn(&fat_image_install.step);
|
||||||
|
|
||||||
@@ -901,7 +915,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
// log captured to serial0 — without baking serial into the image users flash.
|
// log captured to serial0 — without baking serial into the image users flash.
|
||||||
// Built lazily (only when `run-x86-64` is requested), and never installed.
|
// Built lazily (only when `run-x86-64` is requested), and never installed.
|
||||||
const exe_serial = addKernel(b, kernel_target, optimize, kernel_modules, test_case, true);
|
const exe_serial = addKernel(b, kernel_target, optimize, kernel_modules, test_case, true);
|
||||||
const fat_image_serial = addBootImage(b, exe_serial.getEmittedBin(), efiexe.getEmittedBin(), manifest_file, capsule_img, &bundled);
|
const fat_image_serial = addBootImage(b, exe_serial.getEmittedBin(), efiexe.getEmittedBin(), manifest_file, capsule_img, bundled);
|
||||||
|
|
||||||
// `zig build check-fat-image` — validate the produced image is a real FAT32
|
// `zig build check-fat-image` — validate the produced image is a real FAT32
|
||||||
// with the EFI stub present (the builder's own --verify, no external tools).
|
// with the EFI stub present (the builder's own --verify, no external tools).
|
||||||
|
|||||||
Reference in New Issue
Block a user