Flakes/zh: Difference between revisions
Created page with "请注意,这将下载 nixpkgs 的完整 tarball 压缩档。如果您已有本地克隆,由于增量压缩机制,使用它可能会更快:" |
Updating to match new version of source page |
||
| (48 intermediate revisions by 3 users not shown) | |||
| Line 3: | Line 3: | ||
{{Cleanup}} | {{Cleanup}} | ||
'''Nix | '''Nix flakes''' 是 [[Nix]] 2.4 版本中首次引入的一项[[Experimental Nix features|实验性功能]]{{Cite manual|nix|development/experimental-features|number=13.8|title=Experimental Features|subsection=xp-feature-flakes|subtitle=flakes}}{{Cite manual|nix|release-notes/rl-2.4|number=14.27|title=Release 2.4 (2021-11-01)}},旨在解决 Nix 生态系统许多领域的改进问题:它们为 Nix 项目提供了一个统一结构、允许固定每个依赖项的特定版本并通过锁文件共享这些依赖项,同时总体上使编写可复现的 Nix 表达式变得更加方便。 | ||
Flake 是一个直接包含 <code>flake.nix</code> 文件的目录,该文件内容遵循一种特定结构。Flakes 引入了一种类似 URL 的语法{{Cite manual|nix|command-ref/new-cli/nix3-flake|number=8.5.17|title=nix flake|subsection=url-like-syntax|subtitle=URL-like syntax}} 来指定远程资源。为了简化这种 URL 语法,Flakes 使用符号标识符注册表{{Cite manual|nix|command-ref/new-cli/nix3-registry|number=8.5.62|title=nix registry}},这允许通过类似 <code>github:NixOS/nixpkgs</code> 的语法直接指定资源。 | Flake 是一个直接包含 <code>flake.nix</code> 文件的目录,该文件内容遵循一种特定结构。Flakes 引入了一种类似 URL 的语法{{Cite manual|nix|command-ref/new-cli/nix3-flake|number=8.5.17|title=nix flake|subsection=url-like-syntax|subtitle=URL-like syntax}} 来指定远程资源。为了简化这种 URL 语法,Flakes 使用符号标识符注册表{{Cite manual|nix|command-ref/new-cli/nix3-registry|number=8.5.62|title=nix registry}},这允许通过类似 <code>github:NixOS/nixpkgs</code> 的语法直接指定资源。 | ||
| Line 9: | Line 9: | ||
Flakes 还允许锁定引用和版本,然后通过 inputs {{cite manual|nix|command-ref/new-cli/nix3-flake-lock|number=7.5.19|title=nix flake lock}}{{cite manual|nix|command-ref/new-cli/nix3-flake-info|number=7.5.17|title=nix flake info}} 以可编程方式进行查询和更新。此外,一个实验性的 CLI 实用程序接受 flake 引用作为参数,该引用指向用于构建、运行和部署软件包的表达式。{{Cite manual|nix|command-ref/new-cli/nix|number=8.5.1|title=nix}} | Flakes 还允许锁定引用和版本,然后通过 inputs {{cite manual|nix|command-ref/new-cli/nix3-flake-lock|number=7.5.19|title=nix flake lock}}{{cite manual|nix|command-ref/new-cli/nix3-flake-info|number=7.5.17|title=nix flake info}} 以可编程方式进行查询和更新。此外,一个实验性的 CLI 实用程序接受 flake 引用作为参数,该引用指向用于构建、运行和部署软件包的表达式。{{Cite manual|nix|command-ref/new-cli/nix|number=8.5.1|title=nix}} | ||
<span id="Flake_file_structure"></span> | |||
== Flake 文件结构 == | == Flake 文件结构 == | ||
一个最小化的 flake 文件包含该 flake 的描述(description),一组输入依赖项(inputs)和一个输出(outputs)。您可以随时使用 <code>nix flake init</code> 命令来生成一个非常基础的 flake 文件。这将在当前目录下创建一个名为 <code>flake.nix</code> 的文件,其内容类似于: | 一个最小化的 flake 文件包含该 flake 的描述(description),一组输入依赖项(inputs)和一个输出(outputs)。您可以随时使用 <code>nix flake init</code> 命令来生成一个非常基础的 flake 文件。这将在当前目录下创建一个名为 <code>flake.nix</code> 的文件,其内容类似于: | ||
{{File|3=<nowiki>{ | {{File|3=<nowiki>{ | ||
description = " | description = "A very basic flake"; | ||
inputs = { | inputs = { | ||
| Line 19: | Line 22: | ||
outputs = { self, nixpkgs }: { | outputs = { self, nixpkgs }: { | ||
packages.x86_64-linux = { | |||
default = self.packages.x86_64-linux.hello; | |||
hello = nixpkgs.legacyPackages.x86_64-linux.hello; | |||
}; | |||
}; | |||
}</nowiki>|name=flake.nix|lang=nix}} | |||
在上述示例中,您可以看到对该 flake 的'''描述'''、指定为某 Github 仓库特定分支的'''输入'''(此为 <code>nixos/nixpkgs</code> 仓库的 <code>nixos-unstable</code> 分支)以及一个使用该输入的'''输出'''。该输出简单地指定了该 flake 包含一个用于 x86_64 架构名为 <code>hello</code> 的包。即使您的 flake 输出不使用其输入(尽管这在实践中极不可能),其输出仍需要是一个 Nix 函数。 | |||
{{Note|Flakes require you to specify its outputs for each architecture separately. For more information, read the related section below.}} | |||
<span id="Nix_configuration"></span> | |||
=== Nix 配置 === | |||
为了推导 flake,您可以覆盖 <code>nix.conf</code> 文件中设置的全局 Nix 配置。例如,这可用于设置特定项目的二进制缓存源,同时保持全局配置不变。Flake 文件中可包含一个 nixConfig 属性,并在其中设置相关配置。例如,启用 nix-community 二进制缓存可以通过以下方式实现: | 为了推导 flake,您可以覆盖 <code>nix.conf</code> 文件中设置的全局 Nix 配置。例如,这可用于设置特定项目的二进制缓存源,同时保持全局配置不变。Flake 文件中可包含一个 nixConfig 属性,并在其中设置相关配置。例如,启用 nix-community 二进制缓存可以通过以下方式实现: | ||
{{File|3=<nowiki>{ | {{File|3=<nowiki>{ | ||
... | ... | ||
| Line 40: | Line 48: | ||
]; | ]; | ||
} | } | ||
}</nowiki>|name=flake.nix|lang=nix}}{{Note|如果您习惯通过 NixOS 配置来设置 Nix 配置,则这些选项位于 <code>nix.settings</code> 下,而不是 <code>nix</code> 下。例如,您无法在 <code>nix.optimization.enable</code> 下指定自动存储优化。}} | }</nowiki>|name=flake.nix|lang=nix}} | ||
{{Note|如果您习惯通过 NixOS 配置来设置 Nix 配置,则这些选项位于 <code>nix.settings</code> 下,而不是 <code>nix</code> 下。例如,您无法在 <code>nix.optimization.enable</code> 下指定自动存储优化。}} | |||
<span id="Setup"></span> | <span id="Setup"></span> | ||
| Line 49: | Line 59: | ||
当使用任意 [[Nix command|<code>nix</code> 命令]]时,添加如下命令行参数: | 当使用任意 [[Nix command|<code>nix</code> 命令]]时,添加如下命令行参数: | ||
<syntaxhighlight lang="shell"> | <syntaxhighlight lang="shell"> | ||
--experimental-features 'nix-command flakes' | --experimental-features 'nix-command flakes' | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<span id="Enabling_flakes_permanently"></span> | <span id="Enabling_flakes_permanently"></span> | ||
=== 永久启用 Flakes === | === 永久启用 Flakes === | ||
| Line 74: | Line 86: | ||
====Nix 独立程序==== | ====Nix 独立程序==== | ||
{{Note |[https://github.com/DeterminateSystems/nix-installer Determinate Nix 安装程序] 默认启用 Flakes 功能。}} | |||
{{Note | | |||
添加如下内容至 <code>~/.config/nix/nix.conf</code> 或 <code>/etc/nix/nix.conf</code>: | 添加如下内容至 <code>~/.config/nix/nix.conf</code> 或 <code>/etc/nix/nix.conf</code>: | ||
| Line 83: | Line 93: | ||
experimental-features = nix-command flakes | experimental-features = nix-command flakes | ||
</syntaxHighlight> | </syntaxHighlight> | ||
<span id="Usage"></span> | <span id="Usage"></span> | ||
== 用法 == | == 用法 == | ||
| Line 92: | Line 103: | ||
因此,如果您使用 <code>git</code> 管理您的 flake,请确保在首次创建之后使用 <code>git add</code>添加所有项目文件。}} | 因此,如果您使用 <code>git</code> 管理您的 flake,请确保在首次创建之后使用 <code>git add</code>添加所有项目文件。}} | ||
<span id="The_nix_flakes_command"></span> | |||
=== Nix Flakes 命令 === | === Nix Flakes 命令 === | ||
{{Main|Nix (command)}} | {{Main|Nix (command)}} | ||
| Line 114: | Line 127: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ | { | ||
description = " | description = "Example flake with a devShell"; | ||
inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; | |||
outputs = { self, nixpkgs}: | |||
let | let | ||
system = "x86_64-linux"; | system = "x86_64-linux"; | ||
| Line 128: | Line 141: | ||
]; | ]; | ||
shellHook = '' | shellHook = '' | ||
echo " | echo "Welcome to the devShell!" | ||
''; | ''; | ||
}; | }; | ||
| Line 183: | Line 196: | ||
<code>inputs.nixpkgs.url = "github:NixOS/nixpkgs/<branch name>";</code> | <code>inputs.nixpkgs.url = "github:NixOS/nixpkgs/<branch name>";</code> | ||
Nixpkgs | Nixpkgs 也可以指向一个由 NixOS 组织缓存的 URL: | ||
<code>inputs.nixpkgs.url = "<nowiki>https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz</nowiki>";</code> | <code>inputs.nixpkgs.url = "<nowiki>https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz</nowiki>";</code> | ||
在此示例中,输入将指向 <code>nixpkgs-unstable</code> 频道(channel)。 | |||
对于任何包含 flake.nix 文件的仓库,其所属网站也必须被定义。Nix 知道 nixpkgs 仓库的位置,因此没有必要声明它在 GitHub 上。 | 对于任何包含 flake.nix 文件的仓库,其所属网站也必须被定义。Nix 知道 nixpkgs 仓库的位置,因此没有必要声明它在 GitHub 上。 | ||
| Line 200: | Line 212: | ||
<code>inputs.hyprland.inputs.nixpkgs.follows = "nixpkgs";</code> | <code>inputs.hyprland.inputs.nixpkgs.follows = "nixpkgs";</code> | ||
使用大括号 ({}),我们可以缩短这些内容并将其放在一个表中。代码如下所示: | 使用大括号 (<code>{}</code>),我们可以缩短这些内容并将其放在一个表中。代码如下所示: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
| Line 221: | Line 233: | ||
=== 输出规范 === | === 输出规范 === | ||
Nix 包管理器仓库的 [https://github.com/NixOS/nix/blob/master/src/nix/flake-check.md src/nix/flake-check.md] 中对此进行了描述。 | |||
一旦 Inputs 被解析,它们就会与 <code>self</code> 一起传递给函数 <code>outputs</code>,<code>self</code> 是此 flake 在 Store 中的目录。<code>outputs</code> 根据以下规范返回 flake 的输出。 | 一旦 Inputs 被解析,它们就会与 <code>self</code> 一起传递给函数 <code>outputs</code>,<code>self</code> 是此 flake 在 Store 中的目录。<code>outputs</code> 根据以下规范返回 flake 的输出。 | ||
| Line 237: | Line 247: | ||
* <code><store-path></code> 是 <code>/nix/store..</code> 的路径。 | * <code><store-path></code> 是 <code>/nix/store..</code> 的路径。 | ||
< | <syntaxhighlight lang="nix"> | ||
{ self, ... }@inputs: | { self, ... }@inputs: | ||
{ | { | ||
| Line 250: | Line 260: | ||
type = "app"; | type = "app"; | ||
program = "<store-path>"; | program = "<store-path>"; | ||
meta = {description = "..."; inherit otherMetaAttrs; }; | |||
}; | }; | ||
# Executed by `nix run . -- <args?>` | # Executed by `nix run . -- <args?>` | ||
apps."<system>".default = { type = "app"; program = "..."; }; | apps."<system>".default = { type = "app"; program = "..."; meta = {description = "..."; inherit otherMetaAttrs; }; }; | ||
# Formatter (alejandra, nixfmt or nixpkgs-fmt) | # Formatter (alejandra, nixfmt, treefmt-nix or nixpkgs-fmt) | ||
formatter."<system>" = derivation; | formatter."<system>" = derivation; | ||
# Used for nixpkgs packages, also accessible via `nix build .#<name>` | # Used for nixpkgs packages, also accessible via `nix build .#<name>` | ||
| Line 283: | Line 294: | ||
templates.default = { path = "<store-path>"; description = ""; }; | templates.default = { path = "<store-path>"; description = ""; }; | ||
} | } | ||
</ | </syntaxhighlight> | ||
您还可以定义其他任意属性,但以上这些是 Nix 已知的输出。 | 您还可以定义其他任意属性,但以上这些是 Nix 已知的输出。 | ||
| Line 308: | Line 319: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ | { | ||
description = " | description = "A flake targeting multiple architectures"; | ||
inputs = { | |||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; | nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; | ||
}; | }; | ||
outputs = { self, nixpkgs }: let | |||
systems = [ "x86_64-linux" "aarch64-linux" ]; | systems = [ "x86_64-linux" "aarch64-linux" ]; | ||
forAllSystems = f: builtins.listToAttrs (map (system: { | forAllSystems = f: builtins.listToAttrs (map (system: { | ||
| Line 379: | Line 390: | ||
=== 非 Flake 项目中的 Flake 支持 === | === 非 Flake 项目中的 Flake 支持 === | ||
[https://github.com/edolstra/flake-compat flake-compat] 库提供了一个兼容层,允许使用传统 <code>default.nix</code> 和 <code>shell.nix</code> 文件的项目与 Flakes 兼容。更多详情和使用示例,请参阅 [[Flake Compat]] 页面。 | |||
另一个允许在非 flake 项目中使用 Flakes 的项目是 [https://github.com/fricklerhandwerk/flake-inputs flake-inputs]。 | |||
<span id="Accessing_flakes_from_Nix_expressions"></span> | <span id="Accessing_flakes_from_Nix_expressions"></span> | ||
| Line 412: | Line 419: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
这允许构建尚未添加到 nixpkgs 的包。 | |||
< | <span id="How_to_add_a_file_locally_in_git_but_not_include_it_in_commits"></span> | ||
=== | === 如何在 git 中添加一个本地文件但不将其包含在提交中 === | ||
当 [[git]] 文件夹存在时,flake 将仅复制在 git 中添加的文件,以最大限度地提高可复现性(因此,如果您忘记在代码库中添加本地文件,则在尝试编译时会直接出错)。但是,有时出于开发目的您可能需要创建一个备用的 flake 文件,例如包含您首选编辑器的配置,如[https://discourse.nixos.org/t/local-personal-development-tools-with-flakes/22714/8 此处所述],这种情况下当然无需提交此文件,因为它只包含您自己首选的工具。在上述情况下,您可以执行以下操作(例如,创建了一个名为 <code>extra/flake.nix</code> 的文件): | |||
<syntaxHighlight> | <syntaxHighlight> | ||
| Line 429: | Line 431: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
< | <span id="Rapid_iteration_of_a_direct_dependency"></span> | ||
=== | === 直接依赖项的快速迭代 === | ||
使用 Nix 作为开发环境的一个常见痛点是,每次更新依赖项时都需要完全重构并重新进入开发 shell。<code>nix develop --redirect <flake> <directory></code> 命令允许您向 shell 提供可变的依赖项,就像它是由 Nix 构建的一样。 | |||
考虑这样一个场景:您的可执行程序 <code>consumexe</code> 依赖于一个库 <code>libdep</code>。你希望同时开发这两个项目,并且对 <code>libdep</code> 的修改能够实时反映到 <code>consumexe</code> 中。这种工作流程可以通过以下方式实现: | |||
<syntaxHighlight lang=bash> | <syntaxHighlight lang=bash> | ||
| Line 449: | Line 446: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
现在您已经构建了依赖项,<code>consumexe</code> 可以将其作为输入。'''在另一个终端中''': | |||
<syntaxHighlight lang=bash> | <syntaxHighlight lang=bash> | ||
| Line 460: | Line 455: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
< | 如果 Nix 警告您重定向的 flake 实际上并未用作已推导 flake 的输入,请尝试使用 <code>--inputs-from .</code> 标志。如果一切顺利,您应该能够在依赖项更改时执行 <code>buildPhase && installPhase</code> 操作,并使用新版本依赖重建您的程序,而''无需''退出开发 shell。 | ||
== | |||
<span id="See_also"></span> | |||
=== 另见 === | |||
< | <span id="Official_sources"></span> | ||
=== | === 官方来源 === | ||
* [https://nix.dev/concepts/flakes Flakes] - nix.dev | * [https://nix.dev/concepts/flakes Flakes] - nix.dev | ||
* [https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html Nix flake 命令参考手册] - 关于 Flakes 及其各部分的更多附加细节。 | |||
* [https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html Nix flake | |||
* [https://github.com/NixOS/nix/blob/master/src/nix/flake.md 更详细地描述 Flakes Inputs 的规范] | |||
* [https://github.com/NixOS/nix/blob/master/src/nix/flake.md | |||
* [https://github.com/NixOS/rfcs/pull/49 RFC 49] (2019) - 原始 Flakes 规范 | |||
* [https://github.com/NixOS/rfcs/pull/49 RFC 49] (2019) - | |||
< | <span id="Guides"></span> | ||
=== | === 指南 === | ||
* [https://jade.fyi/blog/flakes-arent-real/ Flakes 并非幻象,亦非洪水猛兽] (Jade Lovelace, 2024) | |||
* [https://jade.fyi/blog/flakes-arent-real/ Flakes | |||
* [https://github.com/ryan4yin/nixos-and-flakes-book NixOS & Flakes Book](Ryan4yin, 2023) - 🛠️ ❤️ 一本非官方的 NixOS & Flakes 新手入门书籍。 | |||
* [https://github.com/ryan4yin/nixos-and-flakes-book NixOS & Flakes Book](Ryan4yin, 2023) - 🛠️ ❤️ | |||
* [https://xeiaso.net/blog/nix-flakes-1-2022-02-21 Nix Flakes:一个简要介绍] (Xe Iaso, 2022) | |||
* [https://xeiaso.net/blog/nix-flakes-1-2022-02-21 Nix Flakes | |||
* [https://serokell.io/blog/practical-nix-flakes Practical Nix Flakes] (Alexander Bantyev, 2021) - 关于使用 Nix 和 Flakes 的介绍文章。 | |||
* [https://serokell.io/blog/practical-nix-flakes Practical Nix Flakes] (Alexander Bantyev, 2021) - | |||
* [https://www.tweag.io/blog/2020-05-25-flakes/ Nix Flakes, 第一节:介绍和教程] (Eelco Dolstra, 2020) | |||
* [https://www.tweag.io/blog/2020-05-25-flakes/ Nix Flakes, | |||
* [https://www.tweag.io/blog/2020-06-25-eval-cache/ Nix Flakes, 第二节:推导缓存] (Eelco Dolstra, 2020) | |||
* [https://www.tweag.io/blog/2020-06-25-eval-cache/ Nix Flakes, | |||
* [https://www.tweag.io/blog/2020-07-31-nixos-flakes/ Nix Flakes, 第三节:管理 NixOS 系统] (Eelco Dolstra, 2020) | |||
* [https://www.tweag.io/blog/2020-07-31-nixos-flakes/ Nix Flakes, | |||
* [https://www.youtube.com/watch?v=QXUlhnhuRX4&list=PLgknCdxP89RcGPTjngfNR9WmBgvD_xW0l Nix flakes 101: Introduction to nix flakes] (Jörg Thalheim, 2020) YouTube 视频 | |||
* [https://www.youtube.com/watch?v=QXUlhnhuRX4&list=PLgknCdxP89RcGPTjngfNR9WmBgvD_xW0l Nix flakes 101: Introduction to nix flakes] (Jörg Thalheim, 2020) YouTube | |||
< | <span id="Useful_flake_modules"></span> | ||
=== | === Flake 实用模块 === | ||
* [[Flake Utils|flake-utils]]:一个用于简化 Flakes 编写、避免样板代码的库 | |||
* [[Flake Utils|flake-utils]] | |||
* [[Flake Parts|flake-parts]]:帮助编写模块化、结构化 Flakes 的库 | |||
* [[Flake Parts|flake-parts]] | |||
* [[Flake Compat|flake-compat]]:Flakes 兼容层 | |||
* [[Flake Compat|flake-compat]] | |||
* [https://github.com/nix-community/todomvc-nix 构建 Rust 和 Haskell 的 flakes] | |||
* [https://github.com/nix-community/todomvc-nix | |||
{{references}} | {{references}} | ||
[[Category:Software]] | [[Category:Software|软件]] | ||
[[Category:Nix]] | [[Category:Nix|Nix]] | ||
[[Category:Nix Language]] | [[Category:Nix Language|Nix 语言]] | ||
[[Category:Flakes]] | [[Category:Flakes|Flakes]] | ||