about summary refs log tree commit diff
path: root/src/nix/installables.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-09-06T14·03+0200
committerEelco Dolstra <edolstra@gmail.com>2017-09-06T14·03+0200
commitdf4342bc175a153986ebcf5bce2a758d5353adeb (patch)
treed491cac5bd1c4d45c689fd1a19c98958c32e9674 /src/nix/installables.cc
parent1277aab219c83beae856024eea6e868677f7523b (diff)
nix build: Create result symlinks
Diffstat (limited to 'src/nix/installables.cc')
-rw-r--r--src/nix/installables.cc87
1 files changed, 64 insertions, 23 deletions
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index fdb6004fb3..f3c7d3075f 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -70,17 +70,27 @@ ref<EvalState> SourceExprCommand::getEvalState()
     return ref<EvalState>(evalState);
 }
 
+Buildable Installable::toBuildable()
+{
+    auto buildables = toBuildables();
+    if (buildables.size() != 1)
+        throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
+    return std::move(buildables[0]);
+}
+
 struct InstallableStoreDrv : Installable
 {
-    Path storePath;
+    Path drvPath;
 
-    InstallableStoreDrv(const Path & storePath) : storePath(storePath) { }
+    InstallableStoreDrv(const Path & drvPath) : drvPath(drvPath) { }
 
-    std::string what() override { return storePath; }
+    std::string what() override { return drvPath; }
 
-    Buildables toBuildable(bool singular) override
+    Buildables toBuildables() override
     {
-        return {{storePath, {}}};
+        Buildable b = {drvPath};
+        // FIXME: add outputs?
+        return {b};
     }
 };
 
@@ -92,9 +102,9 @@ struct InstallableStorePath : Installable
 
     std::string what() override { return storePath; }
 
-    Buildables toBuildable(bool singular) override
+    Buildables toBuildables() override
     {
-        return {{storePath, {}}};
+        return {{"", {{"out", storePath}}}};
     }
 };
 
@@ -104,7 +114,7 @@ struct InstallableValue : Installable
 
     InstallableValue(SourceExprCommand & cmd) : cmd(cmd) { }
 
-    Buildables toBuildable(bool singular) override
+    Buildables toBuildables() override
     {
         auto state = cmd.getEvalState();
 
@@ -117,16 +127,32 @@ struct InstallableValue : Installable
         DrvInfos drvs;
         getDerivations(*state, *v, "", autoArgs, drvs, false);
 
-        if (singular && drvs.size() != 1)
-            throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), drvs.size());
-
         Buildables res;
 
-        for (auto & drv : drvs)
-            for (auto & output : drv.queryOutputs())
-                res.emplace(output.second, Whence{output.first, drv.queryDrvPath()});
+        PathSet drvPaths;
+
+        for (auto & drv : drvs) {
+            Buildable b{drv.queryDrvPath()};
+            drvPaths.insert(b.drvPath);
+
+            auto outputName = drv.queryOutputName();
+            if (outputName == "")
+                throw Error("derivation '%s' lacks an 'outputName' attribute", b.drvPath);
+
+            b.outputs.emplace(outputName, drv.queryOutPath());
 
-        return res;
+            res.push_back(std::move(b));
+        }
+
+        // Hack to recognize .all: if all drvs have the same drvPath,
+        // merge the buildables.
+        if (drvPaths.size() == 1) {
+            Buildable b{*drvPaths.begin()};
+            for (auto & b2 : res)
+                b.outputs.insert(b2.outputs.begin(), b2.outputs.end());
+            return {b};
+        } else
+            return res;
     }
 };
 
@@ -214,23 +240,38 @@ static std::vector<std::shared_ptr<Installable>> parseInstallables(
     return result;
 }
 
-PathSet InstallablesCommand::toStorePaths(ref<Store> store, ToStorePathsMode mode)
+Buildables InstallablesCommand::toBuildables(ref<Store> store, RealiseMode mode)
 {
     if (mode != Build)
         settings.readOnlyMode = true;
 
-    PathSet outPaths, buildables;
+    Buildables buildables;
+
+    PathSet pathsToBuild;
 
-    for (auto & i : installables)
-        for (auto & b : i->toBuildable()) {
-            outPaths.insert(b.first);
-            buildables.insert(b.second.drvPath != "" ? b.second.drvPath : b.first);
+    for (auto & i : installables) {
+        for (auto & b : i->toBuildables()) {
+            if (b.drvPath != "")
+                pathsToBuild.insert(b.drvPath);
+            buildables.push_back(std::move(b));
         }
+    }
 
     if (mode == DryRun)
-        printMissing(store, buildables, lvlError);
+        printMissing(store, pathsToBuild, lvlError);
     else if (mode == Build)
-        store->buildPaths(buildables);
+        store->buildPaths(pathsToBuild);
+
+    return buildables;
+}
+
+PathSet InstallablesCommand::toStorePaths(ref<Store> store, RealiseMode mode)
+{
+    PathSet outPaths;
+
+    for (auto & b : toBuildables(store, mode))
+        for (auto & output : b.outputs)
+            outPaths.insert(output.second);
 
     return outPaths;
 }