aboutsummaryrefslogtreecommitdiff
path: root/src/nix-build
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2021-10-01 18:05:53 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-09-07 10:39:37 -0400
commit7ad66cb3ef7615b51a35a099e232640d528c006c (patch)
treee1698ccff0e1b5fcfeef05d9d5c7c78285dd2685 /src/nix-build
parentb7edc2099fffd7d54638122d2d9950e3d3a751f6 (diff)
Allow dynamic derivation deps in `inputDrvs`
We use the same nested map representation we used for goals, again in order to save space. We might someday want to combine with `inputDrvs`, by doing `V = bool` instead of `V = std::set<OutputName>`, but we are not doing that yet for sake of a smaller diff. The ATerm format for Derivations also needs to be extended, in addition to the in-memory format. To accomodate this, we added a new basic versioning scheme, so old versions of Nix will get nice errors. (And going forward, if the ATerm format changes again the errors will be even better.) `parsedStrings`, an internal function used as part of parsing derivations in A-Term format, used to consume the final `]` but expect the initial `[` to already be consumed. This made for what looked like unbalanced brackets at callsites, which was confusing. Now it consumes both which is hopefully less confusing. As part of testing, we also created a unit test for the A-Term format for regular non-experimental derivations too. Co-authored-by: Robert Hensing <roberth@users.noreply.github.com> Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io> Apply suggestions from code review Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Diffstat (limited to 'src/nix-build')
-rw-r--r--src/nix-build/nix-build.cc37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index 66f319c3e..e2189fc66 100644
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -406,8 +406,22 @@ static void main_nix_build(int argc, char * * argv)
}
}
+ std::function<void(ref<SingleDerivedPath>, const DerivedPathMap<StringSet>::ChildNode &)> accumDerivedPath;
+
+ accumDerivedPath = [&](ref<SingleDerivedPath> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
+ if (!inputNode.value.empty())
+ pathsToBuild.push_back(DerivedPath::Built {
+ .drvPath = inputDrv,
+ .outputs = OutputsSpec::Names { inputNode.value },
+ });
+ for (const auto & [outputName, childNode] : inputNode.childMap)
+ accumDerivedPath(
+ make_ref<SingleDerivedPath>(SingleDerivedPath::Built { inputDrv, outputName }),
+ childNode);
+ };
+
// Build or fetch all dependencies of the derivation.
- for (const auto & [inputDrv0, inputOutputs] : drv.inputDrvs) {
+ for (const auto & [inputDrv0, inputNode] : drv.inputDrvs.map) {
// To get around lambda capturing restrictions in the
// standard.
const auto & inputDrv = inputDrv0;
@@ -416,10 +430,7 @@ static void main_nix_build(int argc, char * * argv)
return !std::regex_search(store->printStorePath(inputDrv), std::regex(exclude));
}))
{
- pathsToBuild.push_back(DerivedPath::Built {
- .drvPath = makeConstantStorePathRef(inputDrv),
- .outputs = OutputsSpec::Names { inputOutputs },
- });
+ accumDerivedPath(makeConstantStorePathRef(inputDrv), inputNode);
pathsToCopy.insert(inputDrv);
}
}
@@ -482,13 +493,21 @@ static void main_nix_build(int argc, char * * argv)
if (env.count("__json")) {
StorePathSet inputs;
- for (auto & [depDrvPath, wantedDepOutputs] : drv.inputDrvs) {
- auto outputs = evalStore->queryPartialDerivationOutputMap(depDrvPath);
- for (auto & i : wantedDepOutputs) {
+
+ std::function<void(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accumInputClosure;
+
+ accumInputClosure = [&](const StorePath & inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
+ auto outputs = evalStore->queryPartialDerivationOutputMap(inputDrv);
+ for (auto & i : inputNode.value) {
auto o = outputs.at(i);
store->computeFSClosure(*o, inputs);
}
- }
+ for (const auto & [outputName, childNode] : inputNode.childMap)
+ accumInputClosure(*outputs.at(outputName), childNode);
+ };
+
+ for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map)
+ accumInputClosure(inputDrv, inputNode);
ParsedDerivation parsedDrv(drvInfo.requireDrvPath(), drv);