Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at python-updates 126 lines 3.6 kB view raw
1# buildEnv creates a tree of symlinks to the specified paths. This is 2# a fork of the hardcoded buildEnv in the Nix distribution. 3 4{ 5 buildPackages, 6 runCommand, 7 lib, 8 replaceVars, 9 writeClosure, 10}: 11 12let 13 builder = replaceVars ./builder.pl { 14 inherit (builtins) storeDir; 15 }; 16in 17 18lib.makeOverridable ( 19 { 20 name, 21 22 # The manifest file (if any). A symlink $out/manifest will be 23 # created to it. 24 manifest ? "", 25 26 # The paths to symlink. 27 paths, 28 29 # Whether to ignore collisions or abort. 30 ignoreCollisions ? false, 31 32 # Whether to ignore outputs that are a single file instead of a directory. 33 ignoreSingleFileOutputs ? false, 34 35 # Whether to include closures of all input paths. 36 includeClosures ? false, 37 38 # If there is a collision, check whether the contents and permissions match 39 # and only if not, throw a collision error. 40 checkCollisionContents ? true, 41 42 # The paths (relative to each element of `paths') that we want to 43 # symlink (e.g., ["/bin"]). Any file not inside any of the 44 # directories in the list is not symlinked. 45 pathsToLink ? [ "/" ], 46 47 # The package outputs to include. By default, only the default 48 # output is included. 49 extraOutputsToInstall ? [ ], 50 51 # Root the result in directory "$out${extraPrefix}", e.g. "/share". 52 extraPrefix ? "", 53 54 # Shell commands to run after building the symlink tree. 55 postBuild ? "", 56 57 # Additional inputs 58 nativeBuildInputs ? [ ], # Handy e.g. if using makeWrapper in `postBuild`. 59 buildInputs ? [ ], 60 61 passthru ? { }, 62 meta ? { }, 63 pname ? null, 64 version ? null, 65 }: 66 let 67 chosenOutputs = map (drv: { 68 paths = 69 # First add the usual output(s): respect if user has chosen explicitly, 70 # and otherwise use `meta.outputsToInstall`. The attribute is guaranteed 71 # to exist in mkDerivation-created cases. The other cases (e.g. runCommand) 72 # aren't expected to have multiple outputs. 73 ( 74 if 75 (!drv ? outputSpecified || !drv.outputSpecified) && drv.meta.outputsToInstall or null != null 76 then 77 map (outName: drv.${outName}) drv.meta.outputsToInstall 78 else 79 [ drv ] 80 ) 81 # Add any extra outputs specified by the caller of `buildEnv`. 82 ++ lib.filter (p: p != null) (builtins.map (outName: drv.${outName} or null) extraOutputsToInstall); 83 priority = drv.meta.priority or lib.meta.defaultPriority; 84 }) paths; 85 86 pathsForClosure = lib.pipe chosenOutputs [ 87 (map (p: p.paths)) 88 lib.flatten 89 (lib.remove null) 90 ]; 91 in 92 runCommand name 93 ( 94 rec { 95 inherit 96 manifest 97 ignoreCollisions 98 checkCollisionContents 99 ignoreSingleFileOutputs 100 passthru 101 meta 102 pathsToLink 103 extraPrefix 104 postBuild 105 nativeBuildInputs 106 buildInputs 107 ; 108 pkgs = builtins.toJSON chosenOutputs; 109 extraPathsFrom = lib.optional includeClosures (writeClosure pathsForClosure); 110 preferLocalBuild = true; 111 allowSubstitutes = false; 112 # XXX: The size is somewhat arbitrary 113 passAsFile = if builtins.stringLength pkgs >= 128 * 1024 then [ "pkgs" ] else [ ]; 114 } 115 // lib.optionalAttrs (pname != null) { 116 inherit pname; 117 } 118 // lib.optionalAttrs (version != null) { 119 inherit version; 120 } 121 ) 122 '' 123 ${buildPackages.perl}/bin/perl -w ${builder} 124 eval "$postBuild" 125 '' 126)