Linux系统存在多个同名动态库时如何指定使用目标版本?
同名动态库优先级指定方案
基础疑问解答:DT_RPATH与RUNPATH的区别
你看到的RUNPATH段是正常特性:Ubuntu 18.04 自带的gcc 7.5默认会给链接器传递--enable-new-dtags参数,该参数会用优先级更低的DT_RUNPATH段替代传统的DT_RPATH段。二者的运行时搜索优先级顺序为:
DT_RPATH > LD_LIBRARY_PATH > DT_RUNPATH > 系统ld缓存路径 > 默认系统库路径
这就是你当前配置下,LD_LIBRARY_PATH和系统库优先级高于你设置的rpath的核心原因。
方案1:编译时注入DT_RPATH(推荐,符合优先级要求,全项目统一配置)
该方案无需修改运行时环境,所有项目内的可执行文件编译后自动优先加载同仓库下的动态库,且满足DT_RPATH优先级高于LD_LIBRARY_PATH的要求:
原始编译选项配置
链接时添加以下参数即可:
-Wl,--disable-new-dtags,-rpath='$ORIGIN/src'
--disable-new-dtags:关闭新标签特性,强制生成DT_RPATH段$ORIGIN是链接器内置变量,指代可执行文件自身所在的目录,你提到可执行文件存放在build目录,动态库存放在build/src目录,所以$ORIGIN/src会自动定位到同仓库下的动态库路径,无需硬编码绝对路径,项目目录移动后也能正常运行。
CMake项目统一配置
如果你用CMake构建项目,直接在顶层CMakeLists.txt中添加以下配置即可全局生效,所有生成的可执行文件自动携带正确的DT_RPATH:
# 开启BUILD阶段的RPATH配置 set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) # 强制生成DT_RPATH而非RUNPATH set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--disable-new-dtags") # 设置BUILD阶段的RPATH为相对路径 set(CMAKE_BUILD_RPATH "$ORIGIN/src")
验证方法
编译完成后执行以下命令检查:
- 检查RPATH段:
objdump -x 可执行文件路径 | grep RPATH,能看到输出值为$ORIGIN/src即为配置成功 - 检查动态库链接:
ldd 可执行文件路径,此时libmyproject.so的路径会指向/home/ziqi.liu/workspace/myproject/build/src/libmyproject.so而非系统路径
方案2:临时修改LD_LIBRARY_PATH(适合临时测试场景)
如果不想修改编译配置,可以在运行可执行文件前临时指定动态库搜索路径,示例命令如下:
LD_LIBRARY_PATH=/home/ziqi.liu/workspace/myproject/build/src ./your_executable
注意:该方案下LD_LIBRARY_PATH优先级高于DT_RUNPATH,仅适合临时测试使用,不符合你要求的rpath优先级高于LD_LIBRARY_PATH的需求。
内容的提问来源于stack exchange,提问作者Ziqi Liu
相关产品推荐
相关产品推荐

