dc895fb281
the fix to extendDerivation in #140051 unwittingly worsened eval performance by quite a bit. set elements alone needed over 1GB extra after the change, which seems disproportionate to how small it was. if we flip the logic used to determine which outputs to install around and keep a "this one exactly" flag in the specific outputs instead of a "all of them" in the root we can avoid most of that cost.
82 lines
2.6 KiB
Nix
82 lines
2.6 KiB
Nix
# buildEnv creates a tree of symlinks to the specified paths. This is
|
|
# a fork of the buildEnv in the Nix distribution. Most changes should
|
|
# eventually be merged back into the Nix distribution.
|
|
|
|
{ buildPackages, runCommand, lib, substituteAll }:
|
|
|
|
lib.makeOverridable
|
|
({ name
|
|
|
|
, # The manifest file (if any). A symlink $out/manifest will be
|
|
# created to it.
|
|
manifest ? ""
|
|
|
|
, # The paths to symlink.
|
|
paths
|
|
|
|
, # Whether to ignore collisions or abort.
|
|
ignoreCollisions ? false
|
|
|
|
, # If there is a collision, check whether the contents and permissions match
|
|
# and only if not, throw a collision error.
|
|
checkCollisionContents ? true
|
|
|
|
, # The paths (relative to each element of `paths') that we want to
|
|
# symlink (e.g., ["/bin"]). Any file not inside any of the
|
|
# directories in the list is not symlinked.
|
|
pathsToLink ? ["/"]
|
|
|
|
, # The package outputs to include. By default, only the default
|
|
# output is included.
|
|
extraOutputsToInstall ? []
|
|
|
|
, # Root the result in directory "$out${extraPrefix}", e.g. "/share".
|
|
extraPrefix ? ""
|
|
|
|
, # Shell commands to run after building the symlink tree.
|
|
postBuild ? ""
|
|
|
|
# Additional inputs
|
|
, nativeBuildInputs ? [] # Handy e.g. if using makeWrapper in `postBuild`.
|
|
, buildInputs ? []
|
|
|
|
, passthru ? {}
|
|
, meta ? {}
|
|
}:
|
|
|
|
let
|
|
builder = substituteAll {
|
|
src = ./builder.pl;
|
|
inherit (builtins) storeDir;
|
|
};
|
|
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 5;
|
|
}) paths);
|
|
preferLocalBuild = true;
|
|
allowSubstitutes = false;
|
|
# XXX: The size is somewhat arbitrary
|
|
passAsFile = if builtins.stringLength pkgs >= 128*1024 then [ "pkgs" ] else [ ];
|
|
}
|
|
''
|
|
${buildPackages.perl}/bin/perl -w ${builder}
|
|
eval "$postBuild"
|
|
'')
|