【Linux】动态库与静态库,如何打包库,如何使用第三方库
文章目录
- 回顾基础
- 学会打包自己的库并使用
- 静态库
- 打包库
- 第三方库的使用
- 动态库
- 打包库
- 第三方库的使用
- 动态库加载以及周边问题
回顾基础
这篇文章主要对动静态库进行进一步的学习,关于动静态库的一些基础知识,请点击这篇文章的链接:【Linux】初识动静态库
- 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
- 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
- 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。
- 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)。
- 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
1.我们在vs编译器下安装开发环境——本质就是安装编译器软件,安装要开发的语言配套的库和头文件。
2.我们在使用编译器的时候,都会有语法的自动提醒功能,有这个提醒功能的前提是要先包含对应的头文件的,所以语法提醒的本质就是编译器或者编辑器,会自动根据用户输入的内容,不断的在被包含的头文件中进行搜索,自动提醒功能是依赖头文件的。
3.系统已经预装了C/C++的头文件和库文件,头文件提供方法说明,库才提供方法实现,头和库是有对应关系的,是要组合在一起使用的。
4.头文件是在预处理的阶段就引入的,链接的本质实际是在链接库。
学会打包自己的库并使用
静态库
打包库
这里我们用一个简单的加减函数来示范,我们先创建以下几个文件,并在mysub,myadd文件中实现对应的功能。(简单的加减函数这里就不赘述了)
当别入需要使用我们实现的代码功能时,我们不可能把myadd.c,mysub.c源代码直接交出去,因为这就暴露了我们代码的实现细节,所以我们往往将.c .h
文件打包成一个库(二进制文件),再给别人。
所以我们这里又创建了一个目录otherPerson代表需要用我们打包的库的其他人。
开始演示:
原因:当我们有了一个库,接下来,要将库引入我们的项目,必须让编译器找到头文件+库文件。
看!现在“别人”通过库文件和头文件就可以成功运行程序了。
步骤:
- 先准备好
.h和.c
文件,然后用gcc
的-c
选项生成.o
目标文件; - 命令
ar -rc libmymath.a *.o
生成静态库,ar是gnu归档工具,rc表示(replace and create); - 查看静态库的目录列表:
ar -tv libmymath.a
,t:列出静态库中的文件,v:详细信息; - 运行程序命令:
gcc -o mytest main.c -L. -lmymath
,-L:指定库路径,-l:指定库名。 - 测试目标文件生成后,静态库删掉,程序照样可以运行。
但实际上一般是打包头文件和库文件给其他人的:
第三方库的使用
1.需要指定的头文件和库文件;
2. 如果没有默认安装到系统gcc,g++默认的搜索路径下,用户必须指明对应的选项,告知编译器头文件在哪里,库文件在哪里,库文件具体是谁。
3. 将我们下载下来的库和头文件,拷贝到系统默认路径下——这个行为就是在Linux下安装库。对任何软件而言,安装和卸载的本质就是拷贝到系统的特定路径。
4. 如果我们按安装的是第三方的(1,2语言,操作系统接口)库,我们要正常使用,即便是已经全部安装到了系统中,gcc/g++必须用-l
指明具体库的名称。
5. 无论是从网络中直接下好的库,或者源代码(可能会提供内置编译方法)——必须有make install安装的命令,实际上就是拷贝安装到系统中,所以我们安装大部分命令,库等等,都是需要sudo或者超级用户操作(因为需要访问系统)。
将第三方库安装到系统中:(还是以上述为例子)
a.提取权限将我们include目录下的所有头文件拷贝到系统头文件/usr/include/
中:
sudo cp -rf include/* /usr/include/
b.提取权限将我们lib目录下的静态库拷贝到系统的库/lib64
中:
sudo cp lib/* /lib64
c.这时就算我们删除了lib和include目录,只有main.c文件,也能成功生成可执行程序,正确编译:
gcc -o mytest main.c -lmymath
云服务器一般都只会提供动态库,下面是安装静态库的命令:
sudo yum install -y glibc-static
sudo yum install -y libstdc++-static
动态库
打包库
还是以上面的加减函数为例:
编译生成.o
目标文件:
fPIC:产生位置无关码(position independent code)
进行打包,动态库的打包就不是用ar了,而是还是用gcc,用法如下:
shared: 表示生成共享库格式
将.o
文件打包成动态库:
还是一样的准备两个自己的目录:include和lib,分别装填自己的头文件和动态库。
将头文件include和lib库文件打包:
第三方库的使用
将mylib中我们已创建好的包mymath.tgz传给“其他人”,本质是拷贝到指定目录下的一个过程。
报的错是找不到动态库,但是我们已经采用上面讲到过的方法,告诉了编译器头文件的位置-I
和库的位置-L
,还有文件名-l
,但是竟然没有成功!为什么呢?
那是因为,运行的时候.so
文件并没有在系统的默认路径下,所以操作系统依旧找不到,静态库能找到的原因是,静态库的链接原则是将用户使用的二进制代码拷贝到了目标可执行程序中,但是动态库的链接原则不是这样的。
那么运行时,OS是如何查找动态库?方法如下:
方法一:配置环境变量
环境变量:LD_LIBRARY_PATH(临时方案,因为环境变量只在当前会话有效,退出了就没了)
echo $LD_LIBRARY_PATH //查看环境变量
方法二:软链接方案
我们在/lib64
下建立了一个软链接,指向libmymath.so
目标文件的所在路径。
方法三:配置文件方案
1.所要配置的文件名称:/etc/ld.so.conf.d/
2.获取权限在该配置文件下创建一个你的文件,如:sudo touch /etc/ld.so.conf.d/nan_test.conf
3.查看是否创建成功:ls /etc/ld.so.conf.d/
4.查看所需第三方动态库所在路径,以上述例子为例,lib动态库的路径是:
/home/nan/linux-learning/基础IO/动态库/otherPerson/lib
5.获取权限vim打开你刚刚在配置文件下创建的文件:sudo vim /etc/ld.so.conf.d/nan_test.conf
将你刚刚获得的动态库路径添加进去,并保存。
6.ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新:sudo ldconfig
7.查看动态库是否添加成功:ldd mytest(可执行程序)
8.最后执行程序,over!!!
动态库加载以及周边问题
静态链接的加载:静态链接形成的可执行程序,本身就有静态库中对应方法的实现,但是非常占用资源!(可执行程序变大加载占用内存,下载周期变长,占用网络资源)
动态链接的加载:将可执行程序中的外部符号,替换成为库中的具体地址。只要我们把库加载到内存,映射到进程的虚拟地址空间之后,我们的代码执行库中的方法,在自己的地址空间内进行函数跳转即可。
库中地址的理解
动态库面临一个问题:不同的进程,运行程度不同,需要使用的第三方库是不同的,每一个进程的共享空间(栈和堆之间有一块共享区)中空闲位置是不确定的!那么动态库和静态库加载的地址是怎么处理的呢?
答:由编译器确定,编译器确定地址分为两种形式:
1.根据当前PC+偏移量确定地址(动态库采用)
2.直接用链接地址(通过链接脚本指定)(静态库采用)
区别就是:代码运行的时候,是否和所处内存地址有关。
位置有关码要求运行是代码必须在特定位置;
位置无关码则没有要求,动态库中的所有地址,都是相对于当前PC值的偏移量,默认地址从0地址开始。动态库,在进程的地址空间中,随便加载,与我们加载到地址空间的什么位置,就毫无关系了,动态库中地址,都是偏移量。
这也就是为什么,上面我们在制作动态库的时候,要加上-fPIC选项:
位置无关码和位置有关码可以用下面一个生活的例子感性理解一下:
1.我在这条路的60米处左右——绝对编址
2.我在这条路的一棵大树左边,大约距离20米——相对编址
【Linux】动态库与静态库,如何打包库,如何使用第三方库相关推荐
- Linux 动态链接和静态链接简析(库名与库文件名)
原文请见 Linux动态链接和静态链接简析 0. 库名与真正的库文件名 就拿数学库来说,他的库名是 m,他的库文件名是libm.so,很容易看出,把库文件名的头 lib 和尾.so去掉就是库名.(gc ...
- pip安装更新、第三方库对应的python解释器版本、pip安装第三方库,压缩包离线安装,pycharm快捷安装及pycharm中terminal的使用,timeout超时报错
文章有点长,但是很详细,还望大家耐心看 之前在安装python的文章中已经给大家配置了pip环境变量(不了解的点这里去看看),这里就能直接在cmd窗口,不用切换路径,就能使用pip了. 首先 使用pi ...
- python调用第三方库需要联网吗_离线环境安装python第三方库
0. 概述 这个方法是使用pip换本地源下载依赖库的方式执行的,分为以下几个步骤 1. 安装/更新pip到最新版本. 2. 在联网环境下载依赖库的包和建立requirement.txt. 3. 将上一 ...
- 艺赛旗RPA 第三方库系列(一):如何调用 Python 第三方库
目前艺赛旗RPA已经更新到8.0版本,可以让所有用户免费下载试用http://www.i-search.com.cn/index.html?from=line1 (复制链接下载) 当你需要调用使用 p ...
- python json库安装_【Python基础】安装python第三方库
pip命令行安装(推荐) 打开cmd命令行 安装需要的第三方库如:pip install numpy 在安装python的相关模块和库时,我们一般使用"pip install 模块名&quo ...
- spacy库的安装与使用_Python 安装、使用第三方库的一些经验
(一)更改pip源至国内镜像 清华大学的pip源像 https://pypi.tuna.tsinghua.edu.cn/simple 临时使用: 可以在使用pip的时候加参数 -i https://p ...
- 下面不属于python第三方库的安装方法的是-关于python中第三方库安装方法和问题解决...
一.安装方法 方法一: 1.管理员身份启动命令行(运行--->cmd) 2.pip install 库的绝对路径和库的详细名称 :或者运用cd命令跳转到下载好的库所在的位置然后pip insta ...
- python中安装一个第三方库的命令格式是-PyCharm 如何安装python第三方库及插件
一.如何安装python第三方库: 1.有一个专门可下载安装第三方库的网址: http://www.lfd.uci.edu/~gohlke/pythonlibs/ Ctrl+f 搜索要下载的第三方库, ...
- python安装成功第三方库但import出问题_解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程...
一.问题具体描述: 在cmd控制台 pip install xxxx 后并显示安装成功后,并且尝试用cmd 的python 中import xxxx ,没有显示异常,说明这个库是安装成功了的.(这里以 ...
- c调用python第三方库_c/c++调用python程序且含tensorflow第三方库
对于纯python程序而言,用c程序来调用是比较适合的,如果python程序中包含了其他第三方库,则调用极可能出错,且不易查明原因.如笔者曾用c程序调用包含tensorflow的python程序,有的 ...
最新文章
- 【IOC 控制反转】Android 事件依赖注入 ( 事件三要素 | 修饰注解的注解 | 事件依赖注入步骤 )
- Mysql 的源码包安装
- MySQL新建匿名用户_初始化MySQL用户(删除匿名用户)
- 计算机整个文稿应用回顾主题,《计算机应用基础》精品课程电子教案-PowerPoint 2003...
- 阿里云高级技术专家:面向5G的云网一体及云原生应用实践
- 试驾Marvel R :传统车企认真起来,就没新势力什么事了
- 父类指针指向子类实例,用父类指针调用虚函数,调用的是子类的函数还是父类的函数...
- javaweb基础(36)_jdbc进行批处理
- HBuilder X 报 Error: Unbalanced delimiter found in string 错误
- SSH和SSM的区别
- SKLEARN实例:【用随机森林回归填补缺失值】
- 基于STM32F103的多种波形示波器制作
- 使用搜狗翻译实现网页多国语言转换
- Marvell宣战博通网络交换芯片,一大波饿狼扑食而来
- 电子商务新发展 海峡两岸智富惠论坛今日在厦召开
- HTML5基础:布局和标签
- 【JAVA】学习java 基础知识
- firefox windows旧版本下载
- 商店销售某一商品,每天公布统一的折扣discount,同时允许销售人员在销售时灵活掌握售价price,在此基础上,一次购入10件以上这,还可享受9.8折优惠。
- fedora的官方镜像地址列表
热门文章
- 基于java springboot物品租赁小程序源码
- 二级分类 php,PHP二级分类查询显示方法
- ...device found for this connection (device lo not available because device is strictly unmanaged).
- 华为AC_DHCP配置
- 怎么从src包中文件直接访问WebContent下面文件
- 20151120 - 蓝牙鼠标与 WiFi 冲突的解决办法
- 每天一道大厂SQL题【Day25】脉脉真题实战(一)每日活跃用户
- VScode配置makefile编译
- HTML+CSS+JS简易实现校园表白墙,快去给心仪的人表白吧
- APIJSON教程:上手apijson项目,学习apijson语法,并实现持久层配置