高级C/C++编译技术之读书笔记(四)之定位库文件

最近有幸阅读了《高级C/C++编译技术》深受启发,该书深入浅出地讲解了构建过程(编译、链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架构设计方法,以及系统开发过程中疑难问题的解决方案。
以下将回头记录下其中的关键要点,以便后面查阅。
本节思维导图

1. linux库命名规则
(1)静态库:lib+<library name>. + a
(2)动态库:lib+<<library name> + .so + <library version information>
(3)动态库的版本信息
dynamic libaray version information = <M>.<m>.<p>
M:主版本号
m:次版本号
p:补丁(很小的代码改动)版本号
(4)动态库的soname
soname = lib+<libaray name>+.so+M
动态库的soname通常由连接器嵌入二进制文件的专有ELF字段中,通常用特定的连接器选项,将表示库soname的字符串传递给链接器
g++ -shared <list of object files> -Wl, -soname, libfoo.so. -o libfoo.so.1.0.
注意:(1)-Wl选项告诉编译器将后面的参数传递给链接器
(2)凡是间接调用链接器时,我们需要在链接器参数前追加“Wl,”
2. 构建过程中库文件定位规则
在Linux中用-L和-l选项来指定构建过程中库文件路径
(1)将完整的库文件路径分成两个部分:目录路径和库文件名
(2)将目录路径添加到-L连接器选项后面,并传递给链接器
(3)将库文件名添加到-l参数后面,并传递给连接器
g++ main.o -L../sharedlib -lwokingdemo -o demo
在使用g++命令行一次性完整编译链接两个过程时,应在在链接器前添加-Wl,
g++ -Wall -fPIC main.cpp -Wl, -L../sharedlib -Wl, -lworkingdeno -o demo
3. 运行时动态库文件定位规则
对于经验不足的linux软件工程师经常会遇到找到不动态库的情况而不知所措,主要是对以下内容不够了解。
动态库运行时搜索算法由一组规则约束,按照优先级从高到低列出
(1)预加载库
毫无疑问,预加载库应该拥有最高的搜索优先级,装载器会首先加载这些库,然后才开始搜索其它库,有两种方法可以指定预加载库
a:通过设置LD_PRELOAD环境变量
export LD_PRELOAD=/home/fate/shareddir/libtest.so:$LD_PRELOAD
b:通过修改、etc/ld.so.preload文件
指定预加载库并不符合标准的设计规范。相反,该方案仅用于特殊情况,比如设计压力测试、诊断已经对原始代码的紧急补丁等
(2)rpath
rpath和runpath都可供我们使用,但是runpath在运行时搜索优先级列表中赋予了更高的优先级,只有在runpath缺失的情况下,rpath才是linux装载器剩余的搜索路径信息中具有最高优先级的。
但如果ELF二进制文件的runpath(DT_RUNPATH)字段是非空的,那么rpath会被忽略
g++ -Wl, -R/home/fate/shared/ -ltestlibrary
或者,也可以用LD_RUN_PATH环境变量来设置rpath
export LD_RUN_PATH=/home/fate/shared:$LD_RUN_PATH
(3)LD_LIBARAY_PATH
从库搜索概念发展初期开始,开发人员就希望可以使用一种临时应急的有效机制来验证它们的设计,通过特定的环境变量(LD_LIBRARY_PATH)就能解决我们遇到的问题,当没有rpath时,该路径就是路径搜索信息中优先级最高的
export LD_LIBRARY_PATH=/home/fate/shared/:$LD_LIBRARY_PATH
注意:该机制只应用于实验目的,软件产品的产品版本不应该依赖于这种机制
(4)runpath
设置runpath的方法和设置rpath的方法非常相似,为了传递-R或-rpath链接器选项,需要使用额外的--enable-new-dtags链接选项
g++ -Wl,-R/home/fate/shared/ -Wl, --enable-new-dtags -ltestlibrary
(5)ldconfig缓存
一种标准的代码部署过程是基于运行linux的ldconfig工具,ldconfig会将指定的目录路径插入动态库搜索列表中,该列表维护在文件/etc/ld.so.conf中。同样地,系统会扫描新加入的目录路径,其结果是将发现的库文件名添加到库文件名列表中,该表维护在/etc/ld.so.cache文件中
4. 默认库文件路径
/lib和/usr/lib是linux操作系统保存动态库的两个默认路径
5. 优先级方案小节
总的来说,优先级方案可以归纳为以下两种版本:
(1)如果指定了RUNPATH(即LD_RUNPATH字段非空)
a. LD_LIBRARY_PATH
b. runpath(LD_RUNPATH)
c. ld.so.cache
d. 默认路径
(2)如果没有指定runpath
a. 被加载库的RPATh,然后是二进制文件的RPATH,直到可执行文件或者动态库将这些库全部加载完毕为止
b. LD_LIBRAYR_PATH
c. ld.so.cache
d. 默认路径
6.示例:动态库的创建和函数调用
linux_so.h
#pragma once #ifdef __cplusplus
extern "C"
{
#endif
void fun();
#ifdef __cplusplus
}
#endif
linux_so.c
#include "linux_so.h" #include <iostream>
using namespace std; void fun()
{
cout << "print fun" << endl;
}
main.c
#include "stdio.h" #include "linux_so.h" int main()
{
fun();
return ;
}
编译、链接
g++ -Wall -g -o0 -fPIC -shared linux_so.c -o liblinux_so.so
g++ -Wall -g -o0 -fPIC main.c -Wl,-L./ -Wl,-llinux_so -o out
export LD_LIBRARY_PATH=/home/fate/sharedir/dlltest/:$LD_LIBRAYR_PATH
输出

高级C/C++编译技术之读书笔记(四)之定位库文件的更多相关文章
- 高级C/C++编译技术之读书笔记(一)之编译/链接
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- 高级C/C++编译技术之读书笔记(二)之库的概念
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- 高级C/C++编译技术之读书笔记(三)之动态库设计
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- 高级C/C++编译技术之读书笔记(五)之动态库版本控制
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- webkit技术内幕读书笔记 (四)
资源缓存 资源缓存的目的是为了提高资源使用的效率,其基本思想是建立一个资源的缓存池,当需要请求资源的时候先去资源池查找是否有相应的资源,如果没有则向服务器发送请求,webkit收到资源后将其设置到该资 ...
- 深入理解linux网络技术内幕读书笔记(四)--通知链
Table of Contents 1 概述 2 定义链 3 链注册 4 链上的通知事件 5 网络子系统的通知链 5.1 包裹函数 5.2 范例 6 测试实例 概述 [注意] 通知链只在内核子系统之间 ...
- 深入探索Android热修复技术原理读书笔记 —— 代码热修复技术
在前一篇文章 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍中,对热修复技术进行了介绍,下面将详细介绍其中的代码修复技术. 1 底层热替换原理 在各种 Android 热修复方案中 ...
- 深入探索Android热修复技术原理读书笔记 —— 资源热修复技术
该系列文章: 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍 深入探索Android热修复技术原理读书笔记 -- 代码热修复技术 1 普遍的实现方式 Android资源的热修复,就 ...
- 深入探索Android热修复技术原理读书笔记 —— so库热修复技术
热修复系列文章: 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍 深入探索Android热修复技术原理读书笔记 -- 代码热修复技术 深入探索Android热修复技术原理读书笔记 ...
随机推荐
- datagrid 用法
http://blog.csdn.net/xhhuang1979/article/details/8331682
- 双camera景深计算 (1)
http://www.52rd.com/S_TXT/2016_6/TXT85047.HTM?WebShieldDRSessionVerify=Wz3h6srvu76qRI4MFxK8 前面介绍了双ca ...
- SpringBoot服务器压测对比(jetty、tomcat、undertow)
1.本次对比基础环境信息如下: springboot版本1.5.10 centos虚机4c6G,版本7.4 centos实机2u16c40G,版本7.4,虚机运行在实机上 ab版本2.3 jprofi ...
- python3爬虫全国地址信息
PHP方式写的一团糟所以就用python3重写了一遍,所以因为第二次写了,思路也更清晰了些. 提醒:可能会有502的错误,所以做了异常以及数据库事务处理,暂时没有想到更好的优化方法,所以就先这样吧.待 ...
- Cocos2d-x项目移植到WP8系列之九:使用自定义shader
本文原链接:http://www.cnblogs.com/zouzf/p/3995132.html 有时候想得到一些例如灰度图等特殊的渲染效果,就得用到自定义shader,关于shader的一些背景知 ...
- 聊聊这两天在linux安装PHP7遇到的坑,真的是坑死人不偿命啊
前情摘要: 这两天要在虚拟机上部署项目,用于测试在linux上项目效果怎样,然后这两天就一直在部署apache+mysql+php 其实部署还是很简单的具体的apache和mysql部署方法请看其他两 ...
- 金中半日baoling游-----stoi
蒟蒻又来水博客了,写个游记啦啦啦啦,好像是第一篇游记咯. 温馨提示:愚人节写的博客看了后会变棒棒哦!(麻麻再也不用担心我被骗) 进入正题 3月31日早6:30左右起床了,然后就是....(此处可省略) ...
- java基础(5)--流程控制结构
流程控制结构 if结构 当关系表达式为true时,执行语句 if(关系表达式){ //语句块 } if-else结构 当关系表达式为true时,执行语句块1,否则执行语句块2 if(关系表达式){ / ...
- Hive-开启动态分区
开启动态分区 --开启动态分区 set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict ...
- Java集合Collection&Map
Map<K,V>是键值对,K - 此映射所维护的键的类型,V - 映射值的类型.键值是一一对应的关系: Collection是只有键,底层也是由键值对,但是值的类型被隐藏起来. Colle ...