【问题标题】:gcc fails with "undefined reference" in Cygwin, but the reference exists in a linked librarygcc 在 Cygwin 中因“未定义引用”而失败,但引用存在于链接库中
【发布时间】:2015-05-17 20:45:53
【问题描述】:

我在 Cygwin 中构建并安装了 libmarpa,最终结果位于 /usr/local/lib/libmarpa.a

我有一个简单的文件:

#include "libmarpa/dist/marpa.h"

int main() {
  return marpa_check_version(8, 3, 0);
}

但是链接器找不到marpa_check_version:

$ gcc test.cc -L/usr/local/lib -lmarpa
/tmp/ccdYM1vV.o:test.cc:(.text+0x1e): undefined reference to `marpa_check_version(int, int, int)'
/tmp/ccdYM1vV.o:test.cc:(.text+0x1e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `marpa_check_version(int, int, int)'
collect2: error: ld returned 1 exit status

但是符号作为函数存在:

$ nm /usr/local/lib/libmarpa.a | grep marpa_check_version
0000000000002780 T marpa_check_version

那么这里发生了什么?尝试在 Cygwin 中执行此操作是否有问题,还是我错误地调用了 gcc?

【问题讨论】:

  • 你能试试 1) 在 tst.c 中重命名 tst.cc 2) 用这个命令行编译:gcc tst.c /usr/local/lib/libmarpa.a
  • 您可以尝试检查几件事。首先,确保您链接的库确实与您的构建目标在同一平台中(x86 与 x64 或反之亦然,显然不会很好地结合在一起)。其次,尝试在源文件之前传递您的库和库位置。第三,可能是一个错位的名字? (gcc 专门用三个int 参数调用了一个缺少的函数,所以也许有人在某个关键的地方忽略了extern "C",或者该库仅适用于 C 客户端?
  • @WhozCraig @ouah 我认为你们都是对的,谢谢。我最初试图编译 C++,然后切换到 gcc,认为这会导致编译为 C,没有意识到文件名结尾决定了文件的处理方式。编译“test.c”,编译“test.cc”并在头文件周围添加extern "C" { }
  • 您可以使用-x 告诉gcc 忽略扩展并使用特定语言:gcc -x c test.cc -L/usr/local/lib -lmarpa

标签: c gcc linker


【解决方案1】:

这个符号:

undefined reference to `marpa_check_version(int, int, int)'

是 C++ mangled。这个符号不是:

0000000000002780 T marpa_check_version

问题是marpa.h 的开发人员没想到他们的代码会被C++ 使用,并且没有为此设置适当的保护措施。您可以像这样解决问题:

extern "C" {
#include "libmarpa/dist/marpa.h"
}

int main() { ...as before ...

附:您还应该更改命令行以使用g++ 而不是gcc。与流行的看法相反,它们不是相同的东西。

【讨论】:

  • 我实际上是在 尝试 使用 gcc,认为它会简化我的问题。但我没有意识到 gcc 仍然会将“test.cc”视为 C++ 文件。因此,将文件重命名为“test.c”是可行的,就像使用 g++ 的外部“C”链接一样(这是我想要的)。
猜你喜欢
  • 1970-01-01
  • 2020-04-11
  • 2017-03-15
  • 2011-12-08
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
  • 2022-12-07
  • 1970-01-01
相关资源
最近更新 更多