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