【问题标题】:How to force Nix to "install packages" by building them locally instead of downloading a pre-built binary?如何通过在本地构建而不是下载预构建的二进制文件来强制 Nix“安装包”?
【发布时间】:2021-05-16 09:44:35
【问题描述】:

安装包”是指评估 Nix 构建表达式(使用 nix-envnix-shell -p 等)以从源代码构建而不是使用 substitute

还有cross-posted to Unix& Linux,因为与Charles Duffy pointed out 一样,如果它是关于命令行工具或配置的,它会更受关注。仍然将其留在这里,因为我假设仅使用 Nix 语言就可以强制一个包始终从源代码编译,我只是还不知道如何。 (或者如果事实上不可能的话,有人会指出来,那么这个问题确实属于这里。)

【问题讨论】:

  • 问得好,但也许更多的话题在Unix & Linux
  • 谢谢 - 约。我遇到的所有 Nix/NixOS/Nixpkgs 线程中有 80% 都在 Stackoverflow 上,所以我总是感到困惑..
  • 如果是关于 Nix 语言,它绝对属于这里。如果是关于命令行工具或配置,那里可能会更好。
  • 为什么要在本地构建?
  • @RobertHensing 这个问题很明确——我什至忘记添加关于它的注释。做了一个聊天室,以防这会很长:chat.stackoverflow.com/rooms/228653/why-ignore-substitute

标签: nix nixos


【解决方案1】:

nix.conf 中将substitute option 设置为false(默认为true)或在调用Nix 命令时使用--option substitute false

nix-env --options substitute false -i hello

nix-shell --options substitute false -p hello

可能不是你要找的机器人

正如 Robert Hensing (comment, chat)、Henri Menke (comment) 和 Vladimír Čunát (comment) 指出的那样,这可能不是您真正想要的。

详细说明:我一直自信地使用最基本的 Nix 功能,但到了需要维护和部署一个用 C 编写的大型应用程序的自定义分支的地步,这在开始时非常令人生畏。

试图以最简单的方式解决问题,只需 fetch 我的 fork 并使用新源重新构建它,所以我将其归结为这个问题。虽然,我怀疑对我来说正确的方向是类似于NixOS Wiki 中的Nixpkgs/Create and debug packages

只重新构建包本身

Vladimír Čunát commented 表示“禁用替代品会让您重建本地缺少的所有内容,尽管我怀疑提出此类问题的人通常只想重建指定的包本身。

(这可能是通过nix-build 或“只是”覆盖原始包来实现的,但可能是错误的。后者在 NixOS wiki 文章 Development environment with nix-shell 中被提及(甚至可能被证明?)但无法仔细阅读它。)

重复性测试

如果他们想确保后续构建是确定性的,他们可能会提出同样的问题。作为Henri Menke comments,应该使用nix-build --check

--check 选项很容易错过;它没有记录在man nix-buildNix manual 中的nix-build 中,但在nix-store --realize 中,因为(正如man nix-build 所解释的那样):

nix-build 本质上是nix-instantiate 的包装器(到 将高级 Nix 表达式转换为低级存储派生) 和nix-store --realise(建立商店派生)[等等]所有 此处未列出的选项将传递给nix-store --realise,除了 对于--arg--attr / -A,它们被传递给nix-instantiate

查看Nix manual18.1. Spot-Checking Build Determinismthe next section right after it 中的详细示例。


Nix manualthe nix.conf sectionsubstitute配置选项的相关部分:

名称

nix.conf — Nix 配置文件

说明

Nix 从两个配置文件中读取设置:

  • 系统范围的配置文件sysconfdir/nix/nix.conf(即大多数系统上的/etc/nix/nix.conf),如果设置了NIX_CONF_DIR,则为$NIX_CONF_DIR/nix.conf

  • 用户配置文件$XDG_CONFIG_HOME/nix/nix.conf,如果未设置XDG_CONFIG_HOME,则为~/.config/nix/nix.conf

您可以使用--option 标志覆盖命令行上的设置, 例如--option keep-outputs false.

以下设置当前可用:

[..]

替代
如果设置为 true(默认),Nix 将使用二进制替代(如果可用)。可以禁用此选项以强制从源代码构建。

(以前称为use-binary-caches。)


注意事项

如果命令多次发出,将substitute 设置为false(使用--optionsnix.conf)将不会重新编译包。即上面的hello是第一次从源码编译,如果再次发出命令,它会访问已经存在的存储路径。

这是它变得模糊的地方:很明显没有重新编译发生,因为除非包的 Nix 构建表达式没有改变,否则存储输出哈希也不会改变,使得下一个编译输出等同于前一个,因此该操作将是多余的。

因此,如果有人对一个包进行一些简单的修改,并且只是想在本地尝试一下(例如,使用nix-shell),那么就必须使用-I nixpkgs=a/local/nixpkgs/dir 来获取这些更改 - 并最终做一个重新编译?还是应该使用nix-build

另见问题How to nix-build again a built store path?

【讨论】:

  • 如果要重建现有的存储路径以检查它是否可重现,只需使用nix-build --check
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多