我正在努力使GHC Haskell编译器的编译100%可重复(字节相同)。
目标文件已经是字节相同的,但最终的链接二进制文件不是。
GHC将最终链接委托给gcc
,如:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -o Main Main.o [..some more files..] /tmp/ghc21220_0/ghc21220_5.o /tmp/ghc21220_0/ghc21220_7.o [...] '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads
有趣的是,临时文件ghc21220_7.o
的文件名出现在链接的二进制文件中。
似乎我可以使用strip
工具删除它。
为什么文件名出现在那里,它的目的是什么?
是否有标志告诉gcc
(或者ld
?)不包含这些文件名?
更新:如果我在二进制文件上运行objdump --syms
,我会看到
0000000000000000 l df *ABS* 0000000000000000 ghc21220_5.c
0000000000000000 l df *ABS* 0000000000000000 ghc21220_7.c
根据this d
表示调试,f
表示文件。我的问题仍然存在:为什么以及如何将.c
文件命名为最终二进制文件的文件名,我可以在编译时抑制它(而不是稍后运行strip
)?
答案 0 :(得分:3)
源文件名在可执行文件中显示为符号,因为GCC在发出汇编时所做的第一件事就是将.file
指令写入输出。汇编器然后将其转换为目标文件中的符号,链接器将所有其他符号放入可执行文件中。我不确定它是否有用,但它可能允许链接器提供源文件名而不是错误的目标文件名。
如果没有修改代码,那么就无法阻止GCC生成.file
指令或阻止汇编程序将它们转换为目标文件中的符号。您可以使用-x
选项告诉链接器不要将它们包含在可执行文件中,该选项告诉它剥离所有本地符号。
另一个更有针对性的选择是使用strip
命令从目标文件中仅删除文件名符号:
strip -N ghc21220_5.c ghc21220_5.o
最后,您可以选择在C源文件相同时为其提供相同的名称。最终,您选择的文件名是您在可执行文件中看到的差异的来源。