-L和-rpath-link和-rpath

知识点

现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。
链接器ld的选项有 -L,-rpath 和 -rpath-link,看了下 man ld,大致是这个意思:

-L: “链接”的时候,去找的目录,也就是所有的 -l 选项里的库,都会先从 -L 指定的目录去找,然后是默认的地方。编译时的-L选项并不影响环境变量LD_LIBRARY_PATH,-L只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库,如果找不到,还是会报错,类似cannot open shared object file。

-rpath-link:这个也是用于“链接”的时候的,例如你显示指定的需要 FOO.so,但是 FOO.so 本身是需要 BAR.so 的,后者你并没有指定,而是 FOO.so 引用到它,这个时候,会先从 -rpath-link 给的路径里找。

-rpath: “运行”的时候,去找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找。对于交叉编译,交叉编译链接器需已经配置 –with-sysroot 选项才能起作用。也就是说,-rpath指定的路径会被记录在生成的可执行程序中,用于运行时查找需要加载的动态库。 

知识点2

  -Wa,<options>   Pass comma-separated <options> on to the assembler
  -Wp,<options>   Pass comma-separated <options> on to the preprocessor
  -Wl,<options>   Pass comma-separated <options> on to the linker 

the -rpath option encodes the path in the binary, either as DT_RPATH or DR_RUNPATH

通常,您不需要它,事实上,最好不要在可执行文件中对库搜索路径进行编码(使用-rpath选项将路径编码为二进制,可以是DT_rpath或DR_RUNPATH)

注:我自己的一般方法是在可执行文件位于构建树中,并依赖于构建树中的其他库时,将其与–rpath选项链接,以便于调试,但在安装(make install,building packages)时,需要在不使用–rpath选项的情况下重新链接,并将查找共享库的任务留给目标平台的适当动态链接器配置,例如ld.so.conf。 

知识点3

binutils在2.22版本以后,默认把–no-copy-dt-needed-entries这个选项打开了。当打开了这个选项的时候,编译器在链接的时候是不会递归的去获取依赖动态库的依赖项的,于是就会出现上述的问题。

   --copy-dt-needed-entries
   --no-copy-dt-needed-entries
       This option affects the treatment of dynamic libraries referred to by DT_NEEDED tags inside ELF dynamic libraries mentioned on the command line.  Normally the linker won't add a DT_NEEDED
       tag to the output binary for each library mentioned in a DT_NEEDED tag in an input dynamic library.  With --copy-dt-needed-entries specified on the command line however any dynamic
       libraries that follow it will have their DT_NEEDED entries added.  The default behaviour can be restored with --no-copy-dt-needed-entries.

       This option also has an effect on the resolution of symbols in dynamic libraries.  With --copy-dt-needed-entries dynamic libraries mentioned on the command line will be recursively
       searched, following their DT_NEEDED tags to other libraries, in order to resolve symbols required by the output binary.  With the default setting however the searching of dynamic
       libraries that follow it will stop with the dynamic library itself.  No DT_NEEDED links will be traversed to resolve symbols.
跟在–no-copy-dt-needed-entries它后面的库都不会遍历其依赖项,使用–copy-dt-needed-entries则相反。即可以遍历所有依赖项目,保证编译成功。

实例

//a.cc == main.cc
#include <iostream>
#include "b.h"int main()
{bbb();std::cout << "Hello world" << std::endl;return 0;
}//b.h-----
#pragma oncevoid bbb();//b.cc-----
#include <iostream>
#include "ccc.h"void bbb()
{ccc();std::cout << "Hello world" << std::endl;
}// ccc.h-----
#pragma once
void ccc();// ccc.cc-----
#include <iostream>void ccc()
{std::cout << "Hello world" << std::endl;
}

编译过程1

