C++ 为什么LD_LIBRARY_PATH不好以及加载动态库的正确方法

C++ 为什么LD_LIBRARY_PATH不好以及加载动态库的正确方法,c++,c,compiler-errors,shared-libraries,C++,C,Compiler Errors,Shared Libraries,所以,我有一个用OpenBlas运行的程序,我想编译它。链接过程如下所示: gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas 到目前为止还不错。如果删除-L选项,则链接过程中会出现错误 /usr/bin/ld: cannot find -lopenblas 使用-L所有链接都没有错误。但是,当我尝试运行它时,会出现以下错误: ./prog: error while loading sha

所以,我有一个用OpenBlas运行的程序,我想编译它。链接过程如下所示:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas
到目前为止还不错。如果删除
-L
选项,则链接过程中会出现错误

/usr/bin/ld: cannot find -lopenblas
使用
-L
所有链接都没有错误。但是,当我尝试运行它时,会出现以下错误:

./prog: error while loading shared libraries: libopenblas.so.0: cannot open shared object file: No such file or directory

如果将Env变量<代码> LD-LabyLogyPosith <代码> /opt/OpenBlas /LIB < /代码>,我可以运行程序,但很多源认为这是一个坏的实践,我几乎可以理解所有的推理。文章中提到的另一种方法(修改ld配置)也被认为是一种不好的做法。最后,您可以在

/usr/lib
中向库添加一个符号链接。最后两种方法的一个大问题是您需要sudo访问


因此,我的问题是,我如何编译和运行一个链接到共享库的程序,而该库不位于默认路径(
/usr/lib
)中,而不使用
LD\u library\u path
和sudo访问。在这篇文章中,他们说你可以用二进制“写”来查找共享库,但我不知道怎么做(
-L
标志似乎没有这样做)。如果有人能解释这件事,我将不胜感激,因为我已经到处找了,而且我很困惑(一些参考资料似乎建议国旗“-L”应该这样做,但我不为我工作)。提前感谢。

将路径添加到运行库搜索路径

gcc -Wl,-rpath=/opt/OpenBlas/lib ...

-L
选项在链接时执行的操作,以及
-rpath
选项在运行时执行的操作。

在linux上,还可以在rpath中使用$ORIGIN表示应用程序的目录路径,并从中构建相对的rpath。然后将库移动到二进制文件的已知相对路径

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -Wl,-rpath=\$ORIGIN/lib -L/opt/OpenBLAS/lib -lopenblas
您还可以使用库的完整路径,它将链接到:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include /opt/OpenBLAS/lib/libopenblas.so

如果在可执行文件上运行“ldd”,您应该会看到编码的完整路径。

您可以使用-rpath设置运行时库搜索路径这可能是OP正在寻找的答案,但它也不好,因为它将路径构建到可执行文件中,需要重新编译可执行文件以重新定位库。所以你应该基本上理解所有的解决方案,为什么它们都不好,然后选择一个对你的用例最不坏的解决方案@DavidSchwartz:您可以重新定位库而无需重新编译,您只需将其重新定位到运行时搜索路径中的其他位置。。。如果不使用
-rpath
,您可以使用相同的选项。如果您真的想将库移动到其他地方,您可以始终使用
LD\u LIBRARY\u PATH
。很抱歉,我没有看到缺点,除了如果将二进制文件复制到另一个系统中,
-rpath
可能有点吵。@DavidSchwartz:您也可以使用
chrpath
工具修改
rpath
,而无需重新编译。除非新的
rpath
更短,否则您无法在OS X上执行此操作,但遗憾的是,没有什么是完美的。谢谢!这确实是我一直在寻找的答案。但是,我在文档中找不到-rpath选项,我还想知道-Wl选项是什么,以及它们是否必要。“-Wl”是在链接器“ld”创建可执行文件时将rpath选项传递给链接器。您需要引用
$ORIGIN
,否则shell会将其展开(可能是空字符串)<代码>'-Wl,-rpath=$ORIGIN/lib'将起作用。