 6da4584acf
			
		
	
	
		6da4584acf
		
			
		
	
	
	
	
		
			
			- rewrite documentation - automate whole process into update.sh - remove all legacy snippets
		
			
				
	
	
		
			890 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			890 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
| <chapter xmlns="http://docbook.org/ns/docbook"
 | ||
|          xmlns:xlink="http://www.w3.org/1999/xlink"
 | ||
|          xml:id="chap-package-notes">
 | ||
|  <title>Package Notes</title>
 | ||
|  <para>
 | ||
|   This chapter contains information about how to use and maintain the Nix
 | ||
|   expressions for a number of specific packages, such as the Linux kernel or
 | ||
|   X.org.
 | ||
|  </para>
 | ||
| <!--============================================================-->
 | ||
|  <section xml:id="sec-linux-kernel">
 | ||
|   <title>Linux kernel</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    The Nix expressions to build the Linux kernel are in
 | ||
|    <link
 | ||
| xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel"><filename>pkgs/os-specific/linux/kernel</filename></link>.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    The function that builds the kernel has an argument
 | ||
|    <varname>kernelPatches</varname> which should be a list of <literal>{name,
 | ||
|    patch, extraConfig}</literal> attribute sets, where <varname>name</varname>
 | ||
|    is the name of the patch (which is included in the kernel’s
 | ||
|    <varname>meta.description</varname> attribute), <varname>patch</varname> is
 | ||
|    the patch itself (possibly compressed), and <varname>extraConfig</varname>
 | ||
|    (optional) is a string specifying extra options to be concatenated to the
 | ||
|    kernel configuration file (<filename>.config</filename>).
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    The kernel derivation exports an attribute <varname>features</varname>
 | ||
|    specifying whether optional functionality is or isn’t enabled. This is
 | ||
|    used in NixOS to implement kernel-specific behaviour. For instance, if the
 | ||
|    kernel has the <varname>iwlwifi</varname> feature (i.e. has built-in support
 | ||
|    for Intel wireless chipsets), then NixOS doesn’t have to build the
 | ||
|    external <varname>iwlwifi</varname> package:
 | ||
| <programlisting>
 | ||
| modulesTree = [kernel]
 | ||
|   ++ pkgs.lib.optional (!kernel.features ? iwlwifi) kernelPackages.iwlwifi
 | ||
|   ++ ...;
 | ||
| </programlisting>
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    How to add a new (major) version of the Linux kernel to Nixpkgs:
 | ||
|    <orderedlist>
 | ||
|     <listitem>
 | ||
|      <para>
 | ||
|       Copy the old Nix expression (e.g. <filename>linux-2.6.21.nix</filename>)
 | ||
|       to the new one (e.g. <filename>linux-2.6.22.nix</filename>) and update
 | ||
|       it.
 | ||
|      </para>
 | ||
|     </listitem>
 | ||
|     <listitem>
 | ||
|      <para>
 | ||
|       Add the new kernel to <filename>all-packages.nix</filename> (e.g., create
 | ||
|       an attribute <varname>kernel_2_6_22</varname>).
 | ||
|      </para>
 | ||
|     </listitem>
 | ||
|     <listitem>
 | ||
|      <para>
 | ||
|       Now we’re going to update the kernel configuration. First unpack the
 | ||
|       kernel. Then for each supported platform (<literal>i686</literal>,
 | ||
|       <literal>x86_64</literal>, <literal>uml</literal>) do the following:
 | ||
|       <orderedlist>
 | ||
|        <listitem>
 | ||
|         <para>
 | ||
|          Make an copy from the old config (e.g.
 | ||
|          <filename>config-2.6.21-i686-smp</filename>) to the new one (e.g.
 | ||
|          <filename>config-2.6.22-i686-smp</filename>).
 | ||
|         </para>
 | ||
|        </listitem>
 | ||
|        <listitem>
 | ||
|         <para>
 | ||
|          Copy the config file for this platform (e.g.
 | ||
|          <filename>config-2.6.22-i686-smp</filename>) to
 | ||
|          <filename>.config</filename> in the kernel source tree.
 | ||
|         </para>
 | ||
|        </listitem>
 | ||
|        <listitem>
 | ||
|         <para>
 | ||
|          Run <literal>make oldconfig
 | ||
|          ARCH=<replaceable>{i386,x86_64,um}</replaceable></literal> and answer
 | ||
|          all questions. (For the uml configuration, also add
 | ||
|          <literal>SHELL=bash</literal>.) Make sure to keep the configuration
 | ||
|          consistent between platforms (i.e. don’t enable some feature on
 | ||
|          <literal>i686</literal> and disable it on <literal>x86_64</literal>).
 | ||
|         </para>
 | ||
|        </listitem>
 | ||
|        <listitem>
 | ||
|         <para>
 | ||
|          If needed you can also run <literal>make menuconfig</literal>:
 | ||
| <screen>
 | ||
| $ nix-env -i ncurses
 | ||
| $ export NIX_CFLAGS_LINK=-lncurses
 | ||
| $ make menuconfig ARCH=<replaceable>arch</replaceable></screen>
 | ||
|         </para>
 | ||
|        </listitem>
 | ||
|        <listitem>
 | ||
|         <para>
 | ||
