使用 Bitkake 构建的复杂程序具有基于路径的不同校验和,简单程序始终产生相同的校验和

问题描述 投票:0回答:1

执行摘要:根据构建路径,为 yocto 图像构建的一些二进制文件具有不同的 md5sum。路径不会影响构建的最小项目的校验和。

我正在使用 TI 提供的 Yocto 平台来构建我们的产品图像。它运行良好。我们有几个专有软件项目作为附加层连接在那里,以制作我们的实际应用程序映像。

最近我们发现,我们为应用程序映像构建的几个帮助程序的校验和根据它们的构建位置会产生不同的校验和。

在 /tmp/Project-xxxxx_Yocto 和 ~/repos/Project-xxxxx_Yocto 下构建时的示例:

user@MACHINE:/tmp/Project-xxxxx_Yocto$ md5sum ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/canbus-handler/git+AUTOINC+b99a8424b6-r0/packages-split/canbus-handler/usr/bin/canbus-handler
4f1b270a374c14bcd95d093095f4354d ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/canbus-handler/git+AUTOINC+b99a8424b6-r0/packages-split/canbus-handler/usr/bin/canbus-handler

user@MACHINE:~/repos/Project-xxxxx_Yocto$ md5sum ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/canbus-handler/git+AUTOINC+b99a8424b6-r0/packages-split/canbus-handler/usr/bin/canbus-handler
db35646094dc2f05022e012666973d7f md5sum ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/canbus-handler/git+AUTOINC+b99a8424b6-r0/packages-split/canbus-handler/usr/bin/canbus-handler

好吧,接下来我想创建一个最小的可编译调试项目(https://github.com/usvi/helloyoctoworld)来演示。你猜怎么着?该项目的校验和始终相同,路径不会影响!

user@MACHINE:/tmp/Project-xxxxx_Yocto$ md5sum ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/helloyoctoworld/git+AUTOINC+6716589062-r0/packages-split/helloyoctoworld/usr/bin/helloyoctoworld
40ae08fc09eb08ef8f519ee9312659c9  ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/helloyoctoworld/git+AUTOINC+6716589062-r0/packages-split/helloyoctoworld/usr/bin/helloyoctoworld

user@MACHINE:~/repos/Project-xxxxx_Yocto$ md5sum ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/helloyoctoworld/git+AUTOINC+6716589062-r0/packages-split/helloyoctoworld/usr/bin/helloyoctoworld
40ae08fc09eb08ef8f519ee9312659c9  ./workdir/arago-tmp-default-glibc/work/armv7at2hf-neon-oe-linux-gnueabi/helloyoctoworld/git+AUTOINC+6716589062-r0/packages-split/helloyoctoworld/usr/bin/helloyoctoworld

所以重申一下: helloyoctoworld 构建在 /tmp 与构建在 /home/USER/repos

40ae08fc09eb08ef8f519ee9312659c9 vs. 40ae08fc09eb08ef8f519ee9312659c9

canbus-handler 在 /tmp 中构建 vs 在 /home/USER/repos 中构建

4f1b270a374c14bcd95d093095f4354d vs. db35646094dc2f05022e012666973d7f

那么到底是怎么回事呢?如何调试这个?好吧,也许我会首先拿走 canbus 处理程序并剥掉东西,看看它何时开始在两个位置上都有稳定的校验和。

embedded-linux yocto bitbake openembedded
1个回答
0
投票

这将与我通过 IRC 告诉您的内容完全相同,但至少在这里答案将被存档。

这是一个经典的可重现构建 (https://reproducible-builds.org) 问题。 生成的输出中存在最有可能构建路径:它可能是其他非确定性来源,直到您验证了其构建路径为止,您无法确定。

有很多东西可以尝试:

  • 删除二进制文件并查看它们现在是否相同。如果是,那么您就知道您已将问题隔离到调试符号。
  • 在(未剥离的)二进制文件上运行字符串并查找路径。检查路径组件,以防存在转换路径的代码生成,例如
    _home_ross_yocto
    可以是符号名称。
  • 构建两个二进制文件(最好在同一台机器上,只是不同的构建树)并在它们上运行
    diffoscope
    。这会告诉您确切地差异在哪里。

当您知道到底是什么导致了差异时,修复起来通常很简单。

一些常见问题:

  • 构建的一个子集忘记尊重传入的
    CFLAGS
    ,因此不会使用
    -fdebug-prefix-map
    (在
    DEBUG_PREFIX_MAP
    中设置)进行构建。这对于汇编代码很常见,汇编代码仍然可以发出调试符号,但通常不会传递正确的标志。 通过确保传递正确的标志来轻松修复。
  • 生成的源以某种方式嵌入构建路径,可能是在变量名称或对真实源的引用中。
  • 代码可能会将
    CC
    CFLAGS
    等的值嵌入为字符串以提供信息。

工作示例:使用 cython 的包是不可重现的。扩散镜显示有两个原因:

  1. 源包包含嵌入构建路径的生成代码
  2. 二进制文件包含包含构建路径的字符串和符号

对于(1),引用位于构建后不需要的注释中,因此我们可以将它们删除。 对于(2),字符串是原始源文件的路径,幸运的是变量名是从字符串值生成的。所以我实现了路径重新映射 à la

-fdebug-prefix-map
here 并重新映射
S
B

© www.soinside.com 2019 - 2024. All rights reserved.