Ubuntu/CentOS设置LD_LIBRARY_PATH环境变量免安装使用动态库

Ubuntu/CentOS设置LD_LIBRARY_PATH环境变量免安装使用动态库

Linux系统不像Windows,可以把动态库放在可执行程序同级目录下,自动会查找到。Linux可执行程序依赖的动态库在/usr/lib等几个默认文件夹下查找,如果找不到就会报错;设置Linux的LD_LIBRARY_PATH变量可以解决这个问题。
Linux下的库查找顺序可参考博客

为什么想要免安装使用动态库

编译完成动态库之后,一般会make install安装到系统lib路径下,执行可执行程序时,会自动到系统lib路径下查找依赖的.so文件,找不到就会报错提示程序名: error while loading shared libraries: 某动态库.so: cannot open shared object file: No such file or directory

设置LD_LIBRARY_PATH

在系统根目录下,有.bash_rc文本文件,每次打开终端时会加载这一文件中的环境变量。
使用vim或gedit打开它,在里面加入内容:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:你的动态库路径

如下图所示,/usr/local/lib/ceres_solver/bin是我的动态库的放置位置:
Ubuntu/CentOS设置LD_LIBRARY_PATH环境变量免安装使用动态库_第1张图片
修改完成后,保存退出,重新打开终端,运行可执行程序,即可找到该路径下的动态库。

VS2019/VS2022远程编译时设置链接依赖库

一般设置共享库依赖时,会在属性页中的“链接器-输入-附加依赖项”中添加库的绝对路径或相对路径,然而这样编译生成的结果对该库的依赖就只会按照该绝对路径去查找,找不到就报错。为了让生成的可执行程序自动去LD_LIBRARY_PATH下查找库,需要按下面两图进行设置:

  1. 在附加库目录中添加所依赖的共享库的绝对路径。
    Ubuntu/CentOS设置LD_LIBRARY_PATH环境变量免安装使用动态库_第2张图片
  2. 在库依赖项中添加所依赖共享库的名称(没有开头的lib前缀和结尾的.so后缀)
    Ubuntu/CentOS设置LD_LIBRARY_PATH环境变量免安装使用动态库_第3张图片
    以上两处设置其实分别对应编译器的-L-l选项,分别表示编译时搜索库的路径和依赖库的名称。
  3. --rpath-link选项:一个可执行程序依赖libceres.solibceres.so又依赖libcholmod.so,这时如果libcholmod.so不在相同路径下,编译器就会提示找不到libcholmod.so中的符号定义。这个选项刚好能解决这个问题。在“共享库搜索路径”中添加libceres.so的依赖库的路径,即可编译通过。--rpath-link也即“链接时动态库搜索路径”,链接完成后,可执行程序加载各共享库,共享库去查找各子共享库,都还是按照环境变量$LD_LIBRARY_PATH所指定位置去搜索。
    Ubuntu/CentOS设置LD_LIBRARY_PATH环境变量免安装使用动态库_第4张图片
  4. --rpath选项:与-rpath-link不同之处在于,该选项会把路径信息直接写入生成的共享库,生成的共享库便根据这个路径在运行时去加载其依赖的子共享库。如果找不到,就没救了。它却因此有一个巨大的优点:如果你出于某些原因不能修改环境变量,使用-rpath-link就会让你无法找到库,而-rpath就是救火队长了。

总结

  • -L只是在编译时指定库的位置,但是运行时无法找到该位置;
  • -rpath-rpath-link都可以在链接时指定库的路径;
    但是运行时,-rpath-link指定的路径就不再有效;而-rpath指定的路径,已被链接器写入可执行文件中或库中,仍然有效。

所以一般都把-L-rpath-link指定的库目录设置到LD_LIBRARY_PATH环境变量中,以便这些编译时被链接的库在运行时也能被找到。

你可能感兴趣的:(ubuntu,linux)