|          Copy <filename>.config</filename> over the new config file (e.g.
 | ||
|          <filename>config-2.6.22-i686-smp</filename>).
 | ||
|         </para>
 | ||
|        </listitem>
 | ||
|       </orderedlist>
 | ||
|      </para>
 | ||
|     </listitem>
 | ||
|     <listitem>
 | ||
|      <para>
 | ||
|       Test building the kernel: <literal>nix-build -A kernel_2_6_22</literal>.
 | ||
|       If it compiles, ship it! For extra credit, try booting NixOS with it.
 | ||
|      </para>
 | ||
|     </listitem>
 | ||
|     <listitem>
 | ||
|      <para>
 | ||
|       It may be that the new kernel requires updating the external kernel
 | ||
|       modules and kernel-dependent packages listed in the
 | ||
|       <varname>linuxPackagesFor</varname> function in
 | ||
|       <filename>all-packages.nix</filename> (such as the NVIDIA drivers, AUFS,
 | ||
|       etc.). If the updated packages aren’t backwards compatible with older
 | ||
|       kernels, you may need to keep the older versions around.
 | ||
|      </para>
 | ||
|     </listitem>
 | ||
|    </orderedlist>
 | ||
|   </para>
 | ||
|  </section>
 | ||
| <!--============================================================-->
 | ||
|  <section xml:id="sec-xorg">
 | ||
|   <title>X.org</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    The Nix expressions for the X.org packages reside in
 | ||
|    <filename>pkgs/servers/x11/xorg/default.nix</filename>. This file is
 | ||
|    automatically generated from lists of tarballs in an X.org release. As such
 | ||
|    it should not be modified directly; rather, you should modify the lists, the
 | ||
|    generator script or the file
 | ||
|    <filename>pkgs/servers/x11/xorg/overrides.nix</filename>, in which you can
 | ||
|    override or add to the derivations produced by the generator.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    The generator is invoked as follows:
 | ||
| <screen>
 | ||
| $ cd pkgs/servers/x11/xorg
 | ||
| $ cat tarballs-7.5.list extra.list old.list \
 | ||
|   | perl ./generate-expr-from-tarballs.pl
 | ||
| </screen>
 | ||
|    For each of the tarballs in the <filename>.list</filename> files, the script
 | ||
|    downloads it, unpacks it, and searches its <filename>configure.ac</filename>
 | ||
|    and <filename>*.pc.in</filename> files for dependencies. This information is
 | ||
|    used to generate <filename>default.nix</filename>. The generator caches
 | ||
|    downloaded tarballs between runs. Pay close attention to the <literal>NOT
 | ||
|    FOUND: <replaceable>name</replaceable></literal> messages at the end of the
 | ||
|    run, since they may indicate missing dependencies. (Some might be optional
 | ||
|    dependencies, however.)
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    A file like <filename>tarballs-7.5.list</filename> contains all tarballs in
 | ||
|    a X.org release. It can be generated like this:
 | ||
| <screen>
 | ||
| $ export i="mirror://xorg/X11R7.4/src/everything/"
 | ||
| $ cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
 | ||
|   | perl -e 'while (<>) { if (/(href|HREF)="([^"]*.bz2)"/) { print "$ENV{'i'}$2\n"; }; }' \
 | ||
|   | sort > tarballs-7.4.list
 | ||
| </screen>
 | ||
|    <filename>extra.list</filename> contains libraries that aren’t part of
 | ||
|    X.org proper, but are closely related to it, such as
 | ||
|    <literal>libxcb</literal>. <filename>old.list</filename> contains some
 | ||
|    packages that were removed from X.org, but are still needed by some people
 | ||
|    or by other packages (such as <varname>imake</varname>).
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    If the expression for a package requires derivation attributes that the
 | ||
|    generator cannot figure out automatically (say, <varname>patches</varname>
 | ||
|    or a <varname>postInstall</varname> hook), you should modify
 | ||
|    <filename>pkgs/servers/x11/xorg/overrides.nix</filename>.
 | ||
|   </para>
 | ||
|  </section>
 | ||
| <!--============================================================-->
 | ||
| <!--
 | ||
| <section xml:id="sec-package-notes-gnome">
 | ||
|   <title>Gnome</title>
 | ||
|   <para>* Expression is auto-generated</para>
 | ||
|   <para>* How to update</para>
 | ||
| </section>
 | ||
| -->
 | ||
| <!--============================================================-->
 | ||
| <!--
 | ||
| <section xml:id="sec-package-notes-gcc">
 | ||
|   <title>GCC</title>
 | ||
|   <para>…</para>
 | ||
| </section>
 | ||
| -->
 | ||
| <!--============================================================-->
 | ||
|  <section xml:id="sec-eclipse">
 | ||
|   <title>Eclipse</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    The Nix expressions related to the Eclipse platform and IDE are in
 | ||
|    <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/eclipse"><filename>pkgs/applications/editors/eclipse</filename></link>.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    Nixpkgs provides a number of packages that will install Eclipse in its
 | ||
|    various forms. These range from the bare-bones Eclipse Platform to the more
 | ||
|    fully featured Eclipse SDK or Scala-IDE packages and multiple version are
 | ||
|    often available. It is possible to list available Eclipse packages by
 | ||
