Linux下Makefile文件的编写和静态库与动态库的比较

当我们在Linux系统下面编写C程序的时候,经常用到gcc编译器对源文件进行编译,平时学习时写的源文件可能不多。

在工程项目中一般会有比较多的模块分交给每个人写,这样的源文件也比较多,所以想在工程编程中更方便编译代码文件,我们常常会用到Make file文件。

在Windows下可能不需要做这么多,但要是想要成为一个合格的软件工程师就必须学会这项技能。

下面用一个实际的例子说明一下。

一、创建写好的头文件和源文件

sub.c

1 int sub(int var1,int var2)
2 {
3   return var1 - var2;
4 }

div.c

1 int div(int var1,int var2)
2 {
3 
4     return var1 / var2;
5 }

add.c

1 int add(int var1, int var2)
2 {
3     return var1 + var2;
4 
5 }
 

mul.c

1 int mul(int var1,int var2)
2 {
3     return var1 * var2;
4 }

mod.c

1 int mod(int var1, int var2)
2 {
3     return var1 % var2;
4 }

cal.h

 1 #ifndef cal_h
 2 #define cal_h
 3 
 4 int add(int,int);
 5 int sub(int,int);
 6 int mul(int,int);
 7 int div(int,int);
 8 int mod(int,int);
 9 
10 #endif

