274 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			274 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
| <chapter xmlns="http://docbook.org/ns/docbook"
 | |
| 	 xmlns:xlink="http://www.w3.org/1999/xlink"
 | |
| 	 xml:id="chap-functions">
 | |
| 
 | |
| <title>Functions reference</title>
 | |
| 
 | |
| <para>
 | |
|   The nixpkgs repository has several utility functions to manipulate Nix expressions.
 | |
| </para>
 | |
| 
 | |
| <section xml:id="sec-pkgs-overridePackages">
 | |
|   <title>pkgs.overridePackages</title>
 | |
| 
 | |
|   <para>
 | |
|     This function inside the nixpkgs expression (<varname>pkgs</varname>)
 | |
|     can be used to override the set of packages itself.
 | |
|   </para>
 | |
|   <para>
 | |
|     Warning: this function is expensive and must not be used from within
 | |
|     the nixpkgs repository.
 | |
|   </para>
 | |
|   <para>
 | |
|     Example usage:
 | |
| 
 | |
|     <programlisting>let
 | |
|   pkgs = import <nixpkgs> {};
 | |
|   newpkgs = pkgs.overridePackages (self: super: {
 | |
|     foo = super.foo.override { ... };
 | |
|   };
 | |
| in ...</programlisting>
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     The resulting <varname>newpkgs</varname> will have the new <varname>foo</varname>
 | |
|     expression, and all other expressions depending on <varname>foo</varname> will also
 | |
|     use the new <varname>foo</varname> expression.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     The behavior of this function is similar to <link 
 | |
|     linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     The <varname>self</varname> parameter refers to the final package set with the
 | |
|     applied overrides. Using this parameter may lead to infinite recursion if not
 | |
|     used consciously.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     The <varname>super</varname> parameter refers to the old package set.
 | |
|     It's equivalent to <varname>pkgs</varname> in the above example.
 | |
|   </para>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section xml:id="sec-pkg-override">
 | |
|   <title><pkg>.override</title>
 | |
| 
 | |
|   <para>
 | |
|     The function <varname>override</varname> is usually available for all the
 | |
|     derivations in the nixpkgs expression (<varname>pkgs</varname>).
 | |
|   </para>
 | |
|   <para>
 | |
|     It is used to override the arguments passed to a function.
 | |
|   </para>
 | |
|   <para>
 | |
|     Example usages:
 | |
| 
 | |
|     <programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
 | |
|     <programlisting>pkgs.overridePackages (self: super: {
 | |
|   foo = super.foo.override { barSupport = true ; };
 | |
| })</programlisting>
 | |
|     <programlisting>mypkg = pkgs.callPackage ./mypkg.nix {
 | |
|   mydep = pkgs.mydep.override { ... };
 | |
| })</programlisting>
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     In the first example, <varname>pkgs.foo</varname> is the result of a function call
 | |
|     with some default arguments, usually a derivation.
 | |
|     Using <varname>pkgs.foo.override</varname> will call the same function with
 | |
|     the given new arguments.
 | |
|   </para>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section xml:id="sec-pkg-overrideDerivation">
 | |
|   <title><pkg>.overrideDerivation</title>
 | |
| 
 | |
|   <para>
 | |
|     The function <varname>overrideDerivation</varname> is usually available for all the
 | |
|     derivations in the nixpkgs expression (<varname>pkgs</varname>).
 | |
|   </para> 
 | |
|   <para>
 | |
|     It is used to create a new derivation by overriding the attributes of
 | |
|     the original derivation according to the given function.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     Example usage:
 | |
| 
 | |
|     <programlisting>mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
 | |
|   name = "sed-4.2.2-pre";
 | |
|   src = fetchurl {
 | |
|     url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
 | |
|     sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
 | |
|   };
 | |
|   patches = [];
 | |
| });</programlisting>
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     In the above example, the name, src and patches of the derivation
 | |
|     will be overridden, while all other attributes will be retained from the
 | |
|     original derivation.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     The argument <varname>oldAttrs</varname> is used to refer to the attribute set of
 | |
|     the original derivation.
 | |
|   </para>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| <section xml:id="sec-lib-makeOverridable">
 | |
|   <title>lib.makeOverridable</title>
 | |
| 
 | |
|   <para>
 | |
|     The function <varname>lib.makeOverridable</varname> is used make the result
 | |
|     of a function easily customizable. This utility only makes sense for functions
 | |
|     that accept an argument set and return an attribute set.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     Example usage:
 | |
| 
 | |
|     <programlisting>f = { a, b }: { result = a+b; }
 | |
| c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
 | |
| 
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     The variable <varname>c</varname> is the value of the <varname>f</varname> function
 | |
|     applied with some default arguments. Hence the value of <varname>c.result</varname>
 | |
|     is <literal>3</literal>, in this example.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     The variable <varname>c</varname> however also has some additional functions, like
 | |
|     <link linkend="sec-pkg-override">c.override</link> which can be used to
 | |
|     override the default arguments. In this example the value of
 | |
|     <varname>(c.override { a = 4; }).result</varname> is 6.
 | |
|   </para>
 | |
| 
 | |
| </section>
 | |
