在我们的源文件中,我们通常有一个类似的版本字符串:
static const char srcvers[] = "VERSION/foo.c/1.01/09.04.15";
Run Code Online (Sandbox Code Playgroud)
当该字符串未被优化时,它在某些情况下非常有用,因为可以通过简单地调用来确定链接到可执行文件的每个源文件的版本strings a.out | grep VERSION
.
不幸的是,它被 gcc优化(使用'-O').所以我的问题是,是否有一种简单的方法(编译器开关会很棒)使gcc保持该变量(其名称始终相同)而不关闭任何其他优化.
编辑
在我看来,这个问题与那个不同的是,我希望找到一个解决方案,我不必触及成千上万的源文件.
Dog*_*ert 28
您可以使用__attribute__((used))
gcc(也可以在clang中工作)特定(我看到问题已标记gcc
)属性:
附加到函数的此属性意味着即使看起来函数未被引用,也必须为函数发出代码.例如,仅在内联汇编中引用该函数时,这很有用.
来自https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
演示:
$ cat a.c
static const char srcvers[] __attribute__((used)) = "VERSION/foo.c/1.01/09.04.15";
$ gcc -O3 -c a.c
$ strings a.o
VERSION/foo.c/1.01/09.04.15
Run Code Online (Sandbox Code Playgroud)
你可以使用一些#if
s和#define
s来制作这个terser,也可以在不支持这个扩展的编译器上编译.
据我了解您的问题,您需要在不触及源的情况下将版本字符串添加到每个目标文件.它可以使用下一种方式完成.
创建头文件,例如include/version.h
:
#ifndef VERSION_H
#define VERSION_H
static const char _ver[] __attribute__((used)) = "VERSION/foo.c/1.01/09.04.15";
#endif /* VERSION_H */
Run Code Online (Sandbox Code Playgroud)
然后在你的Makefile
(或任何你的构建系统)添加下一个gcc
标志:
CPPFLAGS += -include include/version.h
Run Code Online (Sandbox Code Playgroud)
当然应该传递给gcc
,例如:
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).c
Run Code Online (Sandbox Code Playgroud)
现在您可以观察_ver
编译到每个目标文件的字符串:
$ objdump -DS src/main.o | grep _ver
Run Code Online (Sandbox Code Playgroud)
哪个会告诉你这样的事情:
Disassembly of section .rodata._ver:
00000000 <_ver>:
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
16069 次 |
最近记录: |