【问题标题】:Can the same code and same compiler produce a different binary on different machines?相同的代码和相同的编译器能否在不同的机器上生成不同的二进制文件?
【发布时间】:2021-04-01 15:28:39
【问题描述】:

Nixos binary caches 的想法让我想到了这个问题。

在 nix 中,每个编译的二进制文件都与一个散列键相关联,该散列键是通过散列所有依赖项和构建脚本获得的,即 nix-speak 中的“派生”。无论如何,这是我的理解。

但是当在不同的机器上编译时,相同的派生不会导致不同的二进制文件吗? 如果机器 A 的处理器的指令集与机器 B 的处理器稍有不同,并且编译器考虑了这种不同的指令集,那么在机器 A 上编译推导生成的二进制文件与在机器 A 上编译推导生成的二进制文件是否有区别? B机?如果是这样,那么不同的二进制文件就不能具有相同的派生,从而具有相同的 nix 哈希吗?

在具有不同指令集的机器上构建的相同派生是否总是产生相同的二进制文件?

【问题讨论】:

  • 运行编译器的机器上的指令集与编译器输出无关。事实上,交叉编译器在输出根本无法在构建机器上运行的情况下很常见。通常,构建在不同系统上的二进制文件之间唯一不同的是二进制文件中的时间戳。

标签: nix nixos


【解决方案1】:

这取决于编译器实现和传递给它的选项。例如,默认情况下 GCC 似乎并不关注当前处理器的细节,除非您指定 -march=native-mtune=native

所以是的,如果您使用这些标志或具有这些标志的默认行为的编译器,您将在具有不同 cpu 型号的机器上获得不同的输出。

由于其他原因,构建也可能无法重现,例如时钟值或随机值的不当使用,甚至是线程以非确定性交错模式访问的计数器。

Nix 确实提供了一个沙盒,可以删除一些熵源;主要是机器上可能存在的所谓不相关的软件。出于实际原因,它不会删除所有这些来源。

出于这些原因,即使使用 Nix 进行包装,也必须考虑可重复性;不是它完全解决的问题。

我将引用菜单“实现确定性构建 " 来自https://reproducible-builds.org/docs/ 并尽我所知用 Nix 的效果对其进行注释。不要引用我的话。

  • SOURCE_DATE_EPOCH:已解决;由 Nixpkgs 设置
  • 确定性构建系统:部分解决; Nixpkgs 可能包含补丁
  • 易失性输入可能会消失:如果您将源上传到(二进制)缓存,则可以使用 Nix 解决。 Hercules CI 就是这样做的。
  • 输入的稳定顺序:大部分已解决。 Nix 语言保留源代码顺序并对属性进行排序。
  • 值初始化:Nix 未解决的低级问题
  • 版本信息:未解决;时钟可在沙盒中访问
  • 时间戳:同上
  • 时区:由沙盒解决
  • 语言环境:由沙盒解决
  • 存档元数据:未解决
  • 稳定的输出顺序:使用沙盒无法解决的随机性
  • 随机性:相同
  • 构建路径:部分; linux使用/build; macOS 可能因安装方法而异
  • 系统图像:从以前的项目中获取元素的广泛问题
  • JVM:相同

【讨论】:

猜你喜欢
  • 2012-11-04
  • 1970-01-01
  • 2020-02-12
  • 2013-02-17
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多