lol
1/* This file contains various functions that take a stdenv and return
2 a new stdenv with different behaviour, e.g. using a different C
3 compiler. */
4
5pkgs:
6
7rec {
8
9
10 # Override the compiler in stdenv for specific packages.
11 overrideCC = stdenv: cc: stdenv.override { allowedRequisites = null; cc = cc; };
12
13
14 # Add some arbitrary packages to buildInputs for specific packages.
15 # Used to override packages in stdenv like Make. Should not be used
16 # for other dependencies.
17 overrideInStdenv = stdenv: pkgs:
18 stdenv.override (prev: { allowedRequisites = null; extraBuildInputs = prev.extraBuildInputs or [] ++ pkgs; });
19
20
21 # Override the setup script of stdenv. Useful for testing new
22 # versions of the setup script without causing a rebuild of
23 # everything.
24 #
25 # Example:
26 # randomPkg = import ../bla { ...
27 # stdenv = overrideSetup stdenv ../stdenv/generic/setup-latest.sh;
28 # };
29 overrideSetup = stdenv: setupScript: stdenv.override { inherit setupScript; };
30
31
32 # Return a modified stdenv that tries to build statically linked
33 # binaries.
34 makeStaticBinaries = stdenv: stdenv //
35 { mkDerivation = args: stdenv.mkDerivation (args // {
36 NIX_CFLAGS_LINK = "-static";
37 configureFlags =
38 toString args.configureFlags or ""
39 + " --disable-shared"; # brrr...
40 });
41 isStatic = true;
42 };
43
44
45 # Return a modified stdenv that builds static libraries instead of
46 # shared libraries.
47 makeStaticLibraries = stdenv: stdenv //
48 { mkDerivation = args: stdenv.mkDerivation (args // {
49 dontDisableStatic = true;
50 configureFlags =
51 toString args.configureFlags or ""
52 + " --enable-static --disable-shared";
53 });
54 };
55
56
57 # Return a modified stdenv that adds a cross compiler to the
58 # builds.
59 makeStdenvCross = stdenv: cross: binutilsCross: gccCross: stdenv //
60 { mkDerivation = {name ? "", buildInputs ? [], nativeBuildInputs ? [],
61 propagatedBuildInputs ? [], propagatedNativeBuildInputs ? [],
62 selfNativeBuildInput ? false, ...}@args: let
63
64 # *BuildInputs exists temporarily as another name for
65 # *HostInputs.
66
67 # In nixpkgs, sometimes 'null' gets in as a buildInputs element,
68 # and we handle that through isAttrs.
69 getNativeDrv = drv: drv.nativeDrv or drv;
70 getCrossDrv = drv: drv.crossDrv or drv;
71 nativeBuildInputsDrvs = map getNativeDrv nativeBuildInputs;
72 buildInputsDrvs = map getCrossDrv buildInputs;
73 buildInputsDrvsAsBuildInputs = map getNativeDrv buildInputs;
74 propagatedBuildInputsDrvs = map getCrossDrv propagatedBuildInputs;
75 propagatedNativeBuildInputsDrvs = map getNativeDrv propagatedNativeBuildInputs;
76
77 # The base stdenv already knows that nativeBuildInputs and
78 # buildInputs should be built with the usual gcc-wrapper
79 # And the same for propagatedBuildInputs.
80 nativeDrv = stdenv.mkDerivation args;
81
82 # Temporary expression until the cross_renaming, to handle the
83 # case of pkgconfig given as buildInput, but to be used as
84 # nativeBuildInput.
85 hostAsNativeDrv = drv:
86 builtins.unsafeDiscardStringContext drv.nativeDrv.drvPath
87 == builtins.unsafeDiscardStringContext drv.crossDrv.drvPath;
88 buildInputsNotNull = stdenv.lib.filter
89 (drv: builtins.isAttrs drv && drv ? nativeDrv) buildInputs;
90 nativeInputsFromBuildInputs = stdenv.lib.filter hostAsNativeDrv buildInputsNotNull;
91
92 # We should overwrite the input attributes in crossDrv, to overwrite
93 # the defaults for only-native builds in the base stdenv
94 crossDrv = if cross == null then nativeDrv else
95 stdenv.mkDerivation (args // {
96 name = name + "-" + cross.config;
97 nativeBuildInputs = nativeBuildInputsDrvs
98 ++ nativeInputsFromBuildInputs
99 ++ [ gccCross binutilsCross ] ++
100 stdenv.lib.optional selfNativeBuildInput nativeDrv;
101
102 # Cross-linking dynamic libraries, every buildInput should
103 # be propagated because ld needs the -rpath-link to find
104 # any library needed to link the program dynamically at
105 # loader time. ld(1) explains it.
106 buildInputs = [];
107 propagatedBuildInputs = propagatedBuildInputsDrvs ++ buildInputsDrvs;
108 propagatedNativeBuildInputs = propagatedNativeBuildInputsDrvs;
109
110 crossConfig = cross.config;
111 } // args.crossAttrs or {});
112 in nativeDrv // {
113 inherit crossDrv nativeDrv;
114 };
115 } // {
116 inherit cross gccCross binutilsCross;
117 ccCross = gccCross;
118 };
119
120
121 /* Modify a stdenv so that the specified attributes are added to
122 every derivation returned by its mkDerivation function.
123
124 Example:
125 stdenvNoOptimise =
126 addAttrsToDerivation
127 { NIX_CFLAGS_COMPILE = "-O0"; }
128 stdenv;
129 */
130 addAttrsToDerivation = extraAttrs: stdenv: stdenv //
131 { mkDerivation = args: stdenv.mkDerivation (args // extraAttrs); };
132
133
134 /* Return a modified stdenv that builds packages with GCC's coverage
135 instrumentation. The coverage note files (*.gcno) are stored in
136 $out/.build, along with the source code of the package, to enable
137 programs like lcov to produce pretty-printed reports.
138 */
139 addCoverageInstrumentation = stdenv:
140 overrideInStdenv stdenv [ pkgs.enableGCOVInstrumentation pkgs.keepBuildTree ];
141
142
143 /* Replace the meta.maintainers field of a derivation. This is useful
144 when you want to fork to update some packages without disturbing other
145 developers.
146
147 e.g.: in all-packages.nix:
148
149 # remove all maintainers.
150 defaultStdenv = replaceMaintainersField allStdenvs.stdenv pkgs [];
151 */
152 replaceMaintainersField = stdenv: pkgs: maintainers: stdenv //
153 { mkDerivation = args:
154 stdenv.lib.recursiveUpdate
155 (stdenv.mkDerivation args)
156 { meta.maintainers = maintainers; };
157 };
158
159
160 /* Use the trace output to report all processed derivations with their
161 license name.
162 */
163 traceDrvLicenses = stdenv: stdenv //
164 { mkDerivation = args:
165 let
166 pkg = stdenv.mkDerivation args;
167 printDrvPath = val: let
168 drvPath = builtins.unsafeDiscardStringContext pkg.drvPath;
169 license = pkg.meta.license or null;
170 in
171 builtins.trace "@:drv:${toString drvPath}:${builtins.toString license}:@" val;
172 in pkg // {
173 outPath = printDrvPath pkg.outPath;
174 drvPath = printDrvPath pkg.drvPath;
175 };
176 };
177
178
179 /* Abort if the license predicate is not verified for a derivation
180 declared with mkDerivation.
181
182 One possible predicate to avoid all non-free packages can be achieved
183 with the following function:
184
185 isFree = license: with builtins;
186 if isNull license then true
187 else if isList license then lib.all isFree license
188 else license != "non-free" && license != "unfree";
189
190 This adapter can be defined on the defaultStdenv definition. You can
191 use it by patching the all-packages.nix file or by using the override
192 feature of ~/.nixpkgs/config.nix .
193 */
194 validateLicenses = licensePred: stdenv: stdenv //
195 { mkDerivation = args:
196 let
197 pkg = stdenv.mkDerivation args;
198 drv = builtins.unsafeDiscardStringContext pkg.drvPath;
199 license =
200 pkg.meta.license or
201 # Fixed-output derivations such as source tarballs usually
202 # don't have licensing information, but that's OK.
203 (pkg.outputHash or
204 (builtins.trace
205 "warning: ${drv} lacks licensing information" null));
206
207 validate = arg:
208 if licensePred license then arg
209 else abort ''
210 while building ${drv}:
211 license `${builtins.toString license}' does not pass the predicate.
212 '';
213
214 in pkg // {
215 outPath = validate pkg.outPath;
216 drvPath = validate pkg.drvPath;
217 };
218 };
219
220
221 /* Modify a stdenv so that it produces debug builds; that is,
222 binaries have debug info, and compiler optimisations are
223 disabled. */
224 keepDebugInfo = stdenv: stdenv //
225 { mkDerivation = args: stdenv.mkDerivation (args // {
226 dontStrip = true;
227 NIX_CFLAGS_COMPILE = toString (args.NIX_CFLAGS_COMPILE or "") + " -ggdb -Og";
228 });
229 };
230
231
232 /* Modify a stdenv so that it uses the Gold linker. */
233 useGoldLinker = stdenv: stdenv //
234 { mkDerivation = args: stdenv.mkDerivation (args // {
235 NIX_CFLAGS_LINK = toString (args.NIX_CFLAGS_LINK or "") + " -fuse-ld=gold";
236 });
237 };
238
239 dropCxx = drv: drv.override {
240 stdenv = if pkgs.stdenv.isDarwin
241 then pkgs.allStdenvs.stdenvDarwinNaked
242 else pkgs.stdenv;
243 };
244}