问题描述
“安装包”是指评估 Nix 构建表达式(使用 nix-env
、nix-shell -p
等)从源代码构建而不是使用 {{3 }}。
还有substitute,因为和cross-posted to Unix& Linux一样,如果它是关于命令行工具或配置的,那么它更多是关于主题的。仍然留在这里是因为我认为只使用 Nix 语言就可以强制一个包总是从源代码编译,我只是不知道如何。 (或者如果实际上不可能,有人会指出,那么这个问题确实属于这里。)
解决方法
在 substitute
option 中将 nix.conf
设置为 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 我的叉子并使用新源重新构建它,所以我将其归结为这个问题。虽然,我怀疑对我来说正确的方向是沿着 Nixpkgs/Create and debug packages 中的 NixOS Wiki 的路线。
仅重新构建包本身
Vladimír Čunát commented “禁用替代品会让你重建本地缺少的所有东西,尽管我怀疑问这样问题的人通常只想重建指定的包本身。” >
(这可能是通过 nix-build
或“只是”覆盖原始包实现的,但可能是错误的。后者在 NixOS wiki 文章 Development environment with nix-shell
中被提及(甚至可能被证明?)但没有还没能彻底读完。)
再现性测试
如果他们想确保后续构建是确定性的,那么他们可能会提出同样的问题。作为 Henri Menke comments,应该使用 nix-build --check
。
--check
选项很容易错过;它没有记录在 man nix-build
或 nix-build
的 Nix manual 中,而是记录在 nix-store --realize
中,因为(如 man nix-build
解释的那样):
nix-build
本质上是 nix-instantiate
的包装器(为了
将高级 Nix 表达式转换为低级存储派生)
和 nix-store --realise
(构建商店派生)[等等] 所有
此处未列出的选项将传递给 nix-store --realise
,除了
用于传递给 --arg
的 --attr
和 -A
/ nix-instantiate
。
请参阅 Nix manual 和 18.1. Spot-Checking Build Determinism 处的 the next section right after it 中的详细示例。
the nix.conf
section 中 Nix manual 下的 substitute
配置选项的相关部分:
姓名
nix.conf
— Nix 配置文件
说明
Nix 从两个配置文件中读取设置:
-
系统范围的配置文件
sysconfdir/nix/nix.conf
(即在大多数系统上为/etc/nix/nix.conf
),如果设置了$NIX_CONF_DIR/nix.conf
,则为NIX_CONF_DIR
。 -
用户配置文件
$XDG_CONFIG_HOME/nix/nix.conf
,如果~/.config/nix/nix.conf
未设置,则为XDG_CONFIG_HOME
。
您可以使用 --option
标志覆盖命令行上的设置,
例如--option keep-outputs false
。
以下设置当前可用:
[..]
替代
如果设置为 true(默认),Nix 将使用二进制替代品(如果可用)。可以禁用此选项以强制从源代码构建。
(以前称为 use-binary-caches
。)
注意事项
如果命令多次发出,将 substitute
设置为 false
(使用 --options
或在 nix.conf
中)不会重新编译程序包。也就是说,上面的 hello
会第一次从源代码编译,如果再次发出命令,它将访问已经存在的存储路径。
这就是它变得模糊的地方:很明显没有重新编译发生,因为除非包的 Nix 构建表达式没有改变,否则存储输出哈希也不会改变,使得下一个编译输出等同于前一个,因此该操作将是多余的。
因此,如果您想对软件包进行一些轻微的修改,并且只想在本地试用(例如,使用 nix-shell
),那么您将不得不使用 -I nixpkgs=a/local/nixpkgs/dir
来获取这些更改 -并最终重新编译?还是应该使用nix-build
?