aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build')
-rw-r--r--src/libstore/build/derivation-goal.cc30
-rw-r--r--src/libstore/build/entry-points.cc29
-rw-r--r--src/libstore/build/goal.cc23
-rw-r--r--src/libstore/build/goal.hh16
-rw-r--r--src/libstore/build/local-derivation-goal.cc2
5 files changed, 81 insertions, 19 deletions
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index 26faf8c8e..606f9fd48 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -330,6 +330,10 @@ void DerivationGoal::outputsSubstitutionTried()
produced using a substitute. So we have to build instead. */
void DerivationGoal::gaveUpOnSubstitution()
{
+ /* Make sure checkPathValidity() from now on checks all
+ outputs. */
+ wantedOutputs = OutputsSpec::All { };
+
/* The inputs must be built before we can build this goal. */
inputDrvOutputs.clear();
if (useDerivation)
@@ -570,8 +574,6 @@ void DerivationGoal::inputsRealised()
build hook. */
state = &DerivationGoal::tryToBuild;
worker.wakeUp(shared_from_this());
-
- buildResult = BuildResult { .path = buildResult.path };
}
void DerivationGoal::started()
@@ -1452,12 +1454,28 @@ void DerivationGoal::waiteeDone(GoalPtr waitee, ExitCode result)
{
Goal::waiteeDone(waitee, result);
- if (waitee->buildResult.success())
- if (auto bfd = std::get_if<DerivedPath::Built>(&waitee->buildResult.path))
- for (auto & [output, realisation] : waitee->buildResult.builtOutputs)
+ if (!useDerivation) return;
+ auto & fullDrv = *dynamic_cast<Derivation *>(drv.get());
+
+ auto * dg = dynamic_cast<DerivationGoal *>(&*waitee);
+ if (!dg) return;
+
+ auto outputs = fullDrv.inputDrvs.find(dg->drvPath);
+ if (outputs == fullDrv.inputDrvs.end()) return;
+
+ for (auto & outputName : outputs->second) {
+ auto buildResult = dg->getBuildResult(DerivedPath::Built {
+ .drvPath = dg->drvPath,
+ .outputs = OutputsSpec::Names { outputName },
+ });
+ if (buildResult.success()) {
+ for (auto & [output, realisation] : buildResult.builtOutputs) {
inputDrvOutputs.insert_or_assign(
- { bfd->drvPath, output.outputName },
+ { dg->drvPath, output.outputName },
realisation.outPath);
+ }
+ }
+ }
}
}
diff --git a/src/libstore/build/entry-points.cc b/src/libstore/build/entry-points.cc
index 7d725b881..74eae0692 100644
--- a/src/libstore/build/entry-points.cc
+++ b/src/libstore/build/entry-points.cc
@@ -39,7 +39,7 @@ void Store::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMod
}
}
-std::vector<BuildResult> Store::buildPathsWithResults(
+std::vector<KeyedBuildResult> Store::buildPathsWithResults(
const std::vector<DerivedPath> & reqs,
BuildMode buildMode,
std::shared_ptr<Store> evalStore)
@@ -47,15 +47,23 @@ std::vector<BuildResult> Store::buildPathsWithResults(
Worker worker(*this, evalStore ? *evalStore : *this);
Goals goals;
- for (const auto & br : reqs)
- goals.insert(worker.makeGoal(br, buildMode));
+ std::vector<std::pair<const DerivedPath &, GoalPtr>> state;
+
+ for (const auto & req : reqs) {
+ auto goal = worker.makeGoal(req, buildMode);
+ goals.insert(goal);
+ state.push_back({req, goal});
+ }
worker.run(goals);
- std::vector<BuildResult> results;
+ std::vector<KeyedBuildResult> results;
- for (auto & i : goals)
- results.push_back(i->buildResult);
+ for (auto & [req, goalPtr] : state)
+ results.emplace_back(KeyedBuildResult {
+ goalPtr->getBuildResult(req),
+ /* .path = */ req,
+ });
return results;
}
@@ -68,15 +76,14 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat
try {
worker.run(Goals{goal});
- return goal->buildResult;
+ return goal->getBuildResult(DerivedPath::Built {
+ .drvPath = drvPath,
+ .outputs = OutputsSpec::All {},
+ });
} catch (Error & e) {
return BuildResult {
.status = BuildResult::MiscFailure,
.errorMsg = e.msg(),
- .path = DerivedPath::Built {
- .drvPath = drvPath,
- .outputs = OutputsSpec::All { },
- },
};
};
}
diff --git a/src/libstore/build/goal.cc b/src/libstore/build/goal.cc
index d59b94797..13b2e509a 100644
--- a/src/libstore/build/goal.cc
+++ b/src/libstore/build/goal.cc
@@ -11,6 +11,29 @@ bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) const {
}
+BuildResult Goal::getBuildResult(const DerivedPath & req) {
+ BuildResult res { buildResult };
+
+ if (auto pbp = std::get_if<DerivedPath::Built>(&req)) {
+ auto & bp = *pbp;
+
+ /* Because goals are in general shared between derived paths
+ that share the same derivation, we need to filter their
+ results to get back just the results we care about.
+ */
+
+ for (auto it = res.builtOutputs.begin(); it != res.builtOutputs.end();) {
+ if (bp.outputs.contains(it->first.outputName))
+ ++it;
+ else
+ it = res.builtOutputs.erase(it);
+ }
+ }
+
+ return res;
+}
+
+
void addToWeakGoals(WeakGoals & goals, GoalPtr p)
{
if (goals.find(p) != goals.end())
diff --git a/src/libstore/build/goal.hh b/src/libstore/build/goal.hh
index f4bf6f38b..c0e12a2ed 100644
--- a/src/libstore/build/goal.hh
+++ b/src/libstore/build/goal.hh
@@ -81,11 +81,26 @@ struct Goal : public std::enable_shared_from_this<Goal>
*/
ExitCode exitCode = ecBusy;
+protected:
/**
* Build result.
*/
BuildResult buildResult;
+public:
+
+ /**
+ * Project a `BuildResult` with just the information that pertains
+ * to the given request.
+ *
+ * In general, goals may be aliased between multiple requests, and
+ * the stored `BuildResult` has information for the union of all
+ * requests. We don't want to leak what the other request are for
+ * sake of both privacy and determinism, and this "safe accessor"
+ * ensures we don't.
+ */
+ BuildResult getBuildResult(const DerivedPath &);
+
/**
* Exception containing an error message, if any.
*/
@@ -93,7 +108,6 @@ struct Goal : public std::enable_shared_from_this<Goal>
Goal(Worker & worker, DerivedPath path)
: worker(worker)
- , buildResult { .path = std::move(path) }
{ }
virtual ~Goal()
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 58d6901d3..af937f6b1 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -1335,7 +1335,7 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
result.rethrow();
}
- std::vector<BuildResult> buildPathsWithResults(
+ std::vector<KeyedBuildResult> buildPathsWithResults(
const std::vector<DerivedPath> & paths,
BuildMode buildMode = bmNormal,
std::shared_ptr<Store> evalStore = nullptr) override