build: single-source the default import set; delegate library tests

Review findings from the pilot: the 17-module default import set was
maintained twice (root's array and build-support's userBinary) — drift
would silently make packaged binaries differ from root-built ones. It
now lives once, as build-support.defaultImports; root and userBinary
both draw from it, and root's user-binary wrapper names the shim +
link script through the kernel package like build-support does.
The root aggregate test step likewise duplicated the library domains'
14 test definitions; it now depends on each domain's own standalone
test step (host-only, so root's -Dtarget/-Doptimize deliberately do
not reach them), and the client domain gains an empty test step for
uniformity. Boot-image file list unchanged.
This commit is contained in:
Daniel Samson
2026-07-26 23:10:10 +01:00
parent 6f4fdc2789
commit 15575960bd
3 changed files with 63 additions and 127 deletions
+24 -15
View File
@@ -148,20 +148,20 @@ pub const DomainUserBinaryOptions = struct {
threaded: bool = false,
};
/// Build one user binary against the domain packages' default import set —
/// the library/kernel concern modules (ipc, memory, process, time, logging,
/// file-system, ...), the device/service clients (driver, block, display,
/// input), mmio, acpi-ids, and xkeyboard-config. Per-binary extras go through
/// `programModule(exe).addImport`. This is THE recipe a binary package's
/// build.zig calls; the root shim and user link script come from the kernel
/// domain package's directory.
pub fn userBinary(b: *std.Build, options: DomainUserBinaryOptions) *std.Build.Step.Compile {
const kernel = options.domains.kernel;
const device = options.domains.device;
const client = options.domains.client;
const default_imports = [_]std.Build.Module.Import{
/// THE default import set every user binary sees — the library/kernel concern
/// modules (ipc, memory, process, time, logging, file-system, ...), the
/// device/service clients (driver, block, display, input), mmio, acpi-ids,
/// and xkeyboard-config — assembled from the domain packages. This is the
/// single authoritative list: the root build's stanzas and every binary
/// package both draw from here, so adding a default module is a one-place
/// change (the cross-cutting rule, docs/build-packages-plan.md).
pub fn defaultImports(libraries: Domains) [17]std.Build.Module.Import {
const kernel = libraries.kernel;
const device = libraries.device;
const client = libraries.client;
return .{
.{ .name = "mmio", .module = device.module("mmio") },
.{ .name = "xkeyboard-config", .module = options.domains.xkeyboard_config.module("xkeyboard-config") },
.{ .name = "xkeyboard-config", .module = libraries.xkeyboard_config.module("xkeyboard-config") },
.{ .name = "acpi-ids", .module = device.module("acpi-ids") },
.{ .name = "system-call", .module = kernel.module("system-call") },
.{ .name = "ipc", .module = kernel.module("ipc") },
@@ -178,11 +178,20 @@ pub fn userBinary(b: *std.Build, options: DomainUserBinaryOptions) *std.Build.St
.{ .name = "display", .module = client.module("display") },
.{ .name = "input", .module = client.module("input") },
};
}
/// Build one user binary against the domain packages' default import set
/// (`defaultImports`). Per-binary extras go through
/// `programModule(exe).addImport`. This is THE recipe a binary package's
/// build.zig calls; the root shim and user link script come from the kernel
/// domain package's directory.
pub fn userBinary(b: *std.Build, options: DomainUserBinaryOptions) *std.Build.Step.Compile {
const default_imports = defaultImports(options.domains);
return userBinaryFromImports(b, .{
.name = options.name,
.root_source_file = options.root_source_file,
.shim_source_file = kernel.path("root.zig"),
.linker_script = kernel.path("user.ld"),
.shim_source_file = options.domains.kernel.path("root.zig"),
.linker_script = options.domains.kernel.path("user.ld"),
.target = freestandingTarget(b),
.default_imports = &default_imports,
.threaded = options.threaded,