基于make命令与makefile文件详解分享!

一、多个源文件带来的问题

在编写c/c++测试程序时,我们习惯每次修改一处代码,然后就马上编译运行来查看运行的结果。这种编译方式对于小程序来说是没有多大问题的,可对于大型程序来说,由于包含了大量的源文件,如果每次改动一个地方都需要编译所有的源文件,这个简单的直接编译所有源文件方式对程序员来说简直是噩耗。

我们看一个例子:

  // main.c  #include "a.h"  // 2.c  #include "a.h"  #include "b.h"  // 3.c  #include "b.h"  #include "c.h"

如果程序员只修改了头文件c.h,则源文件main.c和2.c都无需编译,因为它们不依赖这个头文件。而对3.c来说,由于它包含了c.h,所以在头文件c.h改动后,就必须得新编译。

而如果改动了b.h可是忘记编译了2.c,那么最终的程序就可能无法正常工作。

make 工具就是为了解决上述问题而出现的,它会在必要时重新编译所有受改动影响的源文件。

二、make 命令

make命令本身支持许多选项,最常用的是-f选项。如果我们直接运行

  make

那么make命令会首先在当前目录查找名为makefile的文件,如果找不到,就会查找名为Makefile的文件。

为了指示make命令将哪个文件作为makefile文件,可以使用 -f 选项:

  make -f Makefile1

三、makefile 文件

上面提到makefile文件,那么什么是makefile文件呢?

make命令功能虽然十分强大,但是光凭其自身无法了解如何构建应用程序的。这时,makefile就出来了,它告诉make应用程序如何构建的。make命令和makefile文件的结合提供了一个在管理项目的十分强大的工具,它们不仅用于控制源文件的编译,而且还提供了将应用程序安装到目标目录等其他功能。

3.1 依赖关系

依赖关系定义了应用程序里面每个文件与其他源文件之间的关系。例如在上面的例子中,我们可以定义最终应用程序依赖于目标文件main.o,2.o和3.o。同样,main.o依赖于main.c和a.h,2.o依赖于2.c,a.h和b.h,3.o依赖于3.c,b.h和c.h。

在makefile文件中,依赖关系的写法是:先写目标的名称,然后紧跟一个冒号,接着是空格或者制表符tab,最后是用空格或者制表符tab隔开的文件列表。上面的例子的依赖关系如下:

  myapp: main.o 2.o 3.o  main.o: main.c a.h  2.o: 2.c a.h b.h  3.o: 3.c b.h c.h

这组依赖关系形成一个层次结构,展示了源文件之间的关系。例如,如果源文件b.h发生改变,就需要重新编译2.o和3.o,接下来还需要重新编译myapp。

3.2 规则

makefiel文件中的规则定义了目标的创建方式。在上面的例子中,我们使用gcc -c 2.c创建2.o。这个gcc命令即是目标2.o的创建方式,也即是规则。

在makefile文件中,规则都必须以tab开头。

在源文件所在的目录下创建Makefile1文件,其内容如下。

  myapp: main.o 2.o 3.o   gcc -o myapp main.o 2.o 3.o  main.o: main.c a.h   gcc -c main.c  2.o: 2.c a.h b.h   gcc -c 2.c  3.o: 3.c b.h c.h   gcc -c 3.c

三个头文件a.h,b.h,c.h内容都为空,源文件的内容如下:

  /* main.c */  #include <stdlib.h>  #include "a.h"  extern void function_two();  extern void function_three();  int main()  {   function_two();   function_three();   exit(EXIT_SUCCESS);  }
  /* 2.c */  #include <stdio.h>  #include "a.h"  #include "b.h"  void function_two() {   printf("function twon");  }
  /* 3.c */  #include <stdio.h>  #include "b.h"  #include "c.h"  void function_three() {   printf("function threen");  }

执行make命令,:

  $ make -f Makefile1   gcc -c main.c   gcc -c 2.c   gcc -c 3.c   gcc -o myapp main.o 2.o 3.o

运行应用程序:

  $ ./myapp   function two   function three

从输出可以说明应用程序已被正确构建。

如果改变b.h头文件,makefile能够正确处理这一变化,只有2.c和3.c发生重新编译:

  $ touch b.h  $ make -f Makefile1   gcc -c 2.c   gcc -c 3.c   gcc -o myapp main.o 2.o 3.o

3.3 注释

makefile文件使用#来表示注释,一直延续到这一行的结束。

3.4 宏

不同的平台下可能使用不同的编译器,不同的环境(例如开发与线上环境)也可能使用不同的编译器选项,为了便于修改makefile这些可变的参数,我们可以使用宏来实现makefile。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/482136.html

(0)
上一篇 2020年11月9日
下一篇 2020年11月9日

精彩推荐