|    issuing the command:
 | ||
| <screen>
 | ||
| $ nix-env -f '<nixpkgs>' -qaP -A eclipses --description
 | ||
| </screen>
 | ||
|    Once an Eclipse variant is installed it can be run using the
 | ||
|    <command>eclipse</command> command, as expected. From within Eclipse it is
 | ||
|    then possible to install plugins in the usual manner by either manually
 | ||
|    specifying an Eclipse update site or by installing the Marketplace Client
 | ||
|    plugin and using it to discover and install other plugins. This installation
 | ||
|    method provides an Eclipse installation that closely resemble a manually
 | ||
|    installed Eclipse.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    If you prefer to install plugins in a more declarative manner then Nixpkgs
 | ||
|    also offer a number of Eclipse plugins that can be installed in an
 | ||
|    <emphasis>Eclipse environment</emphasis>. This type of environment is
 | ||
|    created using the function <varname>eclipseWithPlugins</varname> found
 | ||
|    inside the <varname>nixpkgs.eclipses</varname> attribute set. This function
 | ||
|    takes as argument <literal>{ eclipse, plugins ? [], jvmArgs ? [] }</literal>
 | ||
|    where <varname>eclipse</varname> is a one of the Eclipse packages described
 | ||
|    above, <varname>plugins</varname> is a list of plugin derivations, and
 | ||
|    <varname>jvmArgs</varname> is a list of arguments given to the JVM running
 | ||
|    the Eclipse. For example, say you wish to install the latest Eclipse
 | ||
|    Platform with the popular Eclipse Color Theme plugin and also allow Eclipse
 | ||
|    to use more RAM. You could then add
 | ||
| <screen>
 | ||
| packageOverrides = pkgs: {
 | ||
|   myEclipse = with pkgs.eclipses; eclipseWithPlugins {
 | ||
|     eclipse = eclipse-platform;
 | ||
|     jvmArgs = [ "-Xmx2048m" ];
 | ||
|     plugins = [ plugins.color-theme ];
 | ||
|   };
 | ||
| }
 | ||
| </screen>
 | ||
|    to your Nixpkgs configuration
 | ||
|    (<filename>~/.config/nixpkgs/config.nix</filename>) and install it by
 | ||
|    running <command>nix-env -f '<nixpkgs>' -iA myEclipse</command> and
 | ||
|    afterward run Eclipse as usual. It is possible to find out which plugins are
 | ||
|    available for installation using <varname>eclipseWithPlugins</varname> by
 | ||
|    running
 | ||
| <screen>
 | ||
| $ nix-env -f '<nixpkgs>' -qaP -A eclipses.plugins --description
 | ||
| </screen>
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    If there is a need to install plugins that are not available in Nixpkgs then
 | ||
|    it may be possible to define these plugins outside Nixpkgs using the
 | ||
|    <varname>buildEclipseUpdateSite</varname> and
 | ||
|    <varname>buildEclipsePlugin</varname> functions found in the
 | ||
|    <varname>nixpkgs.eclipses.plugins</varname> attribute set. Use the
 | ||
|    <varname>buildEclipseUpdateSite</varname> function to install a plugin
 | ||
|    distributed as an Eclipse update site. This function takes <literal>{ name,
 | ||
|    src }</literal> as argument where <literal>src</literal> indicates the
 | ||
|    Eclipse update site archive. All Eclipse features and plugins within the
 | ||
|    downloaded update site will be installed. When an update site archive is not
 | ||
|    available then the <varname>buildEclipsePlugin</varname> function can be
 | ||
|    used to install a plugin that consists of a pair of feature and plugin JARs.
 | ||
|    This function takes an argument <literal>{ name, srcFeature, srcPlugin
 | ||
|    }</literal> where <literal>srcFeature</literal> and
 | ||
|    <literal>srcPlugin</literal> are the feature and plugin JARs, respectively.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    Expanding the previous example with two plugins using the above functions we
 | ||
|    have
 | ||
| <screen>
 | ||
| packageOverrides = pkgs: {
 | ||
|   myEclipse = with pkgs.eclipses; eclipseWithPlugins {
 | ||
|     eclipse = eclipse-platform;
 | ||
|     jvmArgs = [ "-Xmx2048m" ];
 | ||
|     plugins = [
 | ||
|       plugins.color-theme
 | ||
|       (plugins.buildEclipsePlugin {
 | ||
|         name = "myplugin1-1.0";
 | ||
|         srcFeature = fetchurl {
 | ||
|           url = "http://…/features/myplugin1.jar";
 | ||
|           sha256 = "123…";
 | ||
|         };
 | ||
|         srcPlugin = fetchurl {
 | ||
|           url = "http://…/plugins/myplugin1.jar";
 | ||
|           sha256 = "123…";
 | ||
|         };
 | ||
|       });
 | ||
|       (plugins.buildEclipseUpdateSite {
 | ||
|         name = "myplugin2-1.0";
 | ||
|         src = fetchurl {
 | ||
|           stripRoot = false;
 | ||
|           url = "http://…/myplugin2.zip";
 | ||
|           sha256 = "123…";
 | ||
|         };
 | ||
|       });
 | ||
|     ];
 | ||
|   };
 | ||
| }
 | ||
