|
- <chapter xmlns="http://docbook.org/ns/docbook"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xml:id="chap-packageconfig">
- <title>Global configuration</title>
- <para>
- Nix comes with certain defaults about what packages can and cannot be
- installed, based on a package's metadata. By default, Nix will prevent
- installation if any of the following criteria are true:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- The package is thought to be broken, and has had its
- <literal>meta.broken</literal> set to <literal>true</literal>.
- </para>
- </listitem>
- <listitem>
- <para>
- The package isn't intended to run on the given system, as none of its
- <literal>meta.platforms</literal> match the given system.
- </para>
- </listitem>
- <listitem>
- <para>
- The package's <literal>meta.license</literal> is set to a license which is
- considered to be unfree.
- </para>
- </listitem>
- <listitem>
- <para>
- The package has known security vulnerabilities but has not or can not be
- updated for some reason, and a list of issues has been entered in to the
- package's <literal>meta.knownVulnerabilities</literal>.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Note that all this is checked during evaluation already, and the check
- includes any package that is evaluated. In particular, all build-time
- dependencies are checked. <literal>nix-env -qa</literal> will (attempt to)
- hide any packages that would be refused.
- </para>
- <para>
- Each of these criteria can be altered in the nixpkgs configuration.
- </para>
- <para>
- The nixpkgs configuration for a NixOS system is set in the
- <literal>configuration.nix</literal>, as in the following example:
- <programlisting>
- {
- nixpkgs.config = {
- allowUnfree = true;
- };
- }
- </programlisting>
- However, this does not allow unfree software for individual users. Their
- configurations are managed separately.
- </para>
- <para>
- A user's of nixpkgs configuration is stored in a user-specific configuration
- file located at <filename>~/.config/nixpkgs/config.nix</filename>. For
- example:
- <programlisting>
- {
- allowUnfree = true;
- }
- </programlisting>
- </para>
- <para>
- Note that we are not able to test or build unfree software on Hydra due to
- policy. Most unfree licenses prohibit us from either executing or
- distributing the software.
- </para>
- <section xml:id="sec-allow-broken">
- <title>Installing broken packages</title>
-
- <para>
- There are two ways to try compiling a package which has been marked as
- broken.
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- For allowing the build of a broken package once, you can use an
- environment variable for a single invocation of the nix tools:
- <programlisting>$ export NIXPKGS_ALLOW_BROKEN=1</programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- For permanently allowing broken packages to be built, you may add
- <literal>allowBroken = true;</literal> to your user's configuration file,
- like this:
- <programlisting>
- {
- allowBroken = true;
- }
- </programlisting>
- </para>
- </listitem>
- </itemizedlist>
- </section>
- <section xml:id="sec-allow-unsupported-system">
- <title>Installing packages on unsupported systems</title>
-
- <para>
- There are also two ways to try compiling a package which has been marked as
- unsuported for the given system.
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- For allowing the build of a broken package once, you can use an
- environment variable for a single invocation of the nix tools:
- <programlisting>$ export NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1</programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- For permanently allowing broken packages to be built, you may add
- <literal>allowUnsupportedSystem = true;</literal> to your user's
- configuration file, like this:
- <programlisting>
- {
- allowUnsupportedSystem = true;
- }
- </programlisting>
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- The difference between a package being unsupported on some system and
- being broken is admittedly a bit fuzzy. If a program
- <emphasis>ought</emphasis> to work on a certain platform, but doesn't, the
- platform should be included in <literal>meta.platforms</literal>, but marked
- as broken with e.g. <literal>meta.broken =
- !hostPlatform.isWindows</literal>. Of course, this begs the question of what
- "ought" means exactly. That is left to the package maintainer.
- </para>
- </section>
- <section xml:id="sec-allow-unfree">
- <title>Installing unfree packages</title>
-
- <para>
- There are several ways to tweak how Nix handles a package which has been
- marked as unfree.
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- To temporarily allow all unfree packages, you can use an environment
- variable for a single invocation of the nix tools:
- <programlisting>$ export NIXPKGS_ALLOW_UNFREE=1</programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- It is possible to permanently allow individual unfree packages, while
- still blocking unfree packages by default using the
- <literal>allowUnfreePredicate</literal> configuration option in the user
- configuration file.
- </para>
- <para>
- This option is a function which accepts a package as a parameter, and
- returns a boolean. The following example configuration accepts a package
- and always returns false:
- <programlisting>
- {
- allowUnfreePredicate = (pkg: false);
- }
- </programlisting>
- </para>
- <para>
- For a more useful example, try the following. This configuration
- only allows unfree packages named flash player and visual studio
- code:
- <programlisting>
- {
- allowUnfreePredicate = (pkg: builtins.elem
- (builtins.parseDrvName pkg.name).name [
- "flashplayer"
- "vscode"
- ]);
- }
- </programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- It is also possible to whitelist and blacklist licenses that are
- specifically acceptable or not acceptable, using
- <literal>whitelistedLicenses</literal> and
- <literal>blacklistedLicenses</literal>, respectively.
- </para>
- <para>
- The following example configuration whitelists the licenses
- <literal>amd</literal> and <literal>wtfpl</literal>:
- <programlisting>
- {
- whitelistedLicenses = with stdenv.lib.licenses; [ amd wtfpl ];
- }
- </programlisting>
- </para>
- <para>
- The following example configuration blacklists the <literal>gpl3</literal>
- and <literal>agpl3</literal> licenses:
- <programlisting>
- {
- blacklistedLicenses = with stdenv.lib.licenses; [ agpl3 gpl3 ];
- }
- </programlisting>
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- A complete list of licenses can be found in the file
- <filename>lib/licenses.nix</filename> of the nixpkgs tree.
- </para>
- </section>
- <section xml:id="sec-allow-insecure">
- <title>Installing insecure packages</title>
-
- <para>
- There are several ways to tweak how Nix handles a package which has been
- marked as insecure.
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- To temporarily allow all insecure packages, you can use an environment
- variable for a single invocation of the nix tools:
- <programlisting>$ export NIXPKGS_ALLOW_INSECURE=1</programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- It is possible to permanently allow individual insecure packages, while
- still blocking other insecure packages by default using the
- <literal>permittedInsecurePackages</literal> configuration option in the
- user configuration file.
- </para>
- <para>
- The following example configuration permits the installation of the
- hypothetically insecure package <literal>hello</literal>, version
- <literal>1.2.3</literal>:
- <programlisting>
- {
- permittedInsecurePackages = [
- "hello-1.2.3"
- ];
- }
- </programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- It is also possible to create a custom policy around which insecure
- packages to allow and deny, by overriding the
- <literal>allowInsecurePredicate</literal> configuration option.
- </para>
- <para>
- The <literal>allowInsecurePredicate</literal> option is a function which
- accepts a package and returns a boolean, much like
- <literal>allowUnfreePredicate</literal>.
- </para>
- <para>
- The following configuration example only allows insecure packages with
- very short names:
- <programlisting>
- {
- allowInsecurePredicate = (pkg: (builtins.stringLength (builtins.parseDrvName pkg.name).name) <= 5);
- }
- </programlisting>
- </para>
- <para>
- Note that <literal>permittedInsecurePackages</literal> is only checked if
- <literal>allowInsecurePredicate</literal> is not specified.
- </para>
- </listitem>
- </itemizedlist>
- </section>
- <!--============================================================-->
- <section xml:id="sec-modify-via-packageOverrides">
- <title>Modify packages via <literal>packageOverrides</literal></title>
-
- <para>
- You can define a function called <varname>packageOverrides</varname> in your
- local <filename>~/.config/nixpkgs/config.nix</filename> to override Nix
- packages. It must be a function that takes pkgs as an argument and returns a
- modified set of packages.
- <programlisting>
- {
- packageOverrides = pkgs: rec {
- foo = pkgs.foo.override { ... };
- };
- }
- </programlisting>
- </para>
- </section>
- <section xml:id="sec-declarative-package-management">
- <title>Declarative Package Management</title>
-
- <section xml:id="sec-building-environment">
- <title>Build an environment</title>
-
- <para>
- Using <literal>packageOverrides</literal>, it is possible to manage
- packages declaratively. This means that we can list all of our desired
- packages within a declarative Nix expression. For example, to have
- <literal>aspell</literal>, <literal>bc</literal>,
- <literal>ffmpeg</literal>, <literal>coreutils</literal>,
- <literal>gdb</literal>, <literal>nixUnstable</literal>,
- <literal>emscripten</literal>, <literal>jq</literal>,
- <literal>nox</literal>, and <literal>silver-searcher</literal>, we could
- use the following in <filename>~/.config/nixpkgs/config.nix</filename>:
- </para>
-
- <screen>
- {
- packageOverrides = pkgs: with pkgs; {
- myPackages = pkgs.buildEnv {
- name = "my-packages";
- paths = [
- aspell
- bc
- coreutils
- gdb
- ffmpeg
- nixUnstable
- emscripten
- jq
- nox
- silver-searcher
- ];
- };
- };
- }
- </screen>
-
- <para>
- To install it into our environment, you can just run <literal>nix-env -iA
- nixpkgs.myPackages</literal>. If you want to load the packages to be built
- from a working copy of <literal>nixpkgs</literal> you just run
- <literal>nix-env -f. -iA myPackages</literal>. To explore what's been
- installed, just look through <filename>~/.nix-profile/</filename>. You can
- see that a lot of stuff has been installed. Some of this stuff is useful
- some of it isn't. Let's tell Nixpkgs to only link the stuff that we want:
- </para>
-
- <screen>
- {
- packageOverrides = pkgs: with pkgs; {
- myPackages = pkgs.buildEnv {
- name = "my-packages";
- paths = [
- aspell
- bc
- coreutils
- gdb
- ffmpeg
- nixUnstable
- emscripten
- jq
- nox
- silver-searcher
- ];
- pathsToLink = [ "/share" "/bin" ];
- };
- };
- }
- </screen>
-
- <para>
- <literal>pathsToLink</literal> tells Nixpkgs to only link the paths listed
- which gets rid of the extra stuff in the profile. <filename>/bin</filename>
- and <filename>/share</filename> are good defaults for a user environment,
- getting rid of the clutter. If you are running on Nix on MacOS, you may
- want to add another path as well, <filename>/Applications</filename>, that
- makes GUI apps available.
- </para>
- </section>
-
- <section xml:id="sec-getting-documentation">
- <title>Getting documentation</title>
-
- <para>
- After building that new environment, look through
- <filename>~/.nix-profile</filename> to make sure everything is there that
- we wanted. Discerning readers will note that some files are missing. Look
- inside <filename>~/.nix-profile/share/man/man1/</filename> to verify this.
- There are no man pages for any of the Nix tools! This is because some
- packages like Nix have multiple outputs for things like documentation (see
- section 4). Let's make Nix install those as well.
- </para>
-
- <screen>
- {
- packageOverrides = pkgs: with pkgs; {
- myPackages = pkgs.buildEnv {
- name = "my-packages";
- paths = [
- aspell
- bc
- coreutils
- ffmpeg
- nixUnstable
- emscripten
- jq
- nox
- silver-searcher
- ];
- pathsToLink = [ "/share/man" "/share/doc" "/bin" ];
- extraOutputsToInstall = [ "man" "doc" ];
- };
- };
- }
- </screen>
-
- <para>
- This provides us with some useful documentation for using our packages.
- However, if we actually want those manpages to be detected by man, we need
- to set up our environment. This can also be managed within Nix expressions.
- </para>
-
- <screen>
- {
- packageOverrides = pkgs: with pkgs; rec {
- myProfile = writeText "my-profile" ''
- export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
- export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
- '';
- myPackages = pkgs.buildEnv {
- name = "my-packages";
- paths = [
- (runCommand "profile" {} ''
- mkdir -p $out/etc/profile.d
- cp ${myProfile} $out/etc/profile.d/my-profile.sh
- '')
- aspell
- bc
- coreutils
- ffmpeg
- man
- nixUnstable
- emscripten
- jq
- nox
- silver-searcher
- ];
- pathsToLink = [ "/share/man" "/share/doc" "/bin" "/etc" ];
- extraOutputsToInstall = [ "man" "doc" ];
- };
- };
- }
- </screen>
-
- <para>
- For this to work fully, you must also have this script sourced when you are
- logged in. Try adding something like this to your
- <filename>~/.profile</filename> file:
- </para>
-
- <screen>
- #!/bin/sh
- if [ -d $HOME/.nix-profile/etc/profile.d ]; then
- for i in $HOME/.nix-profile/etc/profile.d/*.sh; do
- if [ -r $i ]; then
- . $i
- fi
- done
- fi
- </screen>
-
- <para>
- Now just run <literal>source $HOME/.profile</literal> and you can starting
- loading man pages from your environent.
- </para>
- </section>
-
- <section xml:id="sec-gnu-info-setup">
- <title>GNU info setup</title>
-
- <para>
- Configuring GNU info is a little bit trickier than man pages. To work
- correctly, info needs a database to be generated. This can be done with
- some small modifications to our environment scripts.
- </para>
-
- <screen>
- {
- packageOverrides = pkgs: with pkgs; rec {
- myProfile = writeText "my-profile" ''
- export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
- export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
- export INFOPATH=$HOME/.nix-profile/share/info:/nix/var/nix/profiles/default/share/info:/usr/share/info
- '';
- myPackages = pkgs.buildEnv {
- name = "my-packages";
- paths = [
- (runCommand "profile" {} ''
- mkdir -p $out/etc/profile.d
- cp ${myProfile} $out/etc/profile.d/my-profile.sh
- '')
- aspell
- bc
- coreutils
- ffmpeg
- man
- nixUnstable
- emscripten
- jq
- nox
- silver-searcher
- texinfoInteractive
- ];
- pathsToLink = [ "/share/man" "/share/doc" "/share/info" "/bin" "/etc" ];
- extraOutputsToInstall = [ "man" "doc" "info" ];
- postBuild = ''
- if [ -x $out/bin/install-info -a -w $out/share/info ]; then
- shopt -s nullglob
- for i in $out/share/info/*.info $out/share/info/*.info.gz; do
- $out/bin/install-info $i $out/share/info/dir
- done
- fi
- '';
- };
- };
- }
- </screen>
-
- <para>
- <literal>postBuild</literal> tells Nixpkgs to run a command after building
- the environment. In this case, <literal>install-info</literal> adds the
- installed info pages to <literal>dir</literal> which is GNU info's default
- root node. Note that <literal>texinfoInteractive</literal> is added to the
- environment to give the <literal>install-info</literal> command.
- </para>
- </section>
- </section>
- </chapter>
|