aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/misc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/misc.cc')
-rw-r--r--src/libstore/misc.cc67
1 files changed, 48 insertions, 19 deletions
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index c043b9b93..1035691c7 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -125,14 +125,26 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
std::function<void(DerivedPath)> doPath;
+ std::function<void(ref<SingleDerivedPath>, const DerivedPathMap<StringSet>::ChildNode &)> enqueueDerivedPaths;
+
+ enqueueDerivedPaths = [&](ref<SingleDerivedPath> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
+ if (!inputNode.value.empty())
+ pool.enqueue(std::bind(doPath, DerivedPath::Built { inputDrv, inputNode.value }));
+ for (const auto & [outputName, childNode] : inputNode.childMap)
+ enqueueDerivedPaths(
+ make_ref<SingleDerivedPath>(SingleDerivedPath::Built { inputDrv, outputName }),
+ childNode);
+ };
+
auto mustBuildDrv = [&](const StorePath & drvPath, const Derivation & drv) {
{
auto state(state_.lock());
state->willBuild.insert(drvPath);
}
- for (auto & i : drv.inputDrvs)
- pool.enqueue(std::bind(doPath, DerivedPath::Built { makeConstantStorePathRef(i.first), i.second }));
+ for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) {
+ enqueueDerivedPaths(makeConstantStorePathRef(inputDrv), inputNode);
+ }
};
auto checkOutput = [&](
@@ -322,24 +334,41 @@ std::map<DrvOutput, StorePath> drvOutputReferences(
{
std::set<Realisation> inputRealisations;
- for (const auto & [inputDrv, outputNames] : drv.inputDrvs) {
- const auto outputHashes =
- staticOutputHashes(store, store.readDerivation(inputDrv));
- for (const auto & outputName : outputNames) {
- auto outputHash = get(outputHashes, outputName);
- if (!outputHash)
- throw Error(
- "output '%s' of derivation '%s' isn't realised", outputName,
- store.printStorePath(inputDrv));
- auto thisRealisation = store.queryRealisation(
- DrvOutput{*outputHash, outputName});
- if (!thisRealisation)
- throw Error(
- "output '%s' of derivation '%s' isn't built", outputName,
- store.printStorePath(inputDrv));
- inputRealisations.insert(*thisRealisation);
+ std::function<void(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accumRealisations;
+
+ accumRealisations = [&](const StorePath & inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
+ if (!inputNode.value.empty()) {
+ auto outputHashes =
+ staticOutputHashes(store, store.readDerivation(inputDrv));
+ for (const auto & outputName : inputNode.value) {
+ auto outputHash = get(outputHashes, outputName);
+ if (!outputHash)
+ throw Error(
+ "output '%s' of derivation '%s' isn't realised", outputName,
+ store.printStorePath(inputDrv));
+ auto thisRealisation = store.queryRealisation(
+ DrvOutput{*outputHash, outputName});
+ if (!thisRealisation)
+ throw Error(
+ "output '%s' of derivation '%s' isn’t built", outputName,
+ store.printStorePath(inputDrv));
+ inputRealisations.insert(*thisRealisation);
+ }
}
- }
+ if (!inputNode.value.empty()) {
+ auto d = makeConstantStorePathRef(inputDrv);
+ for (const auto & [outputName, childNode] : inputNode.childMap) {
+ SingleDerivedPath next = SingleDerivedPath::Built { d, outputName };
+ accumRealisations(
+ // TODO deep resolutions for dynamic derivations, issue #8947, would go here.
+ resolveDerivedPath(store, next),
+ childNode);
+ }
+ }
+ };
+
+ for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map)
+ accumRealisations(inputDrv, inputNode);
auto info = store.queryPathInfo(outputPath);