aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorregnat <rg@regnat.ovh>2021-05-19 10:35:31 +0200
committerregnat <rg@regnat.ovh>2021-05-26 16:59:09 +0200
commit8c30acc3e896839283a2c96ec97cc0c811e8ad6a (patch)
treeeb8ec43ea857187c5017a9e94e56d66446826477
parentaf3afd25eafb7866406aee04ef049121a3e3ffb0 (diff)
Properly track the drvoutput references when building
-rw-r--r--src/libstore/build/derivation-goal.cc1
-rw-r--r--src/libstore/misc.cc42
-rw-r--r--src/libstore/store-api.hh5
3 files changed, 48 insertions, 0 deletions
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index 9100d3333..93fc54440 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -927,6 +927,7 @@ void DerivationGoal::resolvedFinished() {
auto newRealisation = *realisation;
newRealisation.id = DrvOutput{initialOutputs.at(wantedOutput).outputHash, wantedOutput};
newRealisation.signatures.clear();
+ newRealisation.drvOutputDeps = drvOutputReferences(worker.store, *drv, realisation->outPath);
signRealisation(newRealisation);
worker.store.registerDrvOutput(newRealisation);
} else {
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index bc5fd968c..8793f9f4a 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -254,5 +254,47 @@ StorePaths Store::topoSortPaths(const StorePathSet & paths)
}});
}
+std::set<DrvOutput> drvOutputReferences(
+ const std::set<Realisation> inputRealisations,
+ const StorePathSet pathReferences)
+{
+ std::set<DrvOutput> res;
+
+ std::map<StorePath, std::set<DrvOutput>> inputsByOutputPath;
+ for (const auto & input : inputRealisations)
+ inputsByOutputPath[input.outPath].insert(input.id);
+
+ for (const auto & path : pathReferences) {
+ auto theseInputs = inputsByOutputPath[path];
+ res.insert(theseInputs.begin(), theseInputs.end());
+ }
+
+ return res;
+}
+std::set<DrvOutput> drvOutputReferences(
+ Store & store,
+ const Derivation & drv,
+ const StorePath & outputPath)
+{
+ std::set<Realisation> inputRealisations;
+
+ for (const auto& [inputDrv, outputNames] : drv.inputDrvs) {
+ auto outputHashes =
+ staticOutputHashes(store, store.readDerivation(inputDrv));
+ for (const auto& outputName : outputNames) {
+ auto thisRealisation = store.queryRealisation(
+ DrvOutput{outputHashes.at(outputName), outputName});
+ if (!thisRealisation)
+ throw Error(
+ "output '%s' of derivation '%s' isn’t built", outputName,
+ store.printStorePath(inputDrv));
+ inputRealisations.insert(*thisRealisation);
+ }
+ }
+
+ auto info = store.queryPathInfo(outputPath);
+
+ return drvOutputReferences(Realisation::closure(store, inputRealisations), info->references);
+}
}
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index f66298991..29af0f495 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -864,4 +864,9 @@ std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri)
std::optional<ContentAddress> getDerivationCA(const BasicDerivation & drv);
+std::set<DrvOutput> drvOutputReferences(
+ Store & store,
+ const Derivation & drv,
+ const StorePath & outputPath);
+
}