// Copyright Vladimir Prus 2002-2004.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
/* The simplest usage of the library.
*/
#include
namespace po = boost::program_options;
#include
#include
using namespace std;
int main(int ac, char* av[])
{
try {
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("compression", po::value<double>(), "set compression level")
;
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc << "\n";
return 0;
}
if (vm.count("compression")) {
cout << "Compression level was set to "
<< vm["compression"].as<double>() << ".\n";
} else {
cout << "Compression level was not set.\n";
}
}
catch(exception& e) {
cerr << "error: " << e.what() << "\n";
return 1;
}
catch(...) {
cerr << "Exception of unknown type!\n";
}
return 0;
}
其中,-I(大写的i)指定头文件搜索路劲,-L指定库搜索路径, -l(小写的L)指定库名字
编译没有问题,pass,生成 a.out,但是运行时会报错。
$ ./a.out
报错如下:
a.out: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21’ not found (required by a.out)
$ ldd a.out
./a.out: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21’ not found (required by ./a.out)
linux-vdso.so.1 => (0x00007ffff7ffd000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ffff7cb4000)
libm.so.6 => /lib64/libm.so.6 (0x00007ffff7a2f000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ffff7819000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffff7485000)
/lib64/ld-linux-x86-64.so.2 (0x0000555555554000)
可以看到a.out依赖动态库:libstdc++.so.6,位置在 /usr/lib64/libstdc++.so.6
为什么会依赖这个位置的这个库呢,肯定是编译期间指定了它。
$ ll /usr/lib64/libstdc++.so.6
lrwxrwxrwx 1 root root 19 Feb 8 2019 /usr/lib64/libstdc++.so.6 -> libstdc++.so.6.0.13
发现libstdc++.so.6是一个软链接,指向了其同目录下的libstdc++.so.6.0.13。
$ strings /usr/lib64/libstdc++.so.6.0.13 | grep GLIB
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.4
GLIBC_2.3.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
发现里面确实没有GLIBCXX_3.4.21。当然这是合理的,要不然就不错报错了。
有了上面的分析,解决办法就很简单了。
解决办法1.
既然libstdc++.so.6是一个软链接,指向了其同目录下的libstdc++.so.6.0.13。那么我只要把这个软链接删除,使其指向包含GLIBCXX_3.4.21的libstdc++.so就可以了,你可以在你使用的g++的版本所在的目录搜索 libstdc++.so 所在的路径:
$ find /home/utils/ -name “libstdc++.so*”
找一个高版本,只要其包含GLIBCXX_3.4.21就可以,我在我系统中找到的是我所使用的g++的版本所在的路径:/home/utils/gcc-5.2.0/lib64/libstdc++.so.6.0.21。
$ strings /home/utils/gcc-5.2.0/lib64/libstdc++.so.6.0.21 | grep GLIB
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBC_2.3
GLIBC_2.2.5
GLIBC_2.3.2
GLIBCXX_DEBUG_MESSAGE_LENGTH
发现该版本的libstdc++.so 确实存在GLIBCXX_3.4.21,那么我们的解决办法就有了:
把libstdc++.so.6是这个软链接删除,重建一个新的软链接,使其指向你找到的 .so就可以了。对于我来讲,即指向/home/utils/gcc-5.2.0/lib64/libstdc++.so.6.0.21
这种方法是网上能查到的普遍的解决方法,参考: 解决类似 /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21’ not found 的问题
解决方法2
解决方法1不太好,这样去删除公共目录下面的东西,还是在公司的服务器上,暂且不说你有没有权限,即使你有,这样做也会影响到其他的用户。
所以,
想办法让a.out在编译的时候,就去链接你找到的高版本的 libstdc++,通过 -Wl, rpath xxx/ 来指定,使用下面的编译a.out的命令
$ g++ main.cpp -Wl,-rpath /home/utils/gcc-5.2.0/lib64/ -I/home/toolroot/boost/boost-1.54.0 -L/home/toolroot/boost/boost-1.54.0/linuxlib/gcc-5.2.0-64 -lboost_program_options
这样的话,生成的a.out就没有运行期的问题了。
解决方法3
设置LD_LIBRARY_PATH,增加目录/home/utils/gcc-5.2.0/lib64/
setenv LD_LIBRARY_PATH /home/utils/gcc-5.2.0/lib64:/home/utils/gcc-5.2.0/lib:$LD_LIBRARY_PATH
这是最简单的方法,最开始的时候就应该想到这种方法的,还是对这种问题的理解不够深刻。
因为这个问题的本质是:在使用头文件的时候 -I(小写的i)指定的是gcc-5.2.0的头文件,但是由于LD_LIBRARY_PATH中并没有指定/home/utils/gcc-5.2.0/lib64/这个目录,导致程序运行时错误的去查找/usr/lib64/这个目录,而拿到了错误的库。所以只要我们在LD_LIBRARY_PATH中指定了正确的库的位置,这个问题就解决了。
并且,当在LD_LIBRARY_PATH中指定了/home/utils/gcc-5.2.0/lib64/之后,此时:
$ ldd a.out
./a.out: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21’ not found (required by ./a.out)
linux-vdso.so.1 => (0x00007ffff7ffd000)
libstdc++.so.6 => /home/utils/gcc-5.2.0/lib64/libstdc++.so.6 (0x00007ffff7c80000)
libm.so.6 => /lib64/libm.so.6 (0x00007ffff79bb000)
libgcc_s.so.1 => /home/utils/gcc-5.2.0/lib64/libgcc_s.so.1 (0x00007ffff77a5000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffff7411000)
/lib64/ld-linux-x86-64.so.2 (0x0000555555554000)
可以看到此时 libstdc++.so.6 => /home/utils/gcc-5.2.0/lib64/libstdc++.so.6 (0x00007ffff7c80000),这正是我们期望的。