Nix Flakesο
Nix claims the reproducibility, but actually it is usually not the case: - Nix can access arbitrary control files from different machines, for example,
~/.config/nixpkgs/config.nixNix search path such as
NIX_PATHAlso, when we use GitFetch etc. to get the 3rd party libarary, itβs difficult to absolutely make sure that the versions we get
are the same from different builds.
Flakes are a solution to these problems.
Note
A flake is simply a source tree (such as a Git repository) containing a file named flake.nix, which provides a standardized interface to Nix packages (therefore, in most cases, the flake works with Git).
What is Nix Flakeο
Flakes are self-contained units that have:
inputs: dependencies
outputs (packages, deployment instructions, Nix functions for use in other flakes).
Flakes have great reproducibility because they are only allowed to depend on their inputs and they pin the exact versions of said inputs in a lockfile.
Create your first flakeο
Here we provide an example about how to use flake to build netCDF:
Step 1: create an empty git repository
First we need to create an empty git environment:
git init netcdf-flake
wget https://downloads.unidata.ucar.edu/netcdf-c/4.9.0/netcdf-c-4.9.0.tar.gz
tar -zxvf netcdf-c-4.9.0.tar.gz
git add netcdf-c-4.9.0
Step 2: create flake.nix
The command nix flake init creates a basic flake.nix for you. For example, we should go to the project root directory, and run
nix flake init
Alternatively, we can create our own flake.nix. An example is given below:
{
description = "A flake for building netCDF";
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-20.03;
inputs.m4.url = "github:divnix/std";
outputs = { self, nixpkgs }: {
defaultPackage.x86_64-linux =
# Notice the reference to nixpkgs here.
with import nixpkgs { system = "x86_64-linux"; };
stdenv.mkDerivation {
name = "netcdf-flake";
src = self;
buildInputs = [ m4 zlib ];
configurePhase = "cd netcdf-c-4.9.0; ./configure --disable-netcdf4 --disable-hdf5 --prefix /tmp/tmp/netcdf-flake";
buildPhase = "make";
installPhase = "make install; mkdir -p $out; mv /tmp/tmp/netcdf-flake/* $out";
};
};
}
The above file can be explained as:
An good example of the flake.nix can be found https://github.com/haskell/haskell-language-server/blob/master/flake.nix
Note that any file that is not tracked by Git is invisible during Nix evaluation, therefore we need to make flake.nix visible to Git:
git add flake.nix
Step 3: build the package
There are a few methods to build the package:
build the package automatically:
We can build the package automatically by running
nix build
within the directory where we have
flake.nixbuild the package step by step (e.g., debug):
For example, we can debug the different phases of the
flake.nixfile, if we want to debug configurePhase, we can do:
nix develop eval $configurePhase