linux下动态共享库的创建,使用与更新(包括ldconfig的使用) 分类: Linux/Unix 2010-09-23 16:50 701人阅读 评论(0) 收藏 举报 linuxlibraryp

2023-11-20

分类: Linux/Unix 2010-09-23 16:50  701人阅读  评论(0)  收藏  举报

目录(?)[+]

一 创建并编译共享库

动态链接库一般以lib开头,形如libmymodule.so.1.0.0.   

后面跟的三个版本号,从左到右的含义为:

(1) 大版本号,当接口变得和之前不兼容,则新增一个大版本号。

(2) 一般增加了接口,不过旧的接口不变,则新增此版本号。

(3) 接口不做任何变化,只是实现做了修改,则新增此版本号。 

假设我们的库只包含 module.cpp, 则用命令

[c-sharp]  view plain copy
  1. g++ -fPIC -Wall -c module.cpp  

生成module.o,再用命令

[c-sharp]  view plain copy
  1. g++ -shared -Wl,-soname,libmymodule.so.1 -o libmymodule.so.1.0.0 module.o  

生成libmymodule.so.1.0.0共享库。这里的libmymodule.so.1.0.0也叫做共享库的real name.

  • -fPIC是使生成的目标文件“位置无关(Position Independent Code)”从而可以被多个程序共享。
  • -shared 指定产生共享库。
  • -Wl,-soname,libmymodule.so.1 指定共享库的soname为libmymodule.so.1,若不指定,则无soname. soname的作用后面会提到。可以用objdump -p libmymodule.so.1.0.0 | grep SONAME  查看soname. 

 一般soname带且只带大版本号,比如这里的libmymodule.so.1, 是因为共享库的相互兼容的不同版本,都具有相同的soname(在升级的时候,需要用soname来对应)。而如果大版本号变了,意味着接口变得不兼容了,也就没有必要让这个版本和之前的共享库兼容了。这个时候,启用一个新的soname是更好的做法。

二 编译主程序

因为gcc中,用-l参数指定的库文件必须满足格式lib*.so 所以我们需要建立软连接libmymodule.so, 并令其指向libmymodule.so.1.0.0

[c-sharp]  view plain copy
  1. ln -s libmymodule.so.1.0.0 libmymodule.so  

这里的libmymodule.so就是所谓的"link name"。 

假设我们的主程序(相对于库来说),代码在main.cpp里,则用命令

[c-sharp]  view plain copy
  1. g++ -o main main.cpp -L. -lmymodule  

生产可执行程序main。注意link name只在编译的时候需要,主程序会记住根据这个文件最终所指的共享库的soname,用来在运行的时候,查找加载动态库。如果共享库没有指定soname, 那么主程序会记住这个'link name",也就是lib*.so这样形式的名字,做为soname, 在运行的时候,用这个名字来查找加载动态库。

  • -L指定搜索库的文件夹,
  • -l 指定所依赖的库。注意这里需要去掉前面的“lib”和后面的“.so”

 三 运行期 

这个时候,运行./main会出现以下错误:

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

使用ldd main可以查看所依赖的动态库是否被满足,执行“ldd main":

发现有一行libmymodule.so.1 => not found,说明在运行期,加载器没有找到对应的共享库文件。 

加载器会在以下地方查找main程序中记住的所需要的库的soname:

(1) /etc/ld.so.cache 这是一个cache,存放soname到共享库文件的soname link (一个文件名为soname的软连接) 的映射(key->value值对)。

(2) /usr/lib 和 /lib

(3) 环境变量LD_LIBRARY_PATH指定的文件夹。

可以用ldconfig 命令,解决这个问题。ldconfig主要做2件事情:

一是扫描/lib和/usr/lib和/etc/ld.so.conf里指定文件夹,对里面的共享库建立soname link (ldconfig会根据文件名里的版本号,自动找到最新的共享库文件,并把soname link指向这个最新的共享库文件)

二是更新/etc/ld.so.cache,建立soname到soname link的映射。 

加载器如果在ld.so.cache中查到所需的soname,则会依次找到 soname-->soname link-->实际的共享库文件。如果找不到,则会在/usr/lib和/lib中查找文件名为soname的文件,作为共享库文件加载。注意,在这里,加载器不会去找/etc/ld.so.conf里指定的文件夹,只会找/usr/lib和/lib所以如果在/etc/ld.so.conf里指定的文件夹,增加了soname link,必须要运行ldconfig来更新ld.so.cache。 

ldconfig -n /path/to/dir 命令可以指定某文件夹,不过只会做第一件事,也就是建立soname link-->实际的共享库文件。不会更新ld.so.cache 所以不需要root权限。 

