2020-12-08 12:59:23 +02:00
# Hacking
2020-12-18 00:42:49 +02:00
This section provides some notes on how to hack on Nix. To get the
latest version of Nix from GitHub:
```console
$ git clone https://github.com/NixOS/nix.git
$ cd nix
```
2022-11-25 15:47:05 +02:00
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].
2023-11-27 15:48:11 +02:00
[installation instructions]: ../installation/index.md
2022-11-25 15:47:05 +02:00
2023-06-20 14:44:04 +03:00
## Building Nix with flakes
2022-11-25 15:47:05 +02:00
2023-06-20 14:44:04 +03:00
This section assumes you are using Nix with the [`flakes`] and [`nix-command`] experimental features enabled.
See the [Building Nix ](#building-nix ) section for equivalent instructions using stable Nix interfaces.
2022-11-25 15:47:05 +02:00
2023-06-20 14:44:04 +03:00
[`flakes`]: @docroot@/contributing/experimental -features.md#xp-feature-flakes
[`nix-command`]: @docroot@/contributing/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:
2020-12-18 00:42:49 +02:00
```console
2022-11-25 15:47:05 +02:00
$ nix develop
2020-12-18 00:42:49 +02:00
```
2022-11-25 15:47:05 +02:00
This shell also adds `./outputs/bin/nix` to your `$PATH` so you can run `nix` immediately after building it.
To get a shell with one of the other [supported compilation environments ](#compilation-environments ):
2020-12-18 00:42:49 +02:00
```console
2024-01-04 21:31:09 +02:00
$ nix develop .#native-clangStdenvPackages
2020-12-18 00:42:49 +02:00
```
2022-11-25 15:47:05 +02:00
> **Note**
>
> Use `ccacheStdenv` to drastically improve rebuild time.
> 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
2023-10-09 19:52:58 +03:00
[nix-shell]$ autoreconfPhase
[nix-shell]$ configurePhase
2024-02-08 10:50:12 +02:00
[nix-shell]$ make -j $NIX_BUILD_CORES OPTIMIZE=0
2020-12-18 00:42:49 +02:00
```
2022-11-25 15:47:05 +02:00
To install it in `$(pwd)/outputs` and test it:
2020-12-18 00:42:49 +02:00
```console
2024-02-08 10:50:12 +02:00
[nix-shell]$ make install OPTIMIZE=0
2024-01-12 20:01:55 +02:00
[nix-shell]$ make installcheck check -j $NIX_BUILD_CORES
2022-11-25 15:47:05 +02:00
[nix-shell]$ nix --version
nix (Nix) 2.12
2020-12-18 00:42:49 +02:00
```
2024-01-12 20:01:55 +02: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:
2021-07-08 19:13:55 +03:00
```console
2022-11-25 15:47:05 +02: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
2023-06-20 14:44:04 +03:00
## Building Nix
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
2022-11-25 15:47:05 +02:00
$ nix-shell
2021-07-08 19:13:55 +03:00
```
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-01-04 21:31:09 +02:00
$ nix-shell --attr devShells.x86_64-linux.native-clangStdenvPackages
2021-07-08 19:13:55 +03:00
```
2022-11-25 15:47:05 +02:00
> **Note**
>
2022-03-02 04:40:18 +02: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/`.
2022-09-23 12:21:19 +03:00
2020-12-18 00:42:49 +02:00
To build Nix itself in this shell:
```console
2023-10-09 19:52:58 +03:00
[nix-shell]$ autoreconfPhase
2020-12-18 00:42:49 +02:00
[nix-shell]$ ./configure $configureFlags --prefix=$(pwd)/outputs/out
[nix-shell]$ make -j $NIX_BUILD_CORES
```
To install it in `$(pwd)/outputs` and test it:
```console
[nix-shell]$ make install
[nix-shell]$ make installcheck -j $NIX_BUILD_CORES
[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:
2020-12-18 00:42:49 +02:00
```console
2022-11-25 15:47:05 +02: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
2024-01-17 05:23:16 +02:00
## Makefile variables
2024-01-17 05:39:26 +02:00
You may need `profiledir=$out/etc/profile.d` and `sysconfdir=$out/etc` to run `make install` .
2024-01-17 05:23:16 +02:00
2024-01-19 01:32:30 +02:00
Run `make` with [`-e` / `--environment-overrides` ](https://www.gnu.org/software/make/manual/make.html#index-_002de ) to allow environment variables to override `Makefile` variables:
2024-01-17 05:23:16 +02:00
- `ENABLE_BUILD=yes` to enable building the C++ code.
- `ENABLE_DOC_GEN=yes` to enable building the documentation (manual, man pages, etc.).
The docs can take a while to build, so you may want to disable this for local development.
- `ENABLE_FUNCTIONAL_TESTS=yes` to enable building the functional tests.
- `ENABLE_UNIT_TESTS=yes` to enable building the unit tests.
- `OPTIMIZE=1` to enable optimizations.
2024-01-17 05:39:26 +02:00
- `libraries=libutil programs=` to only build a specific library.
This will fail in the linking phase if the other libraries haven't been built, but is useful for checking types.
- `libraries= programs=nix` to only build a specific program.
This will not work in general, because the programs need the libraries.
2024-01-17 05:23:16 +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.
In order to facilitate this, Nix has some support for being built out of tree – that is, placing build artefacts in a different directory than the source code:
1. Create a directory for the build, e.g.
```bash
mkdir build
```
2. Run the configure script from that directory, e.g.
```bash
cd build
../configure < configure flags >
```
3. Run make from the source directory, but with the build directory specified, e.g.
```bash
make builddir=build < make flags >
```
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 ).
To use the LSP with your editor, you first need to [set up `clangd` ](https://clangd.llvm.org/installation#project-setup ) by running:
```console
2024-03-21 17:54:28 +02:00
make compile_commands.json
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-18 22:59:39 +03:00
## Formatting and pre-commit
You may run the formatters as a one-off using:
```console
make format
```
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_ .
To refresh the config, do the following:
- if you use `make format` : stop and start your `nix develop` shell.
- if you use the pre-commit hook: stop and start, and run `pre-commit-hooks-install` again.
2023-11-19 16:05:21 +02:00
## Add a release note
`doc/manual/rl-next` contains release notes entries for all unreleased changes.
User-visible changes should come with a release note.
### Add an entry
Here's what a complete entry looks like. The file name is not incorporated in the document.
```
2023-12-09 20:51:20 +02:00
---
2023-11-19 16:05:21 +02:00
synopsis: Basically a title
2023-12-09 20:51:20 +02:00
issues: 1234
prs: 1238
---
2023-11-19 16:05:21 +02:00
Here's one or more paragraphs that describe the change.
- It's markdown
- Add references to the manual using @docroot @
```
Significant changes should add the following header, which moves them to the top.
```
significance: significant
```
<!-- Keep an eye on https://codeberg.org/fgaz/changelog - d/issues/1 -->
See also the [format documentation ](https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#changelog ).
### Build process
Releases have a precomputed `rl-MAJOR.MINOR.md` , and no `rl-next.md` .
2023-12-11 13:26:31 +02:00
## Branches
- [`master` ](https://github.com/NixOS/nix/commits/master )
The main development branch. All changes are approved and merged here.
When developing a change, create a branch based on the latest `master` .
Maintainers try to [keep it in a release-worthy state ](#reverting ).
- [`maintenance-*.*` ](https://github.com/NixOS/nix/branches/all?query=maintenance )
These branches are the subject of backports only, and are
also [kept ](#reverting ) in a release-worthy state.
See [`maintainers/backporting.md` ](https://github.com/NixOS/nix/blob/master/maintainers/backporting.md )
- [`latest-release` ](https://github.com/NixOS/nix/tree/latest-release )
The latest patch release of the latest minor version.
See [`maintainers/release-process.md` ](https://github.com/NixOS/nix/blob/master/maintainers/release-process.md )
- [`backport-*-to-*` ](https://github.com/NixOS/nix/branches/all?query=backport )
Generally branches created by the backport action.
See [`maintainers/backporting.md` ](https://github.com/NixOS/nix/blob/master/maintainers/backporting.md )
- [_other_ ](https://github.com/NixOS/nix/branches/all )
Branches that do not conform to the above patterns should be feature branches.
## Reverting
If a change turns out to be merged by mistake, or contain a regression, it may be reverted.
A revert is not a rejection of the contribution, but merely part of an effective development process.
It makes sure that development keeps running smoothly, with minimal uncertainty, and less overhead.
If maintainers have to worry too much about avoiding reverts, they would not be able to merge as much.
By embracing reverts as a good part of the development process, everyone wins.
However, taking a step back may be frustrating, so maintainers will be extra supportive on the next try.