1<chapter xmlns="http://docbook.org/ns/docbook"
2 xmlns:xlink="http://www.w3.org/1999/xlink"
3 xml:id="chap-package-notes">
4
5<title>Package Notes</title>
6
7<para>This chapter contains information about how to use and maintain
8the Nix expressions for a number of specific packages, such as the
9Linux kernel or X.org.</para>
10
11
12<!--============================================================-->
13
14<section xml:id="sec-linux-kernel">
15
16<title>Linux kernel</title>
17
18<para>The Nix expressions to build the Linux kernel are in <link
19xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel"><filename>pkgs/os-specific/linux/kernel</filename></link>.</para>
20
21<para>The function that builds the kernel has an argument
22<varname>kernelPatches</varname> which should be a list of
23<literal>{name, patch, extraConfig}</literal> attribute sets, where
24<varname>name</varname> is the name of the patch (which is included in
25the kernel’s <varname>meta.description</varname> attribute),
26<varname>patch</varname> is the patch itself (possibly compressed),
27and <varname>extraConfig</varname> (optional) is a string specifying
28extra options to be concatenated to the kernel configuration file
29(<filename>.config</filename>).</para>
30
31<para>The kernel derivation exports an attribute
32<varname>features</varname> specifying whether optional functionality
33is or isn’t enabled. This is used in NixOS to implement
34kernel-specific behaviour. For instance, if the kernel has the
35<varname>iwlwifi</varname> feature (i.e. has built-in support for
36Intel wireless chipsets), then NixOS doesn’t have to build the
37external <varname>iwlwifi</varname> package:
38
39<programlisting>
40modulesTree = [kernel]
41 ++ pkgs.lib.optional (!kernel.features ? iwlwifi) kernelPackages.iwlwifi
42 ++ ...;
43</programlisting>
44
45</para>
46
47<para>How to add a new (major) version of the Linux kernel to Nixpkgs:
48
49<orderedlist>
50
51 <listitem>
52 <para>Copy the old Nix expression
53 (e.g. <filename>linux-2.6.21.nix</filename>) to the new one
54 (e.g. <filename>linux-2.6.22.nix</filename>) and update it.</para>
55 </listitem>
56
57 <listitem>
58 <para>Add the new kernel to <filename>all-packages.nix</filename>
59 (e.g., create an attribute
60 <varname>kernel_2_6_22</varname>).</para>
61 </listitem>
62
63 <listitem>
64 <para>Now we’re going to update the kernel configuration. First
65 unpack the kernel. Then for each supported platform
66 (<literal>i686</literal>, <literal>x86_64</literal>,
67 <literal>uml</literal>) do the following:
68
69 <orderedlist>
70
71 <listitem>
72 <para>Make an copy from the old
73 config (e.g. <filename>config-2.6.21-i686-smp</filename>) to
74 the new one
75 (e.g. <filename>config-2.6.22-i686-smp</filename>).</para>
76 </listitem>
77
78 <listitem>
79 <para>Copy the config file for this platform
80 (e.g. <filename>config-2.6.22-i686-smp</filename>) to
81 <filename>.config</filename> in the kernel source tree.
82 </para>
83 </listitem>
84
85 <listitem>
86 <para>Run <literal>make oldconfig
87 ARCH=<replaceable>{i386,x86_64,um}</replaceable></literal>
88 and answer all questions. (For the uml configuration, also
89 add <literal>SHELL=bash</literal>.) Make sure to keep the
90 configuration consistent between platforms (i.e. don’t
91 enable some feature on <literal>i686</literal> and disable
92 it on <literal>x86_64</literal>).
93 </para>
94 </listitem>
95
96 <listitem>
97 <para>If needed you can also run <literal>make
98 menuconfig</literal>:
99
100 <screen>
101$ nix-env -i ncurses
102$ export NIX_CFLAGS_LINK=-lncurses
103$ make menuconfig ARCH=<replaceable>arch</replaceable></screen>
104
105 </para>
106 </listitem>
107
108 <listitem>
109 <para>Copy <filename>.config</filename> over the new config
110 file (e.g. <filename>config-2.6.22-i686-smp</filename>).</para>
111 </listitem>
112
113 </orderedlist>
114
115 </para>
116
117 </listitem>
118
119 <listitem>
120 <para>Test building the kernel: <literal>nix-build -A
121 kernel_2_6_22</literal>. If it compiles, ship it! For extra
122 credit, try booting NixOS with it.</para>
123 </listitem>
124
125 <listitem>
126 <para>It may be that the new kernel requires updating the external
127 kernel modules and kernel-dependent packages listed in the
128 <varname>linuxPackagesFor</varname> function in
129 <filename>all-packages.nix</filename> (such as the NVIDIA drivers,
130 AUFS, etc.). If the updated packages aren’t backwards compatible
131 with older kernels, you may need to keep the older versions
132 around.</para>
133 </listitem>
134
135</orderedlist>
136
137</para>
138
139</section>
140
141
142<!--============================================================-->
143
144<section xml:id="sec-xorg">
145
146<title>X.org</title>
147
148<para>The Nix expressions for the X.org packages reside in
149<filename>pkgs/servers/x11/xorg/default.nix</filename>. This file is
150automatically generated from lists of tarballs in an X.org release.
151As such it should not be modified directly; rather, you should modify
152the lists, the generator script or the file
153<filename>pkgs/servers/x11/xorg/overrides.nix</filename>, in which you
154can override or add to the derivations produced by the
155generator.</para>
156
157<para>The generator is invoked as follows:
158
159<screen>
160$ cd pkgs/servers/x11/xorg
161$ cat tarballs-7.5.list extra.list old.list \
162 | perl ./generate-expr-from-tarballs.pl
163</screen>
164
165For each of the tarballs in the <filename>.list</filename> files, the
166script downloads it, unpacks it, and searches its
167<filename>configure.ac</filename> and <filename>*.pc.in</filename>
168files for dependencies. This information is used to generate
169<filename>default.nix</filename>. The generator caches downloaded
170tarballs between runs. Pay close attention to the <literal>NOT FOUND:
171<replaceable>name</replaceable></literal> messages at the end of the
172run, since they may indicate missing dependencies. (Some might be
173optional dependencies, however.)</para>
174
175<para>A file like <filename>tarballs-7.5.list</filename> contains all
176tarballs in a X.org release. It can be generated like this:
177
178<screen>
179$ export i="mirror://xorg/X11R7.4/src/everything/"
180$ cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
181 | perl -e 'while (<>) { if (/(href|HREF)="([^"]*.bz2)"/) { print "$ENV{'i'}$2\n"; }; }' \
182 | sort > tarballs-7.4.list
183</screen>
184
185<filename>extra.list</filename> contains libraries that aren’t part of
186X.org proper, but are closely related to it, such as
187<literal>libxcb</literal>. <filename>old.list</filename> contains
188some packages that were removed from X.org, but are still needed by
189some people or by other packages (such as
190<varname>imake</varname>).</para>
191
192<para>If the expression for a package requires derivation attributes
193that the generator cannot figure out automatically (say,
194<varname>patches</varname> or a <varname>postInstall</varname> hook),
195you should modify
196<filename>pkgs/servers/x11/xorg/overrides.nix</filename>.</para>
197
198</section>
199
200
201
202<!--============================================================-->
203
204<!--
205<section>
206 <title>Gnome</title>
207 <para>* Expression is auto-generated</para>
208 <para>* How to update</para>
209</section>
210-->
211
212
213<!--============================================================-->
214
215<!--
216<section>
217 <title>GCC</title>
218 <para>…</para>
219</section>
220-->
221
222<!--============================================================-->
223
224<section xml:id="sec-eclipse">
225
226 <title>Eclipse</title>
227
228 <para>
229 The Nix expressions related to the Eclipse platform and IDE are in
230 <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/eclipse"><filename>pkgs/applications/editors/eclipse</filename></link>.
231 </para>
232
233 <para>
234 Nixpkgs provides a number of packages that will install Eclipse in
235 its various forms, these range from the bare-bones Eclipse
236 Platform to the more fully featured Eclipse SDK or Scala-IDE
237 packages and multiple version are often available. It is possible
238 to list available Eclipse packages by issuing the command:
239
240<screen>
241$ nix-env -f '<nixpkgs>' -qaP -A eclipses --description
242</screen>
243
244 Once an Eclipse variant is installed it can be run using the
245 <command>eclipse</command> command, as expected. From within
246 Eclipse it is then possible to install plugins in the usual manner
247 by either manually specifying an Eclipse update site or by
248 installing the Marketplace Client plugin and using it to discover
249 and install other plugins. This installation method provides an
250 Eclipse installation that closely resemble a manually installed
251 Eclipse.
252 </para>
253
254 <para>
255 If you prefer to install plugins in a more declarative manner then
256 Nixpkgs also offer a number of Eclipse plugins that can be
257 installed in an <emphasis>Eclipse environment</emphasis>. This
258 type of environment is created using the function
259 <varname>eclipseWithPlugins</varname> found inside the
260 <varname>nixpkgs.eclipses</varname> attribute set. This function
261 takes as argument <literal>{ eclipse, plugins ? [], jvmArgs ? []
262 }</literal> where <varname>eclipse</varname> is a one of the
263 Eclipse packages described above, <varname>plugins</varname> is a
264 list of plugin derivations, and <varname>jvmArgs</varname> is a
265 list of arguments given to the JVM running the Eclipse. For
266 example, say you wish to install the latest Eclipse Platform with
267 the popular Eclipse Color Theme plugin and also allow Eclipse to
268 use more RAM. You could then add
269
270<screen>
271packageOverrides = pkgs: {
272 myEclipse = with pkgs.eclipses; eclipseWithPlugins {
273 eclipse = eclipse-platform;
274 jvmArgs = [ "-Xmx2048m" ];
275 plugins = [ plugins.color-theme ];
276 };
277}
278</screen>
279
280 to your Nixpkgs configuration
281 (<filename>~/.config/nixpkgs/config.nix</filename>) and install it by
282 running <command>nix-env -f '<nixpkgs>' -iA
283 myEclipse</command> and afterward run Eclipse as usual. It is
284 possible to find out which plugins are available for installation
285 using <varname>eclipseWithPlugins</varname> by running
286
287<screen>
288$ nix-env -f '<nixpkgs>' -qaP -A eclipses.plugins --description
289</screen>
290 </para>
291
292 <para>
293 If there is a need to install plugins that are not available in
294 Nixpkgs then it may be possible to define these plugins outside
295 Nixpkgs using the <varname>buildEclipseUpdateSite</varname> and
296 <varname>buildEclipsePlugin</varname> functions found in the
297 <varname>nixpkgs.eclipses.plugins</varname> attribute set. Use the
298 <varname>buildEclipseUpdateSite</varname> function to install a
299 plugin distributed as an Eclipse update site. This function takes
300 <literal>{ name, src }</literal> as argument where
301 <literal>src</literal> indicates the Eclipse update site archive.
302 All Eclipse features and plugins within the downloaded update site
303 will be installed. When an update site archive is not available
304 then the <varname>buildEclipsePlugin</varname> function can be
305 used to install a plugin that consists of a pair of feature and
306 plugin JARs. This function takes an argument <literal>{ name,
307 srcFeature, srcPlugin }</literal> where
308 <literal>srcFeature</literal> and <literal>srcPlugin</literal> are
309 the feature and plugin JARs, respectively.
310 </para>
311
312 <para>
313 Expanding the previous example with two plugins using the above
314 functions we have
315<screen>
316packageOverrides = pkgs: {
317 myEclipse = with pkgs.eclipses; eclipseWithPlugins {
318 eclipse = eclipse-platform;
319 jvmArgs = [ "-Xmx2048m" ];
320 plugins = [
321 plugins.color-theme
322 (plugins.buildEclipsePlugin {
323 name = "myplugin1-1.0";
324 srcFeature = fetchurl {
325 url = "http://…/features/myplugin1.jar";
326 sha256 = "123…";
327 };
328 srcPlugin = fetchurl {
329 url = "http://…/plugins/myplugin1.jar";
330 sha256 = "123…";
331 };
332 });
333 (plugins.buildEclipseUpdateSite {
334 name = "myplugin2-1.0";
335 src = fetchurl {
336 stripRoot = false;
337 url = "http://…/myplugin2.zip";
338 sha256 = "123…";
339 };
340 });
341 ];
342 };
343}
344</screen>
345 </para>
346
347</section>
348
349<section xml:id="sec-elm">
350
351<title>Elm</title>
352
353<para>
354The Nix expressions for Elm reside in
355<filename>pkgs/development/compilers/elm</filename>. They are generated
356automatically by <command>update-elm.rb</command> script. One should
357specify versions of Elm packages inside the script, clear the
358<filename>packages</filename> directory and run the script from inside it.
359<literal>elm-reactor</literal> is special because it also has Elm package
360dependencies. The process is not automated very much for now -- you should
361get the <literal>elm-reactor</literal> source tree (e.g. with
362<command>nix-shell</command>) and run <command>elm2nix.rb</command> inside
363it. Place the resulting <filename>package.nix</filename> file into
364<filename>packages/elm-reactor-elm.nix</filename>.
365</para>
366
367</section>
368
369<section xml:id="sec-shell-helpers">
370
371<title>Interactive shell helpers</title>
372
373<para>
374 Some packages provide the shell integration to be more useful. But
375 unlike other systems, nix doesn't have a standard share directory
376 location. This is why a bunch <command>PACKAGE-share</command>
377 scripts are shipped that print the location of the corresponding
378 shared folder.
379
380 Current list of such packages is as following:
381
382 <itemizedlist>
383 <listitem>
384 <para>
385 <literal>autojump</literal>: <command>autojump-share</command>
386 </para>
387 </listitem>
388 <listitem>
389 <para>
390 <literal>fzf</literal>: <command>fzf-share</command>
391 </para>
392 </listitem>
393 </itemizedlist>
394
395 E.g. <literal>autojump</literal> can then used in the .bashrc like this:
396<screen>
397 source "$(autojump-share)/autojump.bash"
398</screen>
399</para>
400
401</section>
402
403<section xml:id="sec-steam">
404
405<title>Steam</title>
406
407<section xml:id="sec-steam-nix">
408
409<title>Steam in Nix</title>
410
411<para>
412 Steam is distributed as a <filename>.deb</filename> file, for now only
413 as an i686 package (the amd64 package only has documentation).
414 When unpacked, it has a script called <filename>steam</filename> that
415 in ubuntu (their target distro) would go to <filename>/usr/bin
416 </filename>. When run for the first time, this script copies some
417 files to the user's home, which include another script that is the
418 ultimate responsible for launching the steam binary, which is also
419 in $HOME.
420</para>
421<para>
422 Nix problems and constraints:
423<itemizedlist>
424 <listitem><para>We don't have <filename>/bin/bash</filename> and many
425 scripts point there. Similarly for <filename>/usr/bin/python</filename>
426 .</para></listitem>
427 <listitem><para>We don't have the dynamic loader in <filename>/lib
428 </filename>.</para></listitem>
429 <listitem><para>The <filename>steam.sh</filename> script in $HOME can
430 not be patched, as it is checked and rewritten by steam.</para></listitem>
431 <listitem><para>The steam binary cannot be patched, it's also checked.</para></listitem>
432</itemizedlist>
433</para>
434<para>
435 The current approach to deploy Steam in NixOS is composing a FHS-compatible
436 chroot environment, as documented
437 <link xlink:href="http://sandervanderburg.blogspot.nl/2013/09/composing-fhs-compatible-chroot.html">here</link>.
438 This allows us to have binaries in the expected paths without disrupting the system,
439 and to avoid patching them to work in a non FHS environment.
440</para>
441
442</section>
443
444<section xml:id="sec-steam-play">
445
446<title>How to play</title>
447
448<para>
449 For 64-bit systems it's important to have
450 <programlisting>hardware.opengl.driSupport32Bit = true;</programlisting>
451 in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
452 <programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
453 if you are using PulseAudio - this will enable 32bit ALSA apps integration.
454 To use the Steam controller, you need to add
455 <programlisting>services.udev.extraRules = ''
456 SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", MODE="0666"
457 KERNEL=="uinput", MODE="0660", GROUP="users", OPTIONS+="static_node=uinput"
458 '';</programlisting>
459 to your configuration.
460</para>
461
462</section>
463
464<section xml:id="sec-steam-troub">
465
466<title>Troubleshooting</title>
467
468<para>
469<variablelist>
470
471 <varlistentry>
472 <term>Steam fails to start. What do I do?</term>
473 <listitem><para>Try to run
474 <programlisting>strace steam</programlisting>
475 to see what is causing steam to fail.</para></listitem>
476 </varlistentry>
477
478 <varlistentry>
479 <term>Using the FOSS Radeon drivers</term>
480 <listitem><itemizedlist><listitem><para>
481 The open source radeon drivers need a newer libc++ than is provided
482 by the default runtime, which leads to a crash on launch. Use
483 <programlisting>environment.systemPackages = [(pkgs.steam.override { newStdcpp = true; })];</programlisting>
484 in your config if you get an error like
485 <programlisting>
486libGL error: unable to load driver: radeonsi_dri.so
487libGL error: driver pointer missing
488libGL error: failed to load driver: radeonsi
489libGL error: unable to load driver: swrast_dri.so
490libGL error: failed to load driver: swrast</programlisting></para></listitem>
491 <listitem><para>
492 Steam ships statically linked with a version of libcrypto that
493 conflics with the one dynamically loaded by radeonsi_dri.so.
494 If you get the error
495 <programlisting>steam.sh: line 713: 7842 Segmentation fault (core dumped)</programlisting>
496 have a look at <link xlink:href="https://github.com/NixOS/nixpkgs/pull/20269">this pull request</link>.
497 </para></listitem>
498
499 </itemizedlist></listitem></varlistentry>
500
501 <varlistentry>
502 <term>Java</term>
503 <listitem><orderedlist>
504 <listitem><para>
505 There is no java in steam chrootenv by default. If you get a message like
506 <programlisting>/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found</programlisting>
507 You need to add
508 <programlisting> steam.override { withJava = true; };</programlisting>
509 to your configuration.
510 </para></listitem>
511 </orderedlist></listitem></varlistentry>
512
513</variablelist>
514</para>
515
516</section>
517
518<section xml:id="sec-steam-run">
519
520<title>steam-run</title>
521<para>
522The FHS-compatible chroot used for steam can also be used to run
523other linux games that expect a FHS environment.
524To do it, add
525<programlisting>pkgs.(steam.override {
526 nativeOnly = true;
527 newStdcpp = true;
528 }).run</programlisting>
529to your configuration, rebuild, and run the game with
530<programlisting>steam-run ./foo</programlisting>
531</para>
532
533</section>
534
535</section>
536
537<section xml:id="sec-emacs">
538
539<title>Emacs</title>
540
541<section xml:id="sec-emacs-config">
542
543<title>Configuring Emacs</title>
544
545<para>
546 The Emacs package comes with some extra helpers to make it easier to
547 configure. <varname>emacsWithPackages</varname> allows you to manage
548 packages from ELPA. This means that you will not have to install
549 that packages from within Emacs. For instance, if you wanted to use
550 <literal>company</literal>, <literal>counsel</literal>,
551 <literal>flycheck</literal>, <literal>ivy</literal>,
552 <literal>magit</literal>, <literal>projectile</literal>, and
553 <literal>use-package</literal> you could use this as a
554 <filename>~/.config/nixpkgs/config.nix</filename> override:
555</para>
556
557<screen>
558{
559 packageOverrides = pkgs: with pkgs; {
560 myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
561 company
562 counsel
563 flycheck
564 ivy
565 magit
566 projectile
567 use-package
568 ]));
569 }
570}
571</screen>
572
573<para>
574 You can install it like any other packages via <command>nix-env -iA
575 myEmacs</command>. However, this will only install those packages.
576 It will not <literal>configure</literal> them for us. To do this, we
577 need to provide a configuration file. Luckily, it is possible to do
578 this from within Nix! By modifying the above example, we can make
579 Emacs load a custom config file. The key is to create a package that
580 provide a <filename>default.el</filename> file in
581 <filename>/share/emacs/site-start/</filename>. Emacs knows to load
582 this file automatically when it starts.
583</para>
584
585<screen>
586{
587 packageOverrides = pkgs: with pkgs; rec {
588 myEmacsConfig = writeText "default.el" ''
589;; initialize package
590
591(require 'package)
592(package-initialize 'noactivate)
593(eval-when-compile
594 (require 'use-package))
595
596;; load some packages
597
598(use-package company
599 :bind ("<C-tab>" . company-complete)
600 :diminish company-mode
601 :commands (company-mode global-company-mode)
602 :defer 1
603 :config
604 (global-company-mode))
605
606(use-package counsel
607 :commands (counsel-descbinds)
608 :bind (([remap execute-extended-command] . counsel-M-x)
609 ("C-x C-f" . counsel-find-file)
610 ("C-c g" . counsel-git)
611 ("C-c j" . counsel-git-grep)
612 ("C-c k" . counsel-ag)
613 ("C-x l" . counsel-locate)
614 ("M-y" . counsel-yank-pop)))
615
616(use-package flycheck
617 :defer 2
618 :config (global-flycheck-mode))
619
620(use-package ivy
621 :defer 1
622 :bind (("C-c C-r" . ivy-resume)
623 ("C-x C-b" . ivy-switch-buffer)
624 :map ivy-minibuffer-map
625 ("C-j" . ivy-call))
626 :diminish ivy-mode
627 :commands ivy-mode
628 :config
629 (ivy-mode 1))
630
631(use-package magit
632 :defer
633 :if (executable-find "git")
634 :bind (("C-x g" . magit-status)
635 ("C-x G" . magit-dispatch-popup))
636 :init
637 (setq magit-completing-read-function 'ivy-completing-read))
638
639(use-package projectile
640 :commands projectile-mode
641 :bind-keymap ("C-c p" . projectile-command-map)
642 :defer 5
643 :config
644 (projectile-global-mode))
645 '';
646 myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
647 (runCommand "default.el" {} ''
648mkdir -p $out/share/emacs/site-lisp
649cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
650'')
651 company
652 counsel
653 flycheck
654 ivy
655 magit
656 projectile
657 use-package
658 ]));
659 };
660}
661</screen>
662
663<para>
664 This provides a fairly full Emacs start file. It will load in
665 addition to the user's presonal config. You can always disable it by
666 passing <command>-q</command> to the Emacs command.
667</para>
668
669</section>
670
671</section>
672
673</chapter>