this organization can be confusing, so how about a little story
...because to understand the purpose of this organization, one must understand the nature of nix flakes
Flakes...
This means that the flake has no dependency or access to the outer environment for the sake of purity. This ensures reproducibility without requiring a container or virtual environment. And, on its own, flakes do not have any facilities to configure, modify, or override the flake without updating the flake.lock or overriding inputs.
This comes as a double edge sword for those that external input to options or configurations inside the flake.
Imagine you had a package provided by your flake which could be ran by:
$ nix run github:username/hello-world
hello, world!
But you want to have some variants:
- support for multiple system architectures (ie -
x86_64-linux
,aarch64-linux
, etc) - debug and release mode
- support for multiple C libs (ie - gnu, musl, etc)
Then you'd have to specify a new output for each combination of features and have to run it like:
$ nix run github:username/hello-world#packages.{x86_64-linux,aarch64-linux}.{release,debug}.{gnu,musl}
hello, world!
This becomes at least 2 to the power of N outputs for just N features and higher than base 2 for features with more possibilities.
We prepare our flake to have inputs for the values that we want:
{
inputs = {
# True flake inputs:
nixpkgs.url = "github:NixOS/nixpkgs";
# Options:
debug-mode.url = "github:nix-values/false"; # release-mode by default
system.url = "github:nix-values/x86_64-linux"; # "x86_64-linux" by default
musl-libc.url = "github:nix-values/false"; # gnu lib c by default
};
outputs = { nixpkgs, debug-mode, musl-libc, system, ... }: let
pkgs = import nixpkgs { inherit system; };
in {
packages."${system}".hello = pkgs.callPackage ./hello {
# pass the values into the package derivation
inherit debug-mode musl-libc;
};
};
}
And then we can just run it with the exact values we want to enable debug mode:
$ nix run github:username/hello-world --override-input debug-mode github:nix-values/true
hello, world!
As you can see, with a pretty ugly hack, you can provide an override to values in order to configure a pure flake without the complex traversal and creation of several flake outputs.