GCC 生成静态库和动态库以及相关学习
引言:GCC是一款强大的编译器,其不仅可以将源代码编译成可执行文件,还可以生成静态库和动态库。生成静态库可以将常用的函数和代码打包,方便其他程序调用,而生成动态库则可以在运行时动态加载,提高程序的灵活性和可维护性。通过学习GCC生成静态库和动态库的过程,我们可以更好地理解编译器的工作原理,提高代码的复用性和可移植性,为软件开发提供更多可能性。
文章目录
一、静态库与动态库的相关讲解
-
什么是静态库
静态库即静态链接库(Windows 下的 .lib,Linux 和 Mac 下的 .a)。之所以叫做静态,是因为静态库在编译的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。
静态库的好处很明显,编译完成之后,库文件实际上就没有作用了。目标程序没有外部依赖,直接就可以运行。当然其缺点也很明显,就是会使用目标程序的体积增大。 -
静态库的特点
- 静态库对函数库的链接是放在编译时期完成的。
- 程序在运行时与函数库再无瓜葛,移植方便。
- 浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
-
什么是动态库
动态库即动态链接库(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib)。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来。
-
动态库的特点
- 动态库把对一些库函数的链接载入推迟到程序运行的时期。
- 可以实现进程之间的资源共享。(因此动态库也称为共享库)
- 将一些程序升级变得简单。
- 甚至可以真正做到链接载入完全由程序员在程序代码中控制。(显示调用)
-
动态库与静态库的区别
二者的不同点在于代码被载入的时刻不同。
-
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
-
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
二、相关的指令代码
序号 | 名称 | 代码 |
---|---|---|
1 | 移动文件 | sudo mv libmyx2xx2y.so /usr/lib |
2 | 创建目录 | mkdir test1 |
3 | 动态库链接 | gcc main.c libmyx2xx2y.so -o main_so |
4 | 动态库生成 | gcc -shared -fPIC -o libmyx2xx2y.so x2x.o x2y.o |
5 | 静态库链接 | gcc main.c libmyx2xx2y.a -o main_a |
6 | 静态库生成 | ar -crv libmyx2xx2y.a x2y.o x2x.o |
7 | gcc链接 | gcc main.c x2x.o x2y.o -o main |
8 | gcc编译.o文件 | gcc -c x2y.c |
9 | 创建文件 | touch x2x.c |
三、相关文件编写
x2x.h文件
#ifndef __x2x_h
#define __x2x_h
float x2x(float a, float b); // 用于计算两个数相除
#endif __x2x_h
x2x.c文件
#include <stdio.h>
float x2x(float a,float b)
{
return a / b;
}
x2y.h文件
#ifndef __x2y_h
#define __x2y_h
float x2y(float a, float b); // 用于计算两个数相乘
#endif __x2y_h
x2y.c文件
#include <stdio.h>
float x2y(float a,float b)
{
return a * b;
}
main.c文件
#include <stdio.h>
#include "x2x.h"
#include "x2y.h"
int main()
{
float a = 2.5;
float b = 2;
printf("%.2f\n",x2x(a,b)); // 计算 2.5/2 = 1.25
printf("%.2f\n",x2y(a,b)); // 计算 2.5*2 = 5.0
printf("%.2f\n",x2y(a,b) * x2x(a,b)); // 计算 1.25 * 5.0 = 6.25
return 0;
}
四、过程实操
-
创建文件夹test1
使用命令 mkdir
-
创建对应的文件
使用touch命令
-
文件代码编写
相应的文件代码,在本文上方已经编写,请参考写入
-
使用gcc编译生成.o文件
对x2x.c文件以及x2y.c 文件分别用gcc进行编译生成对应的.o文件
对应的编译命令,在本文上方已经编写
最后生成两个.o文件
-
生成静态库
命令:ar -crv libmyx2xx2y.a x2y.o x2x.o
文件信息:
-
gcc链接main.c与静态库
命令:gcc main.c libmyx2xx2y.a -o main_a
执行生成完后的main文件
-
生成动态库
生成命令:gcc -shared -fPIC -o libmyx2xx2y.so x2x.o x2y.o
移动命令:sudo mv libmyx2xx2y.so /usr/lib
文件信息:
-
gcc链接main.c与静态库
命令:gcc main.c libmyx2xx2y.so -o main_so
-
五、总结
- 通过对比可知动态库的文件大小明显大于静态库
- 静态库是在编译时链接到可执行文件中,而动态库是在运行时动态链接。
- 静态库的优点是可以在不同的平台上进行移植,但会增加可执行文件的大小。
- 动态库的优点是可以在运行时共享库文件,减小了可执行文件的大小,但需要依赖正确的动态库文件。
- 学习使用GCC生成静态库和动态库可以帮助我们更好地管理和使用代码库,提高代码的可重用性和可维护性。
大佬的友情链接
- https://www.cnblogs.com/skynet/p/3372855.html