[Linux] 动态 / 静态库的生成与使用

简要概念

库一般分为两种:

  • 静态库
  • 动态库

在 Linux 中:

  1. 如果是动态库,库文件是以 .so 作后缀的
  2. 如果是静态库,库文件是以 .a 作后缀的

库文件的命名:

libXXX.so / libXXX.a …

库的真实名称:去掉 lib前缀 ,去掉.a- .so-(且包含)后缀,剩余的为库名称



静态库

生成

在这里插入图片描述

  1. 这里创建一个主文件夹 library 在文件夹内部创建一个my_lib文件夹,用来放所写的库函数,这里用add, sub两个函数

在这里插入图片描述

库文件的命名:

add,sub分别是两个简单的加减函数:

在这里插入图片描述
在这里插入图片描述


  1. library 进行其余代码的编写:

编写makefile文件

在这里插入图片描述

src=mytest.c ./my_lib/add.c ./my_lib/sub.c
obj=mytest.o ./my_lib/add.o ./my_lib/sub.o
    
mytest:$(obj)    
    gcc -o $@ $~    
%.o:%.c    
    gcc -c $<    
    
.PHONY:clean    
clean:    
    rm -f *.o mytest 

此时我们有以下文件

在这里插入图片描述


  1. 通过将.o文件打包形成静态库

进入my_lib文件夹写Makefile

在这里插入图片描述

lib_mymath.a:add.o sub.o    
    ar -rc $@ $^    
%.o:%.c
    gcc -c $<

在这里插入图片描述

此时 lib_mymath.a 就是一个 静态库

静态库的本质:将所有的.o文件打包形成库


  1. 为了保证库的保密性
    再次完善Makefile:
    在这里插入图片描述
lib_mymath.a:add.o sub.o    
    ar -rc $@ $^    
%.o:%.c    
    gcc -c $<    
    
.PHONY:clean    
clean:    
    rm -f *.o lib_mymath.a output

.PHONY:output
output:    
    mkdir output    
    cp -rf *.h output     
    cp lib_mymath.a output    

重新make,再进行output操作

在这里插入图片描述
在这里插入图片描述
此时查看output中的文件:

在这里插入图片描述



使用

创建一个 caller 文件夹(在my_lib中,与output同级目录),为调用库的调用者:

output 给调用者(移动到caller文件夹里),更名为caller_lib

caller下写一段测试代码:

#include "add.h"    
#include "sub.h"    
      
void test()    
{    
    int x = 20;    
    int y = 10;    
    int r1 = my_add(x, y);    
    int r2 = my_sub(x, y);    
    
    printf("add : %d\n", r1);   
	printf("sub : %d\n", r2);    
}    
    
int main()    
{    
    test();    
    return 0;    
}  

运行后会发现:

在这里插入图片描述
报错,程序找不到 add.h ,因为系统默认只在统计目录下找头文件,而 add.h / sub.h 都在 caller_lib 文件夹中,所以找不到,这里引入一个指令:

gcc test.c -I./caller_lib -L./caller_lib -l_mymath

这里进行解释:

在这里插入图片描述

为什么库名称为 _mymath ?
注意 这里指定的是库的真实名称,及去掉前后缀的名称。

此时执行操作,运行a.out文件,发现正常生成结果,则库的使用没有问题。

在这里插入图片描述


可以将该指令写入caller 的 makefile文件中

在这里插入图片描述

不再进行后续演示




动态库

生成

  1. 先执行 make clean 命令,清除之前的部分文件

更改 my_lib 中的 Makefile 文件

在这里插入图片描述

 # 动态库实现    
# 形成一个动态链接的共享库    
lib_mymath.o:add.o sub.o                                                               
    gcc -shared -o $@ $^    
    
#产生 .o 目标文件,程序内部的地址方案:与位置无关,库文件可以在内存的任何位置加载,而且不影响和其他程序的关联性
%.o:%.c    
    gcc -fPIC -c $<    
    
.PHONY:clean    
clean:    
    rm -f lib_mymath.so *.o    
    
.PHONY: lib    
lib:    
    mkdir lib    
    cp *.h lib    
    cp lib_mymath.so lib    

并 更改 callermakefile 文件

在这里插入图片描述

mytest:test.c    
    gcc -o $@ $^ -I./caller_lib -L./caller_lib -l_mymath    
        
.PHONY:clean    
clean:    
    rm -f mytest    

使用

执行 caller 中的 makefile 文件 发现报错

在这里插入图片描述

原因如下:

  • 静态库编译时需要,运行时直接拷贝
  • 动态库编译和运行时都需要

这里引入一个新指令

  • LIBRARY_PATH 可以用于指定非标准位置的库文件,以便编译器能够正确地链接程序。

在这里插入图片描述
解释:

  1. 这个命令将环境变量 LD_LIBRARY_PATH 设置为 /home/aiyimu/myLinux/libiary/static/my_lib/caller/caller_lib,并将其导出,使得在当前终端中启动的所有子进程都能够访问这个环境变量。
  2. LD_LIBRARY_PATH 环境变量用于指定系统动态链接库查找的路径。

此时再次执行 make 命令

在这里插入图片描述

执行生成的 mytest

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值