aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build')
-rw-r--r--src/libstore/build/local-derivation-goal.cc63
-rw-r--r--src/libstore/build/substitution-goal.cc13
2 files changed, 34 insertions, 42 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index a372728f5..890a159ac 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -2247,27 +2247,26 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
}
};
- auto rewriteRefs = [&]() -> std::pair<bool, StorePathSet> {
+ auto rewriteRefs = [&]() -> PathReferences<StorePath> {
/* In the CA case, we need the rewritten refs to calculate the
final path, therefore we look for a *non-rewritten
self-reference, and use a bool rather try to solve the
computationally intractable fixed point. */
- std::pair<bool, StorePathSet> res {
- false,
- {},
+ PathReferences<StorePath> res {
+ .hasSelfReference = false,
};
for (auto & r : references) {
auto name = r.name();
auto origHash = std::string { r.hashPart() };
if (r == scratchPath)
- res.first = true;
+ res.hasSelfReference = true;
else if (outputRewrites.count(origHash) == 0)
- res.second.insert(r);
+ res.references.insert(r);
else {
std::string newRef = outputRewrites.at(origHash);
newRef += '-';
newRef += name;
- res.second.insert(StorePath { newRef });
+ res.references.insert(StorePath { newRef });
}
}
return res;
@@ -2296,20 +2295,26 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
break;
}
auto got = caSink.finish().first;
- auto refs = rewriteRefs();
-
- auto finalPath = worker.store.makeFixedOutputPath(
- outputHash.method,
- got,
- outputPathName(drv->name, outputName),
- refs.second,
- refs.first);
- if (scratchPath != finalPath) {
+ ValidPathInfo newInfo0 {
+ worker.store,
+ {
+ .name = outputPathName(drv->name, outputName),
+ .info = FixedOutputInfo {
+ {
+ .method = outputHash.method,
+ .hash = got,
+ },
+ rewriteRefs(),
+ },
+ },
+ Hash::dummy,
+ };
+ if (scratchPath != newInfo0.path) {
// Also rewrite the output path
auto source = sinkToSource([&](Sink & nextSink) {
StringSink sink;
dumpPath(actualPath, sink);
- RewritingSink rsink2(oldHashPart, std::string(finalPath.hashPart()), nextSink);
+ RewritingSink rsink2(oldHashPart, std::string(newInfo0.path.hashPart()), nextSink);
rsink2(sink.s);
rsink2.flush();
});
@@ -2320,19 +2325,8 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
}
HashResult narHashAndSize = hashPath(htSHA256, actualPath);
- ValidPathInfo newInfo0 {
- finalPath,
- narHashAndSize.first,
- };
-
+ newInfo0.narHash = narHashAndSize.first;
newInfo0.narSize = narHashAndSize.second;
- newInfo0.ca = FixedOutputHash {
- .method = outputHash.method,
- .hash = got,
- };
- newInfo0.references = refs.second;
- if (refs.first)
- newInfo0.references.insert(newInfo0.path);
assert(newInfo0.ca);
return newInfo0;
@@ -2353,10 +2347,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
auto narHashAndSize = hashPath(htSHA256, actualPath);
ValidPathInfo newInfo0 { requiredFinalPath, narHashAndSize.first };
newInfo0.narSize = narHashAndSize.second;
- auto refs = rewriteRefs();
- newInfo0.references = refs.second;
- if (refs.first)
- newInfo0.references.insert(newInfo0.path);
+ static_cast<PathReferences<StorePath> &>(newInfo0) = rewriteRefs();
return newInfo0;
},
@@ -2654,12 +2645,12 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
auto i = outputsByPath.find(worker.store.printStorePath(path));
if (i != outputsByPath.end()) {
closureSize += i->second.narSize;
- for (auto & ref : i->second.references)
+ for (auto & ref : i->second.referencesPossiblyToSelf())
pathsLeft.push(ref);
} else {
auto info = worker.store.queryPathInfo(path);
closureSize += info->narSize;
- for (auto & ref : info->references)
+ for (auto & ref : info->referencesPossiblyToSelf())
pathsLeft.push(ref);
}
}
@@ -2698,7 +2689,7 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
auto used = recursive
? getClosure(info.path).first
- : info.references;
+ : info.referencesPossiblyToSelf();
if (recursive && checks.ignoreSelfRefs)
used.erase(info.path);
diff --git a/src/libstore/build/substitution-goal.cc b/src/libstore/build/substitution-goal.cc
index 31e6dbc9f..2aaa89a57 100644
--- a/src/libstore/build/substitution-goal.cc
+++ b/src/libstore/build/substitution-goal.cc
@@ -86,7 +86,10 @@ void PathSubstitutionGoal::tryNext()
subs.pop_front();
if (ca) {
- subPath = sub->makeFixedOutputPathFromCA(storePath.name(), *ca);
+ subPath = sub->makeFixedOutputPathFromCA({
+ .name = std::string { storePath.name() },
+ .info = caWithoutRefs(*ca),
+ });
if (sub->storeDir == worker.store.storeDir)
assert(subPath == storePath);
} else if (sub->storeDir != worker.store.storeDir) {
@@ -116,7 +119,7 @@ void PathSubstitutionGoal::tryNext()
}
if (info->path != storePath) {
- if (info->isContentAddressed(*sub) && info->references.empty()) {
+ if (info->isContentAddressed(*sub) && info->references.empty() && !info->hasSelfReference) {
auto info2 = std::make_shared<ValidPathInfo>(*info);
info2->path = storePath;
info = info2;
@@ -154,8 +157,7 @@ void PathSubstitutionGoal::tryNext()
/* To maintain the closure invariant, we first have to realise the
paths referenced by this one. */
for (auto & i : info->references)
- if (i != storePath) /* ignore self-references */
- addWaitee(worker.makePathSubstitutionGoal(i));
+ addWaitee(worker.makePathSubstitutionGoal(i));
if (waitees.empty()) /* to prevent hang (no wake-up event) */
referencesValid();
@@ -177,8 +179,7 @@ void PathSubstitutionGoal::referencesValid()
}
for (auto & i : info->references)
- if (i != storePath) /* ignore self-references */
- assert(worker.store.isValidPath(i));
+ assert(worker.store.isValidPath(i));
state = &PathSubstitutionGoal::tryToRun;
worker.wakeUp(shared_from_this());