我写了以下开创性的应用程序:
#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 版本之外,还有什么方法可以解决它吗?
- 如果不是,是什么原因造成的?
这是由于 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 依赖于 std::string
的新实现,不提供向后兼容性(与 libstdc++ 不同)。这个问题在 Debian bugtracker 中提到过。