我正在寻找是否可以两次构建相同的 Linux 内核(相同的源、相同的环境、相同的选项、相同的编译器)并获得相同的校验和。有人知道该怎么做吗?
6 回答
构建日期包含在版本中,请参阅 init version.c :
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
并且 UTS_VERSION 在 include/linux/compile.h 中定义:
/* This file is auto generated, version 1 */
/* PREEMPT */
#define UTS_MACHINE "arm"
#define UTS_VERSION "#1 PREEMPT Mon Jun 29 10:49:17 CEST 2009"
#define LINUX_COMPILE_TIME "10:49:17"
#define LINUX_COMPILE_BY "cynove"
#define LINUX_COMPILE_HOST "jp"
#define LINUX_COMPILE_DOMAIN "evonyc"
#define LINUX_COMPILER "gcc version 4.3.2 (crosstool-NG-1.4.0) "
compile.h 由 scripts/mkcompile_h 生成,您可以在其中找到以下行:
UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS `LC_ALL=C LANG=C date`"
通过date
从前面的行中删除,您应该能够摆脱构建时间的依赖。
shodanex 的回答是正确但不完整。经过一些研究,我发现 Linux 内核二进制文件嵌入了一个默认的 ramfs,这是两个内核编译之间存在差异的另一个原因(CPIO RAMFS 标头嵌入日期)。无法禁用此功能,但可以提供默认 ramfs。当你这样做时,你会得到完全相同的校验和。
谢谢你。您的回答对我解决问题有很大帮助。
@gsempe,您想查找以下内容:“使内核构建确定性”参考。http://lwn.net/Articles/437864/
可以消除某些噪音源(噪音是......在旁观者的眼中;-)
即使是一个简单的 hello world 编译两次也会产生不同的二进制文件。不知何故,链接器正在添加一些在每个构建中都会发生变化的信息。
最快的检查方法是制作,复制,清洁,然后再制作。如果校验和匹配,那么它是可能的。如果不是,则表明 Make 正在以某种方式更改某些源文件(构建编号、构建日期等)
据推测,在相同的环境中构建内核将导致相同的校验和。因此,相同的编译器(相同编译器的相同版本)、完全相同的源、相同的依赖项(如果这甚至适用于内核编译)等等。