diff --git a/doc/manual/command-ref/nix-env.xml b/doc/manual/command-ref/nix-env.xml
index e9a5f0e09..2ed4a5d9f 100644
--- a/doc/manual/command-ref/nix-env.xml
+++ b/doc/manual/command-ref/nix-env.xml
@@ -367,6 +367,10 @@ number of possible ways:
linkend="rsec-nix-store-realise">realised and
installed.
+ By default all outputs are installed for each derivation.
+ That can be reduced by setting meta.outputsToInstall.
+
+
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 996c2c5f4..4889fe206 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -30,7 +30,7 @@ string DrvInfo::queryOutPath()
}
-DrvInfo::Outputs DrvInfo::queryOutputs()
+DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
{
if (outputs.empty()) {
/* Get the ‘outputs’ list. */
@@ -55,7 +55,23 @@ DrvInfo::Outputs DrvInfo::queryOutputs()
} else
outputs["out"] = queryOutPath();
}
- return outputs;
+ if (!onlyOutputsToInstall || !attrs)
+ return outputs;
+
+ /* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
+ const Value * outTI = queryMeta("outputsToInstall");
+ if (!outTI) return outputs;
+ const auto errMsg = Error("this derivation has bad ‘meta.outputsToInstall’");
+ /* ^ this shows during `nix-env -i` right under the bad derivation */
+ if (!outTI->isList()) throw errMsg;
+ Outputs result;
+ for (auto i = outTI->listElems(); i != outTI->listElems() + outTI->listSize(); ++i) {
+ if ((*i)->type != tString) throw errMsg;
+ auto out = outputs.find((*i)->string.s);
+ if (out == outputs.end()) throw errMsg;
+ result.insert(*out);
+ }
+ return result;
}
@@ -192,8 +208,8 @@ typedef set Done;
/* Evaluate value `v'. If it evaluates to a set of type `derivation',
- then put information about it in `drvs' (unless it's already in
- `doneExprs'). The result boolean indicates whether it makes sense
+ then put information about it in `drvs' (unless it's already in `done').
+ The result boolean indicates whether it makes sense
for the caller to recursively search for derivations in `v'. */
static bool getDerivation(EvalState & state, Value & v,
const string & attrPath, DrvInfos & drvs, Done & done,
diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh
index 365c66c8d..37fcbe829 100644
--- a/src/libexpr/get-drvs.hh
+++ b/src/libexpr/get-drvs.hh
@@ -42,7 +42,8 @@ public:
string queryDrvPath();
string queryOutPath();
string queryOutputName();
- Outputs queryOutputs();
+ /** Return the list of outputs. The "outputs to install" are determined by `mesa.outputsToInstall`. */
+ Outputs queryOutputs(bool onlyOutputsToInstall = false);
StringSet queryMetaNames();
Value * queryMeta(const string & name);
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index 4e0e28c11..e378d8196 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -63,8 +63,8 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
if (drvPath != "")
mkString(*state.allocAttr(v, state.sDrvPath), i.queryDrvPath());
- // Copy each output.
- DrvInfo::Outputs outputs = i.queryOutputs();
+ // Copy each output meant for installation.
+ DrvInfo::Outputs outputs = i.queryOutputs(true);
Value & vOutputs = *state.allocAttr(v, state.sOutputs);
state.mkList(vOutputs, outputs.size());
unsigned int m = 0;