gcc是否有选项可以在ELF二进制文件中添加版本信息?

24

我是指gcc是否可以将一些源代码版本信息插入ELF二进制文件中,例如作为一个段(section)或类似的方式。 我不想改变我的源文件,而是想在Makefile中使用gcc选项来添加一些信息。

4个回答

11

如果您不介意更改源文件一次,可以添加类似以下内容:

const volatile static char version[] = VERSION;

使用以下命令编译:

gcc -c -DVERSION='"1.2.3"'

volatile关键字可以防止gcc在高优化级别下删除字符串。

按照现有的写法,如果你忘记使用-D选项,代码将无法编译。这取决于你的需求,可能是好事也可能是坏事。


你如何从Linux命令行或Bash脚本中读取这个版本代码?谢谢。 - George
@George,没有直接的方法可以做到这一点。version字符串应该在可执行文件中的某个地方,但你不知道在哪里。一个可能的方法是添加一些可以搜索的唯一字符串(但这假设该字符串不会出现在其他地方)。 - Keith Thompson

7
即使您无法再访问源代码,也可以使用此选项链接对象:
gcc -Wl,--defsym,VERSION_1_2_3=0 prog.o -o prog

您可以使用命令 hexdump -C prog | less 进行检查,并查找 VERSION


将此代码添加到您的 makefile 中,确保始终了解程序的编译时间:

BUILD = $(shell date +"%Y%m%d_%H%M%S")
LDLIBS = -Wl,--defsym,BUILD_$(BUILD)=0

7
您可以将版本信息输出到文本文件中,然后将该文本文件转换为目标文件,再将其静态链接到可执行文件中。
第一步很简单,但您需要编写一些代码:一个脚本或其他内容,以任何您喜欢的格式将版本信息作为纯文本文件编写。然后编写一个makefile规则,使用objcopy从version.txt生成version.o。现在您将拥有一个包含两个有用符号的目标文件:文本版本信息的开始和结束。将该生成的目标文件添加到可执行文件中,您将能够通过两种方式访问版本:通过在二进制文件上运行strings,或通过在应用程序中编写代码来打印版本字符串(您需要在某个头文件中声明开始和结束符号作为变量)。

4
谢谢。我发现用objcopy有更好的方法:objcopy --add-section versection=version_text main main_version。然后可以使用命令"objdump -s -j versection main_version"来获取版本信息。 - Lane
2
嗨 John,我看到你是一个活跃的成员,即使这个答案已经过时了。你可以更新一下它,并提供一些非常基本/简单的编译文本文件为对象的示例吗?比如说“版本1.1.1”之类的东西。这正是我要问的问题,呃,这可能是个“重复”的问题… - DrBeco
1
@DrBeco:在Linux上,您可以使用objcopy并显式指定--input binary--output格式。这里有一个完整的教程:http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967。您还可以使用`ld`和一些选项,我认为是`-b`来完成相同的事情,根据您的具体情况可能更容易。 - John Zwinck

2
使用GNU链接器ld,您可以使用以下内容:
--version-script=version-scriptfile

了解命令行选项的更多信息,请访问: 使用GNU链接器LD - 选项

了解创建版本脚本的更多信息,请访问: 使用GNU链接器LD - 版本脚本

但要提醒您,这不是给心脏脆弱的人看的!


3
版本脚本的用途不仅仅是记录编译器设置,还有其他用途。 - o11c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接