Linux RPATH & $ORIGIN

许多现代C / C ++项目都利用Autotools创建GNU构建系统,例如 根据平台生成make文件。 可执行文件(二进制文件)在生成/编译过程中生成,并且可以在执行编译的计算机上本地执行。 但是,如果将同一可执行文件移动到另一台计算机上,或者只是移到同一台计算机上的其他文件夹,则在运行该可执行文件时可能会遇到“找不到库”错误。

什么是RPATH和$ORIGIN?

RPATH代表运行时搜索路径。 根据Wikipedia的说法,“rpath指定在可执行文件或库中硬编码的运行时搜索路径。 动态链接加载程序使用rpath查找所需的库” 动态链接是所需共享库的一种“惰性”链接,不是在编译阶段,而是在运行一个可执行文件的后期。 如果设置了rpath,覆盖或补充系统默认的共享库搜索路径,则共享库的路径将被编码到可执行文件的头中,就像扩展PATH系统变量链一样。

$ORIGIN是一个特殊的变量,指示实际的可执行文件名。它在运行时解析到可执行文件的位置,在设置RPATH时非常有用。

示例

编写libhello.so动态库文件

hello.h

#pragma oncevoid HelloFunc();

hello.cpp

#include <iostream>void HelloFunc()
{std::cout << "hello function \n";
}

编译

➜ g++ -fPIC -shared -o libhello.so hello.c

main.c

#include <iostream>
#include "hello.h"
int main()
{HelloFunc();std::cout << "hello world \n";return 0;
}

正常编译

➜ g++ main.c -o main -L. -lhello

运行结果

./main: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

我们需要解决找到libhello.so的问题才可以使main运行起来,可以通过以下两种方式

  • export LD_LIBRARY_PATH=yourpath/lib
  • libhello.so拷贝到/usr/local/lib,然后运行ldconfig

使用RPATH

编译期

编译命令改为

➜ g++ main.c -o main -L. -lhello -Wl,-rpath='$ORIGIN/'

运行

➜./main
hello function
hello world

程序正常运行

在编译之后,执行之前

  • 使用chrpath
chrpath -r "\$\ORIGIN/path/to/library" <executable>

如果之前没有为可执行文件设置rpath,上述命令可能会失败。使用patchelf实用程序尝试下面的命令,它不会抱怨没有设置rpath,并且会设置RUNPATH来实现类似的目标。

  • 使用patchelf
patchelf — set-rpath ‘$ORIGIN/path/to/library’ <executable>

如何检查RPATH的值?

有多种方法可以检查可执行文件或库的RPATH值。objdump、readelf和chrpath是3个常用的实用程序。

objdump -x path/to/executable | grep RPATH

或者

readelf -d path/to/executable | head -20

或者

chrpath -l path/to/executable

使用readelf结果

➜  hello readelf -d main | head -20   Dynamic section at offset 0x2dd0 contains 29 entries:标记        类型                         名称/值0x0000000000000001 (NEEDED)             共享库:[libhello.so]0x0000000000000001 (NEEDED)             共享库:[libstdc++.so.6]0x0000000000000001 (NEEDED)             共享库:[libm.so.6]0x0000000000000001 (NEEDED)             共享库:[libgcc_s.so.1]0x0000000000000001 (NEEDED)             共享库:[libc.so.6]0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN/]0x000000000000000c (INIT)               0x4010000x000000000000000d (FINI)               0x4012440x0000000000000019 (INIT_ARRAY)         0x403db80x000000000000001b (INIT_ARRAYSZ)       16 (bytes)0x000000000000001a (FINI_ARRAY)         0x403dc80x000000000000001c (FINI_ARRAYSZ)       8 (bytes)0x000000006ffffef5 (GNU_HASH)           0x4003080x0000000000000005 (STRTAB)             0x4004080x0000000000000006 (SYMTAB)             0x4003300x000000000000000a (STRSZ)              269 (bytes)0x000000000000000b (SYMENT)             24 (bytes)
➜  hello

