Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the <nixpkgs> string / value mean in Nix?

Tags:

nix

nixos

For example in the following (which I assume is a nix expression):

(import <nixpkgs> {}).haskellPackages.ghcWithPackages (hpkgs: with hpkgs; [
    lens
    aeson
    turtle
])

What does <nixpkgs> reference? I also see it used in other contexts for example:

nix-shell '<nixpkgs>' -A linuxPackages.kernel
like image 452
Chris Stryczynski Avatar asked Nov 19 '17 17:11

Chris Stryczynski


Video Answer


2 Answers

<nixpkgs> is a Nix expression that is evaluated by looking at the Nix search path in the NIX_PATH environment variable and/or -I option.

It is described in more detail in the Nix manual.

Note that the Nix search path is impractical in many situations. You can only pass it from the outside, and it easily creates impurity. In my experience, problems are better solved with explicit argument passing or the functions relating to fix-points like callPackage and the overlay system.

As an example, NixOS has only one extra search path parameter, and it is only read once in nixos/default.nix if no explicit configuration is given. This way, you have the flexibility to provide your own configuration, which is why you (nix-build) and hydra can confidently build the NixOS VM tests, bootable images, docker images, etc.

like image 131
Robert Hensing Avatar answered Oct 13 '22 02:10

Robert Hensing


From the Nix manual, 15.1. Values, section "Simple Values":

Paths can also be specified between angle brackets, e.g. . This means that the directories listed in the environment variable NIX_PATH will be searched for the given file or directory name.

From the NixOS manual, Chapter 18. Common Environment Variables, section NIX_PATH:

A colon-separated list of directories used to look up Nix expressions enclosed in angle brackets (i.e., ). For instance, the value

/home/eelco/Dev:/etc/nixos

will cause Nix to look for paths relative to /home/eelco/Dev and /etc/nixos, in that order. It is also possible to match paths against a prefix. For example, the value

nixpkgs=/home/eelco/Dev/nixpkgs-branch:/etc/nixos

will cause Nix to search for <nixpkgs/path> in /home/eelco/Dev/nixpkgs-branch/path and /etc/nixos/nixpkgs/path.

If a path in the Nix search path starts with http:// or https://, it is interpreted as the URL of a tarball that will be downloaded and unpacked to a temporary location. The tarball must consist of a single top-level directory. For example, setting NIX_PATH to

nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-15.09.tar.gz

tells Nix to download the latest revision in the Nixpkgs/NixOS 15.09 channel.

A following shorthand can be used to refer to the official channels:

nixpkgs=channel:nixos-15.09

The search path can be extended using the -I option, which takes precedence over NIX_PATH.

Examples

1. with import <nixpkgs> {}; /* rest of the expression */

In my case, <nixpkgs> is /nix/var/nix/profiles/per-user/root/channels/nixos:

$ echo $NIX_PATH 
#                                  VVVVVVV
/home/a_user/.nix-defexpr/channels:nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels
#                                  ^^^^^^^

Because <nixpkgs> evaluates to "a directory, the file default.nix in that directory is loaded" by import. (Nix manual, 15.4.1. Advanced Attributes, section import path, builtins.import path)

$ ll /nix/var/nix/profiles/per-user/root/channels/nixos
lrwxrwxrwx 1 root root 80 Dec 31  1969 /nix/var/nix/profiles/per-user/root/channels/nixos -> /nix/store/ywlfq2ns4
a3fzb2ap74lvahmrg1p0lmk-nixos-19.03.172231.7b36963e7a7/nixos/

$ ll $(readlink -f /nix/var/nix/profiles/per-user/root/channels/nixos)
total 3308
dr-xr-xr-x  8 root root    4096 Dec 31  1969 ./
dr-xr-xr-x  4 root root    4096 Dec 31  1969 ../
# (...)
dr-xr-xr-x  7 root root    4096 Dec 31  1969 nixos/
dr-xr-xr-x 17 root root    4096 Dec 31  1969 pkgs/
-r--r--r--  1 root root    1097 Dec 31  1969 COPYING
-r--r--r--  1 root root     968 Dec 31  ---> default.nix <---
# (...)

If my understanding is correct, after the import the provided Nix expression is evaluated with an empty attribute set ({}). The result is an attribute list, and the with expression will include all its containing attributes in the local lexical scope.

2. nix repl '<nixpkgs/nixos>'

Example taken from the NixOS manual, 5.3. Modularity, showing the active NixOS configuration settings in the repl.

# On NixOS 19.03

$ nix repl

Welcome to Nix version 2.2.2. Type :? for help.

nix-repl> <nixpkgs>
/nix/var/nix/profiles/per-user/root/channels/nixos

nix-repl> <nixpkgs/nixos>
/nix/var/nix/profiles/per-user/root/channels/nixos/nixos

Load the systems NixOS configuration on the repl:

nix-repl> :l <nixpkgs/nixos>
Added 6 variables.

Load all Nix expressions from Nixpkgs on the repl:

nix-repl> :l <nixpkgs>
Added 10089 variables.

Or loading them directly into the repl:

$ nix repl '<nixpkgs>'

Welcome to Nix version 2.2.2. Type :? for help.

Loading '<nixpkgs>'...
Added 10089 variables.

$ nix repl '<nixpkgs/nixos>'

Welcome to Nix version 2.2.2. Type :? for help.

Loading '<nixpkgs/nixos>'...
Added 6 variables.

Cheatsheet:

nix-repl> :help
The following commands are available:

  <expr>        Evaluate and print expression
  <x> = <expr>  Bind expression to variable
  :a <expr>     Add attributes from resulting set to scope
  :b <expr>     Build derivation
  :i <expr>     Build derivation, then install result into current profile
  :l <path>     Load Nix expression and add it to scope
  :p <expr>     Evaluate and print expression recursively
  :q            Exit nix-repl
  :r            Reload all files
  :s <expr>     Build dependencies of derivation, then start nix-shell
  :t <expr>     Describe result of evaluation
  :u <expr>     Build derivation, then start nix-shell

Because of the <nixpkgs/path> convention (where path equals nixos), the angle expression will evaluate to /nix/var/nix/profiles/per-user/root/channels/nixos/nixos. The above ll output also shows a nixos folder above default.nix, and inside there is indeed another default.nix that will get evaluated by nix repl:

$ ll $(readlink -f /nix/var/nix/profiles/per-user/root/channels/nixos/nixos)
total 72
dr-xr-xr-x  7 root root  4096 Dec 31  1969 ./
dr-xr-xr-x  8 root root  4096 Dec 31  1969 ../
-r--r--r--  1 root root   886 Dec 31  ---> default.nix <---
-r--r--r--  1 root root   197 Dec 31  1969 README
-r--r--r--  1 root root  6074 Dec 31  1969 release-combined.nix
-r--r--r--  1 root root  9251 Dec 31  1969 release.nix
-r--r--r--  1 root root  2038 Dec 31  1969 release-small.nix

Miscellaneous

  • Issue #338 is still open to improve the Nix manual, documenting the angle syntax in their own section (UPDATE: Fixed and closed, 10/23/2019).
  • Nix Pills sections (e.g., 15.5. Conclusion and Chapter 16. Nixpkgs Parameters) consistently call the angle syntax "angular brackets" syntax.
  • In his answer, Robert Hensing warns against using <nixpkgs> everywhere, and an issue #1161 is still open on just that topic. (Excerpt: "We have an unofficial guideline that nobody should use angle brackets in nixpkgs, but why not make it into a hard requirement?")
like image 22
toraritte Avatar answered Oct 13 '22 02:10

toraritte