aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-02-02 14:42:29 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-02-02 20:43:01 -0700
commit252f4ab2a509c5b8b2e570f4a0de6cb706dd9588 (patch)
treee195a777f8c28b81041d925495d66ffa4dad680a /src/main.zig
parent434a6a4f633f3f9b29bd80f4089e8f403aab4f9b (diff)
downloadzig-252f4ab2a509c5b8b2e570f4a0de6cb706dd9588.tar.gz
zig-252f4ab2a509c5b8b2e570f4a0de6cb706dd9588.zip
build system: implement lazy dependencies, part 1
Build manifest files support `lazy: true` for dependency sections. This causes the auto-generated dependencies.zig to have 2 more possibilities: 1. It communicates whether a dependency is lazy or not. 2. The dependency might be acknowledged, but missing due to being lazy and not fetched. Lazy dependencies are not fetched by default, but if they are already fetched then they are provided to the build script. The build runner reports the set of missing lazy dependenices that are required to the parent process via stdout and indicates the situation with exit code 3. std.Build now has a `lazyDependency` function. I'll let the doc comments speak for themselves: When this function is called, it means that the current build does, in fact, require this dependency. If the dependency is already fetched, it proceeds in the same manner as `dependency`. However if the dependency was not fetched, then when the build script is finished running, the build will not proceed to the make phase. Instead, the parent process will additionally fetch all the lazy dependencies that were actually required by running the build script, rebuild the build script, and then run it again. In other words, if this function returns `null` it means that the only purpose of completing the configure phase is to find out all the other lazy dependencies that are also required. It is allowed to use this function for non-lazy dependencies, in which case it will never return `null`. This allows toggling laziness via build.zig.zon without changing build.zig logic. The CLI for `zig build` detects this situation, but the logic for then redoing the build process with these extra dependencies fetched is not yet implemented.
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/main.zig b/src/main.zig
index 7e2827bc69..07da3b2725 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -5464,6 +5464,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
.location = .{ .relative_path = build_mod.root },
.location_tok = 0,
.hash_tok = 0,
+ .name_tok = 0,
+ .lazy_status = .eager,
.parent_package_root = build_mod.root,
.parent_manifest_ast = null,
.prog_node = root_prog_node,
@@ -5618,10 +5620,14 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
if (process.can_spawn) {
var child = std.ChildProcess.init(child_argv, gpa);
child.stdin_behavior = .Inherit;
- child.stdout_behavior = .Inherit;
+ child.stdout_behavior = .Pipe;
child.stderr_behavior = .Inherit;
- const term = try child.spawnAndWait();
+ try child.spawn();
+ // Since only one output stream is piped, we can simply do a blocking
+ // read until the stream is finished.
+ const stdout = try child.stdout.?.readToEndAlloc(arena, 50 * 1024 * 1024);
+ const term = try child.wait();
switch (term) {
.Exited => |code| {
if (code == 0) return cleanExit();
@@ -5630,6 +5636,15 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
// diagnostics.
if (code == 2) process.exit(2);
+ if (code == 3) {
+ // Indicates the configure phase failed due to missing lazy
+ // dependencies and stdout contains the hashes of the ones
+ // that are missing.
+ std.debug.print("missing lazy dependencies: '{s}'\n", .{stdout});
+ std.debug.print("TODO: fetch them and rebuild the build script\n", .{});
+ process.exit(1);
+ }
+
const cmd = try std.mem.join(arena, " ", child_argv);
fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
},
@@ -7395,6 +7410,8 @@ fn cmdFetch(
.location = .{ .path_or_url = path_or_url },
.location_tok = 0,
.hash_tok = 0,
+ .name_tok = 0,
+ .lazy_status = .eager,
.parent_package_root = undefined,
.parent_manifest_ast = null,
.prog_node = root_prog_node,