authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-10-10 00:40:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-24 23:10:20+02:00
log723085b9bf47f26ee8a91aa10b3859e2946034e9
tree663ccf35d30fd69c08553e37a4991c60c38a5fa5
parent680ab55488798be67fd1744f69045b41580def07

Build: fetch pending lazy dependencies and retry when artifact/etc is not found

Before the changes in this commit, the intention was to gather all pending lazy dependencies of all package scripts, and then only handle fetching after the root package script exits. However, that's not always feasible, since it's possible for a lazy dependency to depend on a lazy dependency, which means that the first fetch-and-retry can only know about the root's lazy dependencies. Then, during the second attempt at configuring, the root package script will see its lazy dependency as available, but in reality that dependency's package script may return error.LazyDependencyNeeded, which won't matter until *after* the root package script has finished running. Therefore, the root package script will continue running as if its lazy dependency is fully available, when in reality it has requested a fetch-and-retry. This means that something like an `artifact` call in the root package script that depends on a lazy dependency of a lazy dependency will fail after the first fetch-and-retry, because the necessary remaining pending lazy dependencies would only get fetched once the root script finished. In case it's helpful, the reproduction looks something like this: root └─ child1 (.lazy = true, gotten in root's build.zig via either `dependency` or `try dependencyLazy`) └─ child2 (.lazy = true, gotten in child1's build.zig via `try dependencyLazy`) To fix this, whenever an artifact/module/etc is looked up and not found while there are pending lazy dependencies, we now immediately exit, fetch, and retry, since that artifact/module/etc could only exist after one of those pending lazy dependencies is made available (i.e. the dependency's configuration stopped part-way due to a missing lazy dependency). Before (fails): > zig build debug(fetch): FileNotFound: zig-pkg\zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN debug(fetch): FileNotFound: C:\Users\Ryan\AppData\Local\zig\p/zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN.tar.gz debug: configuration cache incomplete_manifest info: fetching lazy dependency zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN debug(fetch): FileNotFound: zig-pkg\zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN debug(fetch): FileNotFound: C:\Users\Ryan\AppData\Local\zig\p/zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN.tar.gz debug(fetch): FileNotFound: zig-pkg\zig_test_repo2-0.0.0-eVW_ihsPAAAmwffTitFedoK7HGHiRfQTshvARXs0-qJx debug(fetch): FileNotFound: C:\Users\Ryan\AppData\Local\zig\p/zig_test_repo2-0.0.0-eVW_ihsPAAAmwffTitFedoK7HGHiRfQTshvARXs0-qJx.tar.gz debug: configuration cache incomplete_manifest panic: unable to find artifact "zig_test_repo1_lib" After (succeeds): > zig build debug(fetch): FileNotFound: zig-pkg\zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN debug(fetch): FileNotFound: C:\Users\Ryan\AppData\Local\zig\p/zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN.tar.gz debug: configuration cache incomplete_manifest info: fetching lazy dependency zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN debug(fetch): FileNotFound: zig-pkg\zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN debug(fetch): FileNotFound: C:\Users\Ryan\AppData\Local\zig\p/zig_test_repo1-0.0.0-FuDjYawXAAAK0sFpnAa7IPMoTJpCs44sgfKP7ZBi3oAN.tar.gz debug(fetch): FileNotFound: zig-pkg\zig_test_repo2-0.0.0-eVW_ihsPAAAmwffTitFedoK7HGHiRfQTshvARXs0-qJx debug(fetch): FileNotFound: C:\Users\Ryan\AppData\Local\zig\p/zig_test_repo2-0.0.0-eVW_ihsPAAAmwffTitFedoK7HGHiRfQTshvARXs0-qJx.tar.gz debug: configuration cache incomplete_manifest info: fetching lazy dependency zig_test_repo2-0.0.0-eVW_ihsPAAAmwffTitFedoK7HGHiRfQTshvARXs0-qJx debug(fetch): FileNotFound: zig-pkg\zig_test_repo2-0.0.0-eVW_ihsPAAAmwffTitFedoK7HGHiRfQTshvARXs0-qJx debug(fetch): FileNotFound: C:\Users\Ryan\AppData\Local\zig\p/zig_test_repo2-0.0.0-eVW_ihsPAAAmwffTitFedoK7HGHiRfQTshvARXs0-qJx.tar.gz debug: configuration cache incomplete_manifest

1 files changed, 12 insertions(+), 0 deletions(-)

lib/std/Build.zig+12
...@@ -1867,6 +1867,9 @@ pub const Dependency = struct {...@@ -1867,6 +1867,9 @@ pub const Dependency = struct {
1867 }1867 }
1868 }1868 }
1869 return found orelse {1869 return found orelse {
1870 if (d.builder.graph.unlazy_deps.count() != 0) {
1871 d.builder.serializeConfigurationExiting();
1872 }
1870 for (d.builder.install_tls.step.dependencies.items) |dep_step| {1873 for (d.builder.install_tls.step.dependencies.items) |dep_step| {
1871 const inst = dep_step.cast(Step.InstallArtifact) orelse continue;1874 const inst = dep_step.cast(Step.InstallArtifact) orelse continue;
1872 log.info("available artifact: {q}", .{inst.artifact.name});1875 log.info("available artifact: {q}", .{inst.artifact.name});
...@@ -1877,18 +1880,27 @@ pub const Dependency = struct {...@@ -1877,18 +1880,27 @@ pub const Dependency = struct {
18771880
1878 pub fn module(d: *Dependency, name: []const u8) *Module {1881 pub fn module(d: *Dependency, name: []const u8) *Module {
1879 return d.builder.modules.get(name) orelse {1882 return d.builder.modules.get(name) orelse {
1883 if (d.builder.graph.unlazy_deps.count() != 0) {
1884 d.builder.serializeConfigurationExiting();
1885 }
1880 panic("unable to find module {q}", .{name});1886 panic("unable to find module {q}", .{name});
1881 };1887 };
1882 }1888 }
18831889
1884 pub fn namedWriteFiles(d: *Dependency, name: []const u8) *Step.WriteFile {1890 pub fn namedWriteFiles(d: *Dependency, name: []const u8) *Step.WriteFile {
1885 return d.builder.named_writefiles.get(name) orelse {1891 return d.builder.named_writefiles.get(name) orelse {
1892 if (d.builder.graph.unlazy_deps.count() != 0) {
1893 d.builder.serializeConfigurationExiting();
1894 }
1886 panic("unable to find named writefiles {q}", .{name});1895 panic("unable to find named writefiles {q}", .{name});
1887 };1896 };
1888 }1897 }
18891898
1890 pub fn namedLazyPath(d: *Dependency, name: []const u8) LazyPath {1899 pub fn namedLazyPath(d: *Dependency, name: []const u8) LazyPath {
1891 return d.builder.named_lazy_paths.get(name) orelse {1900 return d.builder.named_lazy_paths.get(name) orelse {
1901 if (d.builder.graph.unlazy_deps.count() != 0) {
1902 d.builder.serializeConfigurationExiting();
1903 }
1892 panic("unable to find named lazypath {q}", .{name});1904 panic("unable to find named lazypath {q}", .{name});
1893 };1905 };
1894 }1906 }