| </screen>
 | ||
|   </para>
 | ||
|  </section>
 | ||
| 
 | ||
|  <section xml:id="sec-elm">
 | ||
|   <title>Elm</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    To update Elm compiler, see <filename>nixpkgs/pkgs/development/compilers/elm/README.md</filename>.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    To package Elm applications, <link xlink:href="https://github.com/hercules-ci/elm2nix#elm2nix">read about elm2nix</link>.
 | ||
|   </para>
 | ||
|  </section>
 | ||
| 
 | ||
|  <section xml:id="sec-shell-helpers">
 | ||
|   <title>Interactive shell helpers</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    Some packages provide the shell integration to be more useful. But unlike
 | ||
|    other systems, nix doesn't have a standard share directory location. This is
 | ||
|    why a bunch <command>PACKAGE-share</command> scripts are shipped that print
 | ||
|    the location of the corresponding shared folder. Current list of such
 | ||
|    packages is as following:
 | ||
|    <itemizedlist>
 | ||
|     <listitem>
 | ||
|      <para>
 | ||
|       <literal>autojump</literal>: <command>autojump-share</command>
 | ||
|      </para>
 | ||
|     </listitem>
 | ||
|     <listitem>
 | ||
|      <para>
 | ||
|       <literal>fzf</literal>: <command>fzf-share</command>
 | ||
|      </para>
 | ||
|     </listitem>
 | ||
|    </itemizedlist>
 | ||
|    E.g. <literal>autojump</literal> can then used in the .bashrc like this:
 | ||
| <screen>
 | ||
|   source "$(autojump-share)/autojump.bash"
 | ||
| </screen>
 | ||
|   </para>
 | ||
|  </section>
 | ||
|  <section xml:id="sec-steam">
 | ||
|   <title>Steam</title>
 | ||
| 
 | ||
|   <section xml:id="sec-steam-nix">
 | ||
|    <title>Steam in Nix</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     Steam is distributed as a <filename>.deb</filename> file, for now only as
 | ||
|     an i686 package (the amd64 package only has documentation). When unpacked,
 | ||
|     it has a script called <filename>steam</filename> that in ubuntu (their
 | ||
|     target distro) would go to <filename>/usr/bin </filename>. When run for the
 | ||
|     first time, this script copies some files to the user's home, which include
 | ||
|     another script that is the ultimate responsible for launching the steam
 | ||
|     binary, which is also in $HOME.
 | ||
|    </para>
 | ||
| 
 | ||
|    <para>
 | ||
|     Nix problems and constraints:
 | ||
|     <itemizedlist>
 | ||
|      <listitem>
 | ||
|       <para>
 | ||
|        We don't have <filename>/bin/bash</filename> and many scripts point
 | ||
|        there. Similarly for <filename>/usr/bin/python</filename> .
 | ||
|       </para>
 | ||
|      </listitem>
 | ||
|      <listitem>
 | ||
|       <para>
 | ||
|        We don't have the dynamic loader in <filename>/lib </filename>.
 | ||
|       </para>
 | ||
|      </listitem>
 | ||
|      <listitem>
 | ||
|       <para>
 | ||
|        The <filename>steam.sh</filename> script in $HOME can not be patched, as
 | ||
|        it is checked and rewritten by steam.
 | ||
|       </para>
 | ||
|      </listitem>
 | ||
|      <listitem>
 | ||
|       <para>
 | ||
|        The steam binary cannot be patched, it's also checked.
 | ||
|       </para>
 | ||
|      </listitem>
 | ||
|     </itemizedlist>
 | ||
|    </para>
 | ||
| 
 | ||
|    <para>
 | ||
|     The current approach to deploy Steam in NixOS is composing a FHS-compatible
 | ||
|     chroot environment, as documented
 | ||
|     <link xlink:href="http://sandervanderburg.blogspot.nl/2013/09/composing-fhs-compatible-chroot.html">here</link>.
 | ||
|     This allows us to have binaries in the expected paths without disrupting
 | ||
|     the system, and to avoid patching them to work in a non FHS environment.
 | ||
|    </para>
 | ||
|   </section>
 | ||
| 
 | ||
|   <section xml:id="sec-steam-play">
 | ||
|    <title>How to play</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     For 64-bit systems it's important to have
 | ||
| <programlisting>hardware.opengl.driSupport32Bit = true;</programlisting>
 | ||
|     in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
 | ||
| <programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
 | ||
|     if you are using PulseAudio - this will enable 32bit ALSA apps integration.
 | ||
|     To use the Steam controller or other Steam supported controllers such as
 | ||
|     the DualShock 4 or Nintendo Switch Pro, you need to add
 | ||
| <programlisting>hardware.steam-hardware.enable = true;</programlisting>
 | ||
|     to your configuration.
 | ||
|    </para>
 | ||
|   </section>
 | ||
| 
 | ||
|   <section xml:id="sec-steam-troub">
 | ||
|    <title>Troubleshooting</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     <variablelist>
 | ||
|      <varlistentry>
 | ||
|       <term>
 | ||
|        Steam fails to start. What do I do?
 | ||
|       </term>
 | ||
|       <listitem>
 | ||
|        <para>
 | ||
|         Try to run
 | ||
