authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-01 14:35:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-07-01 14:35:04-07:00
log554172e6258db4b391d31636ac9274a433f2f401
tree20635622b7217c59f20019072d013c5488bbf752
parent18a568ca576d5e4f8051c5e337563a0c8cc52b04

std.Build: restore `dependency` function

Now it supports lazy dependencies and if it needs to be fetched then it will serialize the configuration and early-exit.

1 files changed, 32 insertions(+), 31 deletions(-)

lib/std/Build.zig+32-31
......@@ -2119,21 +2119,21 @@ pub fn lazyDependency(b: *Build, name: []const u8, args: anytype) ?*Dependency {
21192119 };
21202120}
21212121
2122/// When this function is called, it means that the current build does, in
2123/// fact, require this dependency. If the dependency is already fetched, it is
2124/// returned. However if the dependency is not yet fetched, then when the build
2125/// script is finished running, the toolchain will not proceed to the make phase.
2126/// Instead, the parent process will additionally fetch all the lazy
2127/// dependencies that were actually required by running the build script,
2128/// recompile the build script, and then run it again. In other words, if this
2129/// function returns `error.LazyDependencyNeeded` it means that the only
2130/// purpose of completing the configure phase is to find out all the other lazy
2131/// dependencies that are also required. In this case, one must propagate the
2132/// error all the way up and return it from the main build function.
2122/// Declares that the current configuration does in fact require a potentially
2123/// lazy dependency.
21332124///
2134/// For non-lazy dependencies, this always succeeds.
2125/// If the dependency is already fetched, it is returned. However if the
2126/// dependency is not yet fetched, then when the build script is finished
2127/// running, the toolchain will not proceed to the make phase. Instead, the
2128/// parent process will additionally fetch all the lazy dependencies that were
2129/// actually required by running the build script, recompile the build script,
2130/// and then run it again. In other words, if this function returns
2131/// `error.LazyDependencyNeeded` it means that the only purpose of completing
2132/// the configure phase is to find out all the other lazy dependencies that are
2133/// also required. In this case, one must propagate the error all the way up
2134/// and return it from the main build function.
21352135///
2136/// This function will be eventually renamed to `dependency`.
2136/// For non-lazy dependencies, this always succeeds.
21372137pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDependencyNeeded}!*Dependency {
21382138 const build_runner = @import("root");
21392139 const deps = build_runner.dependencies;
......@@ -2154,24 +2154,25 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe
21542154 unreachable; // bad @dependencies source
21552155}
21562156
2157/// Deprecated in favor of `dependencyLazy`. To get the same behavior as before, use `try` to propagate
2158/// the potential `error.LazyDependencyNeeded` all the way out of your main build function.
2157/// Declares that the current configuration does in fact require a potentially
2158/// lazy dependency.
2159///
2160/// If the dependency is already fetched, it is returned. Otherwise, exits the
2161/// configuration phase with intent to fetch the lazy dependency and rerun the
2162/// configuration script.
2163///
2164/// If it is known to the caller at this point that additional lazy
2165/// dependencies are also required, it would save time to call `dependencyLazy`
2166/// instead, handling `error.LazyDependencyNeeded` in a way that marks multiple
2167/// potentially lazy dependencies as required before eventually returning
2168/// that error from the top level build function.
21592169pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency {
2160 const build_runner = @import("root");
2161 const deps = build_runner.dependencies;
2162 const pkg_hash = findPkgHashOrFatal(b, name);
2163
2164 inline for (@typeInfo(deps.packages).@"struct".decl_names) |decl_name| {
2165 if (mem.eql(u8, decl_name, pkg_hash)) {
2166 const pkg = @field(deps.packages, decl_name);
2167 if (@hasDecl(pkg, "available")) {
2168 panic("dependency '{s}{s}' is marked as lazy in build.zig.zon which means it must use the lazyDependency function instead", .{ b.dep_prefix, name });
2169 }
2170 return dependencyInner(b, name, pkg.build_root, if (@hasDecl(pkg, "build_zig")) pkg.build_zig else null, pkg_hash, pkg.deps, args);
2171 }
2172 }
2173
2174 unreachable; // Bad @dependencies source
2170 return dependencyLazy(b, name, args) catch |err| switch (err) {
2171 error.LazyDependencyNeeded => {
2172 assert(b.graph.needed_lazy_dependencies.count() != 0);
2173 serializeConfigurationExiting(b);
2174 },
2175 };
21752176}
21762177
21772178/// In a build.zig file, this function is to `@import` what `lazyDependency` is to `dependency`.
......@@ -2840,7 +2841,7 @@ fn validateConfigureDependency(lazy_path: LazyPath) void {
28402841}
28412842
28422843/// Build system implementation detail.
2843pub fn serializeConfigurationExiting(b: *Build) void {
2844pub fn serializeConfigurationExiting(b: *Build) noreturn {
28442845 const graph = b.graph;
28452846 const io = graph.io;
28462847