diff --git a/build.zig.zon.nix b/build.zig.zon.nix index ddfa5d28d..a1f044eaf 100644 --- a/build.zig.zon.nix +++ b/build.zig.zon.nix @@ -21,7 +21,7 @@ '' # workaround https://codeberg.org/ziglang/zig/issues/31866 # https://github.com/Cloudef/zig2nix/issues/54 - mkdir "$TMPDIR/src" "$TMPDIR/cache" + mkdir "$TMPDIR/src" "$TMPDIR/cache" "$TMPDIR/cache/tmp" touch "$TMPDIR/src/build.zig" hash="$(cd "$TMPDIR/src" && zig fetch --global-cache-dir "$TMPDIR/cache" ${artifact})" mkdir "$out" @@ -95,8 +95,47 @@ }; in fetcher.${proto}; + # The packages, as real directories holding symlinked files, rather than as + # a farm of symlinked directories. + # + # Zig runs a dependency's own build steps with the working directory set to + # that dependency, and points at the program to run with a path counted in + # directories up from there. Through a symlink the two disagree: Zig counts + # from `//`, four directories below the root, while the kernel + # resolves the working directory to `/nix/store/`, which is three, so + # the path lands one short of where the program is. + # + # It works anyway when the build directory is `/build`, because the sum then + # overshoots into the root and going above the root stays there. It fails + # when the build directory is under `/nix/var/nix/builds`, which is where Nix + # puts it when the sandbox is off. Real directories make the two depths + # agree, so it works either way. + # + # Only the directories have to be real. `--symbolic-link` leaves the files + # pointing into each dependency's own store path, so the farm is a few + # megabytes of symlinks rather than a second copy of every dependency, two + # projects sharing a dependency share it in the store, and a file keeps the + # mode it was fetched with. + copyFarm = farm: entries: pathDependencyPackages: + runCommandLocal farm + { + # The packages whose own manifest declares a dependency by `.path`. + # Zig 0.16.0 cannot build these through `zig build --system`: it spins + # in userspace forever, because a `.path` dependency's hash is computed + # against the system package directory during the fetch and against the + # real global cache afterwards, and in that mode the two disagree. A + # package that wants `--system` copies each of these into its build + # root and passes `--fork=`; see the README. + passthru = {inherit pathDependencyPackages;}; + } + '' + mkdir -p "$out" + cp --recursive --symbolic-link --dereference --no-preserve=mode \ + ${linkFarm farm entries}/. "$out/" + ''; in - linkFarm name [ + copyFarm name + [ { name = "aro-0.0.0-JSD1Qk6lNgDdcDV4Vh7Sfy-34m2TluIVOdPzMmj_0BjX"; path = fetchZigArtifact { @@ -440,3 +479,5 @@ in }; } ] + [ + ] diff --git a/flake.lock b/flake.lock index 305cb2e4f..d4ca4b73f 100644 --- a/flake.lock +++ b/flake.lock @@ -108,11 +108,11 @@ ] }, "locked": { - "lastModified": 1784080626, - "narHash": "sha256-Hvnmnuu0VpHiZl+8z+UkMoxC7JZJvRYBqu2Asb0ZJOE=", + "lastModified": 1788969032, + "narHash": "sha256-e8kFWqmoPM43Vh5N5JbvE/Nb0LS91BLfIJGHxr36Sk8=", "owner": "jcollie", "repo": "zon2nix", - "rev": "776b5f6864a607c141d7966421b433fa1657ba9a", + "rev": "99f104979784372d3b969dd480d76aeba521b920", "type": "github" }, "original": {