Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

211 строки
7.3 KiB

  1. { lib }:
  2. let
  3. inherit (builtins) attrNames;
  4. in
  5. rec {
  6. /* `overrideDerivation drv f' takes a derivation (i.e., the result
  7. of a call to the builtin function `derivation') and returns a new
  8. derivation in which the attributes of the original are overridden
  9. according to the function `f'. The function `f' is called with
  10. the original derivation attributes.
  11. `overrideDerivation' allows certain "ad-hoc" customisation
  12. scenarios (e.g. in ~/.config/nixpkgs/config.nix). For instance,
  13. if you want to "patch" the derivation returned by a package
  14. function in Nixpkgs to build another version than what the
  15. function itself provides, you can do something like this:
  16. mySed = overrideDerivation pkgs.gnused (oldAttrs: {
  17. name = "sed-4.2.2-pre";
  18. src = fetchurl {
  19. url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
  20. sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
  21. };
  22. patches = [];
  23. });
  24. For another application, see build-support/vm, where this
  25. function is used to build arbitrary derivations inside a QEMU
  26. virtual machine.
  27. */
  28. overrideDerivation = drv: f:
  29. let
  30. newDrv = derivation (drv.drvAttrs // (f drv));
  31. in lib.flip (extendDerivation true) newDrv (
  32. { meta = drv.meta or {};
  33. passthru = if drv ? passthru then drv.passthru else {};
  34. }
  35. //
  36. (drv.passthru or {})
  37. //
  38. (if (drv ? crossDrv && drv ? nativeDrv)
  39. then {
  40. crossDrv = overrideDerivation drv.crossDrv f;
  41. nativeDrv = overrideDerivation drv.nativeDrv f;
  42. }
  43. else { }));
  44. /* `makeOverridable` takes a function from attribute set to attribute set and
  45. injects `override` attibute which can be used to override arguments of
  46. the function.
  47. nix-repl> x = {a, b}: { result = a + b; }
  48. nix-repl> y = lib.makeOverridable x { a = 1; b = 2; }
  49. nix-repl> y
  50. { override = «lambda»; overrideDerivation = «lambda»; result = 3; }
  51. nix-repl> y.override { a = 10; }
  52. { override = «lambda»; overrideDerivation = «lambda»; result = 12; }
  53. Please refer to "Nixpkgs Contributors Guide" section
  54. "<pkg>.overrideDerivation" to learn about `overrideDerivation` and caveats
  55. related to its use.
  56. */
  57. makeOverridable = f: origArgs:
  58. let
  59. ff = f origArgs;
  60. overrideWith = newArgs: origArgs // (if lib.isFunction newArgs then newArgs origArgs else newArgs);
  61. in
  62. if builtins.isAttrs ff then (ff // {
  63. override = newArgs: makeOverridable f (overrideWith newArgs);
  64. overrideDerivation = fdrv:
  65. makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
  66. ${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
  67. makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
  68. })
  69. else if lib.isFunction ff then {
  70. override = newArgs: makeOverridable f (overrideWith newArgs);
  71. __functor = self: ff;
  72. overrideDerivation = throw "overrideDerivation not yet supported for functors";
  73. }
  74. else ff;
  75. /* Call the package function in the file `fn' with the required
  76. arguments automatically. The function is called with the
  77. arguments `args', but any missing arguments are obtained from
  78. `autoArgs'. This function is intended to be partially
  79. parameterised, e.g.,
  80. callPackage = callPackageWith pkgs;
  81. pkgs = {
  82. libfoo = callPackage ./foo.nix { };
  83. libbar = callPackage ./bar.nix { };
  84. };
  85. If the `libbar' function expects an argument named `libfoo', it is
  86. automatically passed as an argument. Overrides or missing
  87. arguments can be supplied in `args', e.g.
  88. libbar = callPackage ./bar.nix {
  89. libfoo = null;
  90. enableX11 = true;
  91. };
  92. */
  93. callPackageWith = autoArgs: fn: args:
  94. let
  95. f = if lib.isFunction fn then fn else import fn;
  96. auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
  97. in makeOverridable f (auto // args);
  98. /* Like callPackage, but for a function that returns an attribute
  99. set of derivations. The override function is added to the
  100. individual attributes. */
  101. callPackagesWith = autoArgs: fn: args:
  102. let
  103. f = if lib.isFunction fn then fn else import fn;
  104. auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
  105. origArgs = auto // args;
  106. pkgs = f origArgs;
  107. mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
  108. in lib.mapAttrs mkAttrOverridable pkgs;
  109. /* Add attributes to each output of a derivation without changing
  110. the derivation itself and check a given condition when evaluating. */
  111. extendDerivation = condition: passthru: drv:
  112. let
  113. outputs = drv.outputs or [ "out" ];
  114. commonAttrs = drv // (builtins.listToAttrs outputsList) //
  115. ({ all = map (x: x.value) outputsList; }) // passthru;
  116. outputToAttrListElement = outputName:
  117. { name = outputName;
  118. value = commonAttrs // {
  119. inherit (drv.${outputName}) type outputName;
  120. drvPath = assert condition; drv.${outputName}.drvPath;
  121. outPath = assert condition; drv.${outputName}.outPath;
  122. };
  123. };
  124. outputsList = map outputToAttrListElement outputs;
  125. in commonAttrs // {
  126. outputUnspecified = true;
  127. drvPath = assert condition; drv.drvPath;
  128. outPath = assert condition; drv.outPath;
  129. };
  130. /* Strip a derivation of all non-essential attributes, returning
  131. only those needed by hydra-eval-jobs. Also strictly evaluate the
  132. result to ensure that there are no thunks kept alive to prevent
  133. garbage collection. */
  134. hydraJob = drv:
  135. let
  136. outputs = drv.outputs or ["out"];
  137. commonAttrs =
  138. { inherit (drv) name system meta; inherit outputs; }
  139. // lib.optionalAttrs (drv._hydraAggregate or false) {
  140. _hydraAggregate = true;
  141. constituents = map hydraJob (lib.flatten drv.constituents);
  142. }
  143. // (lib.listToAttrs outputsList);
  144. makeOutput = outputName:
  145. let output = drv.${outputName}; in
  146. { name = outputName;
  147. value = commonAttrs // {
  148. outPath = output.outPath;
  149. drvPath = output.drvPath;
  150. type = "derivation";
  151. inherit outputName;
  152. };
  153. };
  154. outputsList = map makeOutput outputs;
  155. drv' = (lib.head outputsList).value;
  156. in lib.deepSeq drv' drv';
  157. /* Make a set of packages with a common scope. All packages called
  158. with the provided `callPackage' will be evaluated with the same
  159. arguments. Any package in the set may depend on any other. The
  160. `overrideScope' function allows subsequent modification of the package
  161. set in a consistent way, i.e. all packages in the set will be
  162. called with the overridden packages. The package sets may be
  163. hierarchical: the packages in the set are called with the scope
  164. provided by `newScope' and the set provides a `newScope' attribute
  165. which can form the parent scope for later package sets. */
  166. makeScope = newScope: f:
  167. let self = f self // {
  168. newScope = scope: newScope (self // scope);
  169. callPackage = self.newScope {};
  170. overrideScope = g:
  171. makeScope newScope
  172. (self_: let super = f self_; in super // g super self_);
  173. packages = f;
  174. };
  175. in self;
  176. }