diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index b176bbc824..31aaad5485 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -138,6 +138,7 @@ EvalState::EvalState() , sName(symbols.create("name")) , sSystem(symbols.create("system")) , sOverrides(symbols.create("__overrides")) + , sOutputName(symbols.create("outputName")) , baseEnv(allocEnv(128)) , baseEnvDispl(0) , staticBaseEnv(false, 0) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index a3c55a3886..432a0bad1c 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -93,7 +93,7 @@ public: SymbolTable symbols; const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, - sSystem, sOverrides; + sSystem, sOverrides, sOutputName; /* If set, force copying files to the Nix store even if they already exist there. */ diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index f9e7dc6dbe..2ee55bdcae 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -28,6 +28,17 @@ string DrvInfo::queryOutPath(EvalState & state) const } +string DrvInfo::queryOutputName(EvalState & state) const +{ + if (outputName == "" && attrs) { + Bindings::iterator i = attrs->find(state.sOutputName); + PathSet context; + (string &) outputName = i != attrs->end() ? state.coerceToString(*i->value, context) : ""; + } + return outputName; +} + + MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const { if (metaInfoRead) return meta; diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index 8159417a01..f84636a1ab 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -28,6 +28,7 @@ struct DrvInfo private: string drvPath; string outPath; + string outputName; bool metaInfoRead; MetaInfo meta; @@ -46,6 +47,7 @@ public: string queryDrvPath(EvalState & state) const; string queryOutPath(EvalState & state) const; + string queryOutputName(EvalState & state) const; MetaInfo queryMetaInfo(EvalState & state) const; MetaValue queryMetaInfo(EvalState & state, const string & name) const; diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index a5053c3237..53cd711895 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -62,16 +62,9 @@ void processExpr(EvalState & state, const Strings & attrPaths, Path drvPath = i->queryDrvPath(state); /* What output do we want? */ - Path outPath = i->queryOutPath(state); - Derivation drv = derivationFromPath(*store, drvPath); - string outputName; - foreach (DerivationOutputs::iterator, i, drv.outputs) - if (i->second.path == outPath) { - outputName = i->first; - break; - } + string outputName = i->queryOutputName(state); if (outputName == "") - throw Error(format("derivation `%1%' does not have an output `%2%'") % drvPath % outPath); + throw Error(format("derivation `%1%' lacks an `outputName' attribute ") % drvPath); if (gcRoot == "") printGCWarning();