Hacking
This section provides some notes on how to hack on Nix. To get the latest version of Nix from GitHub:
$ git clone https://github.com/NixOS/nix.git
$ cd nix
To build Nix for the current operating system/architecture use
$ nix-build
or if you have a flake-enabled nix:
$ nix build
This will build defaultPackage
attribute defined in the flake.nix
file. To build for other platforms add one of the following suffixes to
it: aarch64-linux, i686-linux, x86_64-darwin, x86_64-linux. i.e.
$ nix-build -A defaultPackage.x86_64-linux
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
$ nix-shell
or if you have a flake-enabled nix:
$ nix develop
To get a shell with a different compilation environment (e.g. stdenv, gccStdenv, clangStdenv, clang11Stdenv, ccacheStdenv):
$ nix-shell -A devShells.x86_64-linux.clang11StdenvPackages
or if you have a flake-enabled nix:
$ nix develop .#clang11StdenvPackages
Note: you can use ccacheStdenv
to drastically improve rebuild
time. By default, ccache keeps artifacts in ~/.cache/ccache/
.
To build Nix itself in this shell:
[nix-shell]$ ./bootstrap.sh
[nix-shell]$ ./configure $configureFlags --prefix=$(pwd)/outputs/out
[nix-shell]$ make -j $NIX_BUILD_CORES
To install it in $(pwd)/outputs
and test it:
[nix-shell]$ make install
[nix-shell]$ make installcheck -j $NIX_BUILD_CORES
[nix-shell]$ ./outputs/out/bin/nix --version
nix (Nix) 3.0
If you have a flakes-enabled Nix you can replace:
$ nix-shell
by:
$ nix develop
Running tests
Unit-tests
The unit-tests for each Nix library (libexpr
, libstore
, etc..) are defined
under src/{library_name}/tests
using the
googletest framework.
You can run the whole testsuite with make check
, or the tests for a specific component with make libfoo-tests_RUN
. Finer-grained filtering is also possible using the --gtest_filter command-line option.
Functional tests
The functional tests reside under the tests
directory and are listed in tests/local.mk
.
Each test is a bash script.
The whole test suite can be run with:
$ make install && make installcheck
ran test tests/foo.sh... [PASS]
ran test tests/bar.sh... [PASS]
...
Individual tests can be run with make
:
$ make tests/${testName}.sh.test
ran test tests/${testName}.sh... [PASS]
or without make
:
$ ./mk/run-test.sh tests/${testName}.sh
ran test tests/${testName}.sh... [PASS]
To see the complete output, one can also run:
$ ./mk/debug-test.sh tests/${testName}.sh
+ foo
output from foo
+ bar
output from bar
...
The test script will then be traced with set -x
and the output displayed as it happens, regardless of whether the test succeeds or fails.
Debugging failing functional tests
When a functional test fails, it usually does so somewhere in the middle of the script.
To figure out what's wrong, it is convenient to run the test regularly up to the failing nix
command, and then run that command with a debugger like GDB.
For example, if the script looks like:
foo
nix blah blub
bar
edit it like so:
foo
-nix blah blub
+gdb --args nix blah blub
bar
Then, running the test with ./mk/debug-test.sh
will drop you into GDB once the script reaches that point:
$ ./mk/debug-test.sh tests/${testName}.sh
...
+ gdb blash blub
GNU gdb (GDB) 12.1
...
(gdb)
One can debug the Nix invocation in all the usual ways.
For example, enter run
to start the Nix invocation.
Integration tests
The integration tests are defined in the Nix flake under the hydraJobs.tests
attribute.
These tests include everything that needs to interact with external services or run Nix in a non-trivial distributed setup.
Because these tests are expensive and require more than what the standard github-actions setup provides, they only run on the master branch (on https://hydra.nixos.org/jobset/nix/master).
You can run them manually with nix build .#hydraJobs.tests.{testName}
or nix-build -A hydraJobs.tests.{testName}
Installer tests
After a one-time setup, the Nix repository's GitHub Actions continuous integration (CI) workflow can test the installer each time you push to a branch.
Creating a Cachix cache for your installer tests and adding its authorization token to GitHub enables two installer-specific jobs in the CI workflow:
-
The
installer
job generates installers for the platforms below and uploads them to your Cachix cache:x86_64-linux
armv6l-linux
armv7l-linux
x86_64-darwin
-
The
installer_test
job (which runs onubuntu-latest
andmacos-latest
) will try to install Nix with the cached installer and run a trivial Nix command.
One-time setup
- Have a GitHub account with a fork of the Nix repository.
- At cachix.org:
- Create or log in to an account.
- Create a Cachix cache using the format
<github-username>-nix-install-tests
. - Navigate to the new cache > Settings > Auth Tokens.
- Generate a new Cachix auth token and copy the generated value.
- At github.com:
- Navigate to your Nix fork > Settings > Secrets > Actions > New repository secret.
- Name the secret
CACHIX_AUTH_TOKEN
. - Paste the copied value of the Cachix cache auth token.
Using the CI-generated installer for manual testing
After the CI run completes, you can check the output to extract the installer URL:
-
Click into the detailed view of the CI run.
-
Click into any
installer_test
run (the URL you're here to extract will be the same in all of them). -
Click into the
Run cachix/install-nix-action@v...
step and click the detail triangle next to the first log line (it will also beRun cachix/install-nix-action@v...
) -
Copy the value of
install_url
-
To generate an install command, plug this
install_url
and your GitHub username into this template:sh <(curl -L <install_url>) --tarball-url-prefix https://<github-username>-nix-install-tests.cachix.org/serve
Checking links in the manual
The build checks for broken internal links.
This happens late in the process, so nix build
is not suitable for iterating.
To build the manual incrementally, run:
make html -j $NIX_BUILD_CORES
In order to reflect changes to the Makefile, clear all generated files before re-building:
rm $(git ls-files doc/manual/ -o | grep -F '.md') && rmdir doc/manual/src/command-ref/new-cli && make html -j $NIX_BUILD_CORES
mdbook-linkcheck
does not implement checking URI fragments yet.
@docroot@
variable
@docroot@
provides a base path for links that occur in reusable snippets or other documentation that doesn't have a base path of its own.
If a broken link occurs in a snippet that was inserted into multiple generated files in different directories, use @docroot@
to reference the doc/manual/src
directory.
If the @docroot@
literal appears in an error message from the mdbook-linkcheck
tool, the @docroot@
replacement needs to be applied to the generated source file that mentions it.
See existing @docroot@
logic in the Makefile.
Regular markdown files used for the manual have a base path of their own and they can use relative paths instead of @docroot@
.