【问题标题】:Undefined reference to symbol on a static library对静态库上符号的未定义引用
【发布时间】:2025-12-31 09:10:06
【问题描述】:

我正在尝试编译将其与静态库 libfoo.a 链接的二进制文件:

gcc -L. -o myapp myapp.o -lfoo

但我从链接器收到以下错误:

libfoo.c:101: undefined reference to `_TRACE'

问题是我没有 libfoo.a 库的源代码。 我试图在库中获取_TRACE 符号的参考,我得到了这个:

nm libfoo.a | grep TRACE
    U _TRACE

假设_TRACE 不会影响libfoo.a 中的内部工作,是否可以让链接器为这个符号定义一些占位符值以便我可以编译我的代码?

【问题讨论】:

    标签: c gcc linker linker-errors undefined-symbol


    【解决方案1】:

    假设_TRACE不会影响libfoo.a的内部工作

    这似乎是一个不合理的充满希望的假设。

    是否可以让链接器为这个符号定义一些占位符值,以便我可以编译我的代码?

    首先要做的是检查libfoo 的文档。静态库依赖于用户期望定义的符号是不寻常的。事实上,这样的安排与传统的链接器并不能完全兼容。我看到了几个似是而非的解释:

    1. 您需要在libfoo 之后链接一些其他(特定)库以提供该符号的定义。

    2. 使用libfoo 的代码应为#include 关联的标头,并且该标头提供_TRACE 的暂定定义。

    3. 使用libfoo 的程序需要使用特定的工具链和特定的选项来构建。

    4. 刚刚坏了。

    仅在情况 (4) 中尝试手动提供相关符号的定义是合适的,在这种情况下,您最好的选择是或多或少地按照情况 (1) 进行,通过构建一个对象提供定义并在库之后链接它。当然,这会让您尝试猜测定义应该是什么。

    如果_TRACE 是一个全局变量,那么即使库需要不同大小的整数或具有不同符号的整数,将其定义为初始值为0 的intmax_t 也可能有效。但是,如果它应该是一个函数,那么你可能会干杯。它可能有太多的签名,对行为有太多可能的期望。没有理由认为您可以提供合适的占位符。

    【讨论】:

    • 如果 intmax_t _TRACE = 0; 不起作用,int _TRACE(){ return( 0 ); } 可能就像 _TRACE 可能是一个没有正确定义的宏,所以它默认为返回 int 的隐式定义函数.我怀疑我是否会相信这样一个图书馆有任何重要的东西,但是,如果这些恶作剧是让它甚至链接所需要的。
    • 我最初的想法是类似于 #define _TRACE 只是为了编译。我的假设是 _TRACE 是一个打印调试信息的函数,因此占位符就可以了。我想知道这是否可能。
    • @Gustavo - 你是在编译libfoo.a,还是只有静态库本身?
    • 我只有静态库本身。我不打算生成可靠的二进制文件。我知道这可能会导致严重的问题,我只是想知道这是否可能。
    • @Gustavo,链接器看不到宏。它们在您的代码编译之前被扩展,更不用说链接了。要满足链接中未定义的符号,您需要链接到包含该符号的适当定义的目标文件。
    【解决方案2】:

    正如我所怀疑的,_TRACE 函数是一种调试函数。我假设它不会影响libfoo.a 的内部运作是正确的。

    我解决了将_TRACE 函数定义为的问题:

    int _TRACE(char*, ...) { return 0; }
    

    当然,这个解决方案只是暂时的,不能在生产中使用,但它符合我编译代码的目的。

    【讨论】:

      【解决方案3】:

      如果您使用的是 GCC 5.1 或更高版本和/或 C++11,则有一个 ABI change

      您可以使用nm -C 发现此问题:如果已定义符号(不是U)但附加了[abi:cxx11],则它是使用新的ABI 编译的。从链接:

      如果您收到有关未定义符号引用的链接器错误,这些符号涉及 std::__cxx11 命名空间或标签 [abi:cxx11] 中的类型,则可能表明您正在尝试将使用不同值编译的目标文件链接在一起_GLIBCXX_USE_CXX11_ABI 宏。

      如果您可以访问源代码(不是您的具体情况),您可以使用-Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0,后者会强制编译器使用新的 ABI。 您的所有代码(包括库)都应该是一致的。

      【讨论】: