链接器找不到符号,但它们在那里?

时间:2016-12-14 03:07:51

标签: c++11 linker symbols

尝试编译此cfgparser example

{{1}}

但显然那些符号在那里:

{{1}}

与SO上的其他类似问题不同,这不是关于链接顺序,因为只有一个目标文件被链接。我错过了什么?

1 个答案:

答案 0 :(得分:13)

  

但显然那些符号在那里:

显然,他们不是。仔细看看,你会看到 您报告的签名之间没有匹配项 链接器未定义,以及从库中报告的链接器 nm

标准标题<string>std::string定义为typedef:

std::basic_string<char, std::char_traits<char>, std::allocator<char>>

<string>的GCC实施,cxx11 ABI(GCC 4.7.0) 将std::string定义为typedef:

std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>

std::__cxx11名称空间包含二进制实现的类型 符合cxx11 ABI。

该类型定义意味着包含标准标题<string>的C ++翻译单元不会 使用GCC&gt; = 4.7编译为包含符号解析为std::string的符号的对象代码。

如果二进制文件(例如libcfgparser.so - 包含一个符号为std::string的符号),那么 无论该符号在构建它的源中引用了什么,它都没有引用 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, 并且不能与使用std::string的定义编译的其他二进制文件链接。

libcfgparser.so是由libcfgparser0_1.1.2_amd64.deb安装的example.cc cfgparser Sourceforce project (三年前最后更新)。我想这就是我的事实 使用与该软件包安装的库链接的相同/usr/lib$ strings -a libcfgparser.so | grep "GCC: (" GCC: (Debian 4.3.2-1.1) 4.3.2 ... 程序获取链接错误。

错误的解释通过以下方式揭示:

std::string

告诉我们这个库是用GCC 4.3.2构建的 - 在cxx11 ABI之前。

nm输出中显示的std::basic_string<char, std::char_traits<char>, std::allocator<char>>是前cxx11 demangling缩写 libcfgparser.so

libcfgparser与您当前的GCC ABI不兼容,所以您 无法将它与您使用该编译器构建的程序链接。你能做的是 从源包libcfgparser-1.1.2.tar.bz2构建./configure, 使用当前的编译器,然后将程序与您拥有的库链接 建立自己。

这有效,但不是毫不费力。首先,你需要修复破损 和源代码包的过时自动调整以创建一个有效的{{1}} 脚本。

这并没有给出包维护者熟练程度的令人安心的印象。 此外,该软件包的源代码(2008版权所有)具有业余品质。如果 你所追求的是INI风格文件的C ++解析器,然后是boost::property_tree::ini_parser 转到解决方案。见this answer