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 ready to copy to (or from) nixpkgs
.
nixpkgs
structure
Before we start with an example let’s take 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 = { ... };
structure. 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
}:
.mkDerivation rec {
stdenvpname = "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!