未定义的Boost参考

时间:2017-11-10 22:40:04

标签: c++ c++11 boost devtoolset

我正在尝试链接使用Boost的第三方库。我已经链接到了正确的boost库(libboost_program_options.a),但仍未找到它。

错误消息(为清晰起见,格式化了一点):

undefined reference to `boost::program_options::validate(boost::any&, 
                              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&, 
                              std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, 
                              int)'

nm --demangle libboost_program_options.a | grep验证

boost::program_options::validate(boost::any&,                                   std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, 
                                  bool*, 
                                  int)
 boost::program_options::validate(boost::any&, 
                                  std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, 
                                  std::string*, 
                                  int)
 boost::program_options::validate(boost::any&, 
                                  std::vector<std::string, std::allocator<std::string> > const&, 
                                  bool*, 
                                  int)
 boost::program_options::validate(boost::any&, 
                                  std::vector<std::string, std::allocator<std::string> > const&, 
                                  std::string*, 
                                  int)

第二张唱片看起来很相似,但显然还不够近。知道如何编译Boost以获得与库中的内容相匹配的签名吗?我向图书馆老板请求查看他们正在使用的Boost版本等等,但尚未收到回复。

这是在CentOS 7盒子上,它使用g ++版本4.8.5。但我试图链接的库大量使用C ++ 11并使用g ++ v 6.1编译,因此我安装了devtoolset-6,这给了我一个g ++ 6环境(g ++版本6.3.1)

我从头开始下载并构建了Boost(v1.65.1),以便它使用相同的编译器而不是系统版本构建。

编辑... 我认为John Zwinck走在正确的轨道上,但是我无法将boost库编译成新的ABI。

validate()函数位于value_semantic.cpp

将构建拆分为基础知识,并添加讨论的标记:

g++ -std=c++11 -D_GLIBCXX_USE_CXX11_ABI -c -o test.o libs/program_options/src/value_semantic.cpp

nm --demangle test.o | grep validate
00000000000008b6 T boost::program_options::validate(boost::any&, std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, bool*, int)
0000000000000c02 T boost::program_options::validate(boost::any&, std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, std::string*, int)
00000000000005f2 T boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, bool*, int)
0000000000000b9a T boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, std::string*, int)

_GLIBCXX_USE_CXX11_ABI宏仅适用于gcc 5.1吗?

3 个答案:

答案 0 :(得分:2)

您似乎在C ++ 11中与std::string的GCC Dual ABI发生冲突:https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

您的程序正在尝试使用

链接API
std::__cxx11::basic_string<char>* 

但你的Boost图书馆有

std::basic_string<char>*

这意味着您的Boost库是使用早于5.1的GCC构建的,或者是关闭了新的ABI。在任何一种情况下,您都可以通过添加此编译器标志来关闭新ABI来编译自己的代码:

-D_GLIBCXX_USE_CXX11_ABI=0

通过编译程序,可以使用系统提供的(旧ABI)Boost库。但问题是你的供应商编写代码的C ++ ABI(问他们,或者在他们的库中寻找__cxx11)。

答案 1 :(得分:1)

https://stackoverflow.com/a/52611576/981959所述,您不能在GCC的devtoolset版本中使用新的cxx11 ABI(因为devtoolset GCC的全部目的是保持与系统libstdc ++的ABI兼容)。

您可以选择以下任一方式:

  • 获取使用兼容gcc4的ABI的第三方库的新版本,以便您可以使用devtoolset编译器链接到该库;或
  • 自己构建并安装更新的GCC,使用它代替devtoolset GCC,并确保the new libstdc++.so gets used at runtime

答案 2 :(得分:0)

好的,我想我已经弄清楚为什么我无法获得g ++来生成cxx11签名(新的ABI)。

如果我使用-v选项运行g ++:

g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-6/root/usr/libexec/gcc/x86_64-redhat-linux/6.3.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-6/root/usr --mandir=/opt/rh/devtoolset-6/root/usr/share/man --infodir=/opt/rh/devtoolset-6/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-default-libstdcxx-abi=gcc4-compatible --with-isl=/builddir/build/BUILD/gcc-6.3.1-20170216/obj-x86_64-redhat-linux/isl-install --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 6.3.1 20170216 (Red Hat 6.3.1-3) (GCC)

请注意以下&#34;配置&#34;字段

- 与 - 缺省 - libstdcxx-ABI = GCC4兼容

我认为这意味着g ++的devtoolset-6版本是用旧式ABI&#34;在&#34;中编写的,因此它不会响应_GLIBCXX_USE_CXX11_ABI宏。

根据此链接:https://gcc.gnu.org/onlinedocs/libstdc++/manual/configure.html

- 与 - 缺省 - libstdcxx-ABI = OPTION 设置_GLIBCXX_USE_CXX11_ABI宏的默认值(请参阅宏)。默认值为OPTION = new,将宏设置为1,使用OPTION = gcc4-compatible将其设置为0.此选项不会更改库ABI。

它似乎只会更改_GLIBCXX_USE_CXX11_ABI的默认值,但在我的尝试中设置_GLIBCXX_USE_CXX11_ABI并没有任何效果。

这不是积极的,但它是我现在的工作理论。任何额外的见解都表示赞赏。