= Nixpkgs

The Nix Packages collection (nixpkgs) is a large set of Nix expressions containing hundreds of software packages.
The collection includes functions, definitions and other tools provided by Nix for
creating, using, and maintaining Nix packages.
This chapter will explore some of the most useful tools provided by nixpkgs.

In order to use nixpkgs, you must import it.
As discussed in <<#type-path>>, enclosing a path in angle brackets, e.g. <nixpkgs> causes the directories
listed in the environment variable NIX_PATH to be searched for the given
file or directory name.
In the REPL, the command `:l <nixpkgs>` will import nixpkgs.

[source]
.Example
....
nix-repl> :l <nixpkgs>
Added 25694 variables.
....

Alternatively, you can automatically import nixpkgs when you enter the REPL
using the command `nix repl '<nixpkgs>'`.

Within a Nix flake or module, you would use the `import` command.
For example,

[source, nix]
....
with (import <nixpkgs> {}); ...
....

[NOTE]
====
When you import nixpkgs, you are importing a file, which imports other files, which import still more files.
You can find the location of the nixpkgs directory.

[source]
....
nix-repl> <nixpkgs>
/nix/store/5izw1shpjxb9qhlf67bx427cih5czj8w-source
....

In that directory is a file called `default.nix`, which is what is actually imported.
That file contains an import directive, which triggers more imports, and so on.
As a result, tens of thousands of variables are added to the scope.
Don't worry; this doesn't cause those hundreds of packages to be installed on your system.
It merely gives you access to the recipes for those packages,
plus some tools for working with packages.
====

This chapter will focus on a few especially useful Nixpkgs library functions.
You can find a full list in the
https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library[Nixpkgs manual].

[#genAttrs]
== `lib.genAttrs`

The function
https://nixos.org/manual/nixpkgs/stable/#function-library-lib.attrsets.genAttrs[`lib.genAttrs`]
generates an attribute set by mapping a function over a list of attribute names.
It is an alias for `lib.attrsets.genAttrs`.

It takes two arguments:
- names of values in the resulting attribute set
- a function which, given the name of the attribute, returns the attribute's value

[source]
.Example
....
nix-repl> lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: "some definitions for ${system}")
{
  aarch64-linux = "some definitions for aarch64-linux";
  x86_64-linux = "some definitions for x86_64-linux";
}
....

As we shall see later, this is very useful when writing flakes.

[#getExe]
== `lib.getExe` and `lib.getExe'`

The function
https://nixos.org/manual/nixpkgs/stable/#function-library-lib.meta.getExe[`lib.getExe`]
returns the path to the main program of a package.
It is an alias for `lib.meta.getExe`.

[source]
.Example
....
nix-repl> system = "x86_64-linux"

nix-repl> pkgs = import <nixpkgs> { inherit system; }

nix-repl> lib.getExe pkgs.hello
"/nix/store/s9p0adfpzarzfa5kcnqhwargfwiq8qmj-hello-2.12.2/bin/hello"
....

The function
https://nixos.org/manual/nixpkgs/stable/#function-library-lib.meta.getExe[`lib.getExe'`]
returns the path to the specified program of a package.
It is an alias for `lib.meta.getExe'`.

[source]
.Example
....
nix-repl> lib.getExe' pkgs.imagemagick "convert"
"/nix/store/rn6ck85zkpkgdnm00jmn762z22wz86w6-imagemagick-7.1.2-3/bin/convert"
....

[#flakeExposed]
== `lib.systems.flakeExposed`

This attribute is a list of systems that can support flakes.

[source]
.Example
....
nix-repl> lib.systems.flakeExposed
[
  "x86_64-linux"
  "aarch64-linux"
  "x86_64-darwin"
  "armv6l-linux"
  "armv7l-linux"
  "i686-linux"
  "aarch64-darwin"
  "powerpc64le-linux"
  "riscv64-linux"
  "x86_64-freebsd"
]
....

[IMPORTANT]
====
This attribute is considered experimental and is subject to change.
====

[#mkShell]
== `pkgs.mkShell` and `pkgs.mkShellNoCC`

The function
https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell[`pkgs.mkShell`]
defines a Bash environment.
It is a wrapper around `stdenv.mkDerivation`, discussed in <<#mkDerivation>>.

The following attributes are accepted,
along with all attributes of `stdenv.mkDerivation`.

[%autowidth]
|===
|attribute|description|default

|`name`
|the name of the derivation
|`nix-shell`

|`packages`
|executable packages to add the shell
|`[]`

|`inputsFrom`
|build dependencies to add to the shell
|`[]`

|`shellHook`
|Bash statements to be executed by the shell
|`""`
|===

If you don't need a C compiler, you can use `mkShellNoCC` instead.

[#mkDerivation]
== `stdenv.mkDerivation`

The function
https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell[`pkgs.mkShell`]
is a wrapper around the primitive `derivation` function, discussed in <<#derivations>>.
Some of the commonly used attributes are listed below.

[%autowidth]
|===
|attribute|description

|`pname`
|package name

|`version`
|version number. Use https://semver.org/[semantic versioning], i.e., MAJOR.MINOR.PATCH

|`src`
|location of the source files

|`unpackPhase`
|Bash command to copy/unpack the source files. If set to `"true"`, copies/unpacks all files in `src`, including subdirectories.

|`buildPhase`
|Bash commands to build the package. If no action is required, use the no-op `":"` command.

|`installPhase`
|Bash commands to install the package into the Nix store.
|===

Older Nix flakes combined the package name and version number into a single `name` attribute;
however, this is now discouraged.

A complete list of phases is available in the
https://nixos.org/manual/nixpkgs/stable/#sec-stdenv-phases[Nixpkgs manual].
Additional arguments are also listed in the
https://nixos.org/manual/nixpkgs/stable/#ssec-stdenv-attributes[Nixpkgs manual].
