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

本文介绍在Linux环境下如何修改应用程序的SO库链接路径,包括使用chrpath、patchelf工具,通过gcc编译选项及cmake配置等方式,并提供设置LD_LIBRARY_PATH环境变量的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简述

前段时间,遇到一个开发的业务需求,即在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.youkuaiyun.com/sinat_35178307/article/details/109165060
https://blog.youkuaiyun.com/sinat_35178307/article/details/109164966

### 回答1: 在 Linux 上可以通过使用 LD_LIBRARY_PATH 环境变量来指定程序动态连接的位置。可以使用 export 命令将 LD_LIBRARY_PATH 设置为动态链接库所在的路径,以便程序可以正确加载和使用它们。 ### 回答2: 在Linux中,可以使用以下方法指定程序动态连接的位置: 1. 使用LD_LIBRARY_PATH环境变量: 可以通过设置LD_LIBRARY_PATH环境变量来指定动态连接的位置。例如,如果要将动态连接路径设置为"/usr/local/mylib",可以执行以下命令: ``` export LD_LIBRARY_PATH=/usr/local/mylib ``` 这样,在运行程序时,系统会首先在指定的路径中查找动态连接。 2. 使用rpath选项编译程序: 在编译程序时,可以通过指定-rpath选项来设置动态连接的位置。例如,使用gcc编译程序并指定动态连接路径为"/usr/local/mylib",可以执行以下命令: ``` gcc -o myprogram myprogram.c -Wl,-rpath=/usr/local/mylib ``` 这样,在运行程序时,系统也会优先在指定的路径中查找动态连接。 3. 使用ld.so.conf配置文件: 可以修改ld.so.conf配置文件来指定动态连接的位置。可以通过以下步骤实现: - 打开/etc/ld.so.conf文件,可以使用文本编辑器进行修改。 - 在文件中添加动态连接路径,每行一个路径。 - 保存并关闭文件。 - 运行以下命令更新动态连接的缓存: ``` sudo ldconfig ``` 这样,系统会根据ld.so.conf配置文件中的路径进行动态连接的查找。 需要注意的是,在使用以上方法指定动态连接位置时,要确保所设置的路径是正确的,并且动态连接文件存在且可访问。使用以上方法可以指定程序动态连接的位置,以便程序能够正确地加载所需的文件。 ### 回答3: 在Linux系统中,可以使用以下几种方式指定程序动态连接的位置: 1. 使用LD_LIBRARY_PATH环境变量: 在终端中运行 export LD_LIBRARY_PATH=/path/to/library:$LD_LIBRARY_PATH,其中/path/to/library是文件所在的路径。该环境变量会告诉系统在运行程序时搜索文件的位置,并优先使用这些路径中的文件。 2. 使用rpath选项:编译时可以使用-Wl,-rpath选项指定程序运行时搜索文件的路径。例如,gcc -o executable program.c -Wl,-rpath=/path/to/library 会将指定的路径添加到程序中。 3. 使用ldconfig工具: ldconfig是一个配置文件的工具,可以用于指定程序运行时的文件搜索路径。通过配置/etc/ld.so.conf文件,在文件中添加文件的路径,然后运行sudo ldconfig命令来更新文件的缓存。 以上是几种常用的方式,根据实际情况选择其中的一种来指定程序动态连接的位置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值