diff options
-rw-r--r-- | doc/manual/expressions/advanced-attributes.xml | 21 | ||||
-rw-r--r-- | src/libstore/build.cc | 20 | ||||
-rw-r--r-- | tests/local.mk | 2 | ||||
-rw-r--r-- | tests/pass-as-file.sh | 17 |
4 files changed, 55 insertions, 5 deletions
diff --git a/doc/manual/expressions/advanced-attributes.xml b/doc/manual/expressions/advanced-attributes.xml index 274e36f5c1d0..fee35f0bef48 100644 --- a/doc/manual/expressions/advanced-attributes.xml +++ b/doc/manual/expressions/advanced-attributes.xml @@ -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 diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 4841c9373ede..0b1985828b52 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -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; diff --git a/tests/local.mk b/tests/local.mk index 69a227495d94..7a24fadcb8b9 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -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)) diff --git a/tests/pass-as-file.sh b/tests/pass-as-file.sh new file mode 100644 index 000000000000..b61576e05799 --- /dev/null +++ b/tests/pass-as-file.sh @@ -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 + ''; +} +") |