Linux条记之LD_LIBRARY_PATH详解
参考博文:
1.C++条记之实行一个可实行文件时指定动态库所存放的文件夹lib的路径
2.Linux条记之LD_LIBRARY_PATH详解
3.qt-C++条记之使用QProcess去实行一个可实行文件时指定动态库所存放的文件夹lib的路径
code review!
1.常见使用命令来设置动态链接库路径
- export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH
复制代码 命令 export LD_LIBRARY_PATH=$PWD/libLD_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 大概会导致维护难度增加,尤其是在多用户系统或复杂的部署环境中。
为了避免这些问题,通常推荐的做法是尽大概使用标准路径来安装共享库,或者使用如 rpath 或 runpath 如许的链接器选项在编译时指定库的搜索路径。
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 是更好的选择。
留意事项
- 当使用 rpath 或 runpath 时,要确保指定的路径是可靠和安全的。
- 如果共享库的位置在部署后大概会发生厘革,过度依赖这些选项大概会导致以后的维护问题。
- 一些系统大概配置有安全机制,比如 SELinux,这大概会限制应用程序只能从特定的目录加载共享库。
在决定使用 rpath、runpath 还是 LD_LIBRARY_PATH 时,必要根据应用程序的具体需求和部署环境来衡量。尽大概使用标准路径或者系统包管理器来管理共享库,如许可以最小化环境设置对应用程序正常运行的影响。
4.export LD_LIBRARY_PATH 在CMakeLists.txt中有对应的功能吗?
在 CMake 中,没有直接设置 LD_LIBRARY_PATH 环境变量的命令。不外,可以通过其他方式实现类似的功能,以确保在运行时能够精确找到动态库。
解决方案
- 设置 RPATH(运行时搜索路径):
使用 RPATH(运行时库搜索路径)可以在编译时指定运行时库的搜索路径。如许在运行时,程序会使用指定的路径查找动态库,而无需设置 LD_LIBRARY_PATH。
- 自界说命令:
通过 add_custom_command 或 add_custom_target 设置环境变量。
4.1.设置 RPATH
CMake 提供了几个变量来控制 RPATH 的设置:
- CMAKE_INSTALL_RPATH: 指定安装后的 RPATH。
- CMAKE_BUILD_RPATH: 指定构建时的 RPATH。
- CMAKE_INSTALL_RPATH_USE_LINK_PATH: 控制是否将链接目录添加到 RPATH。
示例:
- # 指定项目名称
- project(MyProject)
- # 设置 C++ 标准
- set(CMAKE_CXX_STANDARD 17)
- # 添加可执行文件
- add_executable(myprogram "myprogram.cpp")
- # 链接库
- target_link_libraries(myprogram mylib)
- # 设置构建时的 RPATH
- set(CMAKE_BUILD_RPATH "/path/to/libs")
- # 设置安装后的 RPATH
- set(CMAKE_INSTALL_RPATH "/path/to/libs")
- # 控制是否将链接目录添加到 RPATH
- set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE
- )
复制代码 在这个示例中,/path/to/libs 是动态库所在的路径。如许,生成的可实行文件在运行时会使用指定的路径查找动态库。
4.2.设置 RPATH补充条记
代码
- # 设置运行时库路径(rpath)
- set_target_properties(main PROPERTIES
- BUILD_RPATH "${CMAKE_SOURCE_DIR}"
- INSTALL_RPATH "${CMAKE_SOURCE_DIR}"
- INSTALL_RPATH_USE_LINK_PATH TRUE
- )
复制代码 这段代码的作用是配置 main 目标的运行时库查找路径,使得在构建和安装后都能在指定目录(即源目录 ${CMAKE_SOURCE_DIR})中查找运行时库。
- BUILD_RPATH:构建时的运行时库查找路径。
- INSTALL_RPATH:安装后的运行时库查找路径。
- INSTALL_RPATH_USE_LINK_PATH:将链接时的路径主动添加到 INSTALL_RPATH 中。
这种配置方式在开发中很有用,特殊是当库文件位于源目录中时,可以确保可实行文件在运行时能够精确找到所需的库文件。
set_target_properties 命令用于设置目标的各种属性。在这个例子中,紧张关注的是设置运行时库路径(rpath)。下面是对这段代码的具体解释。
set_target_properties
set_target_properties 命令用于设置给定目标的属性。在这个例子中,目标是 main。
PROPERTIES
PROPERTIES 关键字后面跟着一系列属性及其对应的值。这里设置了三个属性:BUILD_RPATH、INSTALL_RPATH 和 INSTALL_RPATH_USE_LINK_PATH。
BUILD_RPATH
BUILD_RPATH 指定了在构建时用于查找运行时库的路径。在这个例子中,BUILD_RPATH 被设置为 ${CMAKE_SOURCE_DIR},即 CMake 项目标源目录。
- BUILD_RPATH "${CMAKE_SOURCE_DIR}"
复制代码 这意味着在构建 main 目标时,运行时库会在源目录下查找。
INSTALL_RPATH
INSTALL_RPATH 指定了在安装时用于查找运行时库的路径。同样地,这里也被设置为 ${CMAKE_SOURCE_DIR}。
- INSTALL_RPATH "${CMAKE_SOURCE_DIR}"
复制代码 这意味着在安装 main 目标后,运行时库会在源目录下查找。
INSTALL_RPATH_USE_LINK_PATH
INSTALL_RPATH_USE_LINK_PATH 是一个布尔属性。设置为 TRUE 时,它会将链接器路径主动添加到 INSTALL_RPATH 中。
- INSTALL_RPATH_USE_LINK_PATH TRUE
复制代码 这意味着如果在链接时指定了某些路径,这些路径也会被添加到 INSTALL_RPATH 中。
4.3.自界说命令
如果确实必要在编译过程中设置环境变量,可以使用 add_custom_command 或 add_custom_target:
- # 指定项目名称
- project(MyProject)
- # 设置 C++ 标准
- set(CMAKE_CXX_STANDARD 17)
- # 添加可执行文件
- add_executable(myprogram "myprogram.cpp")
- # 链接库
- target_link_libraries(myprogram mylib)
- # 添加自定义命令来设置环境变量
- add_custom_command(TARGET myprogram POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH="/path/to/libs" $<TARGET_FILE:myprogram>)
复制代码 这会在构建后运行可实行文件时设置 LD_LIBRARY_PATH 环境变量。
总结
- 使用 RPATH:是最推荐的方式,因为它不依赖于环境变量,且更便于部署和管理。
- 自界说命令:可以在构建后通过临时设置环境变量来运行程序,但这种方法不实用于所有情况。
通过以上方式,可以在 CMake 项目中实现类似于设置 LD_LIBRARY_PATH 的效果。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |