nixpkgs overlay nano howto
nixpkgs
is a huge repository of various packages. But what if you want
to package a tiny package and don’t plan to share it with anyone. Is it
hard? How would you go about it?
There are many ways to do it: maintain a nixpkgs
fork, use
packageOverrides
, overlays
, flakes
and many others methods.
I’ll focus here only on overlays
method as it feels to me like the
simplest way to write packages readily copyable to (or from) nixpkgs
.
nixpkgs stucture
before we start with an example let’s have a look at nixpkgs
“schema”. nixpkgs
provides a pkgs
map (“attribute set”) from package
name to package definition (it’s nested in a few places):
{
pkgs = callPackage = pkgPath: ...somehow-load-the-package;
# unnested examples:
glibc = callPackage ../development/libraries/glibc { ... };
re2c = callPackage ../development/tools/parsing/re2c { };
# ...
# nested examples:
python39Packages = {
# the name is slightly changed for clarity
callPythonPackage = pkgPath: ...somehow-load-python-package;
black = callPackage ../development/python-modules/black { };
blessed = callPackage ../development/python-modules/blessed { };
# ...
};
};
Our goal here is to inject something very simple into top-level
pkgs = { ... };
sturcture. We’ll ignore nested attributes.
overlays
allow us to override existing attributes in pkgs
or
introduce the existing ones. Until you get familiar with the way
attributes interact with one another I suggest adding only new
attributes.
an example
Our running example will be ski package.
It’s an autotools
-based package with very conventional dependencies.
Let’s package it!
I’ll do 3 things below:
- create
/tmp/overlay/ski/default.nix
expression ready to be included intonixpkgs
repository - create
/tmp/overlay/local-packages.nix
expression ready to be used in/etc/nixos/configuration.nix
and/or in~/.config/nixpkgs/overlays/
. - add our overlay to
/etc/nixos/configuration.nix
.
Here is a simple /tmp/overlay/ski/default.nix
expression enough to
build it:
# $ cat /tmp/overlay/ski/default.nix
{ lib , stdenv , fetchFromGitHub
, autoconf, automake, bison, flex, gperf
, libtool, pkg-config
, elfutils, libbfd, libiberty , ncurses
}:
rec {
stdenv.mkDerivation pname = "ski";
version = "unstable-2022-07-07";
src = fetchFromGitHub {
owner = "trofi";
repo = "ski";
rev = "568efd789fab1f932aa926b1db86dcb75e9c115c";
sha256 = "sha256-dwHccL89bXzsjDr8O1DmVHlBQQ6aHgNLEaHJCJqHG9w=";
};
postPatch = ''
./autogen.sh
'';
nativeBuildInputs = [ autoconf automake
];
bison flex gperf libtool pkg-config
buildInputs = [ elfutils libbfd libiberty ncurses ];
meta = with lib; {
description = "ia64 (Itanium) instruction set simulator.";
homepage = "https://github.com/trofi/ski";
license = licenses.gpl2Only;
platforms = platforms.linux;
};
}
Now we need to create an actual overlay expression. I’ll put it in a
separate /tmp/overlay/local-packages.nix
file as well:
# $ cat /tmp/overlay/local-packages.nix
final: prev: {
# we create new 'ski' attribute here!
ski = final.callPackage ./ski {};
# add more packages below:
# ...
}
Now we are ready to use the overlay in our
/etc/nixos/configuration.nix
:
{ config, pkgs, ... }:
{
# Add an overlay to augment existing 'pkgs' map.
nixpkgs.overlays = [
(import /tmp/overlay/local-packages.nix)
];
# use augmented 'pkgs':
environment.systemPackages = with pkgs; [
ski];
# ...
}
Now we can get ski
installed into our system:
$ sudo nixos-rebuild switch
$ ski -help
Options:
-help Display command-line options
-i <file> Process initialization file at startup
-rest <file> Restore simulation state from <file>
-nonet Disable networking feature
-srcroot Source Root Directory
-forceuser Force user-level simulation
-forcesystem Force system-level simulation
-strace Trace system call execution
-simroot Simulated root directory
-conslog <file> Log the console output to the specified file
-palen <n> Implemented physical address bits. Default: 63
-valen <n> Implemented virtual address bits. Default: 61
-ridlen <n> Implemented RR.rid bits. Default: 24
-keylen <n> Implemented PKR.key bits. Default: 24
-grfile <n> GR file size. Default: 128
Seems to work!
We can also get the packages pulled into user’s <nixpkgs>
expression:
$ mkdir -p ~/.config/nixpkgs/overlays/
$ ln -s /tmp/overlay/local-packages.nix ~/.config/nixpkgs/overlays/
Now we can use it as a nixpkgs
attribute:
$ nix-build '<nixpkgs>' -A ski
/nix/store/rpb5iikr6p0x49zkpw5cjwp9lg8lnl7d-ski-unstable-2022-07-07
A few relevant links:
Done!