linux – 说服gcc忽略系统库,转而使用本地安装的库

linux – 说服gcc忽略系统库,转而使用本地安装的库,第1张

概述我正在尝试构建一个使用boost_serialization和boost_iostreams的简单可执行文件. #include <fstream>#include <iostream>#include <boost/archive/xml_iarchive.hpp>#include <boost/archive/xml_oarchive.hpp>#include <boost/iostr @H_403_2@ 我正在尝试构建一个使用boost_serialization和boost_iostreams的简单可执行文件.

#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的绝对路径.

解决方法 PS输入以下信息后,我认为我会善良,并为您的具体案例添加您需要的内容:

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忽略系统库,转而使用本地安装的库所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1017921.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存