Linux 动静态库

news2024/11/28 12:54:23

目录

静态库和动态库

gcc规则使用动静态库的规则:

制作静态库

使用静态库

方法1.

方法2.

制作动态库

使用动态库

方法1:

方法2:

方法3:

方法4:

进程,静态库,动态库


静态库和动态库

1. 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库,生成的可执行程序中自己的代码和静态库的代码是一体的,进程运行起来之后,全部都在代码区。

2. 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

所以,在编译链接时,静态库就会和自己的源文件合并,生成一个可执行程序,之后再执行此可执行程序时,不再需要静态库,因为已经在可执行程序内部了。而使用动态库时,动态库并不在可执行程序内部,每次运行过程中,才会去加载动态库。

gcc规则使用动静态库的规则:

1. gcc默认使用动态库,若只有静态库,gcc只能对该库进行静态链接。

2. 若动静态库同时存在,则gcc默认使用动态库

3. 若动静态库同时存在,-static 即可指定使用静态库,进行静态链接。

制作静态库

如上,两个.c 两个.h    .h头文件包含库里面的函数声明 .c文件包含函数定义。

1. 将源文件,预处理,编译,汇编为.o可重定向二进制目标文件。

gcc -c mymath.c -o mymath.o   gcc -c myprint.c -o myprint.o

2. 将所有.o文件归档为静态库(静态库文件)至此,静态库就生成好了

ar -rc *.o -o libplus.a    (静态库文件的格式:  libxxx.a) 

3. 创建一个文件夹(目录),比如名为plus,将所有的头文件放在文件夹的include子目录下,将所有归档打包好的静态库放在plus的lib子目录下。   至此,这个plus文件就可以用来发布或者发给别人使用了。

使用静态库

方法1.

1. 将我们的第三方头文件和静态库放在系统存放头文件和库文件的默认路径下。

