Skip to content

Commit 8cbcf3d

Browse files
authored
Fix: materialize propagatedNativeBuildInputs file for runtimeInputs propagation (#231)
* Fix: write nix-support/propagated-native-build-inputs file writeShellApplication uses writeTextFile internally, which does NOT run stdenv.mkDerivation's fixupPhase. Setting propagatedNativeBuildInputs via overrideAttrs only adds the attribute to the derivation but never materializes the $out/nix-support/propagated-native-build-inputs file that setup.sh's findInputs actually reads at runtime. Without this file, curl was invisible to the shell environment despite being set as a propagated dep — the wrapper script itself had curl on its internal PATH, but other programs (like GHC's stage0 cabal) could not find it. Fix: explicitly create the nix-support file in postInstall. * Fix: use buildCommand instead of postInstall for nix-support file writeTextFile sets `buildCommand` in the derivation, which causes stdenv's genericBuild to skip the entire phase system — installPhase, postInstall, fixupPhase — none of them execute. The previous commit used postInstall which was silently ignored, leaving the wrapper output without nix-support/propagated-native-build-inputs. Append the file creation directly to buildCommand, which is the only code path the builder actually runs.
1 parent bae2b4f commit 8cbcf3d

1 file changed

Lines changed: 35 additions & 4 deletions

File tree

writers.nix

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,25 @@
3232
#
3333
# ─── The fix ───────────────────────────────────────────────────────────────────
3434
#
35-
# We use overrideAttrs to add propagatedNativeBuildInputs to the wrapper
36-
# derivation. When stdenv's setup.sh processes the wrapper from
37-
# nativeBuildInputs, it:
35+
# We use overrideAttrs to:
36+
#
37+
# 1. Set propagatedNativeBuildInputs on the derivation
38+
# 2. Write the $out/nix-support/propagated-native-build-inputs file
39+
#
40+
# Step 2 is critical: writeShellApplication uses writeTextFile internally,
41+
# which sets `buildCommand` in the derivation. When buildCommand is set,
42+
# stdenv's genericBuild skips the entire phase system — installPhase,
43+
# postInstall, fixupPhase — none of them run. The fixupPhase is what
44+
# normally materializes the propagatedNativeBuildInputs derivation
45+
# attribute into the $out/nix-support/propagated-native-build-inputs file
46+
# that setup.sh's findInputs reads at runtime. Without the file on disk,
47+
# setting the attribute alone has no effect — setup.sh never sees it.
48+
#
49+
# We therefore append the file creation directly to buildCommand, since
50+
# that is the only code path the builder actually executes.
51+
#
52+
# With the file in place, when stdenv's setup.sh processes the wrapper
53+
# from buildInputs or nativeBuildInputs, it:
3854
#
3955
# 1. Adds $wrapper/bin to PATH (the wrapper itself)
4056
# 2. Reads $wrapper/nix-support/propagated-native-build-inputs
@@ -64,8 +80,23 @@
6480
{ pkgs }:
6581
{
6682
writeShellApplicationWithRuntime = args@{ runtimeInputs ? [], ... }:
83+
let
84+
allPropagated = runtimeInputs;
85+
# Space-separated store paths for the propagation file, matching the
86+
# format that stdenv's setup.sh findInputs expects.
87+
propagatedPathsStr = builtins.concatStringsSep " "
88+
(map (dep: "${dep}") allPropagated);
89+
in
6790
(pkgs.writeShellApplication args).overrideAttrs (old: {
6891
propagatedNativeBuildInputs =
69-
(old.propagatedNativeBuildInputs or []) ++ runtimeInputs;
92+
(old.propagatedNativeBuildInputs or []) ++ allPropagated;
93+
94+
# writeTextFile uses `buildCommand` which bypasses stdenv's entire
95+
# phase system — neither postInstall nor fixupPhase ever runs.
96+
# We must append our file creation directly to buildCommand.
97+
buildCommand = (old.buildCommand or "") + ''
98+
mkdir -p $out/nix-support
99+
echo "${propagatedPathsStr}" > $out/nix-support/propagated-native-build-inputs
100+
'';
70101
});
71102
}

0 commit comments

Comments
 (0)