diff options
author | regnat <rg@regnat.ovh> | 2021-05-19 10:35:31 +0200 |
---|---|---|
committer | regnat <rg@regnat.ovh> | 2021-05-26 16:59:09 +0200 |
commit | 8c30acc3e896839283a2c96ec97cc0c811e8ad6a (patch) | |
tree | eb8ec43ea857187c5017a9e94e56d66446826477 | |
parent | af3afd25eafb7866406aee04ef049121a3e3ffb0 (diff) |
Properly track the drvoutput references when building
-rw-r--r-- | src/libstore/build/derivation-goal.cc | 1 | ||||
-rw-r--r-- | src/libstore/misc.cc | 42 | ||||
-rw-r--r-- | src/libstore/store-api.hh | 5 |
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); + } |