| <programlisting>strace steam</programlisting>
 | ||
|         to see what is causing steam to fail.
 | ||
|        </para>
 | ||
|       </listitem>
 | ||
|      </varlistentry>
 | ||
|      <varlistentry>
 | ||
|       <term>
 | ||
|        Using the FOSS Radeon or nouveau (nvidia) drivers
 | ||
|       </term>
 | ||
|       <listitem>
 | ||
|        <itemizedlist>
 | ||
|         <listitem>
 | ||
|          <para>
 | ||
|           The <literal>newStdcpp</literal> parameter was removed since NixOS
 | ||
|           17.09 and should not be needed anymore.
 | ||
|          </para>
 | ||
|         </listitem>
 | ||
|         <listitem>
 | ||
|          <para>
 | ||
|           Steam ships statically linked with a version of libcrypto that
 | ||
|           conflics with the one dynamically loaded by radeonsi_dri.so. If you
 | ||
|           get the error
 | ||
| <programlisting>steam.sh: line 713: 7842 Segmentation fault (core dumped)</programlisting>
 | ||
|           have a look at
 | ||
|           <link xlink:href="https://github.com/NixOS/nixpkgs/pull/20269">this
 | ||
|           pull request</link>.
 | ||
|          </para>
 | ||
|         </listitem>
 | ||
|        </itemizedlist>
 | ||
|       </listitem>
 | ||
|      </varlistentry>
 | ||
|      <varlistentry>
 | ||
|       <term>
 | ||
|        Java
 | ||
|       </term>
 | ||
|       <listitem>
 | ||
|        <orderedlist>
 | ||
|         <listitem>
 | ||
|          <para>
 | ||
|           There is no java in steam chrootenv by default. If you get a message
 | ||
|           like
 | ||
| <programlisting>/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found</programlisting>
 | ||
|           You need to add
 | ||
| <programlisting> steam.override { withJava = true; };</programlisting>
 | ||
|           to your configuration.
 | ||
|          </para>
 | ||
|         </listitem>
 | ||
|        </orderedlist>
 | ||
|       </listitem>
 | ||
|      </varlistentry>
 | ||
|     </variablelist>
 | ||
|    </para>
 | ||
|   </section>
 | ||
| 
 | ||
|   <section xml:id="sec-steam-run">
 | ||
|    <title>steam-run</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     The FHS-compatible chroot used for steam can also be used to run other
 | ||
|     linux games that expect a FHS environment. To do it, add
 | ||
| <programlisting>pkgs.(steam.override {
 | ||
|           nativeOnly = true;
 | ||
|           newStdcpp = true;
 | ||
|         }).run</programlisting>
 | ||
|     to your configuration, rebuild, and run the game with
 | ||
| <programlisting>steam-run ./foo</programlisting>
 | ||
|    </para>
 | ||
|   </section>
 | ||
|  </section>
 | ||
|  <section xml:id="sec-emacs">
 | ||
|   <title>Emacs</title>
 | ||
| 
 | ||
|   <section xml:id="sec-emacs-config">
 | ||
|    <title>Configuring Emacs</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     The Emacs package comes with some extra helpers to make it easier to
 | ||
|     configure. <varname>emacsWithPackages</varname> allows you to manage
 | ||
|     packages from ELPA. This means that you will not have to install that
 | ||
|     packages from within Emacs. For instance, if you wanted to use
 | ||
|     <literal>company</literal>, <literal>counsel</literal>,
 | ||
|     <literal>flycheck</literal>, <literal>ivy</literal>,
 | ||
|     <literal>magit</literal>, <literal>projectile</literal>, and
 | ||
|     <literal>use-package</literal> you could use this as a
 | ||
|     <filename>~/.config/nixpkgs/config.nix</filename> override:
 | ||
|    </para>
 | ||
| 
 | ||
| <screen>
 | ||
| {
 | ||
|   packageOverrides = pkgs: with pkgs; {
 | ||
|     myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
 | ||
|       company
 | ||
|       counsel
 | ||
|       flycheck
 | ||
|       ivy
 | ||
|       magit
 | ||
|       projectile
 | ||
|       use-package
 | ||
|     ]));
 | ||
|   }
 | ||
| }
 | ||
| </screen>
 | ||
| 
 | ||
|    <para>
 | ||
|     You can install it like any other packages via <command>nix-env -iA
 | ||
|     myEmacs</command>. However, this will only install those packages. It will
 | ||
|     not <literal>configure</literal> them for us. To do this, we need to
 | ||
|     provide a configuration file. Luckily, it is possible to do this from
 | ||
|     within Nix! By modifying the above example, we can make Emacs load a custom
 | ||
|     config file. The key is to create a package that provide a
 | ||
|     <filename>default.el</filename> file in
 | ||
|     <filename>/share/emacs/site-start/</filename>. Emacs knows to load this
 | ||
|     file automatically when it starts.
 | ||
|    </para>
 | ||
| 
 | ||
| <screen>
 | ||
