1

我编写了以下开创性的应用程序:

#include <boost/program_options.hpp>
int main(int argc, char** argv)
{
    boost::program_options::options_description generic_options("foo");
    return 0;
}

我正在尝试在 Debian Stretch 上构建它,默认编译器是 GCC 5.3.1-5,安装的 Boost 版本是 1.58.0。

但是,由于我不会在此处介绍的原因(如果这不是 MCVE,这将很明显g++-4.9),我需要使用 编译和链接二进制文件,而不是g++-5.3. 编译工作正常,但是当我尝试链接时,会发生这种情况:

/usr/bin/g++-4.9   -Wall -std=c++11   CMakeFiles/tester3.dir/src/altmain2.cpp.o  -o bin/tester3 -rdynamic -lboost_log -lboost_system -lboost_program_options 
CMakeFiles/tester3.dir/src/altmain2.cpp.o: In function `main':
altmain2.cpp:(.text+0x61): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
  • 这是由于 gcc 4 和 5 之间的某些 ABI 不兼容造成的吗?
  • 如果是这样,除了构建我自己的 Boost 版本之外,还有什么办法可以绕过它?
  • 如果不是,是什么原因造成的?
4

1 回答 1

3

这是由于 gcc 4 和 5 之间的某些 ABI 不兼容造成的吗?

看起来是这样。默认情况下,GCC 5 为几个重要的标准库类使用新的 ABI,包括std::basic_string模板(因此也包括std::string)。不幸的是,如果不破坏 ABI,就不可能使 std::string 完全符合 C++11 及更高版本。

libstdc++ 实现双 ABI,因此使用旧版本 GCC 编译的二进制文件将与新库链接(并正常工作)。有关详细信息,请参阅Jason Merrill(GCC 的 C++ 前端的维护者)的这篇文章。

如果是这样,除了构建我自己的 Boost 版本之外,还有什么办法可以绕过它?

可能不是。Boost 依赖于新的实现std::string并且不提供向后兼容性(与 libstdc++ 不同)。Debian bugtracker中提到了这个问题。

于 2016-01-24T14:53:28.440 回答