zoukankan      html  css  js  c++  java
  • 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的强大功能,而静态库和动态库的选择很重要,因为这两种库的空间大小相差很多。

  • 相关阅读:
    SVG ViewBox
    svg中改变class调用的线条颜色
    SVG 箭头线绘制
    Spring3中的mvc:interceptors标签配置拦截器
    MyBatis入门学习
    MyBatis 配置sql语句输出
    使用iBATIS3.0完成增删改查
    iBatis简单入门教程
    SpringMVC常用注解,返回方式,路径匹配形式,验证
    springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序
  • 原文地址:https://www.cnblogs.com/bookercheng/p/12549671.html
Copyright © 2011-2022 走看看