nix - 相同的代码和相同的编译器可以在不同的机器上生成不同的二进制文件吗?

标签 nix nixos

Nixos binary caches的想法导致我考虑这个问题。
在 nix 中,每个编译的二进制文件都与一个散列键相关联,该键是从散列所有依赖项和构建脚本中获得的,即 nix 中的“派生”。反正这是我的理解。
但是,在不同的机器上编译时,相同的派生不能导致不同的二进制文件吗?
如果机器 A 的处理器与机器 B 的处理器的指令集略有不同,并且编译器考虑了这种不同的指令集,那么在机器 A 上编译推导产生的二进制文件是否与在机器 A 上编译推导产生的二进制文件有区别?机器B?如果是这样,那么不同的二进制文件不能具有相同的派生,从而具有相同的 nix 哈希值吗?
在具有不同指令集的机器上构建的相同推导是否总是产生相同的二进制文件?

最佳答案

这取决于编译器实现和传递给它的选项。比如默认情况下GCC似乎并不关注当前处理器的细节,除非你指定-march=native-mtune=native .
所以是的,如果您使用这些标志或具有这些标志的默认行为的编译器,您将在具有不同 CPU 型号的机器上获得不同的输出。
构建也可能由于其他原因不可重现,例如时钟值或随机值的不当使用,甚至是线程以非确定性交错模式访问的计数器。
Nix 确实提供了一个沙箱,可以去除一些熵源;主要是可能存在于机器上的假定不相关的软件。出于实际原因,它不会删除所有这些来源。
由于这些原因,即使在使用 Nix 进行包装时,也必须考虑可重复性;不是由它完全解决的东西。
我将引用菜单“实现确定性构建
"来自 https://reproducible-builds.org/docs/ 并尽我所知用 Nix 的效果对其进行注释。不要引用我的话。

  • SOURCE_DATE_EPOCH:已解决;由 Nixpkgs 设置
  • 确定性构建系统:部分解决; Nixpkgs 可能包含补丁
  • volatile 输入可能会消失:如果您将源上传到(二进制)缓存,则可以使用 Nix 解决。 Hercules CI 做到了这一点。
  • 输入的稳定顺序:大部分已解决。 Nix 语言保留源代码顺序并对属性进行排序。
  • 值初始化:Nix Unresolved 低级问题
  • 版本信息:未解决;时钟可在沙箱中访问
  • 时间戳:同上
  • 时区:由沙箱解决
  • 语言环境:通过沙箱解决
  • 存档元数据:未解决
  • 输出的稳定顺序:使用沙箱无法解决的随机性
  • 随机性:相同
  • 构建路径:部分; linux 使用 /build ; macOS 可能因安装方法而异
  • 系统镜像:从以前的项目中获取元素的广泛问题
  • JVM:相同
  • 关于nix - 相同的代码和相同的编译器可以在不同的机器上生成不同的二进制文件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66907407/

    相关文章:

    nixos - fetchFromGitHub,过滤并用作 environment.etc ."file".source

    linux - Nix/OS 架构概述?

    python - 试图从/nix/store 中删除一个包,现在系统出现错误,如何修复?

    haskell - 使用 Hydra 测试多个 Haskell 依赖项版本

    haskell - 如何提供 C 库以在 NixOS 上进行堆栈?

    nix - 如何将我的 nix 环境重置为原始用户配置文件?

    NixOS:在 configuration.nix 中设置默认 channel

    package-managers - Nix/NixOS 中的循环依赖以一个简单的例子解释

    haskell - 在 NixOs 上安装 Haskell 软件包 Euterpea 失败

    nix - 如何在 Nix 中组合两个列表?