ldconfig -p 命令可以打印ld.so.conf里已经有的键值对。 

好了,了解了以上知识,我们可以用以下方法解决找不到共享库的问题: 

(a) 将libmymodule.so.1.0.0拷到/lib或者/usr/lib里,或者/etc/ld.so.conf指定的文件夹,然后执行sudo ldconfig. 于是ldconfig会自动在/lib或/usr/lib或/etc/ld.so.conf指定的文件夹里生成soname link (文件名为libmymodule.so.1) 指向libmymodule.so.1.0.0,然后在ld.so.cache中增加libmymodule.so.1到/lib /libmymodule.so.1或/usr/lib/libmymodule.so.1的映射(前者是个名字,后者是个软连接文件) 

(b) 使用LD_LIBRARY_PATH=/PATH/TO/SO ./main来运行程序。前提是在/PATH/TO/SO中建立一个名字为soname的软连接,使其指向实际的共享文件。 

(c) 在/lib或/usr/lib中,手动建立软连接 libmymodule.so.1 令其指向实际的共享库文件 libmymodule.so.1.0.0。 因为前面提到的,加载器在ld.so.cache中找不到要找的键为soname的项,会在/lib或/usr/lib中找名字为soname的文件。这方法虽然可以用,不过感觉比较粗暴。不推荐。

四 升级共享库

如果是用上述(a)方法使用共享库的,只需要将新的共享库,比如 libmymodule.so.1.0.1拷到原来的目录(/lib或/usr/lib或者/etc/ld.so.conf指定的文件夹),然后运行 ldconfig即可。ldconfig会更新soname link, 使其指向最新的共享库文件libmymodule.so.1.0.1,ld.so.cache不需要更新。 

如果是用上述(b)(c)方法是用共享库的,需要更新相应的软连接,使其指向最新的共享库文件。 

 

五 动态加载共享库

在主程序中动态加载共享库时,如果指定的是绝对路径("/"开头的),则加载该绝对路径指向的共享库文件。如果不是绝对路径,而是一个文件名,则将这个文件名当作soname,然后依照上述的方法,查找加载相应的共享库文件。

六 注意点

如果在共享库中,要用到主程序的变量或者方法,要在编译主程序时,加上-rdynamic参数,使得所有名字在共享库的空间中可见。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux下动态共享库的创建,使用与更新(包括ldconfig的使用) 分类: Linux/Unix 2010-09-23 16:50 701人阅读 评论(0) 收藏 举报 linuxlibraryp 的相关文章

