【问题标题】:Undefined linker symbol at runtime when the symbol equals zero当符号等于零时,运行时未定义的链接器符号
【发布时间】:2013-12-12 18:22:57
【问题描述】:

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

在我的 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时,结果如下:

./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 表达式?
  • 我做错了什么?
  • 有没有更好/更简单的方法来实现这一点?

【问题讨论】:

    标签: c linker makefile undefined-symbol


    【解决方案1】:

    如果你想使用

    gcc -D__VERSION_MIN=0
    

    那么你必须从你的头文件中删除定义

    extern char __VERSION_MIN;
    

    gcc -D__VERSION_MIN=0
    

    相当于在你的c代码中定义__VERSION_MIN为宏

    #define __VERSION_MIN 0
    

    然后你不能在你的 C 代码中定义 __VERSION_MIN 两次

    extern char __VERSION_MIN;
    #define __VERSION_MIN 0
    

    这是不允许的

    所以如果你想使用

    gcc -D__VERSION_MIN=0
    

    那么你必须从你的代码中删除extern char __VERSION_MIN;

    【讨论】:

    • 谢谢 - 是的,如果我使用 -D 替代方案,那么我确实会删除其他定义(事实上,我只会做 -D__VERSION=\"1.0\" 并将其用作字符串文字)。
    猜你喜欢
    • 2023-03-13
    • 2013-10-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    相关资源
    最近更新 更多