Linux笔记之LD_LIBRARY_PATH详解

一只野生的善逸 2024-06-14 14:37:29 阅读 69

Linux笔记之LD_LIBRARY_PATH详解

参考博文:

1.C++笔记之执行一个可执行文件时指定动态库所存放的文件夹lib的路径

2.Linux笔记之LD_LIBRARY_PATH详解

3.qt-C++笔记之使用QProcess去执行一个可执行文件时指定动态库所存放的文件夹lib的路径

code review!

文章目录

Linux笔记之LD_LIBRARY_PATH详解1.常见使用命令来设置动态链接库路径2.LD_LIBRARY_PATH详解设置 `LD_LIBRARY_PATH`举例注意事项 3.替代方案使用标准路径编译时指定链接路径优先使用 rpath 还是 runpath?注意事项

1.常见使用命令来设置动态链接库路径

export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH

命令 export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH 在类 Unix 操作系统中用来设置环境变量 LD_LIBRARY_PATH,以便在运行时包含一个含有共享库的目录。这里是命令的详细解释:

export:这个 shell 内置命令用来导出环境变量,这样它就可以被 shell 启动的任何子进程使用。

LD_LIBRARY_PATH:这是一个环境变量,动态链接器在运行时用它来找到共享库(.so 文件)。当你运行一个依赖共享库的可执行文件时,动态链接器会使用 LD_LIBRARY_PATH 中列出的目录来定位这些库。

=$PWD/lib:这将 LD_LIBRARY_PATH 设置为包含当前工作目录($PWD)中的 lib 目录。PWD 环境变量包含当前工作目录的路径。

:$LD_LIBRARY_PATH:冒号 : 是一个分隔符,它允许你将多个目录附加到 LD_LIBRARY_PATH。这部分命令将现有的 LD_LIBRARY_PATH 内容附加到新值的前面,这样新目录就会首先被搜索,然后是之前设置的目录。

综合起来,这个命令将当前工作目录的 lib 目录添加到 LD_LIBRARY_PATH 的开头,并将这个更新后的路径导出到随后执行的程序的环境中。

这在你想要运行依赖于不在动态链接器标准查找位置(如 /lib/usr/lib)的共享库的程序时非常有用。通过设置 LD_LIBRARY_PATH,你可以引导动态链接器在额外的目录中搜索。

请注意,通常认为使用 LD_LIBRARY_PATH 是最后的手段,因为如果不能将库安装到标准位置或调整动态链接器的配置文件时才会使用,因为它可能会导致版本和兼容性问题。通常最好将其用于临时或开发目的,而不是作为库路径解析的永久解决方案。

2.LD_LIBRARY_PATH详解

LD_LIBRARY_PATH 是一个环境变量,用于在Linux和类Unix操作系统中指定动态链接器搜索共享库时应查看的目录的列表。动态链接器用于加载和链接应用程序在运行时需要的共享库(动态库,通常是.so文件)。

默认情况下,动态链接器会按照一定的规则(例如查看 /lib/usr/lib 等目录)来搜索这些共享库。但是,如果你的应用程序使用了非标准路径中的共享库,或者你想覆盖默认的库版本,你可以设置 LD_LIBRARY_PATH 来告诉动态链接器在哪些额外的目录中查找。

设置 LD_LIBRARY_PATH

你可以通过在命令行中导出环境变量来设置 LD_LIBRARY_PATH,如下所示:

export LD_LIBRARY_PATH=/path/to/mylibs:$LD_LIBRARY_PATH

这里,/path/to/mylibs 应该替换为实际的目录路径。如果有多个目录,可以用冒号分隔它们。注意,$LD_LIBRARY_PATH 在末尾包括了原始的 LD_LIBRARY_PATH 值,这样可以在添加新路径的同时保留旧的路径。

举例

假设你有一个应用程序需要使用位于 /home/user/mylibs 目录中的共享库。你可以这样设置环境变量:

export LD_LIBRARY_PATH=/home/user/mylibs:$LD_LIBRARY_PATH

然后运行你的应用程序。动态链接器现在会首先在 /home/user/mylibs 目录中查找共享库,如果在那里找不到,再按照默认的规则进行搜索。

注意事项

虽然 LD_LIBRARY_PATH 很方便,但过度使用或不当使用可能会导致一些问题:

安全性:如果不小心设置了错误的路径,可能会加载到错误的库,这可能会导致安全问题或应用程序崩溃。依赖性:依赖于 LD_LIBRARY_PATH 的应用程序可能在其他环境中运行起来比较困难,因为它需要确保环境变量被正确设置。维护性:长期依赖 LD_LIBRARY_PATH 可能会导致维护难度增加,尤其是在多用户系统或复杂的部署环境中。

为了避免这些问题,通常推荐的做法是尽可能使用标准路径来安装共享库,或者使用如 rpathrunpath 这样的链接器选项在编译时指定库的搜索路径。

3.替代方案

为了避免使用 LD_LIBRARY_PATH 可能带来的问题,可以采用以下方法确保动态链接器能够找到共享库:

使用标准路径

将共享库安装到系统的标准路径下(如 /usr/lib/lib),这样动态链接器默认就会在这些路径下查找所需的库。这通常需要管理员权限,因为涉及到修改系统目录。

编译时指定链接路径

在编译和链接应用程序时,可以使用链接器(如 ld)的选项来指定共享库的路径。这种方法在编译时将库的路径固定到二进制文件中,减少了运行时的路径搜索和环境变量的依赖。

rpath: 使用 -rpath 选项可以指定运行时搜索路径,链接器会将这个路径写入到二进制文件中。例如:

gcc -o myapp myapp.c -L/path/to/mylibs -lmylib -Wl,-rpath,/path/to/mylibs

这里 -L 选项告诉编译器在哪个目录下搜索库文件,-l 选项指定库的名称,-Wl,-rpath,/path/to/mylibs 告诉链接器添加一个 rpath

runpath: 类似于 rpath,但是如果设置了 LD_LIBRARY_PATH 环境变量,LD_LIBRARY_PATH 会优先于 runpath。使用 runpath 的语法类似于 rpath

gcc -o myapp myapp.c -L/path/to/mylibs -lmylib -Wl,-rpath-link,/path/to/mylibs

优先使用 rpath 还是 runpath?

如果你希望 LD_LIBRARY_PATH 环境变量能够覆盖编译时设置的路径,使用 runpath 是一个更好的选择。如果你希望编译时设置的路径总是被使用,即使存在 LD_LIBRARY_PATH 环境变量,那么 rpath 是更好的选择。

注意事项

当使用 rpathrunpath 时,要确保指定的路径是可靠和安全的。如果共享库的位置在部署后可能会发生变化,过度依赖这些选项可能会导致以后的维护问题。一些系统可能配置有安全机制,比如 SELinux,这可能会限制应用程序只能从特定的目录加载共享库。

在决定使用 rpathrunpath 还是 LD_LIBRARY_PATH 时,需要根据应用程序的具体需求和部署环境来权衡。尽可能使用标准路径或者系统包管理器来管理共享库,这样可以最小化环境设置对应用程序正常运行的影响。

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。