mirror of
https://codeberg.org/mhwombat/nix-book.git
synced 2025-12-27 00:34:58 +08:00
131 lines
3.8 KiB
Text
131 lines
3.8 KiB
Text
= Flake structure
|
||
|
||
The basic structure of a flake is shown below.
|
||
|
||
[source,nix,subs=quotes]
|
||
....
|
||
{
|
||
description = _package description_
|
||
inputs = _dependencies_
|
||
outputs = _what the flake produces_
|
||
nixConfig = _advanced configuration options_
|
||
}
|
||
....
|
||
|
||
The `description` part is self-explanatory; it's just a string. You
|
||
probably won't need `nixConfig` unless you're doing something fancy. I'm
|
||
going to focus on what goes into the `inputs` and `outputs` sections,
|
||
and highlight some of the things I found confusing when I began using flakes.
|
||
|
||
== Inputs
|
||
|
||
This section specifies the dependencies of a flake. It's an _attribute
|
||
set_; it maps keys to values.
|
||
|
||
To ensure that a build is reproducible, the build step runs in a _pure_
|
||
environment with no network access. Therefore, any external dependencies
|
||
must be specified in the "`inputs`" section so they can be fetched in
|
||
advance (before we enter the pure environment).
|
||
|
||
Each entry in this section maps an input name to a _flake reference_.
|
||
This commonly takes the following form.
|
||
|
||
....
|
||
NAME.url = URL-LIKE-EXPRESSION
|
||
....
|
||
|
||
As a first example of a flake reference, all (almost all?) flakes depend on "`nixpkgs`",
|
||
which is a large Git repository of programs and libraries that are
|
||
pre-packaged for Nix. We can write that as
|
||
|
||
[source,nix,subs=quotes]
|
||
....
|
||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-__version__";
|
||
....
|
||
|
||
where _version_ is replaced with the version number that you used to build
|
||
the package, e.g. `22.11`. Information about the latest nixpkgs releases
|
||
is available at https://status.nixos.org/. You can also write the entry
|
||
without the version number
|
||
|
||
[source,nix]
|
||
....
|
||
nixpkgs.url = "github:NixOS/nixpkgs/nixos";
|
||
....
|
||
|
||
or more simply,
|
||
|
||
[source,nix]
|
||
....
|
||
nixpkgs.url = "nixpkgs";
|
||
....
|
||
|
||
You might be concerned that omitting the version number would make the
|
||
build non-reproducible. If someone else builds the flake, could they end
|
||
up with a different version of nixpkgs? No! remember that the lockfile
|
||
(`flake.lock`) _uniquely_ specifies all flake inputs.
|
||
|
||
Git and Mercurial repositories are the most common type of flake
|
||
reference, as in the examples below.
|
||
|
||
A Git repository::
|
||
`git+https://github.com/NixOS/patchelf`
|
||
A specific branch of a Git repository::
|
||
`git+https://github.com/NixOS/patchelf?ref=master`
|
||
A specific revision of a Git repository::
|
||
+
|
||
`git+https://github.com/NixOS/patchelf?ref=master&rev=f34751b88bd07d7f44f5cd3200fb4122bf916c7e`
|
||
A tarball::
|
||
`https://github.com/NixOS/patchelf/archive/master.tar.gz`
|
||
|
||
You can find more examples of flake references in the
|
||
https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#examples[Nix
|
||
Reference Manual].
|
||
|
||
[NOTE]
|
||
====
|
||
Although you probably won't need to use it, there is another syntax for
|
||
flake references that you might encounter. This example
|
||
|
||
[source,nix]
|
||
....
|
||
inputs.import-cargo = {
|
||
type = "github";
|
||
owner = "edolstra";
|
||
repo = "import-cargo";
|
||
};
|
||
....
|
||
|
||
is equivalent to
|
||
|
||
[source,nix]
|
||
....
|
||
inputs.import-cargo.url = "github:edolstra/import-cargo";
|
||
....
|
||
====
|
||
|
||
Each of the `inputs` is fetched, evaluated and passed to the `outputs`
|
||
function as a set of attributes with the same name as the corresponding
|
||
input.
|
||
|
||
== Outputs
|
||
|
||
This section is a function that essentially returns the recipe for
|
||
building the flake.
|
||
|
||
We said above that `inputs` are passed to the `outputs`, so we need to
|
||
list them as parameters. This example references the `import-cargo`
|
||
dependency defined in the previous example.
|
||
|
||
[source,nix,subs=quotes]
|
||
....
|
||
outputs = { self, nixpkgs, import-cargo }: {
|
||
#_definitions for outputs_#
|
||
};
|
||
....
|
||
|
||
So what actually goes in the highlighted section?
|
||
That depends on the programming languages your software is written in,
|
||
the build system you use, and more. There are Nix functions and tools
|
||
that can simplify much of this, and new, easier-to-use ones are released
|
||
regularly. We'll look at some of these in the next section.
|