为什么LD_LIBRARY_PATH是BAD以及加载动态库的正确方法

时间:2014-09-18 17:04:00

标签: 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 shared libraries: libopenblas.so.0: cannot open shared object file: No such file or directory

如果我将env变量LD_LIBRARY_PATH设置为/opt/OpenBlas/lib我可以运行该程序,但许多来源如http://xahlee.info/UnixResource_dir/_/ldpath.html认为这是一种不好的做法,我几乎可以理解所有的推理。文章中提到的另一种方法(修改ld配置)也被认为是一种不好的做法。最后,您只需在/usr/lib中向库添加符号链接即可。最后两种方法的一个大问题是您需要sudo访问权限。

所以我的问题是如何在不使用/usr/lib和sudo访问权限的情况下编译和运行链接到不在默认路径(LD_LIBRARY_PATH)中的共享库的程序。在文章中他们说你可以在二进制文件中“写”寻找共享库,但我不知道如何做到(-L标志似乎没有这样做)。我很感激,如果有人能解释这个问题,因为我一直在寻找各处,我很困惑(一些参考文献似乎表明标志'-L'应该这样做,但我不适合我)。提前谢谢。

2 个答案:

答案 0 :(得分:18)

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

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

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

答案 1 :(得分:6)

在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"在可执行文件上,您应该看到编码的完整路径。