3 分钟学会 Makefile

/ makefilemake / 没有评论 / 1993浏览

20191212195522-makefile-img

Makefile 介绍

Makefile 规则

Makefile 语法

target: prerequisites
        commands

目标文件: 依赖项
         命令1
         命令2
         ...

目标

目标即要生成的文件。如果目标文件的更新时间晚于依赖文件的更新时间,则说明依赖文件没有改动,目标文件不需要重新编译。否则重新编译并更新目标。

依赖

即目标文件由哪些文件生成。如果依赖条件中存在不存在的依赖条件,则会寻找其它规则是否可以产生依赖条件。例如:规则一是生成目标 hello.out 需要使用到依赖条件 hello.o,但是 hello.o 不存在。则 Makefile 会寻找到一个生成 hello.o 的规则二并执行。

命令

即通过执行该命令,由依赖文件生成目标文件。注意每条命令前必须有且仅有一个 tab 保持缩进,这是语法要求。

示例

#include <stdio.h>
 
int main()
{
    printf("Hello World !\n");
    return 0;
ALL: hello.out
 
hello.out: hello.c
    # 必须是 tab 不能是四个空格
    gcc hello.c -o hello.out

编译运行

$ make
gcc hello.c -o hello.out
$ ./hello.out
Hello World !

ALL

由于 Makefile 只能有一个目标,所以可以构造一个没有规则的终极目标 ALLMakefile 文件默认只生成第一个目标文件即完成编译,但是我们可以通过 ALL 指定需要生成的目标文件。直接 makemake all 的话会用 gcc 编译 hello.c

注意这里 ALL 并不是一个关键词,随便写什么 ABC 都行,只是大家习惯写 ALL 来代表整个目标。

.PHONY

phony ['fəuni] adj. 假的

PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字。有两种理由需要使用 PHONY 目标:避免和同名文件冲突,改善性能。

继续上面的例子,假设我们需要清理 hello.out 这个产物,重新编译,那么 Makefile 会这么写

ALL: hello.out
 
hello.out: hello.c
    # 必须是 tab 不能是四个空格
    gcc hello.c -o hello.out
clean:
    rm hello.out

当执行 make clean 的时候,可以正常清理文件,但是假设有一种情况,我们有一个叫 clean 的文件在同级目录,那么执行 make clean 的时候就会报下面的错误:

$ make clean 
make: `clean' is up to date.

报错的原因是文件名冲突了,因为 make 认为默认的依赖是文件,为了避免这种情况,我们加上 .PHONY 告诉 make 这不是一个依赖的文件。更新后 Makefile 如下:

ALL: hello.out
 
hello.out: hello.c
    # 必须是 tab 不能是四个空格
    gcc hello.c -o hello.out

.PHONY: clean    
clean:     
    rm hello.out