Skip to content

Nix

  • Building Nix packages nix-build involves two steps:
    • evaluation/instantiation (nix-instantiate): goes from nix expression (.nix) to a derivation (.drv)
    • realization (nix-store --realize): goes from a derivation to a store path
sequenceDiagram
  actor U as User / CLI
  participant E as Evaluation (Nix)
  participant S as Nix Store
  participant R as Realisation (Build)

  U->>E: nix build (expression.nix)
  Note over E: Evaluate Nix code
  E->>S: nix-instantiate
  Note right of S: Create .drv file
  S-->>U: Store path (.drv)
  U->>R: nix-store --realise
  Note over R: Run builder in sandbox
  R->>S: Store result
  S-->>U: Resulting output path
flowchart LR
  A[Substitutors] --> B{remainingOutput?}
  B --No--> C[BuildInputs]
  C --> D[Build]
  D --> E[RegisterOutputPaths]
  B --Yes--> Stop
  • Nix package is unique across: source, dependencies, build steps, architecture, platform
    • Nix can determine the derivation and the final output path ahead of time (needed for caching)
  • derivation is platform-specific way to build a package
    • output of derivation depends only on the inputs and the build script, and each package has a unique hash
  • NixOS boot process:
  • Bootloader loads kernel and initrd
  • initrd mounts partitions
  • initrd runs /run/current-system/activate
  • if first time, it populates POSIX directories (/bin, /etc, /run, /usr, /var)
  • Nix binary cache
    • NAR file is a serialized file format for packages used by the Nix package manager (v/s tar files) because they don't contain any non-deterministic information
    • .narinfo files contain metadata info about each package, such as dependencies
  • Use of mkIf within module system requires all options to be valid

Useful commands

sudo -i nix-store --gc --print-roots | egrep -v '^(/nix/var|/run/current-system|/run/booted-system|/proc|{memory|{censored)'
nix-store --query --roots /nix/store/...
nix-store -q --references $(which hello)
nix-store -q --referrers $(which hello)
nix-store -qR $(which hello)
nix-store -q --tree $(which hello)

Flakes

let pkgs = import nixpkgs { system = "x86_64-linux"; config.allowUnfree = true; };
  • Make nixpkgs refer to the same one in your flake enabled nixos
nix.registry.nixpkgs.flake = inputs.nixpkgs;

Misc

  • IFD uses a nix expression to generate another nix expression as the output of its realization. The generated nix expression is then used to generate desired output.
  • FOD(Fixed-Output Derivation) are derivation for which has of the output is already known, and therefore network access is allowed during derivation. This is typically used for bundling pre-fetched dependencies, when building an application that typically fetches dependencies during the build process, such as building a Scala mill project