2024-07-25 05:53:06 +03:00
# Building Nix
2020-12-18 00:42:49 +02:00
2024-07-25 05:53:06 +03:00
This section provides some notes on how to start hacking on Nix.
To get the latest version of Nix from GitHub:
2020-12-18 00:42:49 +02:00
```console
$ git clone https://github.com/NixOS/nix.git
$ cd nix
```
2024-07-25 05:53:06 +03:00
> **Note**
>
> The following instructions assume you already have some version of Nix installed locally, so that you can use it to set up the development environment.
> If you don't have it installed, follow the [installation instructions](../installation/index.md).
2022-11-25 15:47:05 +02:00
2023-06-20 14:44:04 +03:00
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
2020-12-18 00:42:49 +02:00
```console
2024-07-25 05:53:06 +03:00
$ nix-shell
2020-12-18 00:42:49 +02:00
```
2022-11-25 15:47:05 +02:00
To get a shell with one of the other [supported compilation environments ](#compilation-environments ):
2020-12-18 00:42:49 +02:00
```console
2024-07-25 05:53:06 +03:00
$ nix-shell --attr devShells.x86_64-linux.native-clangStdenvPackages
2020-12-18 00:42:49 +02:00
```
2022-11-25 15:47:05 +02:00
> **Note**
>
2024-07-25 05:53:06 +03:00
> You can use `native-ccacheStdenvPackages` to drastically improve rebuild time.
2022-11-25 15:47:05 +02:00
> By default, [ccache](https://ccache.dev) keeps artifacts in `~/.cache/ccache/`.
To build Nix itself in this shell:
2020-12-18 00:42:49 +02:00
```console
2024-08-19 17:24:38 +03:00
[nix-shell]$ mesonFlags+=" --prefix=$(pwd)/outputs/out"
[nix-shell]$ dontAddPrefix=1 mesonConfigurePhase
[nix-shell]$ ninjaBuildPhase
2020-12-18 00:42:49 +02:00
```
2024-08-19 17:24:38 +03:00
To test it:
2020-12-18 00:42:49 +02:00
```console
2024-08-19 17:24:38 +03:00
[nix-shell]$ mesonCheckPhase
```
To install it in `$(pwd)/outputs` :
```console
[nix-shell]$ ninjaInstallPhase
2024-07-25 05:53:06 +03:00
[nix-shell]$ ./outputs/out/bin/nix --version
2022-11-25 15:47:05 +02:00
nix (Nix) 2.12
2020-12-18 00:42:49 +02:00
```
2023-06-20 14:44:04 +03:00
To build a release version of Nix for the current operating system and CPU architecture:
2021-07-08 19:13:55 +03:00
```console
2024-07-25 05:53:06 +03:00
$ nix-build
2021-07-08 19:13:55 +03:00
```
2023-06-21 15:31:09 +03:00
You can also build Nix for one of the [supported platforms ](#platforms ).
2022-11-25 15:47:05 +02:00
2024-07-25 05:53:06 +03:00
## Building Nix with flakes
This section assumes you are using Nix with the [`flakes`] and [`nix-command`] experimental features enabled.
[`flakes`]: @docroot@/development/experimental -features.md#xp-feature-flakes
[`nix-command`]: @docroot@/development/experimental -features.md#xp-nix-command
2022-11-25 15:47:05 +02:00
2023-06-20 14:44:04 +03:00
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
2021-07-08 19:13:55 +03:00
```console
2024-07-25 05:53:06 +03:00
$ nix develop
2021-07-08 19:13:55 +03:00
```
2024-07-25 05:53:06 +03:00
This shell also adds `./outputs/bin/nix` to your `$PATH` so you can run `nix` immediately after building it.
2022-11-25 15:47:05 +02:00
To get a shell with one of the other [supported compilation environments ](#compilation-environments ):
2021-07-08 19:13:55 +03:00
```console
2024-07-25 05:53:06 +03:00
$ nix develop .#native-clangStdenvPackages
2021-07-08 19:13:55 +03:00
```
2022-11-25 15:47:05 +02:00
> **Note**
>
2024-07-25 05:53:06 +03:00
> Use `ccacheStdenv` to drastically improve rebuild time.
2022-11-25 15:47:05 +02:00
> By default, [ccache](https://ccache.dev) keeps artifacts in `~/.cache/ccache/`.
2022-09-23 12:21:19 +03:00
2020-12-18 00:42:49 +02:00
To build Nix itself in this shell:
```console
2024-08-19 17:24:38 +03:00
[nix-shell]$ mesonConfigurePhase
[nix-shell]$ ninjaBuildPhase
2020-12-18 00:42:49 +02:00
```
2024-08-19 17:24:38 +03:00
To test it:
2020-12-18 00:42:49 +02:00
```console
2024-08-19 17:24:38 +03:00
[nix-shell]$ mesonCheckPhase
```
To install it in `$(pwd)/outputs` :
```console
[nix-shell]$ ninjaInstallPhase
2024-07-25 05:53:06 +03:00
[nix-shell]$ nix --version
2022-11-25 15:47:05 +02:00
nix (Nix) 2.12
2020-12-18 00:42:49 +02:00
```
2024-07-25 05:53:06 +03:00
For more information on running and filtering tests, see
[`testing.md` ](./testing.md ).
2023-06-20 14:44:04 +03:00
To build a release version of Nix for the current operating system and CPU architecture:
2020-12-18 00:42:49 +02:00
```console
2024-07-25 05:53:06 +03:00
$ nix build
2020-12-18 00:42:49 +02:00
```
2023-06-21 15:31:09 +03:00
You can also build Nix for one of the [supported platforms ](#platforms ).
2022-11-25 15:47:05 +02:00
2023-02-20 13:20:08 +02:00
## Platforms
2022-11-25 15:47:05 +02:00
2023-06-20 15:10:30 +03:00
Nix can be built for various platforms, as specified in [`flake.nix`]:
2022-11-25 15:47:05 +02:00
[`flake.nix`]: https://github.com/nixos/nix/blob/master/flake.nix
2023-06-20 15:10:30 +03:00
- `x86_64-linux`
- `x86_64-darwin`
- `i686-linux`
- `aarch64-linux`
- `aarch64-darwin`
- `armv6l-linux`
- `armv7l-linux`
2024-04-18 14:10:52 +03:00
- `riscv64-linux`
2023-06-20 15:10:30 +03:00
2022-11-25 15:47:05 +02:00
In order to build Nix for a different platform than the one you're currently
2023-06-20 15:10:30 +03:00
on, you need a way for your current Nix installation to build code for that
2024-02-13 15:13:56 +02:00
platform. Common solutions include [remote build machines] and [binary format emulation]
2022-11-25 15:47:05 +02:00
(only supported on NixOS).
2024-02-13 15:13:56 +02:00
[remote builders]: @docroot@/language/derivations .md#attr-builder
2023-07-20 18:58:14 +03:00
[binary format emulation]: https://nixos.org/manual/nixos/stable/options.html#opt-boot.binfmt.emulatedSystems
2022-11-25 15:47:05 +02:00
2023-07-19 00:21:43 +03:00
Given such a setup, executing the build only requires selecting the respective attribute.
2023-06-20 15:10:30 +03:00
For example, to compile for `aarch64-linux` :
2020-12-18 00:42:49 +02:00
```console
2023-06-20 15:10:30 +03:00
$ nix-build --attr packages.aarch64-linux.default
2022-11-25 15:47:05 +02:00
```
2023-06-20 15:10:30 +03:00
or for Nix with the [`flakes`] and [`nix-command`] experimental features enabled:
2022-11-25 15:47:05 +02:00
```console
2023-06-20 15:10:30 +03:00
$ nix build .#packages.aarch64-linux.default
2020-12-18 00:42:49 +02:00
```
2022-05-10 12:56:47 +03:00
2024-04-18 14:10:52 +03:00
Cross-compiled builds are available for:
- `armv6l-linux`
- `armv7l-linux`
- `riscv64-linux`
2023-06-20 15:10:30 +03:00
Add more [system types ](#system-type ) to `crossSystems` in `flake.nix` to bootstrap Nix on unsupported platforms.
2023-11-25 07:33:21 +02:00
### Building for multiple platforms at once
It is useful to perform multiple cross and native builds on the same source tree,
for example to ensure that better support for one platform doesn't break the build for another.
2024-08-19 17:24:38 +03:00
Meson thankfully makes this very easy by confining all build products to the build directory --- one simple shares the source directory between multiple build directories, each of which contains the build for Nix to a different platform.
Nixpkgs's `mesonConfigurePhase` always chooses `build` in the current directory as the name and location of the build.
This makes having multiple build directories slightly more inconvenient.
The good news is that Meson/Ninja seem to cope well with relocating the build directory after it is created.
2023-11-25 07:33:21 +02:00
2024-08-19 17:24:38 +03:00
Here's how to do that
1. Configure as usual
2023-11-25 07:33:21 +02:00
```bash
2024-08-19 17:24:38 +03:00
mesonConfigurePhase
2023-11-25 07:33:21 +02:00
```
2024-08-19 17:24:38 +03:00
2. Rename the build directory
2023-11-25 07:33:21 +02:00
```bash
2024-08-19 17:24:38 +03:00
cd .. # since `mesonConfigurePhase` cd'd inside
mv build build-linux # or whatever name we want
cd build-linux
2023-11-25 07:33:21 +02:00
```
2024-08-19 17:24:38 +03:00
3. Build as usual
2023-11-25 07:33:21 +02:00
```bash
2024-08-19 17:24:38 +03:00
ninjaBuildPhase
2023-11-25 07:33:21 +02:00
```
2024-08-19 17:24:38 +03:00
> **N.B.**
> [`nixpkgs#335818`](https://github.com/NixOS/nixpkgs/issues/335818) tracks giving `mesonConfigurePhase` proper support for custom build directories.
> When it is fixed, we can simplify these instructions and then remove this notice.
2023-06-20 15:10:30 +03:00
## System type
2024-04-16 16:54:45 +03:00
Nix uses a string with the following format to identify the *system type* or *platform* it runs on:
2023-06-20 15:10:30 +03:00
```
< cpu > -< os > [-< abi > ]
```
It is set when Nix is compiled for the given system, and based on the output of [`config.guess` ](https://github.com/nixos/nix/blob/master/config/config.guess ) ([upstream](https://git.savannah.gnu.org/cgit/config.git/tree/config.guess)):
```
< cpu > -< vendor > -< os > [< version > ][-< abi > ]
```
When Nix is built such that `./configure` is passed any of the `--host` , `--build` , `--target` options, the value is based on the output of [`config.sub` ](https://github.com/nixos/nix/blob/master/config/config.sub ) ([upstream](https://git.savannah.gnu.org/cgit/config.git/tree/config.sub)):
```
< cpu > -< vendor > [-< kernel > ]-< os >
```
2022-11-25 15:47:05 +02:00
2023-07-20 18:58:14 +03:00
For historic reasons and backward-compatibility, some CPU and OS identifiers are translated from the GNU Autotools naming convention in [`configure.ac` ](https://github.com/nixos/nix/blob/master/configure.ac ) as follows:
2022-11-25 15:47:05 +02:00
2023-06-20 15:10:30 +03:00
| `config.guess` | Nix |
|----------------------------|---------------------|
| `amd64` | `x86_64` |
| `i*86` | `i686` |
| `arm6` | `arm6l` |
| `arm7` | `arm7l` |
| `linux-gnu*` | `linux` |
| `linux-musl*` | `linux` |
2023-02-20 13:20:08 +02:00
2022-11-25 15:47:05 +02:00
## Compilation environments
Nix can be compiled using multiple environments:
- `stdenv` : default;
- `gccStdenv` : force the use of `gcc` compiler;
- `clangStdenv` : force the use of `clang` compiler;
- `ccacheStdenv` : enable [ccache], a compiler cache to speed up compilation.
To build with one of those environments, you can use
```console
$ nix build .#nix-ccacheStdenv
```
for flake-enabled Nix, or
```console
2023-04-30 16:52:38 +03:00
$ nix-build --attr nix-ccacheStdenv
2022-11-25 15:47:05 +02:00
```
for classic Nix.
You can use any of the other supported environments in place of `nix-ccacheStdenv` .
## Editor integration
The `clangd` LSP server is installed by default on the `clang` -based `devShell` s.
See [supported compilation environments ](#compilation-environments ) and instructions how to set up a shell [with flakes ](#nix-with-flakes ) or in [classic Nix ](#classic-nix ).
2024-08-19 17:24:38 +03:00
To use the LSP with your editor, you will want a `compile_commands.json` file telling `clangd` how we are compiling the code.
Meson's configure always produces this inside the build directory.
2022-11-25 15:47:05 +02:00
2024-03-22 23:31:41 +02:00
Configure your editor to use the `clangd` from the `.#native-clangStdenvPackages` shell. You can do that either by running it inside the development shell, or by using [nix-direnv ](https://github.com/nix-community/nix-direnv ) and [the appropriate editor plugin ](https://github.com/direnv/direnv/wiki#editor-integration ).
2022-11-25 15:47:05 +02:00
> **Note**
>
> For some editors (e.g. Visual Studio Code), you may need to install a [special extension](https://open-vsx.org/extension/llvm-vs-code-extensions/vscode-clangd) for the editor to interact with `clangd`.
> Some other editors (e.g. Emacs, Vim) need a plugin to support LSP servers in general (e.g. [lsp-mode](https://github.com/emacs-lsp/lsp-mode) for Emacs and [vim-lsp](https://github.com/prabirshrestha/vim-lsp) for vim).
> Editor-specific setup is typically opinionated, so we will not cover it here in more detail.
2023-11-19 16:05:21 +02:00
2024-04-21 14:52:56 +03:00
## Formatting and pre-commit hooks
2024-04-18 22:59:39 +03:00
You may run the formatters as a one-off using:
```console
2024-08-19 17:24:38 +03:00
./maintainers/format.sh
2024-04-18 22:59:39 +03:00
```
If you'd like to run the formatters before every commit, install the hooks:
```
pre-commit-hooks-install
```
This installs [pre-commit ](https://pre-commit.com ) using [cachix/git-hooks.nix ](https://github.com/cachix/git-hooks.nix ).
When making a commit, pay attention to the console output.
If it fails, run `git add --patch` to approve the suggestions _and commit again_ .
2024-04-21 14:52:56 +03:00
To refresh pre-commit hook's config file, do the following:
1. Exit the development shell and start it again by running `nix develop` .
2. If you also use the pre-commit hook, also run `pre-commit-hooks-install` again.