testcal.c

 1 #include <stdio.h>
 2 #include "cal.h"
 3 
 4 int main(int argc, char **argv)
 5 {
 6     int var1;
 7     int var2;
 8     printf("please input var1:");
 9     scanf("%d",&var1);
10     printf("please input var2:");
11     scanf("%d",&var2);
12 
13     printf("%d add %d is %d
",var1, var2, add(var1,var2));
14     printf("%d sub %d is %d
",var1, var2, sub(var1,var2));
15     printf("%d mul %d is %d
",var1, var2, mul(var1,var2));
16     printf("%d div %d is %d
",var1, var2, div(var1,var2));
17     printf("%d mod %d is %d
",var1, var2, mod(var1,var2));
18 
19     return 0;
20 
21 }

利用对两个数的乘除加减创建以上五个源文件和一个头文件。

下面我们开始编写Makefile文件

 1 OBJ = testcal.o add.o div.o sub.o mul.o mod.o
 2 testcxm: $(OBJ) cal.h
 3     gcc $(OBJ) -o testcxm
 4 testcal.o:testcal.c
 5 add.o:add.c
 6 div.o:div.c
 7 sub.o:sub.c
 8 mul.o:mul.c
 9 mod.o:mod.c
10 
11 .PHONY:cleanA clean
12 claenA:
13     rm testcxm $(OBJ)
14 clean:
15     rm $(OBJ)

Makefile文件中的.o后缀文件都是对应着相应的.c文件,会有相互依赖的关系,make有着很强大的功能,及时不用编写gcc -o *.c源文件它也会依据前面的

依赖关系自己补全做这个事情,可以给我们节省编写,也让相应的源文件与之一一对应,更加易读,一目了然。

我们在这里面创建的库文件名称是以我名字首字母testcxm,OBJ类似于C文件里面的宏定义,以这一个代替多个中间目标文件,写.PHONY是为了提醒系统

这是个伪文件,想要运行后面命令应该要在使用make cleanA或者make claen命令进行清除相应的库文件和中间目标文件。

这些源文件和头文件应该在一个文件夹下面,然后运行make命令。

cc    -c -o testCal.o testCal.c
cc    -c -o add.o add.c
cc    -c -o sub.o sub.c
cc    -c -o mul.o mul.c
cc    -c -o div.o div.c
cc    -c -o mod.o mod.c
gcc -o testcxm testCal.o add.o sub.o mul.o div.o mod.o 

进行make命令后生成中间目标文件和库文件

  查看文件的大小命令ls -l:

total 36
-rwxrwxrwx 1 booker booker  237 Mar 22 22:07 Makefile
-rwxrwxrwx 1 booker booker   71 Mar 22 22:11 add.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 22:11 add.o
-rwxrwxrwx 1 booker booker  127 Mar 22 22:09 cal.h
-rwxrwxrwx 1 booker booker   68 Mar 22 13:48 div.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 22:00 div.o
-rwxrwxrwx 1 booker booker   68 Mar 22 13:48 mod.c
-rwxrwxrwx 1 booker booker 1240 Mar 22 22:00 mod.o
-rwxrwxrwx 1 booker booker   68 Mar 22 22:10 mul.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 22:11 mul.o
-rwxrwxrwx 1 booker booker   67 Mar 22 23:14 sub.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 23:51 sub.o
-rwxrwxrwx 1 booker booker  496 Mar 22 13:48 testcal.c
-rwxrwxrwx 1 booker booker 2736 Mar 22 22:00 testcal.o
-rwxrwxrwx 1 booker booker 8696 Mar 22 23:51 testcxm

可以看到我们的生成的可执行文件testcxm大小为8696字节,8K大小左右。

运行后:

[booker@TBB6LFOV9OI82DY Design]$ ./testcxm
please input var1:10
please input var2:20
10 add 20 is 30
10 sub 20 is -10
10 mul 20 is 200
10 div 20 is 0
10 mod 20 is 10

二、使用静态库文件,生成静态库。静态库文件一般的形式为libname.a,其中lib为前缀,.a后缀扩展名,生成静态库的命令为ar,我将静态库name设为我名字首字母:

ar rcs libcxml.a add.o sub.o mul.o div.o mod.o

生成静态库后,使用一下的命令进行编译:

gcc -o testcxm testcal.c -static -L. -lcxm

其中上面的命令表示:

① gcc -o testcxm:表示使用gcc进行编译,-o指定文件名,后面的为生成的文件名。

② -static:表示使用静态库。

③ -L:表示指明使用库,-lcxm:-l表示lib是缩写,cxm:表示文件名。

查看文件的大小ls -l:

[booker@TBB6LFOV9OI82DY Design]$ ls -l
total 972
-rwxrwxrwx 1 booker booker    237 Mar 22 22:07 Makefile
-rwxrwxrwx 1 booker booker     71 Mar 22 22:11 add.c
-rwxrwxrwx 1 booker booker   1232 Mar 22 22:11 add.o
-rwxrwxrwx 1 booker booker    127 Mar 22 22:09 cal.h
-rwxrwxrwx 1 booker booker     68 Mar 22 13:48 div.c
-rwxrwxrwx 1 booker booker   1232 Mar 22 22:00 div.o
-rwxrwxrwx 1 booker booker   6580 Mar 23 00:00 libcxm.a
-rwxrwxrwx 1 booker booker     68 Mar 22 13:48 mod.c
-rwxrwxrwx 1 booker booker   1240 Mar 22 22:00 mod.o
-rwxrwxrwx 1 booker booker     68 Mar 22 22:10 mul.c
-rwxrwxrwx 1 booker booker   1232 Mar 22 22:11 mul.o
-rwxrwxrwx 1 booker booker     67 Mar 22 23:14 sub.c
-rwxrwxrwx 1 booker booker   1232 Mar 22 23:51 sub.o
-rwxrwxrwx 1 booker booker    496 Mar 22 13:48 testcal.c
-rwxrwxrwx 1 booker booker   2736 Mar 22 22:00 testcal.o
-rwxrwxrwx 1 booker booker 958552 Mar 23 00:01 testcxm

从上面我们可以看到使用静态库的可执行文件的大小为958552字节,大概在900多k,运行一下可执行文件:

[booker@TBB6LFOV9OI82DY Design]$ ./testcxm
please input var1:5
please input var2:13
5 add 13 is 18
5 sub 13 is -8
5 mul 13 is 65
5 div 13 is 0
5 mod 13 is 5

三、使用动态文件:生成动态库文件。库文件一般的形式为libname.so,其中lib为前缀,.so为后缀扩展名,在此以我名字的首字母为名创建一个动态文件库。

make之后的文件,运行下面的命令:

[booker@TBB6LFOV9OI82DY Design]$ gcc -shared -fPIC -o libcxm.so add.o sub.o mul.o div.o mod.o

-shared指生成动态库,-fPIC对位置进行引用,方便进行地址链接。

再运行一下命令进行编译:

[booker@TBB6LFOV9OI82DY Design]$ gcc -o testcxm testcal.c -L. -lcxm

没有使用-static说明该库文件为动态库。

查看文件的大小:

[booker@TBB6LFOV9OI82DY Design]$ ls -l
total 44
-rwxrwxrwx 1 booker booker  237 Mar 22 22:07 Makefile
-rwxrwxrwx 1 booker booker   71 Mar 22 22:11 add.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 22:11 add.o
-rwxrwxrwx 1 booker booker  127 Mar 22 22:09 cal.h
-rwxrwxrwx 1 booker booker   68 Mar 22 13:48 div.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 22:00 div.o
-rwxrwxrwx 1 booker booker 7664 Mar 23 00:18 libcxm.so
-rwxrwxrwx 1 booker booker   68 Mar 22 13:48 mod.c
-rwxrwxrwx 1 booker booker 1240 Mar 22 22:00 mod.o
-rwxrwxrwx 1 booker booker   68 Mar 22 22:10 mul.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 22:11 mul.o
-rwxrwxrwx 1 booker booker   67 Mar 22 23:14 sub.c
-rwxrwxrwx 1 booker booker 1232 Mar 22 23:51 sub.o
-rwxrwxrwx 1 booker booker  496 Mar 22 13:48 testcal.c
-rwxrwxrwx 1 booker booker 2736 Mar 22 22:00 testcal.o
-rwxrwxrwx 1 booker booker 8544 Mar 23 00:23 testcxm

可以看到文件的大小为8544字节,在8k左右,比不打包成库大了一点点,不过要比静态库小很多。

从上面可以看到,Makefile文件的书写并不复杂,这个编辑的顺畅在于make的强大功能,而静态库和动态库的选择很重要,因为这两种库的空间大小相差很多。

原文地址:https://www.cnblogs.com/bookercheng/p/12549671.html