How to create a package recipe#
Important
For the list of all available configuration options for package recipes visit the package options reference.
Before writing a recipe, please spend some time to understand the software and gather the basic information from the package’s source code repository:
Metadata
Package name, description
Latest stable version
Homepage URL
License
Main executable name
Language and build system
Look for these files in the repository root:
File |
Build system |
|---|---|
|
Autotools (C/C++) |
|
CMake (C/C++) |
|
Go |
|
Make (C/C++) |
|
Python |
|
Rust |
Dependencies — look in:
CMakeLists.txt:find_package(),pkg_check_modules()configure.ac:PKG_CHECK_MODULES,AC_CHECK_LIBpyproject.toml/setup.py:[project.dependencies],install_requiresREADME.md,INSTALL.md: listed prerequisitesCI config (
.github/workflows/,.gitlab-ci.yml): packages installed before build
Repository structure
Are build files in the repository root or a subdirectory?
Are there git submodules (
.gitmodulesfile)?Does the build download anything at build time? Nix builds run without network access - these must be patched out or disabled via build flags.
Recipe file#
Create the package recipe directory and recipe file:
mkdir recipes/pkgs/<package-name>
touch recipes/pkgs/<package-name>/recipe.nix
Add the recipe file to Git:
git add recipes/pkgs/<package-name>/recipe.nix
Important
Nix can only see recipe files tracked by Git. If the file is not added to Git, the package will not be recognized.
Metadata#
Start the package recipe with the following content:
1{
2 pkgs,
3 ...
4}:
5
6{
7 pkgs.package-name = { # lowercase with hyphens
8 version = "1.0.0"; # latest released version
9 description = "Short description of the package.";
10 homePage = "https://project-website.org";
11 mainProgram = "executable-name";
12 license = lib.licenses.gpl3Only;
13
14 # More configuration to be added here.
15 # ...
16 };
17}
Important
Ensure that the remainder of the package recipe is done within the pkgs.package-name block to avoid nasty infinite recursion errors.
Note
Use the following command to get the list of all available licenses:
nix repl nixpkgs <<<':p lib.licenses'
Source#
Add a source block pointing to the upstream release. Leave hash empty for
now:
1source = {
2 git = "github:owner/repo/v1.0.0";
3 hash = ""; # fill in after first build
4};
For tarball releases use source.url.
If the repository uses git submodules, add source.submodules = true.
Builder#
Enable exactly one builder and configure it as needed.
Condition |
Builder |
|---|---|
CMake, Autotools, or Makefile |
|
Go |
|
Python with CLI tools ( |
|
Python library (no executables) |
|
Rust |
|
Also, add dependencies using packages.build, packages.run or
packages.check options.
1build.builders.standard = {
2 enable = true;
3
4 # build-time dependencies
5 packages.build = [
6 pkgs.bison
7 pkgs.boost
8 ];
9
10 # run-time dependencies
11 packages.run = [
12 pkgs.zlib
13 ];
14}
Run the first build:
nix build .#pkgs.<package-name> --print-build-logs
Nix will fail during the first build due to a missing source hash. Update
source.hash with the value from the error output, then launch the build once
again.
Troubleshooting#
To troubleshoot build failures, enable debug mode to enter an interactive build environment:
1build.debug = true;
Then launch the interactive build and follow the on-screen instructions. Press Ctrl-C to drop into a shell and start investigating.
mkdir dev && cd dev
nix develop .#pkgs.<package-name>
Tests#
Add a test script to verify that package works correctly:
1test.script = ''
2 program --help | grep "Usage: program"
3'';
Run test:
nix build .#pkgs.<package-name>.test --print-build-logs
Examples#
Browse the example package recipes, or create your own Forge project to try them out:
nix flake init --template github:ngi-nix/forge#provider