aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/derivation-goal.cc
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2022-11-14 16:26:20 +0100
committerRobert Hensing <robert@roberthensing.nl>2022-11-14 17:52:55 +0100
commit7e162c69fe6cbfb929b5356a7df9de5c25c22565 (patch)
treed5e57393fea0f9f8f54ac254139bca8cc0d8c0f3 /src/libstore/build/derivation-goal.cc
parent0efc314d4d1add3215810f9034b6041759d5175b (diff)
derivation-goal: Fix `requires non-existing output` error
It occurred when a output of the dependency was already available, so it didn't need rebuilding and didn't get added to the inputDrvOutputs. This process-related info wasn't suitable for the purpose of finding the actual input paths for the builder. It is better to do this in absolute terms by querying the store.
Diffstat (limited to 'src/libstore/build/derivation-goal.cc')
-rw-r--r--src/libstore/build/derivation-goal.cc30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index 41d2e2a1c..00e375fe9 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -528,13 +528,31 @@ void DerivationGoal::inputsRealised()
/* Add the relevant output closures of the input derivation
`i' as input paths. Only add the closures of output paths
that are specified as inputs. */
- for (auto & j : wantedDepOutputs)
- if (auto outPath = get(inputDrvOutputs, { depDrvPath, j }))
+ for (auto & j : wantedDepOutputs) {
+ /* TODO (impure derivations-induced tech debt):
+ Tracking input derivation outputs statefully through the
+ goals is error prone and has led to bugs.
+ For a robust nix, we need to move towards the `else` branch,
+ which does not rely on goal state to match up with the
+ reality of the store, which is our real source of truth.
+ However, the impure derivations feature still relies on this
+ fragile way of doing things, because its builds do not have
+ a representation in the store, which is a usability problem
+ in itself */
+ if (auto outPath = get(inputDrvOutputs, { depDrvPath, j })) {
worker.store.computeFSClosure(*outPath, inputPaths);
- else
- throw Error(
- "derivation '%s' requires non-existent output '%s' from input derivation '%s'",
- worker.store.printStorePath(drvPath), j, worker.store.printStorePath(depDrvPath));
+ }
+ else {
+ auto outMap = worker.evalStore.queryDerivationOutputMap(depDrvPath);
+ auto outMapPath = outMap.find(j);
+ if (outMapPath == outMap.end()) {
+ throw Error(
+ "derivation '%s' requires non-existent output '%s' from input derivation '%s'",
+ worker.store.printStorePath(drvPath), j, worker.store.printStorePath(depDrvPath));
+ }
+ worker.store.computeFSClosure(outMapPath->second, inputPaths);
+ }
+ }
}
}