This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM2432:在 CCS 中重新编译会每次生成不同的二进制文件

Guru**** 2779465 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1614289/am2432-rebuilding-in-ccs-produces-different-binaries-each-time

器件型号: AM2432

问题描述

使用 Code Composer Studio (CCS) 编译工程时、即使使用相同的源代码和相同的提交、每次我编译时生成的二进制文件也会有所不同。

从配置管理的角度来看、只要源代码和构建环境相同、我希望生成的二进制文件保持相同。
在 CCS/ ARM-CGT-CLANG 中、此行为是由设计预期行为、还是由某些构建设置引起?

存在许多风险

  • Code Composer Studio:12.8.1.00005

  • ARM-CGT-CLANG:4.0.1.LTS

  • AM243X-AM243X:11.00.00.08 INDUSTRIAL-COMMUNICATIONS-SDK

Build method

  • CCS 中的“Rebuild Project“(重建工程)

我已经试过了

我比较了两个重建之间的以下输出、但它们都不匹配:

  • .hs_fs间隔

  • .out间隔

  • .bin.out使用转换的文件 tiarmobjcopy

  • .out使用生成的反汇编输出 tiarmobjdump -d

其他意见

最初、我怀疑这可能是我们内部项目配置特有的问题。
不过、我使用 SDK 示例工程重现了相同的行为。

我测试的具体示例是:

ethernetip_adapter_discrete_io_device_mii_demo_am243x-evm_r5fss0-0_freertos_ti-arm-clang  

即使对于此示例、多次重新编译工程也会生成不同的二进制文件。

