《跟我一起写makefile》笔记1~3章

第一章 概述

1、makefile关系整个工程的编译规则,实现自动化编译

2Shell脚本一样,也可执行操作系统的命令。

3make是一个解释makefile指令的命令工具

一般来说,大多数的IDE都有这个命令,比如:DelphimakeVisual C++nmakeLinuxGNUmake。可见,makefile都成为了一种在工程方面的编译方法。

不同产商的make各不相同,也有不同的语法,但其本质都是在文件依赖性

 

这里,仅对GNUmake进行讲述(应用最为广泛,且最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。)

环境是RedHat Linux 8.0make的版本是3.80

默认的编译器是UNIX下的GCCCC

 

第二章 关于程序的编译和链接

1、首先(.c/.h) 经过预编译/编译,生成(.obj/.o)

2、然后通过链接(Link),.obj(.o)和.lib(.a)/.dll(.so)链接可执行文件

(Windows .exe,Linux/unix下随意)。

3、其它:.obj/.o可以生成库文件.lib/.a,多个库文件还可以进行合并。

源文件(.c/.h)

目标文件(.obj/.o)

静态链接库.lib/.a)

动态链接库.dll/.so)

可执行文件(.exe/…)

4、扩展:

内核驱动模块文件(.ko: kernel object)

(如何生成.ko----https://blog.****.net/qq_38880380/article/details/79227760)

 

第三章 Makefile 介绍

一、Makefile的规则

《跟我一起写makefile》笔记1~3章

Target目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的伪目标章节中会有叙述。

Prerequisites(预备材料,先决条件)生成target所需要的文件或是目标。

Commandmake需要执行的命令(任意的Shell命令)。

规则如果Target不存在,或者prerequisites中有文件比target文件新,则command所定义的命令就会被执行。

 

二、一个示例

写一个Makefile来告诉make命令如何编译和链接这几个文件。规则如下:

1)如果工程未编译,那么所有C文件都要编译并被链接。

2)如果工程的某几个C文件被修改,那么只编译被修改的C文件,并链接目标程序。

3)如果工程的头文件被修改,那么引用了这几个头文件的C文件需要编译,并链接目标程序。

《跟我一起写makefile》笔记1~3章

  1. 创建文件并命名为Makefilemakefile
  2. 内容如上图,命令行要以一个Tab键开头
  3. 在该目录下直接输入命令make,就可以生成执行文件edit
  4. Clean不是一个文件,它只不过是一个动作名字,像C语言中的lable,冒号后什么也没有,make不会自动去找文件的依赖性,也不会自动执行后面的命令。

只有在make命令后面指出这个lablemake才会去执行这个命令。

这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。

 

三、make是如何工作的

   在默认的方式下,也就是我们只输入make命令。那么,

1make会在当前目录下找名字叫Makefilemakefile的文件。

2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到edit这个文件,并把这个文件作为最终的目标文件

3、如果edit文件不存在,或是edit所依赖的后面的[.o]文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。

4、如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)

5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生成make的终极任务,也就是执行文件edit了。

这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

 

四、makefile中使用变量

变量的声明和使用如下:

《跟我一起写makefile》笔记1~3章

 

五、让make自动推导

GNUmake可以根据Target,自动推导所需要的依赖文件执行命令

只要make识别到[.o]文件,就会自动的把[.c]文件加在依赖关系中,

如:make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件,并且命令 cc -c whatever.c 也会被推导出来。

《跟我一起写makefile》笔记1~3章

这种方法,也就是make隐晦规则

上面文件内容中,.PHONY表示clean是个伪目标文件。

 

六、另类风格的makefile

使用make隐晦规则将重复使用的依赖文件.h收拢:

《跟我一起写makefile》笔记1~3章

缺点:

1)文件的依赖关系看不清楚

2)加入新的.o文件时,.h依赖关系要重新修改。

 

七、清空目标文件的规则

每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。

一般的风格都是:

clean:

rm edit $(objects)

更为稳健的做法是:

.PHONY : clean

clean :

-rm edit $(objects)

前面说过,.PHONY意思表示clean是一个伪目标。而在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。

clean的规则不要放在文件的开头,不然就会变成make的默认目标,相信谁也不愿意这样。不成文的规矩是——“clean从来都是放在文件的最后