符号等于零时,运行时未定义的链接器符号

时间:2013-11-27 08:03:16

标签: c linker makefile undefined-symbol

我正在尝试使用链接符号在我的可执行文件中自动设置版本号,只要符号未设置为零,它似乎就可以工作......

在我的C代码中:

extern char __VERSION_MAJ;
extern char __VERSION_MIN;

...

printf("Version %u.%u\n", (unsigned) &__VERSION_MAJ, (unsigned) &__VERSION_MIN);

在我的makefile中:

LDFLAGS += -Xlinker --defsym=__VERSION_MAJ=1
LDFLAGS += -Xlinker --defsym=__VERSION_MIN=0

当我尝试运行可执行文件测试

时,会得到以下输出结果
./test: symbol lookup error: ./test: undefined symbol: __VERSION_MIN

如果我按如下方式更改符号定义:

LDFLAGS += -Xlinker --defsym=__VERSION_MAJ=1
LDFLAGS += -Xlinker --defsym=__VERSION_MIN=1

然后它运作得很好:

Version 1.1

我在这里阅读了有关链接器符号的http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/Linker.pdf并搜索了谷歌,但没有发现任何说明0是自定义链接器符号的不允许值。

另外,如果我查看链接器映射输出,它确实有__VERSION_MIN:

0x0000000000000001                __VERSION_MAJ = 0x1
0x0000000000000000                __VERSION_MIN = 0x0

所以,我很难过!

我只会使用gcc -D__VERSION_MIN = 0,但是当版本发生变化时,使用先决条件重建应用程序会导致棘手和makefile丑陋(它将存储在文本文件中,而不是硬编码在makefile中如上所述。)

我正在为目标i686-linux-gnu编译和链接gcc版本4.6.3(Ubuntu / Linaro 4.6.3-1ubuntu5),如果其中任何一个有所不同。

执行摘要:

  • 是否应该允许导致0的--defsym表达式?
  • 我做错了什么?
  • 有更好/更简单的方法来实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

如果你想使用

gcc -D__VERSION_MIN=0

然后你必须从头文件中删除定义

extern char __VERSION_MIN;

gcc -D__VERSION_MIN=0

相当于将__VERSION_MIN定义为c代码中​​的宏

#define __VERSION_MIN 0

然后你无法在C代码中定义__VERSION_MIN两次

extern char __VERSION_MIN;
#define __VERSION_MIN 0

这是不允许的

所以如果你想使用

gcc -D__VERSION_MIN=0

然后您必须从代码中删除extern char __VERSION_MIN;