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


    简述

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

    rpatch参数

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

    readelf命令

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

    使用方式(usage)

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

    ldd命令

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

    使用方式(usage)

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

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

    方式1.chrpath 修改rpath

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

    安装chrpath

      sudo apt install chrpath 
    

    其选项参数如下:

    使用方式(usage)

    1. #显示rpath路径,比如
    2. chrpath -l xxx.so 或者 chrpath -l test
    3. #修改rpath路径,比如
    4. chrpath -r ./lib xxx.so #其中./lib是需要修改的路径,xxx.so为源路径库
    5. 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选项(推荐)

    1. IF(UNIX)
    2. set(CMAKE_SKIP_BUILD_RPATH TRUE)
    3. set(CMAKE_CXX_FLAGS "-Wl,-z,origin,-rpath,$ORIGIN")
    4. ENDIF()

    或者

    1. set(CMAKE_SKIP_BUILD_RPATH FALSE) # 编译时加上RPATH
    2. set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) # 编译时RPATH不使用安装的RPATH
    3. set(CMAKE_INSTALL_RPATH "./") # 安装RPATH为当前目录
    4. 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

  • 相关阅读:
    Pytorch之ConvNeXt图像分类
    SpringMVC源码-不同类型的参数解析
    linux内核进程间通信IPC----消息队列
    【开发心得】ftp下载文件,文件不存在的原因解析
    QT+OSG/osgEarth编译之十二:OpenJPEG+Qt编译(一套代码、一套框架,跨平台编译,版本:OpenJPEG-2.5.0)
    HTML+CSS期末大作业 中国传统美食网站设计 节日美食13页 html5网页设计作业代码 html制作网页案例代码 html大作业网页代码...
    服务的网关-Zuul(1.5.x)
    cp -r, 保留拷贝的文件原本的权限和属性
    超越幻觉:AI在创建信任感医疗记录中的新突破!
    玩转数据可视化之R语言ggplot2:(十一)坐标轴和刻度线设置2
  • 原文地址:https://blog.csdn.net/Youning_Yim/article/details/126582927