diff --git a/pkgs/build-support/buildenv/builder.pl b/pkgs/build-support/buildenv/builder.pl index 975e76df05c0..12d922770a8f 100755 --- a/pkgs/build-support/buildenv/builder.pl +++ b/pkgs/build-support/buildenv/builder.pl @@ -255,6 +255,21 @@ while (scalar(keys %postponed) > 0) { } } +my $extraPathsFilePath = $ENV{"extraPathsFrom"}; +if ($extraPathsFilePath) { + open FILE, $extraPathsFilePath or die "cannot open extra paths file $extraPathsFilePath: $!"; + + while(my $line = ) { + chomp $line; + addPkg($line, + $ENV{"ignoreCollisions"} eq "1", + $ENV{"checkCollisionContents"} eq "1", + 1000) + if -d $line; + } + + close FILE; +} # Create the symlinks. my $nrLinks = 0; diff --git a/pkgs/build-support/buildenv/default.nix b/pkgs/build-support/buildenv/default.nix index cb0c308ec2fa..8f4fad883253 100644 --- a/pkgs/build-support/buildenv/default.nix +++ b/pkgs/build-support/buildenv/default.nix @@ -1,7 +1,7 @@ # buildEnv creates a tree of symlinks to the specified paths. This is # a fork of the hardcoded buildEnv in the Nix distribution. -{ buildPackages, runCommand, lib, substituteAll }: +{ buildPackages, runCommand, lib, substituteAll, writeClosure }: let builder = substituteAll { @@ -23,6 +23,9 @@ lib.makeOverridable , # Whether to ignore collisions or abort. ignoreCollisions ? false +, # Whether to include closures of all input paths. + includeClosures ? false + , # If there is a collision, check whether the contents and permissions match # and only if not, throw a collision error. checkCollisionContents ? true @@ -49,27 +52,31 @@ lib.makeOverridable , passthru ? {} , meta ? {} }: +let + chosenOutputs = map (drv: { + paths = + # First add the usual output(s): respect if user has chosen explicitly, + # and otherwise use `meta.outputsToInstall`. The attribute is guaranteed + # to exist in mkDerivation-created cases. The other cases (e.g. runCommand) + # aren't expected to have multiple outputs. + (if (! drv ? outputSpecified || ! drv.outputSpecified) + && drv.meta.outputsToInstall or null != null + then map (outName: drv.${outName}) drv.meta.outputsToInstall + else [ drv ]) + # Add any extra outputs specified by the caller of `buildEnv`. + ++ lib.filter (p: p!=null) + (builtins.map (outName: drv.${outName} or null) extraOutputsToInstall); + priority = drv.meta.priority or lib.meta.defaultPriority; + }) paths; -runCommand name + pathsForClosure = lib.flatten (map (p: p.paths) chosenOutputs); +in runCommand name rec { inherit manifest ignoreCollisions checkCollisionContents passthru meta pathsToLink extraPrefix postBuild nativeBuildInputs buildInputs; - pkgs = builtins.toJSON (map (drv: { - paths = - # First add the usual output(s): respect if user has chosen explicitly, - # and otherwise use `meta.outputsToInstall`. The attribute is guaranteed - # to exist in mkDerivation-created cases. The other cases (e.g. runCommand) - # aren't expected to have multiple outputs. - (if (! drv ? outputSpecified || ! drv.outputSpecified) - && drv.meta.outputsToInstall or null != null - then map (outName: drv.${outName}) drv.meta.outputsToInstall - else [ drv ]) - # Add any extra outputs specified by the caller of `buildEnv`. - ++ lib.filter (p: p!=null) - (builtins.map (outName: drv.${outName} or null) extraOutputsToInstall); - priority = drv.meta.priority or lib.meta.defaultPriority; - }) paths); + pkgs = builtins.toJSON chosenOutputs; + extraPathsFrom = lib.optional includeClosures (writeClosure pathsForClosure); preferLocalBuild = true; allowSubstitutes = false; # XXX: The size is somewhat arbitrary