1<chapter xmlns="http://docbook.org/ns/docbook"
2 xmlns:xlink="http://www.w3.org/1999/xlink"
3 xml:id="chap-functions">
4
5<title>Functions reference</title>
6
7<para>
8 The nixpkgs repository has several utility functions to manipulate Nix expressions.
9</para>
10
11<section xml:id="sec-pkgs-overridePackages">
12 <title>pkgs.overridePackages</title>
13
14 <para>
15 This function inside the nixpkgs expression (<varname>pkgs</varname>)
16 can be used to override the set of packages itself.
17 </para>
18 <para>
19 Warning: this function is expensive and must not be used from within
20 the nixpkgs repository.
21 </para>
22 <para>
23 Example usage:
24
25 <programlisting>let
26 pkgs = import <nixpkgs> {};
27 newpkgs = pkgs.overridePackages (self: super: {
28 foo = super.foo.override { ... };
29 };
30in ...</programlisting>
31 </para>
32
33 <para>
34 The resulting <varname>newpkgs</varname> will have the new <varname>foo</varname>
35 expression, and all other expressions depending on <varname>foo</varname> will also
36 use the new <varname>foo</varname> expression.
37 </para>
38
39 <para>
40 The behavior of this function is similar to <link
41 linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>.
42 </para>
43
44 <para>
45 The <varname>self</varname> parameter refers to the final package set with the
46 applied overrides. Using this parameter may lead to infinite recursion if not
47 used consciously.
48 </para>
49
50 <para>
51 The <varname>super</varname> parameter refers to the old package set.
52 It's equivalent to <varname>pkgs</varname> in the above example.
53 </para>
54
55</section>
56
57<section xml:id="sec-pkg-override">
58 <title><pkg>.override</title>
59
60 <para>
61 The function <varname>override</varname> is usually available for all the
62 derivations in the nixpkgs expression (<varname>pkgs</varname>).
63 </para>
64 <para>
65 It is used to override the arguments passed to a function.
66 </para>
67 <para>
68 Example usages:
69
70 <programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
71 <programlisting>pkgs.overridePackages (self: super: {
72 foo = super.foo.override { barSupport = true ; };
73})</programlisting>
74 <programlisting>mypkg = pkgs.callPackage ./mypkg.nix {
75 mydep = pkgs.mydep.override { ... };
76})</programlisting>
77 </para>
78
79 <para>
80 In the first example, <varname>pkgs.foo</varname> is the result of a function call
81 with some default arguments, usually a derivation.
82 Using <varname>pkgs.foo.override</varname> will call the same function with
83 the given new arguments.
84 </para>
85
86</section>
87
88<section xml:id="sec-pkg-overrideDerivation">
89 <title><pkg>.overrideDerivation</title>
90
91 <para>
92 The function <varname>overrideDerivation</varname> is usually available for all the
93 derivations in the nixpkgs expression (<varname>pkgs</varname>).
94 </para>
95 <para>
96 It is used to create a new derivation by overriding the attributes of
97 the original derivation according to the given function.
98 </para>
99
100 <para>
101 Example usage:
102
103 <programlisting>mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
104 name = "sed-4.2.2-pre";
105 src = fetchurl {
106 url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
107 sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
108 };
109 patches = [];
110});</programlisting>
111 </para>
112
113 <para>
114 In the above example, the name, src and patches of the derivation
115 will be overridden, while all other attributes will be retained from the
116 original derivation.
117 </para>
118
119 <para>
120 The argument <varname>oldAttrs</varname> is used to refer to the attribute set of
121 the original derivation.
122 </para>
123
124</section>
125
126<section xml:id="sec-lib-makeOverridable">
127 <title>lib.makeOverridable</title>
128
129 <para>
130 The function <varname>lib.makeOverridable</varname> is used make the result
131 of a function easily customizable. This utility only makes sense for functions
132 that accept an argument set and return an attribute set.
133 </para>
134
135 <para>
136 Example usage:
137
138 <programlisting>f = { a, b }: { result = a+b; }
139c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
140
141 </para>
142
143 <para>
144 The variable <varname>c</varname> is the value of the <varname>f</varname> function
145 applied with some default arguments. Hence the value of <varname>c.result</varname>
146 is <literal>3</literal>, in this example.
147 </para>
148
149 <para>
150 The variable <varname>c</varname> however also has some additional functions, like
151 <link linkend="sec-pkg-override">c.override</link> which can be used to
152 override the default arguments. In this example the value of
153 <varname>(c.override { a = 4; }).result</varname> is 6.
154 </para>
155
156</section>
157
158
159<section xml:id="sec-fhs-environments">
160 <title>buildFHSChrootEnv/buildFHSUserEnv</title>
161
162 <para>
163 <function>buildFHSChrootEnv</function> and
164 <function>buildFHSUserEnv</function> provide a way to build and run
165 FHS-compatible lightweight sandboxes. They get their own isolated root with
166 binded <filename>/nix/store</filename>, so their footprint in terms of disk
167 space needed is quite small. This allows one to run software which is hard or
168 unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
169 games distributed as tarballs, software with integrity checking and/or external
170 self-updated binaries.
171 </para>
172
173 <para>
174 <function>buildFHSChrootEnv</function> allows to create persistent
175 environments, which can be constructed, deconstructed and entered by
176 multiple users at once. A downside is that it requires
177 <literal>root</literal> access for both those who create and destroy and
178 those who enter it. It can be useful to create environments for daemons that
179 one can enter and observe.
180 </para>
181
182 <para>
183 <function>buildFHSUserEnv</function> uses Linux namespaces feature to create
184 temporary lightweight environments which are destroyed after all child
185 processes exit. It does not require root access, and can be useful to create
186 sandboxes and wrap applications.
187 </para>
188
189 <para>
190 Those functions both rely on <function>buildFHSEnv</function>, which creates
191 an actual directory structure given a list of necessary packages and extra
192 build commands.
193 <function>buildFHSChrootEnv</function> and <function>buildFHSUserEnv</function>
194 both accept those arguments which are passed to
195 <function>buildFHSEnv</function>:
196 </para>
197
198 <variablelist>
199 <varlistentry>
200 <term><literal>name</literal></term>
201
202 <listitem><para>Environment name.</para></listitem>
203 </varlistentry>
204
205 <varlistentry>
206 <term><literal>targetPkgs</literal></term>
207
208 <listitem><para>Packages to be installed for the main host's architecture
209 (i.e. x86_64 on x86_64 installations).</para></listitem>
210 </varlistentry>
211
212 <varlistentry>
213 <term><literal>multiPkgs</literal></term>
214
215 <listitem><para>Packages to be installed for all architectures supported by
216 a host (i.e. i686 and x86_64 on x86_64 installations).</para></listitem>
217 </varlistentry>
218
219 <varlistentry>
220 <term><literal>extraBuildCommands</literal></term>
221
222 <listitem><para>Additional commands to be executed for finalizing the
223 directory structure.</para></listitem>
224 </varlistentry>
225
226 <varlistentry>
227 <term><literal>extraBuildCommandsMulti</literal></term>
228
229 <listitem><para>Like <literal>extraBuildCommandsMulti</literal>, but
230 executed only on multilib architectures.</para></listitem>
231 </varlistentry>
232 </variablelist>
233
234 <para>
235 Additionally, <function>buildFHSUserEnv</function> accepts
236 <literal>runScript</literal> parameter, which is a command that would be
237 executed inside the sandbox and passed all the command line arguments. It
238 default to <literal>bash</literal>.
239 One can create a simple environment using a <literal>shell.nix</literal>
240 like that:
241 </para>
242
243<programlisting><![CDATA[
244{ pkgs ? import <nixpkgs> {} }:
245
246(pkgs.buildFHSUserEnv {
247 name = "simple-x11-env";
248 targetPkgs = pkgs: (with pkgs;
249 [ udev
250 alsaLib
251 ]) ++ (with pkgs.xlibs;
252 [ libX11
253 libXcursor
254 libXrandr
255 ]);
256 multiPkgs = pkgs: (with pkgs;
257 [ udev
258 alsaLib
259 ]) ++ (with [];
260 runScript = "bash";
261}).env
262]]></programlisting>
263
264 <para>
265 Running <literal>nix-shell</literal> would then drop you into a shell with
266 these libraries and binaries available. You can use this to run
267 closed-source applications which expect FHS structure without hassles:
268 simply change <literal>runScript</literal> to the application path,
269 e.g. <filename>./bin/start.sh</filename> -- relative paths are supported.
270 </para>
271</section>
272
273</chapter>