概述

一个开发工程会有很多的源文件,它们按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译等。makefile文件关系到整个工程的编译规则。写好的makefile,只要运行make命令,就会按makefile里定义好的规则来编译工程。

make 是一个用来解析makefile文件中的指令的命令工具。大多数的 IDE 都有这个命令,如Linux下 GNU 的 make。不同产商的 make各不相同,我们这里只介绍Linux上的make,版本为GNU Make 4.1,默认的编译器是gcc。

编译和链接

可以参考《gcc编译程序的过程》

makefile 的书写规则

target ... : prerequisites ...
command
...
...

target:可以是目标文件、执行文件、标签。
prerequisites: 生成该 target 所依赖的文件或 target。
command:生产该 target 要执行的命令(任意的 shell 命令),即生成规则定义在 command 中。
注意:
prerequisites 中如果有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行。

依赖关系的实质就是说明目标文件是由哪些文件生成的,目标文件是由哪些文件更新的。
在定义好依赖关系后,command定义了生成目标文件的指令,指令前一定要以一个 Tab键作为开头

make命令会比较 targets文件和 prerequisites 文件的修改日期。如果 prerequisites 文件的日期比 targets 文件的日期新,或者 target 不存在的话,那么make 就会执行command定义的命令。

示例

app:main.o hello.o
gcc -o app main.o hello.o
main.o:main.c hello.h
gcc -c main.c
hello.o:hello.c hello.h
gcc -c hello.c
clean:
rm app main.o hello.o

(1)将内容保存到文件名为“makefile”或“Makefile”的文件中。
(2)然后在该目录下直接输入命令 make 就可以生成执行文件 app。
(3)执行make clean可以删除执行文件和产生的目标文件。clean是一个动作名字(可以任意定义),不是一个文件,其冒号后什么也没有,因此make 就不会自动去找它的依赖,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在 make 命令后显式指出这个 label 的名字。这非常有用。我们可以在一个 makefile 中定义一些不用编译或者和编译无关的命令,如程序的打包,程序的备份等。

makefile中的指令都要写在同一行,如果实在要换行,可以在行尾加反斜杠(\ )换行符,如:

app:main.o hello.o
gcc -o app main.o hello.o
main.o:main.c hello.h
gcc -c\
main.c
hello.o:hello.c hello.h
gcc -c hello.c
clean:
rm app main.o hello.o

谢谢阅读!