$ g++ -fPIC -shared ccc.cc -o libccc.so
$ g++ -fPIC -shared b.cc -o libbbb.so -L. -lccc
# g++ a.cc -L. -lb 是不行的,具体看https://blog.csdn.net/zrq293/article/details/105969423
g++ a.cc -L. -lb -Wl,--copy-dt-needed-entries
/usr/bin/ld: warning: libccc.so, needed by ./libb.so, not found (try using -rpath or -rpath-link)
$ g++ a.cc -L. -lb -Wl,--copy-dt-needed-entries,-rpath-link=.
$ ./a.out
./a.out: error while loading shared libraries: libb.so: cannot open shared object file: No such file or directory
$ g++ a.cc -L. -lb -Wl,--copy-dt-needed-entries,-rpath-link=.,-rpath=.
tiantian@DESKTOP-UVN3KRD:~/code$ ./a.out
./a.out: error while loading shared libraries: libccc.so: cannot open shared object file: No such file or directory$ ldd a.outlinux-vdso.so.1 (0x00007ffff5585000)libb.so => ./libb.so (0x00007f44961f0000)libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4495fc0000)libc.so => ./libc.so (0x00007f4495fb0000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4495d80000)libccc.so => not foundlibm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4495c80000)/lib64/ld-linux-x86-64.so.2 (0x00007f4496215000)libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4495c60000)
$ export LD_LIBRARY_PATH=.
$ ./a.out
Hello world
Hello world
Hello world

cmake的扩展

默认cmake设置

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  
设置rpath

SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 
SET(CMAKE_INSTALL_RPATH "\${ORIGIN}/../lib")

  1. 默认情况下,这个PATH在构建产生的中间文件,是不增加的;而是只对安装的目标有效。如果你想针对构建的中间文件也有效果,可以加上
  2. 手动指定添加的RPATH

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/37552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go学习-Day1

Go学习-Day1 个人博客&#xff1a;CSDN博客 打卡。 Go语言的核心开发团队&#xff1a; Ken Thompson (C语言&#xff0c;B语言&#xff0c;Unix的发明者&#xff0c;牛人)Rob Pike(UTF-8发明人)Robert Griesemer(协助HotSpot编译器&#xff0c;Js引擎V8) Go语言有静态语言的…

MongoDB安装

文章目录 MongoDB安装设置yum源安装指定版本的mongodb配置文件连接MongoDB的工具MongoDBCompass MongoDB安装 设置yum源 [rootWDQCVM sbin]# vim /etc/yum.repos.d/mongodb-org-6.0.repo [mongodb-org-6.0] nameMongoDB Repository baseurlhttps://repo.mongodb.org/yum/red…

文件预览/下载方式:通过二进制流(Blob)下载、或者通过文件Url下载

一、 通过二进制流&#xff08;Blob&#xff09;下载 1 、API请求时候带上类型 /*** 文件--下载* */ export function download(fphm) {return axios({url: "/ynpst/download-invoice?fphm" fphm,method: get,responseType: blob}) }2、文件预览和下载 /*** 预览…

JavaScript如何执行语句

目录 语法/词法分析 预编译 解释执行 预编译什么时候发生 js运行三步曲 预编译前奏 预编译步骤 巩固基础练习 语法/词法分析 按语句块的粒度解析成抽象语法树 ,分析该js脚本代码块的语法是否正确&#xff0c;如果出现不正确&#xff0c;则向外抛出一个语法错误&#x…

第4章:决策树

停止 当前分支样本均为同一类时&#xff0c;变成该类的叶子节点。当前分支类型不同&#xff0c;但是已经没有可以用来分裂的属性时&#xff0c;变成类别样本更多的那个类别的叶子节点。当前分支为空时&#xff0c;变成父节点类别最多的类的叶子节点。 ID3 C4.5 Cart 过拟合 缺…

文本挖掘 day5:文本挖掘与贝叶斯网络方法识别化学品安全风险因素

文本挖掘与贝叶斯网络方法识别化学品安全风险因素 1. Introduction现实意义理论意义提出方法&#xff0c;目标 2. 材料与方法2.1 数据集2.2 数据预处理2.3 关键字提取2.3.1 TF-IDF2.3.2 改进的BM25——BM25WBM25BM25W 2.3.3 关键词的产生(相关系数) 2.4 关联规则分析2.5 贝叶斯…

css冒号对齐

实现后的样式效果 实现方式 html&#xff1a; <el-col v-if"item.showInSingle ! false" :span"6" style"padding: 4px 0"><label>{{ item.label }}&#xff1a;</label><span v-if"singleData[item.prop] ! 0 &…

iOS字体像素与磅的对应关系

注意&#xff1a;低于iOS10的系统&#xff0c;显示的字宽和字高比高于iOS10的系统小。 这就是iOS10系统发布时&#xff0c;很多app显示的内容后面出现…&#xff0c;因而出现很多app为了适配iOS10系统而重新发布新版本。 用PS设计的iOS效果图中&#xff0c;字体是以像素&#x…