| {
 | ||
|   packageOverrides = pkgs: with pkgs; rec {
 | ||
|     myEmacsConfig = writeText "default.el" ''
 | ||
| ;; initialize package
 | ||
| 
 | ||
| (require 'package)
 | ||
| (package-initialize 'noactivate)
 | ||
| (eval-when-compile
 | ||
|   (require 'use-package))
 | ||
| 
 | ||
| ;; load some packages
 | ||
| 
 | ||
| (use-package company
 | ||
|   :bind ("<C-tab>" . company-complete)
 | ||
|   :diminish company-mode
 | ||
|   :commands (company-mode global-company-mode)
 | ||
|   :defer 1
 | ||
|   :config
 | ||
|   (global-company-mode))
 | ||
| 
 | ||
| (use-package counsel
 | ||
|   :commands (counsel-descbinds)
 | ||
|   :bind (([remap execute-extended-command] . counsel-M-x)
 | ||
|          ("C-x C-f" . counsel-find-file)
 | ||
|          ("C-c g" . counsel-git)
 | ||
|          ("C-c j" . counsel-git-grep)
 | ||
|          ("C-c k" . counsel-ag)
 | ||
|          ("C-x l" . counsel-locate)
 | ||
|          ("M-y" . counsel-yank-pop)))
 | ||
| 
 | ||
| (use-package flycheck
 | ||
|   :defer 2
 | ||
|   :config (global-flycheck-mode))
 | ||
| 
 | ||
| (use-package ivy
 | ||
|   :defer 1
 | ||
|   :bind (("C-c C-r" . ivy-resume)
 | ||
|          ("C-x C-b" . ivy-switch-buffer)
 | ||
|          :map ivy-minibuffer-map
 | ||
|          ("C-j" . ivy-call))
 | ||
|   :diminish ivy-mode
 | ||
|   :commands ivy-mode
 | ||
|   :config
 | ||
|   (ivy-mode 1))
 | ||
| 
 | ||
| (use-package magit
 | ||
|   :defer
 | ||
|   :if (executable-find "git")
 | ||
|   :bind (("C-x g" . magit-status)
 | ||
|          ("C-x G" . magit-dispatch-popup))
 | ||
|   :init
 | ||
|   (setq magit-completing-read-function 'ivy-completing-read))
 | ||
| 
 | ||
| (use-package projectile
 | ||
|   :commands projectile-mode
 | ||
|   :bind-keymap ("C-c p" . projectile-command-map)
 | ||
|   :defer 5
 | ||
|   :config
 | ||
|   (projectile-global-mode))
 | ||
|     '';
 | ||
|     myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
 | ||
|       (runCommand "default.el" {} ''
 | ||
| mkdir -p $out/share/emacs/site-lisp
 | ||
| cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
 | ||
| '')
 | ||
|       company
 | ||
|       counsel
 | ||
|       flycheck
 | ||
|       ivy
 | ||
|       magit
 | ||
|       projectile
 | ||
|       use-package
 | ||
|     ]));
 | ||
|   };
 | ||
| }
 | ||
| </screen>
 | ||
| 
 | ||
|    <para>
 | ||
|     This provides a fairly full Emacs start file. It will load in addition to
 | ||
|     the user's presonal config. You can always disable it by passing
 | ||
|     <command>-q</command> to the Emacs command.
 | ||
|    </para>
 | ||
| 
 | ||
|    <para>
 | ||
|     Sometimes <varname>emacsWithPackages</varname> is not enough, as this
 | ||
|     package set has some priorities imposed on packages (with the lowest
 | ||
|     priority assigned to Melpa Unstable, and the highest for packages manually
 | ||
|     defined in <filename>pkgs/top-level/emacs-packages.nix</filename>). But you
 | ||
|     can't control this priorities when some package is installed as a
 | ||
|     dependency. You can override it on per-package-basis, providing all the
 | ||
|     required dependencies manually - but it's tedious and there is always a
 | ||
|     possibility that an unwanted dependency will sneak in through some other
 | ||
|     package. To completely override such a package you can use
 | ||
|     <varname>overrideScope'</varname>.
 | ||
|    </para>
 | ||
| 
 | ||
| <screen>
 | ||
| overrides = self: super: rec {
 | ||
|   haskell-mode = self.melpaPackages.haskell-mode;
 | ||
|   ...
 | ||
| };
 | ||
| ((emacsPackagesNgGen emacs).overrideScope' overrides).emacsWithPackages (p: with p; [
 | ||
|   # here both these package will use haskell-mode of our own choice
 | ||
|   ghc-mod
 | ||
|   dante
 | ||
| ])
 | ||
| </screen>
 | ||
|   </section>
 | ||
|  </section>
 | ||
|  <section xml:id="sec-weechat">
 | ||
|   <title>Weechat</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    Weechat can be configured to include your choice of plugins, reducing its
 | ||
|    closure size from the default configuration which includes all available
 | ||
|    plugins. To make use of this functionality, install an expression that
 | ||
|    overrides its configuration such as
 | ||
| <programlisting>weechat.override {configure = {availablePlugins, ...}: {
 | ||
|     plugins = with availablePlugins; [ python perl ];
 | ||
|   }
 | ||
| }</programlisting>
 | ||
|    If the <literal>configure</literal> function returns an attrset without the
 | ||
|    <literal>plugins</literal> attribute, <literal>availablePlugins</literal>
 | ||
|    will be used automatically.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    The plugins currently available are <literal>python</literal>,
 | ||
|    <literal>perl</literal>, <literal>ruby</literal>, <literal>guile</literal>,
 | ||
|    <literal>tcl</literal> and <literal>lua</literal>.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    The python and perl plugins allows the addition of extra libraries. For
 | ||
|    instance, the <literal>inotify.py</literal> script in weechat-scripts
 | ||
|    requires D-Bus or libnotify, and the <literal>fish.py</literal> script
 | ||
|    requires pycrypto. To use these scripts, use the plugin's
 | ||
|    <literal>withPackages</literal> attribute:
 | ||
| <programlisting>weechat.override { configure = {availablePlugins, ...}: {
 | ||
|     plugins = with availablePlugins; [
 | ||
|             (python.withPackages (ps: with ps; [ pycrypto python-dbus ]))
 | ||
|         ];
 | ||
|     };
 | ||
| }
 | ||
| </programlisting>
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    In order to also keep all default plugins installed, it is possible to use
 | ||
|    the following method:
 | ||
| <programlisting>weechat.override { configure = { availablePlugins, ... }: {
 | ||
|   plugins = builtins.attrValues (availablePlugins // {
 | ||
|     python = availablePlugins.python.withPackages (ps: with ps; [ pycrypto python-dbus ]);
 | ||
|   });
 | ||
| }; }
 | ||
| </programlisting>
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    WeeChat allows to set defaults on startup using the
 | ||
|    <literal>--run-command</literal>. The <literal>configure</literal> method
 | ||
|    can be used to pass commands to the program:
 | ||
| <programlisting>weechat.override {
 | ||
|   configure = { availablePlugins, ... }: {
 | ||
|     init = ''
 | ||
|       /set foo bar
 | ||
|       /server add freenode chat.freenode.org
 | ||
|     '';
 | ||
|   };
 | ||
| }</programlisting>
 | ||
|    Further values can be added to the list of commands when running
 | ||
|    <literal>weechat --run-command "your-commands"</literal>.
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    Additionally it's possible to specify scripts to be loaded when starting
 | ||
|    <literal>weechat</literal>. These will be loaded before the commands from
 | ||
|    <literal>init</literal>:
 | ||
| <programlisting>weechat.override {
 | ||
|   configure = { availablePlugins, ... }: {
 | ||
|     scripts = with pkgs.weechatScripts; [
 | ||
|       weechat-xmpp weechat-matrix-bridge wee-slack
 | ||
|     ];
 | ||
|     init = ''
 | ||
|       /set plugins.var.python.jabber.key "val"
 | ||
|     '':
 | ||
|   };
 | ||
| }</programlisting>
 | ||
|   </para>
 | ||
| 
 | ||
|   <para>
 | ||
|    In <literal>nixpkgs</literal> there's a subpackage which contains
 | ||
|    derivations for WeeChat scripts. Such derivations expect a
 | ||
|    <literal>passthru.scripts</literal> attribute which contains a list of all
 | ||
|    scripts inside the store path. Furthermore all scripts have to live in
 | ||
|    <literal>$out/share</literal>. An exemplary derivation looks like this:
 | ||
| <programlisting>{ stdenv, fetchurl }:
 | ||
| 
 | ||
| stdenv.mkDerivation {
 | ||
|   name = "exemplary-weechat-script";
 | ||
|   src = fetchurl {
 | ||
|     url = "https://scripts.tld/your-scripts.tar.gz";
 | ||
|     sha256 = "...";
 | ||
|   };
 | ||
|   passthru.scripts = [ "foo.py" "bar.lua" ];
 | ||
|   installPhase = ''
 | ||
|     mkdir $out/share
 | ||
|     cp foo.py $out/share
 | ||
|     cp bar.lua $out/share
 | ||
|   '';
 | ||
| }</programlisting>
 | ||
|   </para>
 | ||
|  </section>
 | ||
|  <section xml:id="sec-citrix">
 | ||
|   <title>Citrix Receiver</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    The <link xlink:href="https://www.citrix.com/products/receiver/">Citrix
 | ||
|    Receiver</link> is a remote desktop viewer which provides access to
 | ||
|    <link xlink:href="https://www.citrix.com/products/xenapp-xendesktop/">XenDesktop</link>
 | ||
|    installations.
 | ||
|   </para>
 | ||
| 
 | ||
|   <section xml:id="sec-citrix-base">
 | ||
|    <title>Basic usage</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     The tarball archive needs to be downloaded manually as the licenses
 | ||
|     agreements of the vendor need to be accepted first. This is available at
 | ||
|     the
 | ||
|     <link xlink:href="https://www.citrix.com/downloads/citrix-receiver/">download
 | ||
|     page at citrix.com</link>. Then run <literal>nix-prefetch-url
 | ||
|     file://$PWD/linuxx64-$version.tar.gz</literal>. With the archive available
 | ||
|     in the store the package can be built and installed with Nix.
 | ||
|    </para>
 | ||
| 
 | ||
|    <para>
 | ||
|     <emphasis>Note: it's recommended to install <literal>Citrix
 | ||
|     Receiver</literal> using <literal>nix-env -i</literal> or globally to
 | ||
|     ensure that the <literal>.desktop</literal> files are installed properly
 | ||
|     into <literal>$XDG_CONFIG_DIRS</literal>. Otherwise it won't be possible to
 | ||
|     open <literal>.ica</literal> files automatically from the browser to start
 | ||
|     a Citrix connection.</emphasis>
 | ||
|    </para>
 | ||
|   </section>
 | ||
| 
 | ||
|   <section xml:id="sec-citrix-custom-certs">
 | ||
|    <title>Custom certificates</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     The <literal>Citrix Receiver</literal> in <literal>nixpkgs</literal> trusts
 | ||
|     several certificates
 | ||
|     <link xlink:href="https://curl.haxx.se/docs/caextract.html">from the
 | ||
|     Mozilla database</link> by default. However several companies using Citrix
 | ||
|     might require their own corporate certificate. On distros with imperative
 | ||
|     packaging these certs can be stored easily in
 | ||
|     <link xlink:href="https://developer-docs.citrix.com/projects/receiver-for-linux-command-reference/en/13.7/"><literal>$ICAROOT</literal></link>,
 | ||
|     however this directory is a store path in <literal>nixpkgs</literal>. In
 | ||
|     order to work around this issue the package provides a simple mechanism to
 | ||
|     add custom certificates without rebuilding the entire package using
 | ||
|     <literal>symlinkJoin</literal>:
 | ||
| <programlisting>
 | ||
| <![CDATA[with import <nixpkgs> { config.allowUnfree = true; };
 | ||
| let extraCerts = [ ./custom-cert-1.pem ./custom-cert-2.pem /* ... */ ]; in
 | ||
| citrix_receiver.override {
 | ||
|   inherit extraCerts;
 | ||
| }]]>
 | ||
| </programlisting>
 | ||
|    </para>
 | ||
|   </section>
 | ||
|  </section>
 | ||
|  <section xml:id="sec-ibus-typing-booster">
 | ||
|   <title>ibus-engines.typing-booster</title>
 | ||
| 
 | ||
|   <para>
 | ||
|    This package is an ibus-based completion method to speed up typing.
 | ||
|   </para>
 | ||
| 
 | ||
|   <section xml:id="sec-ibus-typing-booster-activate">
 | ||
|    <title>Activating the engine</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     IBus needs to be configured accordingly to activate
 | ||
|     <literal>typing-booster</literal>. The configuration depends on the desktop
 | ||
|     manager in use. For detailed instructions, please refer to the
 | ||
|     <link xlink:href="https://mike-fabian.github.io/ibus-typing-booster/documentation.html">upstream
 | ||
|     docs</link>.
 | ||
|    </para>
 | ||
| 
 | ||
|    <para>
 | ||
|     On NixOS you need to explicitly enable <literal>ibus</literal> with given
 | ||
|     engines before customizing your desktop to use
 | ||
|     <literal>typing-booster</literal>. This can be achieved using the
 | ||
|     <literal>ibus</literal> module:
 | ||
| <programlisting>{ pkgs, ... }: {
 | ||
|   i18n.inputMethod = {
 | ||
|     enabled = "ibus";
 | ||
|     ibus.engines = with pkgs.ibus-engines; [ typing-booster ];
 | ||
|   };
 | ||
| }</programlisting>
 | ||
|    </para>
 | ||
|   </section>
 | ||
| 
 | ||
|   <section xml:id="sec-ibus-typing-booster-customize-hunspell">
 | ||
|    <title>Using custom hunspell dictionaries</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     The IBus engine is based on <literal>hunspell</literal> to support
 | ||
|     completion in many languages. By default the dictionaries
 | ||
|     <literal>de-de</literal>, <literal>en-us</literal>,
 | ||
|     <literal>es-es</literal>, <literal>it-it</literal>,
 | ||
|     <literal>sv-se</literal> and <literal>sv-fi</literal> are in use. To add
 | ||
|     another dictionary, the package can be overridden like this:
 | ||
| <programlisting>ibus-engines.typing-booster.override {
 | ||
|   langs = [ "de-at" "en-gb" ];
 | ||
| }</programlisting>
 | ||
|    </para>
 | ||
| 
 | ||
|    <para>
 | ||
|     <emphasis>Note: each language passed to <literal>langs</literal> must be an
 | ||
|     attribute name in <literal>pkgs.hunspellDicts</literal>.</emphasis>
 | ||
|    </para>
 | ||
|   </section>
 | ||
| 
 | ||
|   <section xml:id="sec-ibus-typing-booster-emoji-picker">
 | ||
|    <title>Built-in emoji picker</title>
 | ||
| 
 | ||
|    <para>
 | ||
|     The <literal>ibus-engines.typing-booster</literal> package contains a
 | ||
|     program named <literal>emoji-picker</literal>. To display all emojis
 | ||
|     correctly, a special font such as <literal>noto-fonts-emoji</literal> is
 | ||
|     needed:
 | ||
|    </para>
 | ||
| 
 | ||
|    <para>
 | ||
|     On NixOS it can be installed using the following expression:
 | ||
| <programlisting>{ pkgs, ... }: {
 | ||
|   fonts.fonts = with pkgs; [ noto-fonts-emoji ];
 | ||
| }</programlisting>
 | ||
|    </para>
 | ||
|   </section>
 | ||
|  </section>
 | ||
| </chapter>
 |