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.

[参考译文] 编译器/RM48L952:每次编译文件时,C编译器目标文件都会更改(源文件未更改)

Guru**** 2595925 points


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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/624681/compiler-rm48l952-c-compiler-object-files-changes-every-time-the-file-is-compiled-source-file-unchanged

部件号:RM48L952

工具/软件:TI C/C++编译器

您好,

是否有一个编译器选项来防止目标文件在重新编译文件时更改内容? 如果是,该选项是什么/在哪里? 装配体文件对象在重新装配时保持1:1,以便按预期工作。

更改看起来始终位于对象中的"字符串"中,其中某些数字更改为不同的值。 当对这些已更改的对象创建库时,也会更改库,但使用库的最终可执行文件为1:1,因此对象或库中的更改不会影响最终输出,因为原始源代码文件是未经修改的。

当库存储在版本控制中并且声称它已更改时,更改会导致令人烦恼的问题,因此不容易看到更改是"表面"更改还是真正的更改。

一个目标文件的比较:
...151.521万.$C$L1.$C$L2.$C$L3.$C$

...126.0818万.$C$L1.$C$L2.$C$L3.$C$

第二个目标文件的比较:
.......... 274.241万.$C$L1.$C$L2.$

.......... 44.041万.$C$L1.$C$L2.$

所有c目标文件看起来都相似...

不知道这些字符串是什么,因此很难创建合适的关键字来尝试搜索正确的项目,快速浏览CCS项目选项不会弹出任何潜在设置。 已测试默认情况下,例如IAR编译器生成1:1对象,因此应该可以实现。

最简单的测试方法是编译代码,备份对象,然后清理项目, 重新编译和比较对象。