问题

  • 使用 CCS 和 ARM-CGT-CLANG 进行构建时、非确定性二进制输出是否为已知或预期行为?

  • 否则、是否有推荐的编译器、链接器或 CCS 设置来确保可重现(确定性)编译?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    这有点紧急。 这是最后一个阶段。 您能提出优先事项吗?

    谢谢你。

    此致、

    Kasai

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    线程所有者将在 2 月 17 日的一周内停止工作。 如果您在这周内没有收到更新、请 ping 通该线程。

    感谢您的耐心。

    此致、
    Harshith

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Kasai、

    您不应使用“Rebuild Project“选项、因为这样会首先清理工程并从头开始构建、这会导致每次生成不同的二进制文件。

    相反、您可以为 CCS 使用“Build Project“选项、因此如果工程未更改、它不会生成任何二进制文件。 当您对库或编译 SDK 进行了更改时、您应该转到 Rebuild Project、因为如果只是“Build Project“、SDK 中所做的库更改将不会反映出来。  

    请参阅下图。

    简而言之、使用 构建工程  选项(如果在 CCS 中更改应用程序)。 (如果没有进行任何更改,这不会构建新的二进制文件)。

    应用 重新编译工程 选项、如果要从头开始构建工程、或在链接的库中进行了任何更改。

    此致、

    Tushar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在此处添加更多阐述。

    重新编译工程时、将执行两个步骤:

    1.清理工程(删除旧的二进制文件)

    2.编译项目(创建新的二进制文件),因此,即使源代码未更改,二进制文件内的元数据也可能发生变化,并且二进制文件之间存在差异。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我理解对两者之间差异的解释 构建工程 重新编译工程
    但是、我观察到即使在使用时也是非确定性的二进制输出 构建工程 这似乎是核心问题。

    复制步骤

    1. 将 SDK 示例工程导入 CCS

    2. 构建工程

    3. 保存生成的二进制文件

    4. 从工作区中删除工程

    5. 再次导入相同的示例工程

    6. 构建工程

    7. 保存生成的二进制文件

    8. 比较两个文件

    结果: 尽管二进制是不同的

    • 源代码相同

    • 构建选项是相同的

    • 工具链和 SDK 版本相同

    • 重新编译工程 驱动器

    问题

    从配置管理的角度来看、只要源代码和编译环境相同、二进制文件就应该相同。

    • 是否有任何编译器、链接器或 CCS 设置来使构建具有确定性?

    附件

    我附加了一个 ZIP 文件、其中包含通过两次导入同一个工程并使用进行编译而生成的两个输出 构建工程 、供参考和比较。

    e2e.ti.com/.../SDK_5F00_example.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在比较两个生成的二进制文件时、我可以看到在某些代码块中几乎没有区别。 看起来所生成的二进制文件的块对齐已更改。  

    发生这种情况的原因可能是编译器优化过程。 在优化过程中、编译器可能会使用多线程来加快进程速度。

    根据哪个线程首先完成、代码块在最终二进制文件中的布局顺序可能会发生变化。

    请参阅下图。

    用户无需担心这些更改。 二进制文件在功能上仍将保持相同。

    希望上述信息有所帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Tushar:

    感谢您的快速分析。  

    哪个优化级别不会导致这种情况?  如果应该咨询编译器专家、能不能告诉我吗?

    此致、

    Kasai

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Kasai、

    哪个优化级别不会导致此问题?

    我不是专门讨论二进制文件优化、而是讨论构建二进制文件的过程。 我不确定是否有任何标志可停止编译过程优化。

    我正在将此线程路由到编译器团队以供进一步评论。

    此致、

    Tushar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Tushar:

    感谢您将此路由到编译器团队。

    此致、

    Kasai

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当我比较来自...的文件时

    我附上了一个 ZIP 文件、其中包含通过两次导入同一个项目并使用编译生成的两个输出 构建工程 、供参考和比较。

    我在二进制文件或反汇编文件上没有看到任何差异。  我只看到中的差异 .debug_line 部分。  这是 CCS 仅使用的一个信息部分。  它不会影响执行。

    这与第一个帖子中报告的内容不匹配...

    [引述 userid=“617515" url="“ url="~“~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1614289/am2432-rebuilding-in-ccs-produces-different-binaries-each-time

    我比较了两个重建之间的以下输出、但它们都不匹配:

    • .hs_fs间隔

    • .out间隔

    • .bin.out使用转换的文件 tiarmobjcopy

    • .out使用生成的反汇编输出 tiarmobjdump -d

    [/报价]

    请关注拆卸差异。  这意味着链接器映射文件中应该会出现差异。  下面是映射文件中的示例行...

      7010fd58    00000150     discrete_io_device_dog.o (.text.DIO_DEVICE_DOG_addObject)
      

    这表明长度为 0x150 字节时、地址 0x7010fd58 处是段的内容 .text:DIO_DEVICE_DOG_addObject 。  它来自目标文件 DISCRETE_IO_DEVICE_DOG.o 。  再把另一种方法、即函数的代码 DIO_DOG_addObject 加载自定义文件 DISCRETE_IO_DEVICE_DOG.c 位于该地址。  聚焦于长度(第 2)列。  对于这两个构建版本、请比较映射文件。  请忽略地址中的差异。  重点关注长度的差异。  对于一个长度不同的源文件、 请遵循 如何提交编译器测试用例一文中的说明。  但执行两次。  每次构建一次。  请检查并确保这两个构建会创建不同的目标文件。

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    同时、您在我的第一篇帖子中处理了所请求的测试案例...考虑您是否可能受到已知问题 EXT_EP-11620的影响。  要避免此问题、请执行以下操作之一:

    • 升级到版本 4.0.x.LTS、其中 x >= 2
    • 使用选项  fno-unique-string-section-name

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    根据您之前的答复、我执行了其他测试并观察到以下情况:

    1. 创建一个新的系统

      tiarmobjcopy --strip-debug a.out a.bin
      

      .bin即使在使用后、生成的文件也是相同的 重新编译工程 只要项目绝对路径相同。

    2. 如果工程绝对路径不同、.bin则生成的文件会有所不同。

    3. 但是、添加选项时

      -fno-unique-string-section-names
      

      然后.bin使用生成文件

      tiarmobjcopy --strip-debug
      

      .bin即使工程绝对路径不同、生成的文件也是相同的。

    问题

    得出以下结论是正确的:

    • 如果.bin生成的文件--strip-debug相同、

    • 然后可执行行为(目标上的运行时行为)保证是相同的?

    换言之、我们是否可以将已去除符号.bin的文件进行比较作为验证执行二进制行为是否没有区别的有效方法?

    我们的主要关切是确保有 运行时行为没有差异 (即使与调试相关的部分或元数据有所不同)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    命令...

    tiarmobjcopy --strip-debug a.out a.bin

    ...不创建二进制文件。  它会创建 ELF 二进制可执行文件的副本 A.OUT 、但没有像这样的调试部分 .debug_info .debug_frame

    要创建二进制文件、必须使用选项 --output-target=binary (或等效的 -O 二进制 )。   有关二进制文件的一般背景信息、请参阅文章 二进制文件简介。   二进制文件绝不包含调试段、符号表或其他类似段。  因此、在使用时 tiarmobjcopy 要创建二进制文件、可使用选项 --条带调试 没有影响。

    如果两个二进制文件是相同的,这意味着...

    执行二进制行为没有区别?

    是的、实际情况是这样。  很多人都是这样想的。

    但为了完整起见,我必须描述一个警告。  二进制文件反映了已初始化段的内容、如所示 .text .rodata 等  因为它并不像那样直接反映未初始化段的内容 .bss .stack 、理论上仍然可能是两个二进制文件相同、但在未初始化的段方面有一些差异。  但这只是一种理论。  我从未在实践中看到过这种情况。  例如、假设唯一的区别是的长度 .stack 部分。  在启动代码中造成某种差异。  这会导致中出现差异 .text 部分。  它是二进制文件的一部分。

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、

    感谢您的答复。

    我们可以说当源相同时、二进制文件始终相同吗? 这是他们想要知道的。

    此致、

    Kasai

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它不仅仅是匹配源代码。  请参阅 此论坛帖子。  忽略有关的详细信息 -- keep_asm 。  不适用于类似的基于 CLANG 的编译器 tiarmclang 编译器 c29clang

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    总之、我确认了以下几点:

    • 通过添加该-fno-unique-string-section-names选项、我们可以.bintiarmobjcopy -O binary.appimage在使用相同的源代码、构建环境和构建选项时重现相同的二进制文件(使用或生成)。

    我也理解您的解释、如果两个二进制文件是相同的、它们的执行行为可以被视为几乎相同的。

    感谢您的详细解释和支持。