build: phase 2 pilot — pci-bus builds as a package

build-support gains the domains-based userBinary: the default import set
(the library/kernel concern modules, driver/service clients, mmio,
acpi-ids, xkeyboard-config) is assembled from the domain packages, and
the root shim + user link script come from the kernel package directory.
system/drivers/pci-bus is the first binary package: a ~15-line
declarative build.zig naming only its extras (device-manager-protocol,
pci-class); the root build consumes the artifact for the boot image and
the driver also builds standalone from its own directory. Boot-image
file list unchanged.
This commit is contained in:
Daniel Samson
2026-07-26 22:55:47 +01:00
parent 721288c516
commit 6f4fdc2789
5 changed files with 116 additions and 5 deletions
+75
View File
@@ -113,3 +113,78 @@ pub fn userBinaryFromImports(b: *std.Build, options: UserBinaryOptions) *std.Bui
pub fn programModule(exe: *std.Build.Step.Compile) *std.Build.Module {
return exe.root_module.import_table.get("program").?;
}
/// The library domain packages a user binary's default import set draws from.
/// A binary package declares these in its build.zig.zon under exactly these
/// dependency names (kernel, device, client, xkeyboard-config) and resolves
/// them with `domains`. Path dependencies deduplicate by resolved location,
/// so every binary and the root build share one instance of each module.
pub const Domains = struct {
kernel: *std.Build.Dependency,
device: *std.Build.Dependency,
client: *std.Build.Dependency,
xkeyboard_config: *std.Build.Dependency,
};
/// Resolve the four default-set domain packages by their conventional
/// dependency names — the one-liner for a binary package's build fn.
pub fn domains(b: *std.Build) Domains {
return .{
.kernel = b.dependency("kernel", .{}),
.device = b.dependency("device", .{}),
.client = b.dependency("client", .{}),
.xkeyboard_config = b.dependency("xkeyboard-config", .{}),
};
}
/// What `userBinary` needs to know about one user binary. The domain wiring
/// (default imports, root shim, link script, target) is derived.
pub const DomainUserBinaryOptions = struct {
name: []const u8,
/// The program's own source file — it becomes the `program` module.
root_source_file: std.Build.LazyPath,
domains: Domains,
/// See UserBinaryOptions.threaded.
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{
.{ .name = "mmio", .module = device.module("mmio") },
.{ .name = "xkeyboard-config", .module = options.domains.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") },
.{ .name = "memory", .module = kernel.module("memory") },
.{ .name = "process", .module = kernel.module("process") },
.{ .name = "thread", .module = kernel.module("thread") },
.{ .name = "time", .module = kernel.module("time") },
.{ .name = "logging", .module = kernel.module("logging") },
.{ .name = "file-system", .module = kernel.module("file-system") },
.{ .name = "service", .module = kernel.module("service") },
.{ .name = "start", .module = kernel.module("start") },
.{ .name = "driver", .module = device.module("driver") },
.{ .name = "block", .module = device.module("block") },
.{ .name = "display", .module = client.module("display") },
.{ .name = "input", .module = client.module("input") },
};
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"),
.target = freestandingTarget(b),
.default_imports = &default_imports,
.threaded = options.threaded,
});
}