qwe*_*iop 6 linker symbols c++11
试图编译这个cfgparser示例.
$ g++ example.cc -lcfgparser
: In function `main':
example.cc:(.text+0x6b): undefined reference to `ConfigParser_t::readFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
example.cc:(.text+0x160): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0x2d9): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int*) const'
example.cc:(.text+0x43c): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double*) const'
example.cc:(.text+0x5b1): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool*) const'
example.cc:(.text+0x78c): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*) const'
example.cc:(.text+0xa15): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0xba2): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0xd15): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0xe7f): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
collect2: error: ld returned 1 exit statu
Run Code Online (Sandbox Code Playgroud)
但显然那些符号在那里:
$ nm -gC /usr/lib/libcfgparser.so
000000000003710 T ConfigParser_t::readFile(std::string const&)
0000000000004880 T ConfigParser_t::ConfigParser_t(std::string const&)
00000000000024c0 T ConfigParser_t::ConfigParser_t()
0000000000004ad0 T ConfigParser_t::ConfigParser_t(std::string const&)
00000000000024a0 T ConfigParser_t::ConfigParser_t()
0000000000004d20 T ConfigParser_t::getOptions(std::string const&) const
00000000000028d0 T ConfigParser_t::getSections() const
0000000000002ff0 T ConfigParser_t::getValue(std::string, std::string, bool*) const
0000000000002de0 T ConfigParser_t::getValue(std::string, std::string, double*) const
0000000000002bd0 T ConfigParser_t::getValue(std::string, std::string, int*) const
00000000000027d0 T ConfigParser_t::getValue(std::string, std::string, std::string*) const
0000000000003500 T ConfigParser_t::getValue(std::string, std::string, std::vector<std::string, std::allocator<std::string> >*) const
Run Code Online (Sandbox Code Playgroud)
与SO上的其他类似问题不同,这不是关于链接顺序,因为只有一个目标文件被链接.我错过了什么?
Mik*_*han 13
但显然那些符号在那里:
显然,他们不是.仔细研究一下,您将看到链接器报告的未定义签名和库中报告的签名之间没有匹配
nm
.
标准头<string>
定义std::string
为typedef:
std::basic_string<char, std::char_traits<char>, std::allocator<char>>
Run Code Online (Sandbox Code Playgroud)
<string>
从cxx11 ABI(GCC 4.7.0)开始的GCC实现定义std::string
为typedef:
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>
Run Code Online (Sandbox Code Playgroud)
该std::__cxx11
命名空间封闭类型其二进制实现都符合cxx11 ABI.
该类型定义意味着包含标准头的C++转换单元<string>
将不会使用GCC> = 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
在
cfgparser Sourceforce项目
(这是最后一次更新三年前).我想这是因为我得到了与example.cc
该软件包安装的库相关联的相同程序的链接错误.
错误的解释通过以下方式揭示:
/usr/lib$ strings -a libcfgparser.so | grep "GCC: ("
GCC: (Debian 4.3.2-1.1) 4.3.2
...
Run Code Online (Sandbox Code Playgroud)
这告诉我们这个库是用GCC 4.3.2构建的 - 在cxx11 ABI之前.
将std::string
出现在你的nm
输出的cxx11预demangling缩写std::basic_string<char, std::char_traits<char>, std::allocator<char>>
.
这libcfgparser.so
与您当前的GCC ABI不兼容,因此您无法将其与使用该编译器构建的程序链接.你可以做的是libcfgparser
从源包构建libcfgparser-1.1.2.tar.bz2
,使用当前的编译器,然后将你的程序链接到你自己构建的库.
这是有效的,但不是毫不费力的.首先,您需要修复源包的损坏和过时的自动调整以创建工作./configure
脚本.
这并没有给出包装维护人员熟练程度的令人安心的印象.此外,该软件包的源代码(2008版权所有)具有业余品质.如果你所追求的是INI风格文件的C++解析器,那么boost::property_tree::ini_parser
将是goto解决方案.看到这个答案