#include <fstream>#include <iostream>#include <boost/archive/xml_iarchive.hpp>#include <boost/archive/xml_oarchive.hpp>#include <boost/iostreams/filtering_stream.hpp>#include <boost/iostreams/filter/gzip.hpp>#include <boost/iostreams/device/file.hpp>int main(){ using namespace boost::iostreams; filtering_ostream os; os.push(boost::iostreams::gzip_compressor()); os.push(boost::iostreams::file_sink("emptyGzipBUG.txt.gz"));}
不幸的是,我正在使用的系统在/usr/lib /中有一个非常过时的boost_serialization版本,我无法改变它.
当我使用构建示例时,我相当肯定
g++ -o main main.cpp -lboost_serialization -lboost_iostreams
链接器错误的结果是因为gcc使用的是boost_serialization的系统版本,而不是我本地安装的版本.将liBRARY_PATH和LD_liBRARY_PATH设置为/ home / andrew / install / lib不起作用.当我建立使用
g++ -o main main.cpp -L/home/andrew/install/lib -lboost_serialization -lboost_iostreams
一切正常.
我的问题是:
>我怎样才能让gcc告诉我它使用的库的文件名?
>是否可以设置环境,以便我不必在gcc的命令行上指定本地boost的绝对路径.
g++ -Wl,-rpath,/home/andrew/install/lib -o main main.cpp -I/home/andrew/install/include -L/home/andrew/install/lib -lboost_serialization -lboost_iostreams
gcc本身并不关心库.链接器确实;).
即使链接器需要找到共享库以便它可以解析
符号,它通常不会在可执行文件中存储这些库的路径.
所以,首先,让我们在链接后找出二进制文件中的实际内容:
$readelf -d main | grep 'libboost' 0x0000000000000001 (NEEDED) Shared library: [libboost_serialization.so.1.54.0] 0x0000000000000001 (NEEDED) Shared library: [libboost_iostreams.so.1.54.0]
只是这样的名字.
实际使用的库由/lib/ld-linux.so.*确定.
在运行时:
$ldd main | grep libboost libboost_serialization.so.1.54.0 => /usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.54.0 (0x00007fd8fa920000) libboost_iostreams.so.1.54.0 => /usr/lib/x86_64-linux-gnu/libboost_iostreams.so.1.54.0 (0x00007fd8fa700000)
通过查看/etc/ld.so.cache找到路径(通常是这样
通过运行ldconfig编译).您可以打印其内容:
ldconfig -p | grep libboost_iostreams libboost_iostreams.so.1.54.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libboost_iostreams.so.1.54.0 libboost_iostreams.so.1.49.0 (libc6,x86-64) => /usr/lib/libboost_iostreams.so.1.49.0 libboost_iostreams.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libboost_iostreams.so
但由于这只是以前查找的缓存结果,
你对以下产量更感兴趣:
$ldconfig -v 2>/dev/null | egrep '^[^[:space:]]|libboost_iostreams'/lib/i386-linux-gnu:/usr/lib/i386-linux-gnu:/usr/local/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu: libboost_iostreams.so.1.54.0 -> libboost_iostreams.so.1.54.0/lib32:/usr/lib32:/lib:/usr/lib: libboost_iostreams.so.1.49.0 -> libboost_iostreams.so.1.49.0
它显示了在查找结果之前查看的路径.
请注意,如果要链接64位程序,它会找到32位
图书馆首先(或反之亦然)然后将被跳过
不相容.否则,使用找到的第一个.
用于搜索的路径在/etc/ld.so.conf中指定
读取(通常在启动时,或安装新的东西后)
以root身份运行ldconfig时.
但是,优先级将路径指定为冒号分隔列表
环境变量LD_liBRARY_PATH中的路径.
例如,如果我这样做:
$export LD_liBRARY_PATH=/tmp$cp /usr/lib/libboost_iostreams.so.1.49.0 /tmp/libboost_iostreams.so.1.54.0$ldd main | grep libboost_iostreams libboost_iostreams.so.1.54.0 => /tmp/libboost_iostreams.so.1.54.0 (0x00007f621add8000)
然后它在/ tmp中找到’libboost_iostreams.so.1.54.0′(即使它是一个libboost_iostreams.so.1.49.0).
请注意,您可以通过传递-rpath来硬编码可执行文件中的路径
链接器:
$unset LD_liBRARY_PATH$g++ -Wl,/tmp -o main main.cpp -lboost_serialization -lboost_iostreams$ldd main | grep libboost_iostreams libboost_iostreams.so.1.54.0 => /tmp/libboost_iostreams.so.1.54.0 (0x00007fbd8bcd8000)
这可以使用
$readelf -d main | grep RPATH 0x000000000000000f (RPATH) library rpath: [/tmp]
您可以使用-print-search-dirs命令行选项显示gcc在编译(链接)时使用的搜索路径:
$g++ -print-search-dirs | grep librarIEslibrarIEs: =/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/:/lib/x86_64-linux-gnu/4.7/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/4.7/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../:/lib/:/usr/lib/
这可以通过添加-L命令行选项来影响.如果在使用-L选项指定的路径中找不到库,则它会查找通过环境变量GCC_EXEC_PREFIX找到的路径(请参见手册页),如果失败则使用环境变量liBRARY_PATH.
当您使用-v选项运行g时,它将打印使用的liBRARY_PATH.
liBRARY_PATH=/tmp/lib g++ -v -o main main.cpp -lboost_serialization -lboost_iostreams 2>&1 | grep liBRARY_PATHliBRARY_PATH=/tmp/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/tmp/lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../:/lib/:/usr/lib/
最后,请注意,特别是对于提升(但总的来说)你应该使用与正确版本匹配的头文件!所以,如果你的图书馆在运行时链接是版本xyz你应该使用-I命令行选项来获取g来查找相应的头文件,或者事情可能没有链接或更糟,导致无法解释的崩溃.
@H_403_2@ 总结以上是内存溢出为你收集整理的linux – 说服gcc忽略系统库,转而使用本地安装的库全部内容,希望文章能够帮你解决linux – 说服gcc忽略系统库,转而使用本地安装的库所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)