Zig Version
0.14.0-dev.1952+9f84f7f92
Steps to Reproduce and Observed Behavior
If two dependencies depend on the same package,
but one does so lazily and the other one does not,
the build.zig of the latter fails to compile
if it does not use lazyDependency()
(which it should not need to use as the dependency is not lazy).
Graphically:
A
/ \
B C
(eager) \ / (lazy)
D
B fails to compile with:
thread 889721 panic: dependency 'b.zqlite' is marked as lazy in build.zig.zon which means it must use the lazyDependency function instead
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/std/Build.zig:2095:32: 0x1414dd5 in dependency__anon_10241 (build)
std.debug.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 });
^
/foo/zig-issue-lazy-dep/b/build.zig:17:39: 0x150b433 in build (build)
.module = b.dependency("zqlite", options).module("zqlite"),
^
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/std/Build.zig:2295:44: 0x149e020 in runBuild__anon_61135 (build)
.error_union => try build_zig.build(b),
^
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/std/Build.zig:2275:29: 0x145a447 in dependencyInner__anon_55211 (build)
sub_builder.runBuild(bz) catch @panic("unhandled error");
^
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/std/Build.zig:2097:35: 0x1414e40 in dependency__anon_10241 (build)
return dependencyInner(b, name, pkg.build_root, if (@hasDecl(pkg, "build_zig")) pkg.build_zig else null, pkg_hash, pkg.deps, args);
^
/foo/zig-issue-lazy-dep/build.zig:14:39: 0x1414909 in build (build)
.module = b.dependency("b", options).module("b"),
^
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/std/Build.zig:2295:44: 0x13f9c10 in runBuild__anon_4961 (build)
.error_union => try build_zig.build(b),
^
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/compiler/build_runner.zig:335:29: 0x13f4725 in main (build)
try builder.runBuild(root);
^
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/std/start.zig:621:37: 0x13cf202 in posixCallMainAndExit (build)
const result = root.main() catch |err| {
^
/nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib/std/start.zig:250:5: 0x13ceddf in _start (build)
asm volatile (switch (native_arch) {
^
???:?:?: 0x0 in ??? (???)
error: the following build command crashed:
/foo/zig-issue-lazy-dep/.zig-cache/o/fb9a870f009dd40dcc1101049c53e9fd/build /nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/bin/zig /nix/store/ypa88d8507lmbqlm6f66s1q9qpzvxlc8-zig-0.14.0-dev.1952+9f84f7f92/lib /foo/zig-issue-lazy-dep /foo/zig-issue-lazy-dep/.zig-cache ~/.cache/zig --seed 0x27cf3f35 -Z5b8c9b2ff9d97b7d
My guess is that the build system marks the deduplicated dependency as lazy even though it is only lazy for C, not B.
In more complex dependency graphs this seems to happen about half the time I run zig build which leads me to conclude that it's related to dependency traversal order. However in this small example, I'm unable to find a --seed that works around the issue.
So without knowing any internals of the build system, I guess that this is what happens:
- The dependency graph is traversed, leading to two entries for
D: One lazy (from C), one eager (from B).
- The eager one is dropped during deduplication because laziness is not taken into account for equality, so now the build system thinks all instances of
D are lazy.
B's build.zig is compiled given the lazy D in @import("@dependencies").
I prepared a repository so you can reproduce easily by running zig build: https://github.com/dermetfan/zig-issue-lazy-dep
Expected Behavior
It should not be necessary to use lazyDependency() instead of dependency() as the dependency is not lazy.
Zig Version
0.14.0-dev.1952+9f84f7f92
Steps to Reproduce and Observed Behavior
If two dependencies depend on the same package,
but one does so lazily and the other one does not,
the
build.zigof the latter fails to compileif it does not use
lazyDependency()(which it should not need to use as the dependency is not lazy).
Graphically:
Bfails to compile with:My guess is that the build system marks the deduplicated dependency as lazy even though it is only lazy for
C, notB.In more complex dependency graphs this seems to happen about half the time I run
zig buildwhich leads me to conclude that it's related to dependency traversal order. However in this small example, I'm unable to find a--seedthat works around the issue.So without knowing any internals of the build system, I guess that this is what happens:
D: One lazy (fromC), one eager (fromB).Dare lazy.B'sbuild.zigis compiled given the lazyDin@import("@dependencies").I prepared a repository so you can reproduce easily by running
zig build: https://github.com/dermetfan/zig-issue-lazy-depExpected Behavior
It should not be necessary to use
lazyDependency()instead ofdependency()as the dependency is not lazy.