(或者头文件放在当前路径下也行,因为#include <>会先去系统默认路径下找,然后去当前路径下找,但是,你使用的头文件一般不会在当前路径下)

因为gcc在编译链接时,会去系统默认路径下去查找所需要的头文件和库文件。同时gcc也能自动链接C标准库。但是没法自动链接我们的第三方库.

Linux下,头文件gcc默认搜索路径:/usr/include  库文件默认搜索路径: /lib64 or  /usr/lib64

2. gcc test.c -lplus -o test.exe

-lplus表示你要使用libplus.a这个静态库,而头文件不需要你在gcc编译时指定,因为你的test.c内部就已经说明了需要哪些头文件。      以上是在将头文件和静态库文件放在系统默认路径之后的操作。

方法2.

不将头文件和库文件放在系统默认路径下,则

gcc test.c -I ./plus/include -L ./plus/lib -lplus  -o test.exe

通过gcc时添加指令的方式,说明头文件的位置,库文件的位置,你要链接哪个静态库文件。即可生成可执行程序。


相比之下,第二种方法更好点。因为不会污染系统默认路径下的环境。

我们将库拷贝到系统默认路径下,就叫做库的安装。

制作动态库

还是基于 myprint.h myprint.c mymath.h mymath.c

1. gcc -fPIC -c myprint.c -o myprint_d.o

gcc -fPIC -c mymath.c -o mymath_d.o

编译.c文件生成.o可重定向二进制目标文件时,加-fPIC指令,表示与位置无关地生成.o文件(这块和动态库使用的本质有关)    

2. gcc -shared mymath_d.o myprint_d.o -o libplus.so

不用ar,用gcc -shared即可。将.o文件合并归档打包生成libxxx.so动态库  (这里若不加-shared,就等于生成可执行程序了)

3. 可以将.h放在plus/include/下 将.so放在plus/lib/下,这样plus文件就可以用来发布或者传给使用库的人了。

 

使用动态库

若我们还是gcc test.c -I ./plus/include -L ./plus/lib -lplus  -o test.exe 生成test.exe文件(这里的/plus/lib下存储的是动态库),然后运行./test.exe  会直接报错。

./haha_dong: error while loading shared libraries: libplus.so: cannot open shared object file: No such file or directory
显示无法找到动态库,这里和动态库和静态库的本质区别有关,因为动态库不是编译链接生成可执行之后就可以随意运行了。在程序运行过程中,会跳转到动态库。而上方报错就是因为查找不到libplus.so

方法1:

拷贝.so文件到系统共享库路径下

Linux下,头文件gcc默认搜索路径:/usr/include  库文件默认搜索路径: /lib64 or  /usr/lib64
因为程序运行过程中,需要动态库时,会自动去系统默认路径下查找动态库。这里不需要头文件,因为生成可执行的时候,头文件已经在你的源文件内部展开的。

方法2:

配置Linux系统环境变量:LD_LIBRARY_PATH

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/yzl/aandso/plus2/lib

相当于,搜索动态库的时候,除了去系统默认路径下找,如果这个环境变量被配置了,还会在这个环境变量指定的路径下去找动态库。这里需要绝对路径。

缺点:这个环境变量在再次登录时,就没有了,因为环境变量的初值是通过系统的配置文件获取的。

方法3:

添加系统配置文件

/etc/ld.so.conf.d/ 路径下添加一个xxx.conf配置文件,将其内容设置为动态库的所在目录路径。

再sudo ldconfig  一下,表示更新配置文件,使其生效。

即可,这个是最安全最有效的了。退出重新登录也还在。

方法4:

在系统默认搜索库的路径下添加一个软链接

sudo ln -s /home/yzl/aandso/plus2/lib/libplus.so /lib64/libplus.so

不太推荐,类似方法1

综上,其实所有方法的目的都是为了在程序运行过程中能够找到动态库,而使用静态库的程序只要编译好之后,就不用再找静态库了,因为静态库已经在可执行程序内部了,目标文件生成后,静态库删掉,程序照样可以运行。。

进程,静态库,动态库

静态库在你的源文件编译汇编,最后链接时,已经进入可执行程序内部了,生成可执行程序之后,不再需要静态库文件。可以独立运行,所有代码都存在于进程地址空间的代码段中。

动态库和可执行程序可以分批加载,先运行可执行,若需要跳转动态库时,加载动态库代码到内存,建立进程地址空间中共享区(栈堆之间),页表,内存中的动态库代码的映射关系。执行动态库代码时,从代码段跳转到共享区,然后执行内存中的动态库代码即可。

这也是为什么动态库的.o文件编译时,要加-fPIC选项,这表示生成的.o文件是一种与位置无关的模式,即动态库的模式。

动态库是一种共享库,动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚 拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。    即,如果多个进程需要用到内存中的一个共享库,则利用虚拟地址空间机制,建立映射关系即可。

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

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

相关文章

传统瀑布模型和实际瀑布模型

传统瀑布模型&#xff1a; 瀑布模型是所有模型的基础框架 特点&#xff1a; 线性的开发流程&#xff0c;不能够应对需求的变化。 必须等前一阶段的工作完成后&#xff0c;才能开始后一阶段的工作 前一阶段的输出文档就是后一阶段的输入文档&#xff0c;因此只有前一阶段的输…

Map及其实现类、锁

HashMap、HashTable、ConcurrentHashMap 区别 一.HashMap和HashTable的区别 1、两者父类不同 HashMap是继承自AbstractMap类&#xff0c;而Hashtable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable&#xff08;可复制&#xff09;、Serializable&#xff0…

朱松纯教授场景理解相关文章简介

朱松纯教授场景理解相关文章简介 Holistic 3D Scene Parsing and Reconstruction from a Single RGB Image 基于单张图像的整体场景解译与重建 我们提出了一个计算框架来联合解译单帧RGB图像&#xff0c;通过使用一系列的随机语法模型生成的CAD模型构成整体的3D结构。具体地说…

智慧农业SaaS系统

真正的大师,永远都怀着一颗学徒的心&#xff01; 一、项目简介 智慧农业SaaS系统 二、实现功能 监控管理&#xff1a;支持海康摄像头监控。 用户管理&#xff1a;支持用户是系统操作者&#xff0c;该功能主要完成系统用户配置。 岗位管理&#xff1a;支持配置系统用户所属担…

bugku渗透测试 1 writeup(无需VPS)

靶场地址&#xff1a;BugKu渗透测试1 该靶场只需要20金币就可以开启两小时&#xff0c;算的上非常良心实惠了&#xff0c;趁着有空赶紧刷一刷题目 目录 第一场景&#xff1a; 第二场景&#xff1a; 第三场景&#xff1a; 第四场景&#xff1a; 第五场景&#xff1a; 第六…

第五章:面向对象(上)

第五章&#xff1a;面向对象(上) 5.1&#xff1a;面向过程与面向对象 面向过程(POP)与面向对象(OOP) ​ 二者都是一种思想&#xff0c;面向对象是相对于面向过程而言的。面向过程&#xff0c;强调的是功能行为&#xff0c;以函数为最小值&#xff0c;考虑怎么做。面向对象&…

【BOOST C++ 线程】boost::thread库的基本使用方法总结

一、说明 boost::thread的六种使用方法总结&#xff0c;本文初步介绍线程的函数、构造、执行的详细解释。 二、boost::thread的几个函数 函数功能join()让主进程等待子线程执行完毕后再继续执行get_id()获得线程的 id 号detach()标线程就成为了守护线程&#xff0c;驻留后台运…

【项目实战:核酸检测平台】第二章 大卸八块

本章目标 完成项目架构设计和数据库结构设计 重点&#xff1a;全是重点 文章目录本章目标总体设计&#xff08;架构设计&#xff09;技术选型部署结构设计工程文档结构设计第一步&#xff1a;项目和模块命名第二步&#xff1a;约定项目工程文件内容第三步&#xff1a;设计文档…

Hadoop高可用环境搭建-HDFSNameNode高可用搭建、Yarn高可用搭建

本文环境搭建的前提条件&#xff1a;JDK、Zookeeper、Hadoop完全分布式环境搭建完成。如果未满足条件且不会搭建&#xff0c;可以前往博主的主页搜索相关文章进行搭建。 目录 一、HDFSNameNode高可用搭建 二、 Yarn高可用搭建 本文主节点hostname&#xff1a;master&#xff0c…

安装semantic segmentation editor

两天啊&#xff0c; 整整两天&#xff0c;知道这两天我是怎么过的吗&#xff1f;&#xff1f;1 步骤概述&#xff08;以下命令行都是在管理员条件下执行&#xff09;1.1 安装choco1.2 安装meteor1.3 安装semantic segmentation editor2过程3 我还是用Ubuntu安装过3.1Window安装…

【Mysql】主从一致

【Mysql】主从一致&#xff08;一&#xff09;主从复制【1】什么是主从复制【2】为什么需要主从复制【3】mysql复制原理【4】具体步骤【5】mysql主从形式【6】具体操作过程&#xff08;1&#xff09;首先在虚拟机服务器上安装mysql&#xff0c;进行简单的配置&#xff08;2&…

力扣(LeetCode)38. 外观数列(C++)

双指针模拟 初始字符串 sss 已给定&#xff0c;根据 sss 构造下一个外观数列 ttt &#xff0c;构造完毕&#xff0c; ststst &#xff0c;循环 n−1n-1n−1 次&#xff0c;构造出一个外观数列。 构造步骤 : 令 jjj 指向当前元素 &#xff0c; kkk 从 jjj 往右&#xff0c;记录…

新库上线 | CnOpenData招聘公司基本信息扩展数据

招聘公司基本信息扩展数据 一、数据简介 线上招聘是指各公司将其岗位需求、工作地点能力要求和薪酬等招聘信息发布在互联网上&#xff0c;供求职者参考&#xff0c;以线上的方式进行招聘。线上招聘网站是通过互联网相关技术&#xff0c;集结这些线上招聘信息&#xff0c;帮助雇…

Linux下自动删除过期备份和自动异地备份的脚本

每天自动删除过期备份 首先编写一个简单的Shell脚本DeleteExpireBackup.sh&#xff1a; 1 2 3 4 5 6 7 #!/bin/bash # 修改需要删除的路径 location"/database/backup/" # 删除最后修改时间为30天以前的备份文件夹 find $location -mtime 30 -type d | xargs rm …

3dmax渲染大图有斑点怎么办?

嗨喽大家好&#xff0c;经常有后台私信问&#xff1a;3dmax渲染大图老是有斑点怎么办&#xff1f;而且斑点有白色的&#xff0c;还有绿色、黑色甚至彩色。怎么去除这些斑点呢&#xff1f; 其实以上的常见的斑点问题&#xff0c;大部分是灯光设置的问题。今天我们便来盘点下下面…

第二章:字节码指令集与解析案例

一、概述执行模型字节码与数据类型字节码指令分类加载与存储指令局部变量压栈指令常量入栈指令出栈装入局部变量表指令算术运算指令代码举例一代码举例二代码举例三&#xff1a;i 和 i 的区别比较指令的说明类型转换指令宽化类型转换(Widening Numeric Conversions)窄化类型转换…

指纹浏览器是什么?可以用来解决跨境电商的什么问题?

如果你是跨境电商中的一员&#xff0c;那我相信你肯定不陌生指纹浏览器吧&#xff01;毕竟指纹浏览器可以说是每个跨境人必备的工具了&#xff0c;更别说它的一系列功能简直是为跨境电商商家量身打造的&#xff01; 龙哥作为跨境老手&#xff0c;对指纹浏览器不要太熟悉&#x…

葡萄糖-顺铂Glucose-cisplatin|葡萄糖-聚乙二醇-顺铂cisplatin-PEG-Glucose

葡萄糖-顺铂Glucose-cisplatin|葡萄糖-聚乙二醇-顺铂cisplatin-PEG-Glucose 中文名称&#xff1a;葡萄糖-顺铂 英文名称&#xff1a;Glucose-cisplatin 别称&#xff1a;生物素修饰葡萄糖&#xff0c;生物素-葡萄糖 PEG接枝修饰葡萄糖 葡萄糖-聚乙二醇-顺铂 cisplatin-PE…

Go:命令行参数解析包 flag 简介

文章目录示例运行小结在 Golang 程序中有很多种方法来处理命令行参数。简单的情况下可以不使用任何库&#xff0c;直接处理 os.Args&#xff1b;其实 Golang 的标准库提供了 flag 包来处理命令行参数&#xff1b;还有第三方提供的处理命令行参数的库&#xff0c;比如 Pflag 等。…

【附源码】计算机毕业设计JAVA研究生推免系统

【附源码】计算机毕业设计JAVA研究生推免系统 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JAVA myba…