Flakes/en: Difference between revisions
Updating to match new version of source page |
Updating to match new version of source page |
||
| Line 1: | Line 1: | ||
<languages /> | |||
'''Nix flakes''' is an [https://nixos.org/manual/nix/stable/contributing/experimental-Features.html experimental feature] that was introduced with Nix 2.4 ([https://nixos.org/manual/nix/unstable/release-notes/rl-2.4.html see release notes]). | '''Nix flakes''' is an [https://nixos.org/manual/nix/stable/contributing/experimental-Features.html experimental feature] that was introduced with Nix 2.4 ([https://nixos.org/manual/nix/unstable/release-notes/rl-2.4.html see release notes]). | ||
| Line 6: | Line 7: | ||
* A [https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html#description flake] refers to a file-system tree whose root directory contains the Nix file specification called <code>flake.nix</code>. | * A [https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html#description flake] refers to a file-system tree whose root directory contains the Nix file specification called <code>flake.nix</code>. | ||
* The contents of <code>flake.nix</code> file follow a uniform naming schema for declaring packages and their dependencies in the Nix language. | * The contents of <code>flake.nix</code> file follow a uniform naming schema for declaring packages and their dependencies in the Nix language. | ||
* Flakes introduce a [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references URL-like syntax] for specifying remote sources. | |||
* Flakes introduce a [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references URL-like syntax] for specifying remote sources. | |||
* To simplify the long URL syntax with shorter names, [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-registry.html flakes uses a registry] of symbolic identifiers. | * To simplify the long URL syntax with shorter names, [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-registry.html flakes uses a registry] of symbolic identifiers. | ||
* Flakes also allow for locking references and versions that can then be queried and updated programmatically. | * Flakes also allow for locking references and versions that can then be queried and updated programmatically. | ||
* An [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html experimental command-line interface] accepts flake references for expressions that build, run, and deploy packages. | * An [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html experimental command-line interface] accepts flake references for expressions that build, run, and deploy packages. | ||
| Line 54: | Line 60: | ||
====Git WARNING==== | ====Git WARNING==== | ||
For flakes in git repos, only files in the working tree will be copied to the store. | For flakes in git repos, only files in the working tree will be copied to the store. | ||
| Line 75: | Line 82: | ||
* <code>description</code> is a string describing the flake. | * <code>description</code> is a string describing the flake. | ||
* <code>inputs</code> is an attribute set of all the dependencies of the flake. The schema is described below. | * <code>inputs</code> is an attribute set of all the dependencies of the flake. The schema is described below. | ||
* <code>outputs</code> is a function of one argument that takes an attribute set of all the realized inputs, and outputs another attribute set whose schema is described below. | * <code>outputs</code> is a function of one argument that takes an attribute set of all the realized inputs, and outputs another attribute set whose schema is described below. | ||
* <code>nixConfig</code> is an attribute set of values which reflect the [https://nixos.org/manual/nix/stable/command-ref/conf-file.html values given to nix.conf]. This can extend the normal behavior of a user's nix experience by adding flake-specific configuration, such as a binary cache. | * <code>nixConfig</code> is an attribute set of values which reflect the [https://nixos.org/manual/nix/stable/command-ref/conf-file.html values given to nix.conf]. This can extend the normal behavior of a user's nix experience by adding flake-specific configuration, such as a binary cache. | ||
| Line 82: | Line 92: | ||
[https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-inputs The nix flake inputs manual]. | [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-inputs The nix flake inputs manual]. | ||
[https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references The nix flake references manual]. | [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references The nix flake references manual]. | ||
The inputs attribute defines the dependencies of the flake. For example, nixpkgs has to be defined as a dependency for a system flake in order for the system to build properly. | The inputs attribute defines the dependencies of the flake. For example, nixpkgs has to be defined as a dependency for a system flake in order for the system to build properly. | ||
Nixpkgs can be defined using the following code: | Nixpkgs can be defined using the following code: | ||
| Line 100: | Line 111: | ||
<code>inputs.hyprland.inputs.nixpkgs.follows = "nixpkgs";</code> | <code>inputs.hyprland.inputs.nixpkgs.follows = "nixpkgs";</code> | ||
Using curly brackets({}), we can shorten all of this and put it in a table. The code will look something like this:<syntaxhighlight lang="nix"> | Using curly brackets({}), we can shorten all of this and put it in a table. The code will look something like this: | ||
<syntaxhighlight lang="nix"> | |||
inputs = { | inputs = { | ||
nixpkgs.url = "github:NixOS/nixpkgs/<branch name>"; | nixpkgs.url = "github:NixOS/nixpkgs/<branch name>"; | ||
| Line 111: | Line 124: | ||
=== Output schema === | === Output schema === | ||
This is described in the nix package manager [https://github.com/NixOS/nix/blob/master/src/nix/flake-check.md src/nix/flake-check.md]. | This is described in the nix package manager [https://github.com/NixOS/nix/blob/master/src/nix/flake-check.md src/nix/flake-check.md]. | ||
| Line 118: | Line 132: | ||
* <code><system></code> is something like "x86_64-linux", "aarch64-linux", "i686-linux", "x86_64-darwin" | * <code><system></code> is something like "x86_64-linux", "aarch64-linux", "i686-linux", "x86_64-darwin" | ||
* <code><name></code> is an attribute name like "hello". | * <code><name></code> is an attribute name like "hello". | ||
* <code><flake></code> is a flake name like "nixpkgs". | * <code><flake></code> is a flake name like "nixpkgs". | ||
* <code><store-path></code> is a <code>/nix/store..</code> path | * <code><store-path></code> is a <code>/nix/store..</code> path | ||
| Line 173: | Line 190: | ||
==== nix run ==== | ==== nix run ==== | ||
When output <code>apps.<system>.myapp</code> is not defined, <code>nix run myapp</code> runs <code><packages or legacyPackages.<system>.myapp>/bin/<myapp.meta.mainProgram or myapp.pname or myapp.name (the non-version part)></code> | When output <code>apps.<system>.myapp</code> is not defined, <code>nix run myapp</code> runs <code><packages or legacyPackages.<system>.myapp>/bin/<myapp.meta.mainProgram or myapp.pname or myapp.name (the non-version part)></code> | ||
| Line 226: | Line 244: | ||
* fetchurl and fetchtar [https://github.com/NixOS/nix/blob/36c4d6f59247826dde32ad2e6b5a9471a9a1c911/src/libexpr/primops/fetchTree.cc#L201 require] a sha256 argument to be considered pure. | * fetchurl and fetchtar [https://github.com/NixOS/nix/blob/36c4d6f59247826dde32ad2e6b5a9471a9a1c911/src/libexpr/primops/fetchTree.cc#L201 require] a sha256 argument to be considered pure. | ||
* builtins.currentSystem is non-hermetic and impure. This can usually be avoided by passing the system (i.e., x86_64-linux) explicitly to derivations requiring it. | * builtins.currentSystem is non-hermetic and impure. This can usually be avoided by passing the system (i.e., x86_64-linux) explicitly to derivations requiring it. | ||
* Imports from channels like <code><nixpkgs></code> can be made pure by instead importing from the <code>output</code> function in <code>flake.nix</code>, where the arguments provide the store path to the flake's inputs: | * Imports from channels like <code><nixpkgs></code> can be made pure by instead importing from the <code>output</code> function in <code>flake.nix</code>, where the arguments provide the store path to the flake's inputs: | ||
| Line 266: | Line 286: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
If you want to pass on the flake inputs to external configuration files, you can use the <code>specialArgs</code> attribute: | If you want to pass on the flake inputs to external configuration files, you can use the <code>specialArgs</code> attribute: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ | { | ||
| Line 280: | Line 302: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Then, you can access the flake inputs from the file <code>configuration.nix</code> like this: | Then, you can access the flake inputs from the file <code>configuration.nix</code> like this: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ config, lib, inputs, ... }: { | { config, lib, inputs, ... }: { | ||
| Line 288: | Line 312: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{Ic|nixos-rebuild}} also allows to specify different flake using the <code>--flake</code> flag (# is optional): | {{Ic|nixos-rebuild}} also allows to specify different flake using the <code>--flake</code> flag (# is optional): | ||
| Line 302: | Line 327: | ||
To switch a remote host you can use: | To switch a remote host you can use: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
$ nixos-rebuild --flake .#mymachine \ | $ nixos-rebuild --flake .#mymachine \ | ||
| Line 369: | Line 395: | ||
{ nixpkgs, ... }: | { nixpkgs, ... }: | ||
{ | { | ||
/* | /* | ||
This example assumes your system is x86_64-linux | This example assumes your system is x86_64-linux | ||
change as neccesary | change as neccesary | ||
| Line 428: | Line 454: | ||
A NixOS config flake could be as follows: | A NixOS config flake could be as follows: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ | { | ||
description = "NixOS configuration with two or more channels"; | description = "NixOS configuration with two or more channels"; | ||
inputs = { | |||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; | nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; | ||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; | nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; | ||
| Line 471: | Line 498: | ||
# ... | # ... | ||
} | } | ||
</syntaxhighlight>If the variable <code>nixpkgs</code> points to the flake, you can also define <code>pkgs</code> with overlays with: | </syntaxhighlight> | ||
If the variable <code>nixpkgs</code> points to the flake, you can also define <code>pkgs</code> with overlays with: | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
| Line 490: | Line 519: | ||
"myHost" | "myHost" | ||
</syntaxhighlight> | |||
However, this won't be instant upon evaluation if any file changes have been done since your last configuration rebuild. Instead, if one puts: | |||
<syntaxHighlight lang=nix> | |||
nix.nixPath = let path = toString ./.; in [ "repl=${path}/repl.nix" "nixpkgs=${inputs.nixpkgs}" ]; | nix.nixPath = let path = toString ./.; in [ "repl=${path}/repl.nix" "nixpkgs=${inputs.nixpkgs}" ]; | ||
</syntaxHighlight> | </syntaxHighlight> | ||
| Line 521: | Line 551: | ||
An alternative approach to the above shell alias is omitting <code>repl</code> from <code>nix.nixPath</code> and creating a shell script: | An alternative approach to the above shell alias is omitting <code>repl</code> from <code>nix.nixPath</code> and creating a shell script: | ||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||
nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; | nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; | ||
| Line 539: | Line 570: | ||
== Development tricks == | == Development tricks == | ||
=== Build a package added in a PR === | === Build a package added in a PR === | ||
<syntaxHighlight> | <syntaxHighlight> | ||
nix build github:nixos/nixpkgs?ref=pull/<PR_NUMBER>/head#<PACKAGE> | nix build github:nixos/nixpkgs?ref=pull/<PR_NUMBER>/head#<PACKAGE> | ||
</syntaxHighlight> | </syntaxHighlight> | ||
this allows building a package that has not yet been added to nixpkgs. | this allows building a package that has not yet been added to nixpkgs. | ||
note that this will download a full source tarball of nixpkgs. if you already have a local clone, using that may be faster due to delta compression: | note that this will download a full source tarball of nixpkgs. if you already have a local clone, using that may be faster due to delta compression: | ||
<syntaxHighlight> | <syntaxHighlight> | ||
git fetch upstream pull/<PR_NUMBER>/head && git checkout FETCH_HEAD && nix build .#PACKAGE | git fetch upstream pull/<PR_NUMBER>/head && git checkout FETCH_HEAD && nix build .#PACKAGE | ||
</syntaxHighlight> | </syntaxHighlight> | ||
this allows building a package that has not yet been added to nixpkgs. | this allows building a package that has not yet been added to nixpkgs. | ||
=== How to add a file locally in git but not include it in commits === | === How to add a file locally in git but not include it in commits === | ||
| Line 560: | Line 597: | ||
=== Rapid iteration of a direct dependency === | === Rapid iteration of a direct dependency === | ||
One common pain point with using Nix as a development environment is the need to completely rebuild dependencies and re-enter the dev shell every time they are updated. The <code>nix develop --redirect <flake> <directory></code> command allows you to provide a mutable dependency to your shell as if it were built by Nix. | One common pain point with using Nix as a development environment is the need to completely rebuild dependencies and re-enter the dev shell every time they are updated. The <code>nix develop --redirect <flake> <directory></code> command allows you to provide a mutable dependency to your shell as if it were built by Nix. | ||
| Line 571: | Line 609: | ||
installPhase # install it like nix does | installPhase # install it like nix does | ||
</syntaxHighlight> | </syntaxHighlight> | ||
Now that you've built the dependency, <code>consumexe</code> can take it as an input. '''In another terminal''': | Now that you've built the dependency, <code>consumexe</code> can take it as an input. '''In another terminal''': | ||
<syntaxHighlight lang=bash> | <syntaxHighlight lang=bash> | ||
cd ~/consumexe-src-checkout/ | cd ~/consumexe-src-checkout/ | ||
| Line 578: | Line 618: | ||
# Output should show ~/libdep-src-checkout/ so you know it worked | # Output should show ~/libdep-src-checkout/ so you know it worked | ||
</syntaxHighlight> | </syntaxHighlight> | ||
If Nix warns you that your redirected flake isn't actually used as an input to the evaluated flake, try using the <code>--inputs-from .</code> flag. If all worked well you should be able to <code>buildPhase && installPhase</code> when the dependency changes and rebuild your consumer with the new version ''without'' exiting the development shell. | If Nix warns you that your redirected flake isn't actually used as an input to the evaluated flake, try using the <code>--inputs-from .</code> flag. If all worked well you should be able to <code>buildPhase && installPhase</code> when the dependency changes and rebuild your consumer with the new version ''without'' exiting the development shell. | ||
| Line 583: | Line 624: | ||
* [https://nix.dev/concepts/flakes Flakes] - nix.dev | * [https://nix.dev/concepts/flakes Flakes] - nix.dev | ||
* [https://github.com/NixOS/rfcs/pull/49 RFC 49] (2019) - Original flakes specification | * [https://github.com/NixOS/rfcs/pull/49 RFC 49] (2019) - Original flakes specification | ||
* [https://jade.fyi/blog/flakes-arent-real/ Flakes aren't real and can't hurt you] (Jade Lovelace, 2024) | * [https://jade.fyi/blog/flakes-arent-real/ Flakes aren't real and can't hurt you] (Jade Lovelace, 2024) | ||
* [https://github.com/ryan4yin/nixos-and-flakes-book NixOS & Flakes Book](Ryan4yin, 2023) - 🛠️ ❤️ An unofficial NixOS & Flakes book for beginners. | * [https://github.com/ryan4yin/nixos-and-flakes-book NixOS & Flakes Book](Ryan4yin, 2023) - 🛠️ ❤️ An unofficial NixOS & Flakes book for beginners. | ||
* [https://xeiaso.net/blog/nix-flakes-1-2022-02-21 Nix Flakes: an Introduction] (Xe Iaso, 2022) | * [https://xeiaso.net/blog/nix-flakes-1-2022-02-21 Nix Flakes: an Introduction] (Xe Iaso, 2022) | ||
* [https://serokell.io/blog/practical-nix-flakes Practical Nix Flakes] (Alexander Bantyev, 2021) - Intro article on working with Nix and Flakes | * [https://serokell.io/blog/practical-nix-flakes Practical Nix Flakes] (Alexander Bantyev, 2021) - Intro article on working with Nix and Flakes | ||
* [https://www.tweag.io/blog/2020-05-25-flakes/ Nix Flakes, Part 1: An introduction and tutorial] (Eelco Dolstra, 2020) | * [https://www.tweag.io/blog/2020-05-25-flakes/ Nix Flakes, Part 1: An introduction and tutorial] (Eelco Dolstra, 2020) | ||
* [https://www.tweag.io/blog/2020-06-25-eval-cache/ Nix Flakes, Part 2: Evaluation caching] (Eelco Dolstra, 2020) | * [https://www.tweag.io/blog/2020-06-25-eval-cache/ Nix Flakes, Part 2: Evaluation caching] (Eelco Dolstra, 2020) | ||
* [https://www.tweag.io/blog/2020-07-31-nixos-flakes/ Nix Flakes, Part 3: Managing NixOS systems] (Eelco Dolstra, 2020) | * [https://www.tweag.io/blog/2020-07-31-nixos-flakes/ Nix Flakes, Part 3: Managing NixOS systems] (Eelco Dolstra, 2020) | ||
* [https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html Nix flake command reference manual] - Many additional details about flakes, and their parts. | * [https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html Nix flake command reference manual] - Many additional details about flakes, and their parts. | ||
* [https://www.youtube.com/watch?v=QXUlhnhuRX4&list=PLgknCdxP89RcGPTjngfNR9WmBgvD_xW0l Nix flakes 101: Introduction to nix flakes] (Jörg Thalheim, 2020) | * [https://www.youtube.com/watch?v=QXUlhnhuRX4&list=PLgknCdxP89RcGPTjngfNR9WmBgvD_xW0l Nix flakes 101: Introduction to nix flakes] (Jörg Thalheim, 2020) | ||
* [https://github.com/NixOS/nix/blob/master/src/nix/flake.md spec describing flake inputs in more detail] | * [https://github.com/NixOS/nix/blob/master/src/nix/flake.md spec describing flake inputs in more detail] | ||
* [https://github.com/numtide/flake-utils flake-utils: Library to avoid some boiler-code when writing flakes] | * [https://github.com/numtide/flake-utils flake-utils: Library to avoid some boiler-code when writing flakes] | ||
* [https://zimbatm.com/NixFlakes/#direnv-integration zimbat's direnv article] | * [https://zimbatm.com/NixFlakes/#direnv-integration zimbat's direnv article] | ||
* [https://github.com/nix-community/todomvc-nix building Rust and Haskell flakes] | * [https://github.com/nix-community/todomvc-nix building Rust and Haskell flakes] | ||
[[Category:Software]] | [[Category:Software]] | ||
[[Category:Nix]] | [[Category:Nix]] | ||
[[Category:Flakes]] | [[Category:Flakes]] | ||