当前使用TI v.16.3 0 STS & CCS 6.1 .3.0.0033万 如果这很重要,并且从不存在版本有其他选项,则此编译器版本中如果不是直接设置,很可能至少有命令行选项。

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

    我认为我们可以找到差异的根本原因。  请使用 cG_xml包中的实用程序objdiff 来比较对象文件。  如果您在解释输出时遇到问题,请将其发布在此处。  一旦我们知道差异的原因,可能的解决方案通常会变得清晰。

    谢谢,此致,

    -George

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

    您好,

    已安装2.50 .........00软件包,但...

    不能让objdiff工作,如果我理解正确,应该以某种方式将对象转换为XML,而'objdiff可能能够自动或通过某些选项执行该操作,并且您可以在不安装任何perl材料的情况下使用这些.exe文件...

    C:\Program Files (x86)\Texas Instruments \CG_xml\bin>objdiff.exe SL_init.obj SL_init1.obj
    正在处理SL_INIT.OBJ...

    行1的格式不正确(无效标记),列0,字节0在XML/Parser.pm行187处。

    我还尝试了"-ofd6x","-ofd"和"ofd6x",但没有帮助,第一个被忽略,结果与上面相同,后一个则抛出错误:
    ""ofd6x""不能识别为内部或外部命令,
    可操作程序或批处理文件。
    运行“ofd6x”失败,在script/objdiff.pl行544停止。

    示例显示:

       % perl objdiff.pl file1.obj file2.obj ofd6x


    objdiff.htm中还提到'ofd6x'可用于任何目标,并且无法找到其他目标选项...

    如果ofd6x是编译器(当然,i尚未安装,也不在PATH中),我还尝试给arm c编译器提供CCS使用的编译器,但这没有帮助:
    C:\Program Files (x86)\Texas Instruments (cg_xml\bin) objdiff.exe SL_init.obj SL_init1.obj "C:16.3 /ti/ccsv6/tools/compiler/ti-CGT-arm_arm.0.sts/bin/armcl"
    正在处理SL_INIT.OBJ...
    >>警告:不支持-x2 (改用-O<n>)
    >>警告:指定了目标文件,但未启用链接
    >>错误:无源文件,无任何操作
    文件不存在: 在XML_TI_OFD.pm第877行。

    该错误与尝试使用“getting started”C:\>ofd6x -x -o=file.xml file.out中的指令运行编译器非常相似
    C:\Program Files (x86)\Texas Instruments (cg_xml\bin>"C:/ti/ccsv6/tools/compiler/ti-CGT-arm_arm.0.sts/bin/armcl" 16.3 -x --output_file=init.xml SL_init.obj
    >>警告:不支持-x2 (改用-O<n>)
    >>警告:指定了目标文件,但未启用链接
    >>错误:无源文件,无任何操作


    还试图从armcl指令中查找xml,以防我不得不手动执行XML,但发现的只是“xml_link_info”,但也不能从中得到任何信息
    C:\Program Files (x86)\Texas Instruments (cg_xml\bin>"C:/ti/ccsv6/tools/compiler/ti-CGT-arm_arm.0.sts/bin/armcl" 16.3 -xml_link_info=init.xml sl_init.obj
    错误:选项-x (#)的参数超出范围

    C:\Program Files (x86)\Texas Instruments (cg_xml\bin>"C:/ti/ccsv6/tools/compiler/ti-CGT-arm_arm.0.sts/bin/armcl" 16.3 -x -xml_link_info=init.xml SL_init.obj
    >>警告:不支持-x2 (改用-O<n>)
    错误:选项-x (#)的参数超出范围

    C:\Program Files (x86)\Texas Instruments:CG_xml\bin>"C:/ti/Ccsv6/tools/compiler/ti-CGT-arm_arm.0.sts/bin/armcl" 16.3 -x0 -xml_link_info=init.xml SL_init.obj
    >>警告:不支持-x0 (使用-pn和-pi)
    错误:选项-x (#)的参数超出范围

    C:\Program Files (x86)\Texas Instruments (cg_xml\bin>"C:/ti/ccsv6/tools/compiler/ti-CGT-arm_arm.0.sts/bin/armcl" 16.3 -x=0 -xml_link_info=init.xml SL_init.obj
    >>警告:不支持-x0 (使用-pn和-pi)
    错误:选项-x (#)的参数超出范围

    因此,很可能至少-x不是任何形式的正确选项...

    我必须放弃,因为老实说,我不知道该如何使用cG_xml或如何正确使用它...

    我将在这里放置一组具有该"数字更改"的对象,如果这样可以加快流程,或者我需要有关如何使用cG_xml的更详细说明。
    e2e.ti.com/.../objects.zip

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

    我在C6x编译器上遇到同样的问题。
    我不知道它是否适用于您的版本,但在我看来,差异可能由两个主要因素造成:
    1.文件名,包括在ELF符号表中:编译器生成一个临时文件名(伪文件名,我猜是假的,因为它看起来像UUID),在每次编译时都会更改
    2.调试信息,有时包含一些附加的TI保留的dwarf属性,每次编译时都可能更改

    要解决ELF文件名问题,请尝试使用汇编器选项“--keep _asm”。 在这种情况下,编译器使用扩展名为“.asm”的源文件名作为文件名

    要解决调试信息问题,请尝试生成不带调试信息的信息。 当然,此选项有问题,因为您无法再看到有关库的调试信息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的参与! 我稍后会标记您的答案"建议/验证的答案",但不要这样做 ,因为您的"输入1"看起来可以解决链中的第一阶段,因此不会显示问题已解决。

    因此,问题现已得到部分解决。 “--keep _asm”是关键 字(GUI中也有此项的设置),它使c对象保持不变。

    但是... 生成的库看起来仍会更改。

    在库中的每个对象名称之后都有类似的"数字更改"(以前没有查看库中实际更改的位置)。 此库中共有8个对象。 而差异总是在ASCII数字的对象名称之后

    第一个差异:

    638c1f6fd78f79ae9e1b1.205万b9faa77.SL_ASM_API.obj/ 1505292304 0     

    638c1f6fd78f79ae9e1b1.205万b9faa77.SL_ASM_API.obj/ 1505292248 0     

    第二个差异(请注意,数字增加了1)
    SL_ESM.OBJ/    1505292305 0    0

    SL_ESM.OBJ/    1505292249 0    0

    ....

    ....


    Eigth (和Last) Difference (最大差值)
    SL_selftest.obj/1505292311 0     

    SL_selftest.obj/1505292256 0     


    因此,这些数字看起来与以前在对象文件中的“伪数字”相似。 归档程序实际上没有任何可配置的GUI选项?


    稍微后退一点,然后再创建库,而不使用--keee_asm来真正查看库中最初的差异->库之间有更多的更改,就像现在使用--kee_asm一样,以前也有这种更改,现在使用--keee_asm就可以消失
    182.761万.ESM_AppCallback


    228.161万.ESM_AppCallback


    260.641万.$C$L1.$C$L2

    295.721万.$C$L1.$C$L2

    所以这些数字很可能是来自已更改的对象文件的数字。  除此之外,正如本文开头所述,目标文件名后面的数字也有类似的区别,因此--keeed_asm可以消除从目标文件继承的库中的差异,但库构建本身有一些类似的“数字”...

    PS。问题不是调试信息。 我已经启用了两个版本,在发行版本版本(--symdebug:none)上也可以看到这个问题 ,在该版本中,对象大小大大缩小,这表明缺少-g确实有影响,输出没有调试。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,
    如果运行归档程序以打印目录(对于C6x,为ar6x t <libname>),您可能会看到它还存储文件日期。 据我所知,这方面没有解决方法。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,

    是的,我可以确认"armar t <libname>"显示每个文件的日期和时间,因此很可能是它的差异。

    如果时间戳存储可以被某种方式阻止,您猜是否必须等待TI员工输入此信息? 在编译和归档之间修改目标文件的日期和时间信息-如果可能的话,很可能是:)?

    如果不可能,是否有一种比较库的简单方法来确定2 lib之间的实际内容(说话代码行为)是否相同, 因为现在每次编译库时,版本控制都会声明它已被更改,这种日期和时间更改将被忽略,因为它没有任何功能效果?

    实际上,如果必须使用已更改的库,则问题可以通过-keep _arm选项来简化:是否有一种方法可以轻松地从库中查看,这是库中文件的唯一不同日期和时间信息?

    这种差异可能涉及一些手动工作/脚本输出解释,因为我们已将库的一个版本存储到版本控制,并且存储的版本将用于构建自动化, 因此,只有在手动编译库的情况下才需要进行区分-如果只更改了日期和时间戳,那么您就会立即知道,如果库“无用”,则需要重新编译,并且不需要确定新版本的库是否应实施版本控制。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我将你的情况分为两个相关问题。  这两个问题的初始条件相同。  源代码,编译器版本,生成选项,生成方法等都相同。  比较多个版本。 1.为什么生成的目标文件不同?  2.为什么生成的库不同?  在这篇文章中,我只回答目标文件问题。

    汇编程序插入一个符号,该符号的名称与源文件的名称相同。  使用默认设置进行编译时,将自动生成此文件的名称,因此在不同的版本之间会有所不同。

    \n一个对象文件的比较:
    ...151.521万.$C$L1.$C$L2.$C$L3.$C$

    ...126.0818万.$C$L1.$C$L2.$C$L3.$C$[/报价]

    在第一个内部版本中,文件名称为 151.521万,在第二个内部版本中,文件名称为  126.081万。 符号名称的字符串存储在字符串表中。  字符串表包含许多空终止的字符串,一个在下一个之后。  您的第一篇文章中的这句话显示了字符串表的开头。  此文件名符号的条目恰好位于字符串表的开头。  在版本16.3 .0.STS中,此自动生成的文件名有七个数字。  在更高版本中,此文件名是一个更长的UUID (通用唯一标识符)。

    正如您所发现的那样,使用--keep _asm (或-k)进行构建可以避免使用自动生成的名称,从而避免出现此问题。  这将在短期内解决这个问题。  但这不是一个长期的解决办法。

    TI从未记录过具有相同条件的多个版本将产生位相同的目标文件。  我们不会测试它。  因此,依靠它是不明智的。

    Jarkko Silvasti 说:
    当库存储在版本控制中且声称已更改时,更改会导致恼人的问题[/QUOT]

    我怀疑这是您想要解决的核心问题。  是这样吗?  请考虑另一种方法。  不要将对象库保留在版本控制中,而是保留源代码,生成脚本,编译器和构建中使用的任何其他工具。  这样,您就可以根据需要可靠地重新创建库。  所有这些神器都是完全由你控制的。  近期内您不太可能更改此方法。  因此,请考虑在下一个项目中使用它。

    谢谢,此致,

    -George

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

    [引述用户="George mock"]

    TI从未记录过具有相同条件的多个版本将产生位相同的目标文件。  我们不会测试它。  因此,您依赖它是不明智的。[/QUOT]

    [引述用户="George mock"]

    我怀疑这是您想要解决的核心问题。  是这样吗?  请考虑另一种方法。  不要将对象库保留在版本控制中,而是保留源代码,生成脚本,编译器和构建中使用的任何其他工具。  这样,您就可以根据需要可靠地重新创建库。  所有这些神器都是完全由你控制的。  近期内您不太可能更改此方法。  因此,请考虑在下一个项目中使用它。

    [/引述]
    是的,您对我的"问题"是正确的,我最初只是因为对象文件而更改了库,但我错了。 我们当然拥有版本控制中的所有源文件和CCS工作室项目文件,但由于我们正在执行IEC6.1508万项目,该项目高度依赖库真正实现其声称的功能(基本上,我们如何向我们的认证合作伙伴证明库的使用/测试合理性) 为此,我认为每次编译库都是不可行的,甚至是不可能的,特别是因为我们不使用TI工具来实现最终产品输出,也不打算认证TI工具链,我认为如果需要,我们将需要认证 每次为产品编译代码时,请使用库的“新版本”。

    因此,我认为将库的"已测试/已验证"副本存储到版本控制中并将其用于版本控制是更安全/合理的(并且更容易证明库的安全性)。

    尽管如此,我有几个选项可以"证明"库中的功能没有改变。

    1)我认为修改目标文件的日期和时间戳是一种方法(在UNIX/cygwin "touch -r"中,将黄金文件与CCS项目文件一起存储并使用该文件),以防使用-kee_arm,并且它适用于某些编译器版本

    这应该提供一对一的库,还是会提供?
    如果是,那么是否可以在编译器和归档文件之间添加构建步骤来处理文件名? 看起来不是这样,但可以通过将任何部分留空并在处理文件后在生成后执行该存档来圈出。 也许这个问题应该在CCS论坛中提出,如果我知道我的选择是什么,尤其是2)可行且对我们的使用足够好,我会这样做,以防这是错误的。

    2)由于1是相当容易的,我看到的另一个选项是重新编译库的人员能够"轻松"确定库中是否存在真正的功能更改或外观更改。 我想这是可以实现的,方法是使用一些"对象"工具来查看库中的内容,并将该输出与存储在版本控制中的库的输出进行比较, 但是,由于这不是我的主要能力领域,如果我能获得一些指示器,我将非常感激,我应该寻找什么工具(以及该工具的首选选项)。

    示例2中的目标)只是帮助设计人员注意到库是否确实更改(基本上,任何其他更改都可以假定为库中对象文件的实际更改预期日期和时间)。 例如,标头中有一些可配置选项,这些选项可能不会影响对象输出,这取决于其他选项的配置方式,或者库将被重新编译,因为您更改了存储库中的分支,并且源文件的时间戳发生了更改等。 如果库未真正更改,则无需执行进一步操作,但如果库更改,则我们需要采取适当的操作,以防我们想要将新版本引入产品。

    提前感谢。

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

    Jarkko Silvasti 说:
    我们正在实施功能安全IEC6.1508万项目[/QUOT]

    对此,请理解,我正努力在帮助与不允许TI承担您项目的任何责任之间走一条很好的线。  这就是为什么我的一些答案不是绝对意义上的措辞,而是有点规避。

    Jarkko Silvasti 说:
    为此原因,我发现将库的"经过测试/验证"的副本存储到版本控制中并在版本中使用,这种做法更安全/合理(并且更容易证明库的安全性)。

    我对您拒绝我关于版本控制中应保留哪些内容的建议没有任何问题。  请记住,其他客户会阅读这些线程。  这一建议可能对其他人有用。

    关于库... 我确认每个文件的操作系统分配的日期戳都存储在库中。  这就是您在构建时看到的不同之处,否则,这些构建将以相同的输入开始。

    [报价用户="Jarkko Silvasti"]

    1)我认为修改目标文件的日期和时间戳是一种方法(在UNIX/cygwin "touch -r"中,将黄金文件与CCS项目文件一起存储并使用该文件),以防使用-kee_arm,并且它适用于某些编译器版本

    这应该提供一对一的库,还是会提供?

    [/引述]

    应该这样做。  也就是说,我不知道有其他客户使用这种方法。

    Jarkko Silvasti 说:
    是否可以在编译器和归档文件之间添加构建步骤来处理文件名称?[/QUOT]

    您是否使用CCS构建?  CCS支持自定义构建后步骤。  请参阅 文章 “CCS项目和构建手册”中的“构建前和构建后步骤”部分。  注意:本文重点介绍如何生成可执行文件,而不是库。  但我认为图书馆的大多数信息都是正确的。

    Jarkko Silvasti 说:
    2)因为1是个很小的问题[/QUOT]

    同意。

    [引用user="Jarkko Silvasti)]我看到的另一个选项是,重新编译库的人员能够"轻松"确定库中是否存在真正的功能更改或外观更改。 我想这是可以实现的,方法是使用一些"对象"工具来查看库中的内容,并将该输出与存储在版本控制中的库输出进行比较[/QUOT]

    我在前面的文章中提到的objdiff实用程序可以做到这一点。 由于您很难使用它,以下是一些使用提示。

    典型的调用类似于...

    objdiff file1 file2 armofd.

    objdiff来自cG_xml包的\bin目录。 armofd来自编译器的\bin目录。  确保这些目录位于您的系统路径中,或提供可执行文件的完整目录路径。  这两个文件可以是目标文件,可执行文件或库。  它会自动确定哪些,并相应地进行比较。  默认情况下,将忽略符号,调试信息和其他元数据。   如果您愿意,可以查看Perl源代码。  它位于cG_xml包的\ofd目录中。  文件名为objdiff.pl。

    谢谢,此致,

    -George

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

    您好,谢谢!

    这种"objdiff file1 file2 armofd"产生了所需的结果,并且脚本在分发库时显示"文件相同",因此脚本也很容易自动检查是否有真正的更改。 我猜测我的初始"手臂"是错误的工具...

    我会将答案标记为已验证。