10

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
Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286

3 Answers3

8

<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.

Robert Hensing
  • 6,708
  • 18
  • 23
  • What does it evaluate to? A collection of packages? Would this be the official nixpkgs repository, or the system 'nix' configuration or something else? – Chris Stryczynski Nov 20 '17 at 10:19
  • It resolves to a path. The value is determined by `NIX_PATH` (and optionally `-I`). Try `echo $NIX_PATH` in your shell to see how yours is configured. For me `` resolves to `/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs`. I'm on NixOS, so that's the system nixpkgs. – Robert Hensing Nov 20 '17 at 21:13
  • @RobertHensing Just to confirm I've understood what the resolved path actually contains: in the OP's 2nd example, is the (latest) nix expression - with respect to your subscribed channel(s) - for `linuxPackages.kernel` downloaded and unpacked to be used in the shell env? – mikerover Nov 01 '20 at 17:27
  • @mikerover not sure if I understand the question completely. OP's 2nd example is equivalent to `nix-shell --expr '(import {}).linuxPackages.kernel'` and gives you a shell you can use to unpack and build a Linux kernel manually. – Robert Hensing Nov 01 '20 at 22:04
6

From the Nix manual, 5.2.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, 7.2. 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

toraritte
  • 6,300
  • 3
  • 46
  • 67
0

One can evaluate the value using nix repl:

 nix repl
Welcome to Nix version 2.1.3. Type :? for help.

nix-repl> <nixpkgs>
/nix/var/nix/profiles/per-user/root/channels/nixos
Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
  • Just to confirm I've understood what the resolved path actually contains: in the OP's 2nd example, is the (latest) nix expression - with respect to your subscribed channel(s) - for `linuxPackages.kernel` downloaded and unpacked to be used in the shell env? I am now confused as to what the following variables exactly are in one of the answers above e.g `nix-repl> :l Added 10089 variables.` – mikerover Nov 01 '20 at 17:33
  • I'm not sure what you mean by OP's 2nd second example. Which value/text exactly? – Chris Stryczynski Nov 01 '20 at 18:14