???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???????? ???? ????
????个人主页 :阿然成长日记 ????点击可跳转
???? 个人专栏: ????数据结构与算法????C语言进阶????C++????Liunx
???? 不能则学,不知则问,耻于问人,决无长进
???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ????
文章目录
- 一、库的基础知识
- 二、如何编写静态库
- 1.原理简述
- 2.实际操作
- 使用makefile文件自动化构建
- 静态库的使用
前言:
本篇博客讲解两个类型的库:动态库(.so) 和 静态库(.a).的制作。
一、库的基础知识
库的作用:提升开发效率。隐藏源代码
库的本质:将所有的[.o
]结尾的可执行目标二进制文件打包形成一个文件夹。
二、如何编写静态库
1.原理简述
你编写了好几个文件,给别人使用,但是又不想让使用者看到内部源代码,此时有没有什么办法呢。
本质就是隐藏.c源文件。
-
第一步:将所有.c的文件形成.o文件
-
第二步:将所有的.o使用
ar
指令打包成一个库文件。 -
具体流程如下图:
这样做的好出有:
(1)将所有的源文件打包好,防止使用者再拷贝时丢失原文件。提高了使用效率。
(2)使用者无法查看源码,提高了安全性
2.实际操作
分别创建了4个文件:mymath.h mymath.c myprint.h myprint.c.
- 1.<mymath.h>:
#pragma once
#include<stdio.h>
extern int addToTarget(int start, int end);//声明函数
- 2.mymath.c
#include "mymath.h" #
//这段函数的作用是计算start-end之间的和
int addToTarget(int start, int end)
{
int sum = 0;
int i = start;
for(i; i <= end; i++)
{
sum += i;
}
return sum;
}
- 3.myprint.h
#pragma once
#include<stdio.h>
#include<time.h>
extern void Print(const char* str);
- 4.myprint.c
#include "myprint.h"
//这段函数功能是输出传入的字符串,后面加上时间戳
void Print(const char* str)
{
printf("%s[%d]\n",str,(int)(time(NULL)));
}
有了上面四个文件后,还需要写一个main方法使用这些函数。
#include "myprint.h"
#include "mymath.h"
int main()
{
Print("hello,world");
int res = addToTarget(1,100);
printf("res: %d\n",res);
return 0;
}
开始制作静态库:
第一步:将所有的.c文件
–>.o文件
使用gcc的【-c
】选项,代码如下:
gcc -o myprint.o -c myprint.c
gcc -o mymath.o -c mymath.c
注意:main函数不用参与,每个使用者都会有自己的main方法去调用库文件。
第二步:o文件打包成名字叫hello的静态库
知识补充:
【ar】指令:
ar
-[选项]
+lib+库文件名.a
+所有.o文件
选项这里只说r
(replace替换),c
(create创建)就可以了,就足以让我们创建静态库了.
注意: 格式一定是lib+库文件名
.a。也就是说要形成的静态库的名字 前缀必须是lib,后缀必须是.a,中间可以随便起名字.
执行代码:
ar -rc libhello.a main.o myprint.o mymath.o
可以发现,此时目录下面就会存在刚打包好的库文件了,但是,还需要结合对应的头文件才能正确的使用库文件中的函数。往下学!
使用makefile文件自动化构建
理清楚一个文件形成静态库的过程后 总结来说: .c文件 —> .o文件 —>
打包形成静态库
既然是这么一套固定的流程,那么我们完全可以用Makefile来完成这些工作。需要注意的是搞清各个文件的依赖关系,然后再进行编写。
所以最后的Makefile编写如下:
libhello.a: mymath.o myprint.o
ar -rc libhello.a mymath.o myprint.o
mymath.o : mymath.c
gcc -o mymath.o -c mymath.c
myprint.o: myprint.c
gcc -o myprint.o -c myprint.c
.PHONY:clean
clean:
rm -rf *.o libhello.a
这样还没有结束:还有对应的许多头文件呢。一般都是.h声明,然后从.o打包形成的库里面找。
-
所以我们还需要做一件工作:将.h和.a文件规整到一起.在Makefile加入以内容:就是将头文件和库文件规整在一起,逻辑如下
-
makefile代码如下
.PHONY:hello
hello:
mkdir -p hello/lib
mkdir -p hello/include
cp -rf *.h hello/include
cp -rf *.a hello/lib
- 总结来说: .c文件 —> .o文件 —> 打包形成静态库–>最后将.h和.a文件规整到一起
这样就制作好了一个静态库!如何去使用呢?
静态库的使用
方法一:直接拷贝到系统路径
头文件gcc系统默认搜索路径是:
/usr/include
库文件gcc系统默认搜索路径是:/lib64 或者 /usr/lib64
- 可以将你编写的静态库拷贝进/usr/lib64。头文件拷贝进/usr/include ;但是这样做会污染原来别人已经写好的库。不建议使用
方法二:指定路径搜索
我们可以直接在编译的时候加上头文件和库文件的路径.
对于上面的代码我们执行:
gcc main.c -I ./hello/include/ -L ./hello/lib/ -lhello
就可以指定路径进行查找。
选项:
-I
(i的大写)表示头文件的搜索路径
-L表示库文件的搜索路径
-l(小写的L)表示在特定路径下,要使用哪一个库.