随机推荐

  • 《论文阅读》CARE:通过条件图生成的共情回复因果关系推理 EMNLP 2022

    论文阅读 CARE 通过条件图生成的移情反应因果关系推理 前言 简介 基础知识 Transformer Variational Graph Auto Encoder 变分图自编码器 邻接矩阵 adjacency matrix 图神经网络 G
  • HDFS 文件读写流程剖析

    Write hadoop fs put czz log wc in 1 Client调用FileSystem create filePath 方法 与NN进行RPC通信 check是否存在及是否有权限创建 假如不ok 就返回错误信息 假如o
  • 【RTT驱动框架分析06】-pwn驱动框架分析+pwm驱动实现

    pwm pwm应用程序开发 访问 PWM 设备API 应用程序通过 RT Thread 提供的 PWM 设备管理接口来访问 PWM 设备硬件 相关接口如下所示 函数 描述 rt device find 根据 PWM 设备名称查找设备获取设备
  • React、Vue2.x、Vue3.0的diff算法

    前言 本文章不讲解 vDom 实现 mount 挂载 以及 render 函数 只讨论三种 diff 算法 VNode 类型不考虑 component functional component Fragment Teleport 只考虑 E
  • 算法篇--链表求和

    问题描述 给两个链表 每个链表为一个整数的倒序 如下 1 2 3 4 5 7 9 两个数字的结果 321 9754 10075 那么 请得到 链表的结果为 5 7 0 0 1 思考 思路总结 两个链表肯定有一个最长的 等于情况取哪个都行 所
  • sudo配置文件/etc/sudoers详解及实战用法

    一 sudo执行命令的流程 将当前用户切换到超级用户下 或切换到指定的用户下 然后以超级用户或其指定切换到的用户身份执行命令 执行完成后 直接退回到当前用户 具体工作过程如下 当用户执行sudo时 系统会主动寻找 etc sudoers文件
  • hudi概念

    近实时摄取 对于 RDBMS 关系型的摄入 Hudi提供了更快的 Upset 操作 例如 你可以通过 MySql binlog 的形式或者 Sqoop 导入到 hdfs上的对应的 Hudi表中 这样操作比 Sqoop 批量合并 job Sq
  • tomcat进程意外退出的问题分析

    节前某个部门的测试环境反馈tomcat会意外退出 我们到实际环境排查后发现不是jvm crash 日志里有进程销毁的记录 从pause到destory的整个过程 org apache coyote AbstractProtocol paus
  • RNA-seq——四、根据序列比对结果筛选差异基因

    目录 1 合并矩阵并进行注释 2 筛选差异基因 DESeq2 写在前面 经过前面的一系列分析 我们得到了几个counts数据 接下来就需要根据这些数据来进行分析 本文使用Rstudio 从序列比对结果中筛选出差异基因 目的是 根据不同基因的
  • 在使用服务器时,配置torch环境(这里是以tengxunyun为例子配置的环境)

    这里配置的环境是使用的bubbliiiing的代码为例子进行配置的 配置环境需要对应自己电脑的显卡以及CUDA版本 最重要是torch的安装 一定要去官网去找对应的版本 1 conda create n pytorch python 3 6
  • 【Vue3.0实战逐步深入系列】使用elementui组件库element-plus美化投票功能

    千字长文 熬夜更新 原创不易 多多支持 感谢大家 前言 小伙伴们大家好 前面一篇文章中我们利用vue3 0实现了一个超级简单的投票功能 虽然功能是实现了也达到了巩固vue3 0知识点的目的 但是页面没有添加任何样式也没有进行任何的UI设计
  • 软件工程基础知识--系统测试

    系统测试与调试 1 系统测试的意义和目的 系统测试是为了发现错误而执行程序的过程 以最少的人力和时间发现潜在的各种错误和缺陷 根据测试的概念和目的 在进行信息系统测试时应遵循以下基本原则 1 应尽早并不断地进行测试 2 测试工作应该避免由原
  • python入门之字符串

    目录 一 字符串的定义 二 字符串的常用操作 三 字符串的切片 一 字符串的定义 字符串就是一串字符 是编程语言中表示文本的数据类型 在python中可以使用一对双引号 或者一对单引号 定义一个字符串 虽然可以使用 或者 做字符串的转义 但
  • 区块链数字存证平台有哪些功能模块

    区块链数字存证平台通常包括以下功能模块 数字存证 将数字文件的哈希值存储到区块链上 确保文件的完整性和不可篡改性 时间戳 记录数字文件的创建时间和存证时间 确保存证的时效性和证据的可信度 鉴定证书 提供数字文件的鉴定证书 证明文件的真实性和
  • 第7章 Linux文件过滤及内容编辑处理

    第7章 Linux文件过滤及内容编辑处理 在第5章 我们讲解了Linux系统文件及目录处理的基本命令知识和应用实践 本章继续为大家讲解处理Linux系统文件内容的一些核心命令 这些命令同样十分重要 7 1 vi vim 纯文本编辑器 Win
  • Fedora又一次哑了,又如何?

    Fedora自从34版本开始使用PipeWire代替原来的PulseAudio 每次更新系统版本就让用户产生怀疑的态度 此前我就写过一篇 Fedora 34成哑巴了 结果在Fedora35又失效了 原因是Fedora35选择WirePlum
  • Unity 分块延迟渲染01 (TBDR)

    现代移动端图形体系结构的概述 现代SoC通常会同时集成CPU和GPU CPU被用于处理需要低内存延迟的序列 大量分支的数据集 其晶体管用于流控制和数据缓存 GPU为处理大型 未分支的数据集 如3D渲染 晶体管专用于寄存器和算术逻辑单元 而不
  • adb链接夜神模拟器以及常用的adb命令整理

    夜神模拟器链接adb 1 打开夜神模拟器 打开设置 调成手机模式 初次进入的话 进入设置 点击版本号5次 可以激活使用开发者模式 进入后打开USB调试功能 2 打开文件资源管理器 进入夜神模拟器的安装位置 在地址栏输入cmd 回车 会打开c
  • 步进电机基础(5.6)-步进电机的驱动与控制-闭环控制

    步进电机基础 5 6 步进电机的驱动与控制 闭环控制 前言 基本信息 前言说明 5 6 闭环控制 前言 基本信息 名称 描述说明 教材名称 步进电机应用技术 作者 坂本正文 译者 王自强 前言说明 根据我读的 步进电机应用技术 这本书 进行
  • linux下动态共享库的创建,使用与更新(包括ldconfig的使用) 分类: Linux/Unix 2010-09-23 16:50 701人阅读 评论(0) 收藏 举报 linuxlibraryp

    linux下动态共享库的创建 使用与更新 包括ldconfig的使用 分类 Linux Unix 2010 09 23 16 50 701人阅读 评论 0 收藏 举报 linux library path file object cache