Skip to content

21.02 Nix

my code is possible if people want it 😃 the real value of NixOS is hardware and OS config can be turned into libraries! (HN)

The nix is a package management system that enforces isolation and can work as a secondary package manager for any Linux without any risk.

It enforces everything is text, allowing easy switching of configurations with zero-efforts and zero-misconfigurations, formally defined as reproducibility.

With nix its impossible to have partially installed applications (closure). It makes development environment too easy, cross-compilation is as easy as choosing an attribute to build.

Basic terminology

The term 'nix' can refer to multiple things and documentation around is very chaotic, that's why basic terminology is essential:

This article by Julia Evans and all the links it leads to, are great starting point for anybody new to nix.

Important projects / features

1. Home Manager

nix-community/home-manager is a part of nix-community github org that provides various "Nix Modules" for installing & configuring user-level programs.

Nix Module System is really interesting, NixCon 2023 - Why choose Nix for configuration? dives deep into it.

2. Comma

nix-community/comma allows running binaries transiently/ephemerally, What if I don't have neofetch?

bash
$ , neofetch

And that's it, I don't need to search the package that provides that binary, nor I have to install it, just run it!

3. DevShells

The numtide/devshell helps one to quickly bootstrap a project's build environment just by running nix develop.

The devshell docs are really good, as well as this article.

Their statement is

It should not take more than 10 minutes from the time you clone a repo and can start contributing.

It prepares the shell with all the build dependencies, the environmental variables, the services (e.g. development database), and provides a handy menu for common commands for the newcomers to the project.

4. SnowfallLib

This snowfallorg/lib is a support library for giving a file structure to system/home configuration based flakes (NixOS, home-manager, and nix-darwin).

I personally prefer it to elliminate boilerplate in flake.nix at root of project.

  • Nix/NixOS Discord (unofficial) - A community of really fast and helpful people.
  • NixOS/patchelf - A binary patcher for modifying lookup paths of existing ELF binary.
  • Tvix (HN) - A new nix implementation in rust, tvixbolt online interpreter is good for AST, Bytecode, Runtime Trace, and Output analysis of nix code.
  • not-os and ZilchOS and NixNG.
  • NUR - Nix User Repository, equivalent of Arch's AUR, any PR will be immediately merged without any checks.
  • Guix - similar goals to nix, except enforces only free softwares. It is toxic to people mentioning nix in thier irc channels.
  • GoboLinux (HN) - is an alternative Linux distribution which redefines the entire filesystem hierarchy.
  • Distri - A linux distro to search fast package management.

Notes

1. Config Dump

bash
nix show-config  # Shows dump of $XDG_CONFIG_HOME/nix/nix.conf

2. [HM] Cleanup older generations

bash
pushd ~/.local/state/nix/profiles && ls | awk "!/$(readlink home-manager)/ && /home-manager-/" | xargs rm && popd
nix-collect-garbage --delete-old
nix store gc --debug

Sometimes if a file is opened in any process it refuses to clean it up, rebooting and cleaning again may help.

3. Cross Compilation

Cross compilation is as easy as to expose package in a flake output or apply an overlay on nixpkgs and then choose flake path to build.

bash
# Custom Flake
nix build '.#packages.x86_64-linux.pkgsCross.mingwW64.my_pkg'

# Pkg from nixpkgs, or your package overlayed on nixpkgs
nix build 'nixpkgs#pkgsCross.mingwW64.my_pkg'

[TODO] Expand on this into an article as this is not very well shown in any article AFAIK.

4. Ephemeral shell-scoped install

Examples:

bash
nix-shell -p hello
nix shell nixpkgs#hello

nix-shell -p 'python3.withPackages(pp: [ packages.numpy ])' --pure
nix develop --impure --expr 'with import <nixpkgs> {}; mkShell { buildInputs = [ python3.withPackages(pp: [ packages.numpy ]) ]; }'

Misc info:

  1. nix-shell -p and nix shell are alike.
  2. nix-shell and nix develop are alike, with no argument former works with shell.nix latter works with outputs.devShells.default definition in flake.nix.
  3. The nix-shell invokes stdenv, whereas nix shell doesn't.

5. Pining flake inputs

Its good to have consistent system with single nixpkgs pin across all the commands, and to not garbage-collect any of the flake inputs, atleast until the profile is activated.

nix
{ inputs, ... }: {
  nix.registry.nixpkgs.flake = inputs.nixpkgs;                  # pin for new command syntax
  home.sessionVariables.NIX_PATH = "nixpkgs=${inputs.nixpkgs}"; # pin for old-command syntax

  # prevent 'all' the flake inputs from being garbage-collected until this profile is activated
  xdg.configFile."nix-flake-inputs".text = lib.concatStringsSep "\n" (map (ip: ip.outPath) (lib.attrValues inputs));
}

Troubleshooting

Cleaning up

Refer nix#6141, if even after rebooting and garbage collection paths aren't removed.

The steps for force removal, in case a path is blocked by a (unlikely to be happen) bug.

bash
nix-store --query --referrers $path | xargs nix-store --delete
nix-store --query --referrers-closure $path | xargs nix-store --delete
sudo nix store delete $path --ignore-liveness