您的位置 首页 教育

静态库和动态库的制作和使用

静态库和动态库的制作和使用 GCC编译选项静态库的制作和使用命名规则制作过程使用静态库 动态库的制作和使用命名…

静态库和动态库的制作和使用

  • GCC编译选项
  • 静态库的制作和使用
    • 命名规则
    • 制作过程
    • 使用静态库
  • 动态库的制作和使用
    • 命名规则
    • 制作过程
    • 使用动态库
  • 静态库与动态库的对比
    • 两者制作过程
    • 静态库的优缺点
    • 动态库优缺点

GCC编译选项

GCC编译选项 说明

-E预处理指定源文件,不进行编译 :.i文件-S编译指定的源文件,不进行汇编 :.s文件-c编译、汇编指定源文件,但不进行链接:.o文件-o [file1] [file2] / [file2] -o [file1]将文件file2 编译成可执行文件file1:.exe/.out文件-I [directory] (大写i)指定include包含文件的搜索目录-g在编译的时候,生成调试信息,该程序可以被调试器调试、-D在程序编译的时候,指定一个宏-w不生成任何警告-Wall生成所有警告-Onn取值范围:0-3.编译器的优先选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3为优化级别最高-l (小写L)在程序编译的时候,指定使用的库-L指定编译的时候,搜索的库的路径-fPIC/fpic生成与位置无关的代码-shared生成共享目标文件,通常用在建立共享库时-std指定C方言:如-std=c99,gcc默认方言为GNU C
静态库的制作和使用
命名规则

  1. Linux: libxxx.a
  2. Windows: libxxx.lib
    其中xxx为指定名称

制作过程

  1. gcc获得 .o 文件
gcc -c xxx.c xxx.c   //生成对应的.o文件
  1. 将.o文件打包,使用ar工具(archive)
ar rcs libxxx.a xxx.o xxx.o   //生成静态库 libxxx.a
	1. r - 将文件插入备存文件中
	2. c - 建立备存文件
	3. s - 索引

使用静态库

gcc main.c -o app -I ./include/ -l calc -L ./lib/       
 
//main.c 为需要编译的函数 app为最终生成可执行文件名称 -I表示头文件搜索目录 -l表示指定库名称 -L表示搜索库路径
//命名规则: calc 会去查找 libcalc.a

动态库的制作和使用
命名规则

  1. Linux:libxxx.so,其在Linux下是一个可执行文件
  2. Windows:libxxx.dll

制作过程

  1. gcc得到 .o 文件,得到和位置无关的代码
gcc -c -fpic a.c b.c  //将a和b两个源文件进行编译、汇编,且生成与位置无关的代码
  1. gcc得到动态库
gcc -shared a.o b.o -o libcalc.so   //将对应的.o文件生成目标动态库

使用动态库

  1. 程序启动后,动态库会被动态加载到内存中,通过 ldd 命令检查动态依赖关系
  2. 如何定位共享库文件:
    1. 当系统加载可执行代码的时候,能够知道其所依赖库的名字,但还需要知道其绝对路径。此时就需要系统的动态载入器来获取该绝对路径。
    2. 对于elf格式的可执行文件,是由ld-linux.so来完成的,他先后搜索elf文件的 DT_RPATH段→ 环境变量 LD_LIBRARY_PATH → /etc/ld.so.cache文件列表 → /lib/, /user/lib目录 找到库文件后将其载入内存。

对于如下的存储,其中include存储头文件,lib存储动态库,main.c为主函数,src存放其他源函数

gcc main.c -o app -I include/ -l calc -L lib/  //生成app可执行文件

ldd app    //检查动态依赖关系
			linux-vdso.so.1 (0x00007ffffd7fc000)
	        libcalc.so => not found                  //内存中没找到动态库
	        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007effdbc92000)
	        /lib64/ld-linux-x86-64.so.2 (0x00007effdbe9b000)   //动态载入器

在生成目标可执行程序后,无法运行,因为动态库需要在运行时,加载进内存中。

一、配置到本地环境变量

  1. 临时的,切换终端就会失效:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/moens/xxx/lib  //添加动态库绝对路径进环境变量
echo $LD_LIBRART_PATH            //查找动态库环境变量
ldd app
					linux-vdso.so.1 (0x00007ffebd74e000)
			        libcalc.so => /home/moens/Linux/xxx/lib/libcalc.so (0x00007fa75a97f000) //找到
			        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa75a77d000)
			        /lib64/ld-linux-x86-64.so.2 (0x00007fa75a98b000)
			        
./app //运行成功

其中$LD_LIBRARY_PATH表示保持之前环境变量 :后面加入后面的变量

  1. 永久的,用户级别配置:
cd ~                          //进入home目录
vim .bashrc     (shift + G 切换到最后一行,  o 在下一行 进行输入)
//最后一行输入 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/moens/xxx/lib     //目标动态库的绝对路径
. .bashrc   //使得修改生效    等价于 source .bashrc
  1. 永久的,系统级别配置:
sudo vim /etc/profile 
//最后一行输入 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/moens/xxx/lib 

source /etc/profile       //更新修改
(如果之前进行过用户级别的配置,建议重新打开一个终端进行系统级别配置,不然会出错)

二、配置/etc/ld.so.cache文件列表

sudo vim /etc/ld.so.conf  //直接在最后一行写入绝对路径 /home/moens/xxx/lib
sudo ldconfig   //更新
ldd app
				linux-vdso.so.1 (0x00007ffc0e9a1000)
		        libcalc.so => /home/moens/Linux/lesson06/library/lib/libcalc.so (0x00007fdf6cc0d000)
		        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdf6ca1b000)
		        /lib64/ld-linux-x86-64.so.2 (0x00007fdf6cc29000)

三、动态库放入/lib/, /user/lib目录
不建议使用(本身包含系统库文件,可能会发生替换)

静态库与动态库的对比
两者制作过程

  1. 静态库制作过程

  2. 动态库制作过程

静态库的优缺点

  1. 优点
    1. 静态库被打包到应用程序中,加载速度快
    2. 发布程序无需提供静态库,移植方便
  2. 缺点
    1. 消耗系统资源,浪费内存
    2. 更新、部署、发布麻烦 (当某个库修改了,需要重新编译)

动态库优缺点

  1. 优点
    1. 可以实现进程间资源共享(共享库)
    2. 更新、部署、发布简单
    3. 可以控制何时加载动态库
  2. 缺点
    1. 加载速度比静态库慢
    2. 发布程序时需要提供依赖的动态库

本文来自网络,不代表0514资讯网立场,转载请注明出处:https://0514zx.com/info/6392.html
0514zx.com

作者: 0514zx.com

优质职场领域创作者
联系我们

联系我们

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部