Properly track the drvoutput references when building

This commit is contained in:
regnat 2021-05-19 10:35:31 +02:00
parent af3afd25ea
commit 8c30acc3e8
3 changed files with 48 additions and 0 deletions

View file

@ -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 {

View file

@ -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' isnt built", outputName,
store.printStorePath(inputDrv));
inputRealisations.insert(*thisRealisation);
}
}
auto info = store.queryPathInfo(outputPath);
return drvOutputReferences(Realisation::closure(store, inputRealisations), info->references);
}
}

View file

@ -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);
}