RPATH $ORIGIN 你的库为什么找不到相关推荐

  1. stm32添加了固件库但是找不到h文件

    stm32添加了固件库但是找不到h文件 像我就会经常使用别的的工程,有时候在上面添加一个功能可能会遇见这种情况. . -\SYSTEM\adc\adc.c(12): error: #20: ident ...

  2. python安装第三方库时找不到“cl.exe”的解决方法(Win10系统)

    闲话不多说,直接上重点. 当我们使用Python安装第三方库时,可能会遇到显示一大堆字母,什么也看不懂,但是里面仿佛有一句在说"找不到'cl.exe'",作为一个Python党.C ...

  3. 【c++开发】C++ Linux Ubuntu imagemagick以及magick++安装;c++调用magick++库;找不到Magick++.h

    ubuntu系统自带的imagemagick没有c++函数库,需要能重新下载一个新一点的库,重新编译并且安装 一.教程 官网详细教程:https://imagemagick.org/script/in ...

  4. apache常见错误:VC运行库(找不到 VCRUNTIME140.dll)

    1. 安装apache为系统服务时报错:找不到 VCRUNTIME140.dll 解决方案:安装 VC2015 2. 下载并安装 VC2015 运行库, 运行 VC_redist.x64.exe 无脑 ...

  5. 关于windows系统中静态库链接找不到的问题

    典型错误提示如下 error LNK2019: 无法解析的外部符号 _GdiplusStartup@12,该符号在函数 "public: __thiscall APPInit::APPIni ...

  6. VS2013编译Duilib界面库,“找不到Riched20.lib”的问题

    如果已安装Windows SDK.Windows Mobile SDK且默认包含这些目录编译源代码没有问题.由于一些改动需要版本管理发现Build Agent运行失败,考虑到迁移各方面原因还是决定修改 ...

  7. 成语接龙 给一个很大的成语库 如何找出其中最长的一条线

    [问题描述] 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记 ...

  8. Leetcode题库1823. 找出游戏的获胜者(约瑟夫环 C实现)

    文章目录 思路 状态转移过程 状态转移方程 递归思路 迭代思路 补充 代码 递归 迭代 思路 状态转移过程 设 n 名小伙伴做游戏,计数为k 有n名小伙伴时,第一个离开的小伙伴编号为k,剩下n-1名小 ...

  9. FFmpeg编译找不到库文件

    在编译FFmpeg的时候,用./configure 进行配置,经常会出现找不到库文件的情况,原因大概就两个: 1.没有安装库文件或者安装的库文件版本不对 2.FFmpeg没有找到库文件 前者的问题好解 ...

最新文章

  1. GARFIELD@12-10-2004
  2. 酷炫Jquery收集
  3. 【Docker】记一次docker container ping domain 和 ping ipv6地址不通问题
  4. 时空大数据 AI 研究院在京成立,助推时空产业高质量发展
  5. JIRA介绍- 一个专业优秀的缺陷跟踪管理软件
  6. 使用IQueryable扩展方法实现复杂查询条件
  7. Java 格式转换:利用格式转换实现随机数生成随机 char 字母及 string 字母串
  8. iOS自定义弹出视图、收音机APP、图片涂鸦、加载刷新、文件缓存等源码 1
  9. 位带操作全解释,个人觉得不错就转过来理解下
  10. php读取doc pdf文件,PHP读取创建txt,doc,xls,pdf类型文件
  11. 生态功能区划方法之一:生态敏感性分析法
  12. DRBD 管理、故障处理部分
  13. linux文件属性全解,Linux文件属性详细图解
  14. 大数据量查询大杀器之Mybatis 流式查询
  15. ACCV 结果出来了,大家来晒一晒吧~
  16. 刷手机流量,反正浪费就完事了
  17. PKUSC2018游记
  18. Ubuntu的一些实用软件
  19. 【Java面试高频-集合】- 读写的场景设计集合是怎么样?对于读多写少要如何设计的呢?对于读少写多又该如何设计呢?
  20. 大数据周会-本周学习内容总结010

热门文章

  1. AI一分钟 |世界级音频专家入职阿里人工智能团队iDST;亚马逊推AI摄像头,开发者专用定价249美元
  2. 蓝桥杯客观题 单片机知识点总结
  3. [数值分析]离散数据拟合-最小二乘法
  4. 对地球币EAC价值趋势发展的解析探讨
  5. eclipse中svn切换用户
  6. Thanks-Giving
  7. 树莓派学习::qt5.10.1交叉编译【带opengl ES2】到非官方64位系统
  8. EDIUS双11嗨购节提前抢!
  9. 程序员35岁真的会失业?我,36岁,揭开北京“码农”的真实状况
  10. Cocoa Touch框架与构建应用界面