| 
 | |
| 
 | |
| <section xml:id="sec-fhs-environments">
 | |
|   <title>buildFHSChrootEnv/buildFHSUserEnv</title>
 | |
| 
 | |
|   <para>
 | |
|     <function>buildFHSChrootEnv</function> and
 | |
|     <function>buildFHSUserEnv</function> provide a way to build and run
 | |
|     FHS-compatible lightweight sandboxes. They get their own isolated root with
 | |
|     binded <filename>/nix/store</filename>, so their footprint in terms of disk
 | |
|     space needed is quite small. This allows one to run software which is hard or
 | |
|     unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
 | |
|     games distributed as tarballs, software with integrity checking and/or external
 | |
|     self-updated binaries.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     <function>buildFHSChrootEnv</function> allows to create persistent
 | |
|     environments, which can be constructed, deconstructed and entered by
 | |
|     multiple users at once. A downside is that it requires
 | |
|     <literal>root</literal> access for both those who create and destroy and
 | |
|     those who enter it. It can be useful to create environments for daemons that
 | |
|     one can enter and observe.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     <function>buildFHSUserEnv</function> uses Linux namespaces feature to create
 | |
|     temporary lightweight environments which are destroyed after all child
 | |
|     processes exit. It does not require root access, and can be useful to create
 | |
|     sandboxes and wrap applications.
 | |
|   </para>
 | |
| 
 | |
|   <para>
 | |
|     Those functions both rely on <function>buildFHSEnv</function>, which creates
 | |
|     an actual directory structure given a list of necessary packages and extra
 | |
|     build commands.
 | |
|     <function>buildFHSChrootEnv</function> and <function>buildFHSUserEnv</function>
 | |
|     both accept those arguments which are passed to
 | |
|     <function>buildFHSEnv</function>:
 | |
|   </para>
 | |
| 
 | |
|   <variablelist>
 | |
|     <varlistentry>
 | |
|     <term><literal>name</literal></term>
 | |
| 
 | |
|     <listitem><para>Environment name.</para></listitem>
 | |
|     </varlistentry>
 | |
| 
 | |
|     <varlistentry>
 | |
|     <term><literal>targetPkgs</literal></term>
 | |
| 
 | |
|     <listitem><para>Packages to be installed for the main host's architecture
 | |
|     (i.e. x86_64 on x86_64 installations).</para></listitem>
 | |
|     </varlistentry>
 | |
| 
 | |
|     <varlistentry>
 | |
|     <term><literal>multiPkgs</literal></term>
 | |
| 
 | |
|     <listitem><para>Packages to be installed for all architectures supported by
 | |
|     a host (i.e. i686 and x86_64 on x86_64 installations).</para></listitem>
 | |
|     </varlistentry>
 | |
| 
 | |
|     <varlistentry>
 | |
|     <term><literal>extraBuildCommands</literal></term>
 | |
| 
 | |
|     <listitem><para>Additional commands to be executed for finalizing the
 | |
|     directory structure.</para></listitem>
 | |
|     </varlistentry>
 | |
| 
 | |
|     <varlistentry>
 | |
|     <term><literal>extraBuildCommandsMulti</literal></term>
 | |
| 
 | |
|     <listitem><para>Like <literal>extraBuildCommandsMulti</literal>, but
 | |
|     executed only on multilib architectures.</para></listitem>
 | |
|     </varlistentry>
 | |
|   </variablelist>
 | |
| 
 | |
|   <para>
 | |
|     Additionally, <function>buildFHSUserEnv</function> accepts
 | |
|     <literal>runScript</literal> parameter, which is a command that would be
 | |
|     executed inside the sandbox and passed all the command line arguments. It
 | |
|     default to <literal>bash</literal>.
 | |
|     One can create a simple environment using a <literal>shell.nix</literal>
 | |
|     like that:
 | |
|   </para>
 | |
| 
 | |
| <programlisting><![CDATA[
 | |
| { pkgs ? import <nixpkgs> {} }:
 | |
| 
 | |
| (pkgs.buildFHSUserEnv {
 | |
|   name = "simple-x11-env";
 | |
|   targetPkgs = pkgs: (with pkgs;
 | |
|     [ udev
 | |
|       alsaLib
 | |
|     ]) ++ (with pkgs.xlibs;
 | |
|     [ libX11
 | |
|       libXcursor
 | |
|       libXrandr
 | |
|     ]);
 | |
|   multiPkgs = pkgs: (with pkgs;
 | |
|     [ udev
 | |
|       alsaLib
 | |
|     ]) ++ (with [];
 | |
|   runScript = "bash";
 | |
| }).env
 | |
| ]]></programlisting>
 | |
| 
 | |
|   <para>
 | |
|     Running <literal>nix-shell</literal> would then drop you into a shell with
 | |
|     these libraries and binaries available. You can use this to run
 | |
|     closed-source applications which expect FHS structure without hassles:
 | |
|     simply change <literal>runScript</literal> to the application path,
 | |
|     e.g. <filename>./bin/start.sh</filename> -- relative paths are supported.
 | |
|   </para>
 | |
| </section>
 | |
| 
 | |
| </chapter>
 | 
