Allow passing attributes via files instead of environment variables

Closes #473.
This commit is contained in:
Eelco Dolstra 2015-02-17 14:42:15 +01:00
parent 29e1ff675b
commit a70d275f3d
4 changed files with 55 additions and 5 deletions

View file

@ -242,6 +242,27 @@ stdenv.mkDerivation {
</varlistentry>
<varlistentry><term><varname>passAsFile</varname></term>
<listitem><para>A list of names of attributes that should be
passed via files rather than environment variables. For example,
if you have
<programlisting>
passAsFile = ["big"];
big = "a very long string";
</programlisting>
then when the builder runs, the environment variable
<envar>big</envar> will contain the absolute path to a temporary
file containing <literal>a very long string</literal>. This is
useful when you need to pass large strings to a builder, since
most operating systems impose a limit on the size of the
environment (typically, a few hundred kilobyte).</para></listitem>
</varlistentry>
<varlistentry><term><varname>preferLocalBuild</varname></term>
<listitem><para>If this attribute is set to

View file

@ -1646,14 +1646,26 @@ void DerivationGoal::startBuilder()
/* The maximum number of cores to utilize for parallel building. */
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
/* Add all bindings specified in the derivation. */
foreach (StringPairs::iterator, i, drv.env)
env[i->first] = i->second;
/* Create a temporary directory where the build will take
place. */
tmpDir = createTempDir("", "nix-build-" + storePathToName(drvPath), false, false, 0700);
/* Add all bindings specified in the derivation via the
environments, except those listed in the passAsFile
attribute. Those are passed as file names pointing to
temporary files containing the contents. */
StringSet passAsFile = tokenizeString<StringSet>(get(drv.env, "passAsFile"));
int fileNr = 0;
for (auto & i : drv.env) {
if (passAsFile.find(i.first) == passAsFile.end()) {
env[i.first] = i.second;
} else {
Path p = tmpDir + "/.attr-" + int2String(fileNr++);
writeFile(p, i.second);
env[i.first] = p;
}
}
/* For convenience, set an environment pointing to the top build
directory. */
env["NIX_BUILD_TOP"] = tmpDir;

View file

@ -11,7 +11,7 @@ nix_tests = \
binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.sh \
multiple-outputs.sh import-derivation.sh fetchurl.sh optimise-store.sh \
binary-cache.sh nix-profile.sh repair.sh dump-db.sh case-hack.sh \
check-reqs.sh
check-reqs.sh pass-as-file.sh
# parallel.sh
install-tests += $(foreach x, $(nix_tests), tests/$(x))

17
tests/pass-as-file.sh Normal file
View file

@ -0,0 +1,17 @@
source common.sh
clearStore
outPath=$(nix-build --no-out-link -E "
with import ./config.nix;
mkDerivation {
name = \"pass-as-file\";
passAsFile = [ \"foo\" ];
foo = [ \"xyzzy\" ];
builder = builtins.toFile \"builder.sh\" ''
[ \"\$(cat \$foo)\" = xyzzy ]
touch \$out
'';
}
")