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 or nouveau (nvidia) drivers</term>
480 <listitem><itemizedlist>
481 <listitem><para>The <literal>newStdcpp</literal> parameter
482 was removed since NixOS 17.09 and should not be needed anymore.
483 </para></listitem>
484
485 <listitem><para>
486 Steam ships statically linked with a version of libcrypto that
487 conflics with the one dynamically loaded by radeonsi_dri.so.
488 If you get the error
489 <programlisting>steam.sh: line 713: 7842 Segmentation fault (core dumped)</programlisting>
490 have a look at <link xlink:href="https://github.com/NixOS/nixpkgs/pull/20269">this pull request</link>.
491 </para></listitem>
492
493 </itemizedlist></listitem></varlistentry>
494
495 <varlistentry>
496 <term>Java</term>
497 <listitem><orderedlist>
498 <listitem><para>
499 There is no java in steam chrootenv by default. If you get a message like
500 <programlisting>/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found</programlisting>
501 You need to add
502 <programlisting> steam.override { withJava = true; };</programlisting>
503 to your configuration.
504 </para></listitem>
505 </orderedlist></listitem></varlistentry>
506
507</variablelist>
508</para>
509
510</section>
511
512<section xml:id="sec-steam-run">
513
514<title>steam-run</title>
515<para>
516The FHS-compatible chroot used for steam can also be used to run
517other linux games that expect a FHS environment.
518To do it, add
519<programlisting>pkgs.(steam.override {
520 nativeOnly = true;
521 newStdcpp = true;
522 }).run</programlisting>
523to your configuration, rebuild, and run the game with
524<programlisting>steam-run ./foo</programlisting>
525</para>
526
527</section>
528
529</section>
530
531<section xml:id="sec-emacs">
532
533<title>Emacs</title>
534
535<section xml:id="sec-emacs-config">
536
537<title>Configuring Emacs</title>
538
539<para>
540 The Emacs package comes with some extra helpers to make it easier to
541 configure. <varname>emacsWithPackages</varname> allows you to manage
542 packages from ELPA. This means that you will not have to install
543 that packages from within Emacs. For instance, if you wanted to use
544 <literal>company</literal>, <literal>counsel</literal>,
545 <literal>flycheck</literal>, <literal>ivy</literal>,
546 <literal>magit</literal>, <literal>projectile</literal>, and
547 <literal>use-package</literal> you could use this as a
548 <filename>~/.config/nixpkgs/config.nix</filename> override:
549</para>
550
551<screen>
552{
553 packageOverrides = pkgs: with pkgs; {
554 myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
555 company
556 counsel
557 flycheck
558 ivy
559 magit
560 projectile
561 use-package
562 ]));
563 }
564}
565</screen>
566
567<para>
568 You can install it like any other packages via <command>nix-env -iA
569 myEmacs</command>. However, this will only install those packages.
570 It will not <literal>configure</literal> them for us. To do this, we
571 need to provide a configuration file. Luckily, it is possible to do
572 this from within Nix! By modifying the above example, we can make
573 Emacs load a custom config file. The key is to create a package that
574 provide a <filename>default.el</filename> file in
575 <filename>/share/emacs/site-start/</filename>. Emacs knows to load
576 this file automatically when it starts.
577</para>
578
579<screen>
580{
581 packageOverrides = pkgs: with pkgs; rec {
582 myEmacsConfig = writeText "default.el" ''
583;; initialize package
584
585(require 'package)
586(package-initialize 'noactivate)
587(eval-when-compile
588 (require 'use-package))
589
590;; load some packages
591
592(use-package company
593 :bind ("<C-tab>" . company-complete)
594 :diminish company-mode
595 :commands (company-mode global-company-mode)
596 :defer 1
597 :config
598 (global-company-mode))
599
600(use-package counsel
601 :commands (counsel-descbinds)
602 :bind (([remap execute-extended-command] . counsel-M-x)
603 ("C-x C-f" . counsel-find-file)
604 ("C-c g" . counsel-git)
605 ("C-c j" . counsel-git-grep)
606 ("C-c k" . counsel-ag)
607 ("C-x l" . counsel-locate)
608 ("M-y" . counsel-yank-pop)))
609
610(use-package flycheck
611 :defer 2
612 :config (global-flycheck-mode))
613
614(use-package ivy
615 :defer 1
616 :bind (("C-c C-r" . ivy-resume)
617 ("C-x C-b" . ivy-switch-buffer)
618 :map ivy-minibuffer-map
619 ("C-j" . ivy-call))
620 :diminish ivy-mode
621 :commands ivy-mode
622 :config
623 (ivy-mode 1))
624
625(use-package magit
626 :defer
627 :if (executable-find "git")
628 :bind (("C-x g" . magit-status)
629 ("C-x G" . magit-dispatch-popup))
630 :init
631 (setq magit-completing-read-function 'ivy-completing-read))
632
633(use-package projectile
634 :commands projectile-mode
635 :bind-keymap ("C-c p" . projectile-command-map)
636 :defer 5
637 :config
638 (projectile-global-mode))
639 '';
640 myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
641 (runCommand "default.el" {} ''
642mkdir -p $out/share/emacs/site-lisp
643cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
644'')
645 company
646 counsel
647 flycheck
648 ivy
649 magit
650 projectile
651 use-package
652 ]));
653 };
654}
655</screen>
656
657<para>
658 This provides a fairly full Emacs start file. It will load in
659 addition to the user's presonal config. You can always disable it by
660 passing <command>-q</command> to the Emacs command.
661</para>
662
663<para>
664 Sometimes <varname>emacsWithPackages</varname> is not enough, as
665 this package set has some priorities imposed on packages (with
666 the lowest priority assigned to Melpa Unstable, and the highest for
667 packages manually defined in
668 <filename>pkgs/top-level/emacs-packages.nix</filename>). But you
669 can't control this priorities when some package is installed as a
670 dependency. You can override it on per-package-basis, providing all
671 the required dependencies manually - but it's tedious and there is
672 always a possibility that an unwanted dependency will sneak in
673 through some other package. To completely override such a package
674 you can use <varname>overrideScope</varname>.
675</para>
676
677<screen>
678overrides = super: self: rec {
679 haskell-mode = self.melpaPackages.haskell-mode;
680 ...
681};
682((emacsPackagesNgGen emacs).overrideScope overrides).emacsWithPackages (p: with p; [
683 # here both these package will use haskell-mode of our own choice
684 ghc-mod
685 dante
686])
687</screen>
688
689</section>
690
691</section>
692
693<section xml:id="sec-weechat">
694<title>Weechat</title>
695<para>
696Weechat can be configured to include your choice of plugins, reducing its
697closure size from the default configuration which includes all available
698plugins. To make use of this functionality, install an expression that
699overrides its configuration such as
700<programlisting>weechat.override {configure = {availablePlugins, ...}: {
701 plugins = with availablePlugins; [ python perl ];
702 }
703}</programlisting>
704</para>
705<para>
706The plugins currently available are <literal>python</literal>,
707<literal>perl</literal>, <literal>ruby</literal>, <literal>guile</literal>,
708<literal>tcl</literal> and <literal>lua</literal>.
709</para>
710<para>
711The python plugin allows the addition of extra libraries. For instance,
712the <literal>inotify.py</literal> script in weechat-scripts requires
713D-Bus or libnotify, and the <literal>fish.py</literal> script requires
714pycrypto. To use these scripts, use the <literal>python</literal>
715plugin's <literal>withPackages</literal> attribute:
716<programlisting>weechat.override {configure = {availablePlugins, ...}: {
717 plugins = with availablePlugins; [
718 (python.withPackages (ps: with ps; [ pycrypto python-dbus ]))
719 ];
720 }
721}
722</programlisting>
723</para>
724</section>
725</chapter>