动态库(共享库)、静态库的制作
零、动态库(共享库)、静态库的联系与区别
这两种库相同点是两种库都是由.o文件生成的,下边讨论一下它们的不同点:
-
静态库
静态库文件名的命名方式是“libxxx.a”,库名前加”lib”,后缀用”.a”,“xxx”为静态库名。
链接时间: 静态库的代码是在编译过程中被载入程序中。
链接方式:静态库的链接是将整个函数库的所有数据都整合进了目标代码。这样做优点是在编译后的执行程序不在需要外部的函数库支持,因为所使用的函数都已经被编进去了。缺点是,如果所使用的静态库发生更新改变,你的程序必须重新编译。 -
动态库
动态库的命名方式与静态库类似,前缀相同,为“lib”,后缀变为“.so”。所以为“libmytime.so”
链接时间:动态库在编译的时候并没有被编译进目标代码,而是当你的程序执行到相关函数时才调用该函数库里的相应函数。这样做缺点是因为函数库并没有整合进程序,所以程序的运行环境必须提供相应的库。优点是动态库的改变并不影响你的程序,所以动态函数库升级比较方便。
它们两个还有很明显的不同点:当同一个程序分别使用静态库,动态库两种方式生成两个可执行文件时,静态链接所生成的文件所占用的内存要远远大于动态链接所生成的文件。(因为静态链接是在编译时将所有的函数都编译进了程序。而动态链接是在运行是才调用库里相应函数)
一、静态库制作:
1. 命名规则
lib+库名+后缀.a
如:libtest.a
2. 制作过程
1)生成 .o文件,gcc *.c -c
2)将 .o 文件打包到 .a 中。ar rcs +静态库名(libtest.a)+ 依赖的所有 .o 文件
3. 发布和使用
1) 静态库
2)头文件
4. 举例
文件夹结构:
各个文件夹代码:
include文件夹:
#ifndef _HEAD_H_
#define _HEAD_H_
int add(int a , int b);
int sub(int a , int b);
int mul(int a , int b);
int div(int a , int b);
#endif
src文件夹是对include文件夹中 头文件的实现:
#include<stdio.h>
#include"head.h"
int sub(int a, int b)
{
return a-b;
}
#include<stdio.h>
#include"head.h"
int add(int a, int b)
{
return a+b;
}
#include<stdio.h>
#include"head.h"
int mul(int a, int b)
{
return a*b;
}
#include<stdio.h>
#include"head.h"
int div(int a, int b)
{
if(b==0)
exit(-1);
return a/b;
}
main.c
#include<stdio.h>
#include "head.h"
int main()
{
int sum = add(2,24);
printf("sum is :%d \n",sum);
return 0;
}
1)生成 .o文件,gcc *.c -c
2)将 .o 文件打包到 .a 中。ar rcs +静态库名(libtest.a)+ 依赖的所有 .o 文件
3) 发布
移动静态库
编译执行测试函数main.c
或者:
- I 指定目录(大写i)
-L 指定静态库目录
-l 指定库文件(小写L)这里参数文静态库文件名,掐头去尾
5. 使用nm 查看
查看静态库:
查看可执行文件:
静态库将源代码(.o 文件为打包单元)编译进入可执行文件:
二、动态库(共享库)制作
1. 命名规则
lib+库名+后缀.so
如:libtest.aso
2. 制作过程
1)生成 .o文件(位置无关),gcc -fPIC *.c -c
2)将 .o 文件打包到 .so中。gcc -shared -o 库名
3. 发布和使用
1) 动态库
2)头文件
4. 举例
文件夹结构:同上
1)生成 .o文件(位置无关)
位置无关的解释:
动态库是在程序运行中加载的,在内存空间中采用相对地址标识。静态库要编译进代码,所有采用绝对地址,位置相关。
2)将 .o 文件打包到 .so中。gcc
3)用户测试
编译执行测试函数main.c
或者:
这里找不到的原因:
动态连接器/lib64/ld-linux-x86-64.so.2 (0x00007fa7ddf42000)找不到我们库的位置:
解决方法:
将我们的库添加到连接器能找到的位置:
临时方法:关闭终端后失效
永久方法:
1. 将export LD_LIBRARY_PATH=/home/linux-net-code/3Day/lib,添加到 ~/.bashrc中,重启终端生效。
2.修改动态连接器的配置文件,将动态库路径写入连接器配置文件/etc/ld.so.conf,更新连接器配置 ldconfig -v。
更新连接器配置 ldconfig -v -v可不加。