SRM订单管理:优化供应商关系

一、概述SRM订单管理的概念&#xff1a; SRM订单管理是指在供应商关系管理过程中&#xff0c;有效管理和控制订单的创建、处理和交付。它涉及与供应商之间的沟通、合作和协调&#xff0c;旨在实现订单的准确性、可靠性和及时性。 二、SRM订单管理的流程&#xff1a; 1. 订单创…

关于onload事件

onload事件是在网页中的所有内容&#xff08;包括图片、样式表、脚本等&#xff09;都加载完成后触发的事件。它常用于在页面加载完成后执行一些操作&#xff0c;例如初始化页面元素、绑定事件监听器等。 可以通过以下方式来使用onload事件&#xff1a; 在HTML标签中直接添加…

NGINX源码安装

文章目录 NGINX源码安装安装依赖包获取源码NGINX官方网站各个目录的用途 编译安装安装结束后的文件设置为服务 NGINX源码安装 安装依赖包 root执行 yum -y install gcc gcc-c make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel这些包是用于开发和构建软件…

递归的用法和例子

b站视频&#xff1a;https://www.bilibili.com/video/BV1iS4y1e7MJ/?spm_id_from333.999.0.0&vd_source1717654b9cbbc6a773c2092070686a95 # 递归的定义&#xff1a;其实就是自己调用自己&#xff0c;一般用函数的形式来进行 """ 特点&#xff1a; 1、一定…

item_review-获得TB商品评论

一、接口参数说明&#xff1a; item_review-获得TB商品评论&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/taobao/item_review 名称类型必须描述keyString是调用key&#xff08;点击获取…

轻拍牛头(约数)

题意&#xff1a;求ai在n个数中&#xff0c;ai可以整除的数有多少个&#xff0c;不包括ai自己。 分析&#xff1a;暴力写需要n^2的时间复杂度&#xff0c;此时想一下预处理每个数的倍数&#xff0c;约数和倍数是有关系的&#xff0c;把每个数的倍数都加上1. #include<bits…

腾讯云SA3服务器AMD处理器CPU网络带宽性能详解

腾讯云AMD服务器SA3实例CPU采用2.55GHz主频的AMD EPYCTM Milan处理器&#xff0c;睿频3.5GHz&#xff0c;搭载最新一代八通道DDR4&#xff0c;内存计算性能稳定&#xff0c;默认网络优化&#xff0c;最高内网收发能力达1900万pps&#xff0c;最高内网带宽可支持100Gbps。腾讯云…

typeScript 之 运算符

工具&#xff1a; PlayGround 算术运算符 运算符描述加-减*乘/除%取模(求余)自增–自减 注意和--&#xff0c;实例&#xff1a; let value 0; console.log(value); //0, 先显示再增加后为1 console.log(value); //2&#xff0c;先增加后为2再显示关系运算符 运算符描述 …

list.stream.filter,List<List>转换为List

1.filter过滤 返回符合查询条件的集合//过滤所有deviceType为1的List<DeviceWorkTimeEntity> list entities.stream().filter(a -> "1".equals(a.getDeviceType())).toList(); 2.List<List>转换为List 可以使用流(Stream)的flatMap操作 public cl…

嵌入式Linux驱动开发系列五:Linux系统和HelloWorld

三个问题 了解Hello World程序的执行过程有什么用? 编译和执行&#xff1a;Hello World程序的执行分为两个主要步骤&#xff1a;编译和执行。编译器将源代码转换为可执行文件&#xff0c;然后计算机执行该文件并输出相应的结果。了解这个过程可以帮助我们理解如何将代码转化…

从一到无穷大 #10 讨论 Apache IoTDB 大综述中看到的优劣势

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言问题定义新技术数据模型schemalessTsfile设计双MemTable高级可扩展查询其他 IotD…

两天入门Linux、搭建Spring环境 第一天

一、Linux简介 1.什么是Linux 一个操作系统&#xff0c;未来公司里面会用到、接触的新操作系统。 2.为什么学Linux (1)个人职务需要&#xff0c;肯定会接触到Linux (2)职业发展&#xff0c;以后的发展肯定需要掌握Linux的许多使用方法 3.学哪些内容 (1)Linux基本介绍 (2)…