Linux下修改可执行程序或者库的动态链接库的路径

简述

前段时间,遇到一个开发的业务需求,即在linux下编译生成可执行文件之后或者修改动态库的链接指向,需要修改其相关的链接库的路径并指定到自定义的目录下。若把相关库拷贝到我们指定应用的目录下,而又没有在编译时执行库的路径,通常默认是指定在系统库/lib目录下。因此,需要修改并指定的rpatch.

rpatch参数

rpath 参数是指定库运行时首先加载系统依赖库的路径,如果找不到依赖库将到系统默认的路径库查找。

readelf命令

readelf命令,一般用于查看ELF格式的文件信息,常见的文件如在Linux上的可执行文件,动态库(.so)或者静态库(.a) 等包含ELF格式的文件。

使用方式(usage)

  readelf -d test   #test为可执行文件
  readelf -d libc.so.6  #libc.so.6为动态库

ldd命令

ldd命令用于打印程序或者库文件所依赖的共享库列表。

使用方式(usage)

  ldd  test         #test为可执行程序
  ldd  libc.so.6    #libc.so.6为动态库

在linux下应用程序so库链接路径rpath修改的方法

方式1.chrpath 修改rpath

此方式可能更适用于关联库较少的情况之下。

安装chrpath

  sudo apt install chrpath 

其选项参数如下:

使用方式(usage)

#显示rpath路径,比如
  chrpath -l xxx.so  或者 chrpath -l test

#修改rpath路径,比如
  chrpath -r ./lib xxx.so    #其中./lib是需要修改的路径,xxx.so为源路径库
  chrpath -r ./lib test    #其中./lib是需要修改的路径,test可执行文件

方式2.patchelf设置rpath

此方式可能更适用于关联库较少的情况之下。

安装patchelf

  sudo apt install patchelf

其选项参数如下:

使用方式(usage)

  patchelf --set-rpath  ./lib  xxx.so   #其中./lib是需要修改的路径,xxx.so为源路径库

用例

测试例程如下:(libc.so.6是复制/lib下到当前路径下)

比如test这个可执行程序用到的关联库如下:(修改之前)。
发现libc.so.6这个动态库指向=>/lib/x86_64-linux-gnu/libc.so.6 (0x00007efc90075000)

rpath的设置情况,没有设置有这个参数。(修改之前)

执行命令

  patchelf --set-rpath  ./  test  #修改可执行程序test的rpatch为当前的路径下

查看关联库指向与rpatch(修改之后)

此时查看libc.so.6的依赖库路径变为./libc.so.6

查看test的文件信息如下这一行:

0x000000000000001d (RUNPATH) Library runpath: [./]

说明设置成功!

方式3.gcc 指定rpath 编译选项(推荐)

查看更多编译知识:

makefile模板以及多层Makefile编译(附源码)

GCC详解的-Wl选项说明与测试

gcc -o test test.c -I. -L. -lc -Wl,-rpath=.   

其中

-I. 是指定头文件路径为当前目录下;

-L. 是指定库文件路径为当前目录下;

-lc 是从-L指定库文件路径下去找libc.so.6这个库,也就是库名砍头去尾(类似使用过-lpthread);

-Wl,-rpath=. 为告诉编译器将后面的参数传递给链接器。

查看关联库指向与rpatch(编译之后)

此时查看libc.so.6的依赖库路径变为./libc.so.6

查看test的文件信息如下这一行:

0x000000000000001d (RUNPATH) Library runpath: [.]

方式4.cmake中指定rpath选项(推荐)

IF(UNIX)
	set(CMAKE_SKIP_BUILD_RPATH TRUE)
    set(CMAKE_CXX_FLAGS   "-Wl,-z,origin,-rpath,$ORIGIN")
ENDIF()

或者

set(CMAKE_SKIP_BUILD_RPATH FALSE)                 # 编译时加上RPATH  
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)         # 编译时RPATH不使用安装的RPATH  
set(CMAKE_INSTALL_RPATH "./")                     # 安装RPATH为当前目录  
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)      # 安装的执行文件不加上RPATH

方式5.设置LD_LIBRARY_PATH

  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/yimning/lib  

冒号:为设置多个路径下的分割符号。设置之后再去编译即可。

参考链接:

https://blog.csdn.net/sinat_35178307/article/details/109165060
https://blog.csdn.net/sinat_35178307/article/details/109164966

猜你喜欢

转载自blog.csdn.net/Youning_Yim/article/details/126582927