From 8c30acc3e896839283a2c96ec97cc0c811e8ad6a Mon Sep 17 00:00:00 2001 From: regnat Date: Wed, 19 May 2021 10:35:31 +0200 Subject: [PATCH] Properly track the drvoutput references when building --- src/libstore/build/derivation-goal.cc | 1 + src/libstore/misc.cc | 42 +++++++++++++++++++++++++++ src/libstore/store-api.hh | 5 ++++ 3 files changed, 48 insertions(+) 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 drvOutputReferences( + const std::set inputRealisations, + const StorePathSet pathReferences) +{ + std::set res; + std::map> 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 drvOutputReferences( + Store & store, + const Derivation & drv, + const StorePath & outputPath) +{ + std::set 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 splitUriAndParams(const std::string & uri) std::optional getDerivationCA(const BasicDerivation & drv); +std::set drvOutputReferences( + Store & store, + const Derivation & drv, + const StorePath & outputPath); + }