← home

Nix cheatsheet

This is collection of common problems/issues I faced working with Nix packages or on NixOS. I find it quite difficult to find necessary information in Nix reference as it missing or hidden too deep in the text.

I just want to build a derivation

From time to time I google for an expression to put into default.nix to build a derivation defined in derivation.nix. Here is oneliner:

nix-build -E 'with import <nixpkgs> { }; callPackage ./derivation.nix { }'

You can also put this expression into default.nix and run with just nix-build. The -K will create nix-build-derivation-ver directory in /tmp so you can debug it.

shell.nix example

I'm always looking for shell.nix example which I create almost in every project:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  # runtime deps
  buildInputs = [
    hello
  ];
}

Why src = ./.; fails but src = fetchFromGithub {...} not?

This is because your local copy is probably dirty; nix does cp which copies all stuff to /nix/store. In some cases running make clean will save you. But I would suggest using git to fetch your local branch:

src = fetchgit {
    url = ./.;
    hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
}

Note that you will need to commit all your changes.

error: cycle detected in build of '/nix/store/xxx.drv' in the references of output 'bin' from output 'out'

Don't know what this error is about but I solved it by removing "bin" from the outputs:

{ pkgs ? import <nixpkgs> {} }:
with pkgs; stdenv.mkDerivation rec {

  ...

  #          "bin" was here
  #          v
  outputs = [ "dev" "out" "doc" ];

  ...

}

Flake input is not the latest commit

From time to time results of the nix build .# didn't have the latest inputs. This probably happens because use specified your input as a git branch and did some changes to the branch. But forgot to tell nix that the branch was changed (with nix flake update):

...
inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    #                                        vvvvvvvvvvvvvvvvvv
    xfsprogs.url = "github:alberand/xfsprogs?branch=fsverity-v2";
    xfsprogs.flake = false;
}
...

The solution to this is always use rev=<commit hash> to pinpoint flake's inputs.

Force rebuild (download sources)

When running something like nix run github:alberand/nix-kernel-vm nix will download the source code. Unfortunately, if repository is updated right after that, nix will not re-download new version if command is run again. I haven't found a way to force nix do it except asking garbage collector to clean the whole /nix/store:

nix-store -gc

Note that this command remove only unused packages (ones which are not installed into the system).

Disable remote builders/distributed build

I have two machines, one is more powerful which is used as Binary cache and remote builder. However, when debugging broken build there's need to build nix derivation locally. To disable distributed build without changing system configuration one can use:

nix-build --builders "" /nix/store/ls9jdiy2ihizrglvba080565rrk1ri3b-xfstests-git.drv

List of derivation phases

The $ marks empty by default phases. Depending on the package other phases could also be empty.

Get a hash of a source

nurl can also use fetcher set with an argument or overwrite any fetcher arguments (pretty handy to set allRefs when commit is not on master)

nix-shell -p nurl --run \
    "nurl https://github.com/alberand/linux 007f6ea233d9d18e7d44dbf643bf900967a55ef9 2>/dev/null"

with allRefs:

nix-shell -p nurl --run \
    "nurl --fetcher builtins.fetchGit --arg allRefs true https://github.com/alberand/linux v6.15 2>/dev/null"


Hey👋 I'm Andrey. In this blog I post my personal short tutorials or interesting technical notes. Over the day I work as a Software Engineer developing and testing Linux filesystems. I use free software mainly #NixOS #Neovim #Kitty. Btw I use NixOS. Subscribe for updates on:

telegram • @alberand@mas.to • twitter