makefile语法

Makefile 是一种常用于编译的脚本语言。它可以更好更方便的管理你的项目的代码编译,节约编译时间(没改动的文件不编译)。
注意 Makefile 文件命令必须是 Makefile 或者 makefile,并使用 make 命令编译。

 

二、1个规则

1. 语法规则


 
 
  1. 目标...: 依赖...
  2. 命令1
  3. 命令2
  4. ...

2. 目标

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

3. 依赖

即目标文件由哪些文件生成。如果依赖条件中存在不存在的依赖条件,则会寻找其它规则是否可以产生依赖条件。

例如:规则一是生成目标 hello.out 需要使用到依赖条件 hello.o,但是 hello.o 不存在。则 Makefile 会寻找到一个生成 hello.o 的规则二并执行。

4. 命令

即通过执行该命令,由依赖文件生成目标文件。

注意每条命令前必须有且仅有一个 tab 保持缩进,这是语法要求。

5. ALL

Makefile 文件默认只生成第一个目标文件即完成编译,但是我们可以通过 “ALL” 指定需要生成的目标文件。

6. 示例

针对以上所说的,先写一个示例让大家了解一下,首先准备一个 hello.c:


 
 
  1. #include <stdio.h>
  2. int main()
  3. {
  4. printf( "Hello World !\n");
  5. return 0;
  6. }

然后写一个 Makefile


 
 
  1. ALL: hello .out
  2. hello .out: hello .c
  3. gcc hello .c -o hello .out

编译并执行:


 
 
  1. $ make
  2. gcc hello.c -o hello. out
  3. $ ./hello. out
  4. Hello World !

 

三、2个函数

1. wildcard

例如

SRC = $(wildcard ./*.c)
 
 

匹配目录下所有的 .c 文件,并将其赋值给 SRC 变量。

2. patsubst

pat 是 pattern 的缩写,subst 是 substring 的缩写。例如

OBJ = $(patsubst %.c, %.o, $(SRC))
 
 

这个函数有三个参数,意思是取出 SRC 中所有的值,然后将 “.c” 替换为 “.o”,最后赋值给 OBJ 变量。

3. 示例

通过上面两个函数,加入我们目录下有很多个 “.c” 后缀的源文件,就不需要写很多条规则语句了,而是可以像下面这样写


 
 
  1. SRC = $(wildcard *.c)
  2. OBJ = $(patsubst %.c, %.o, $(SRC))
  3. ALL: hello.out
  4. hello.out: $(OBJ)
  5. gcc $(OBJ) -o hello.out
  6. $(OBJ): $(SRC)
  7. gcc -c $(SRC) -o $(OBJ)

这里我们先将所有的 “.c” 文件编译为 “.o” 文件,这样后面更改某个 “.c” 文件时,其它的 “.c” 文件将不再编译,而只是编译有更改的 “.c” 文件,可以大大节约大项目中的编译速度。

 

四、3个变量

Makefile 中也有一些已经定义好的常用变量,这里介绍其中常用的3个。

1. $@

表示规则中目标,例如 hello.out。

2. $<

表示规则中的第一个依赖条件,例如 hello.c

3. $^

表示规则中的所有依赖条件,由于我们示例中都只有一个依赖条件,这种情况下 $^ 和 $< 区别不大。

4. 示例

使用这些变量替换上面写的 Makefile,即是:


 
 
  1. SRC = $(wildcard *.c)
  2. OBJ = $(patsubst %.c, %.o, $(SRC))
  3. ALL: hello.out
  4. hello. out: $(OBJ)
  5. gcc $< -o $@
  6. $(OBJ): $(SRC)
  7. gcc -c $< -o $@

 

五、其它常用功能

1. 代码清理 clean

我们可以编译一条属于自己的 clean 语句,来清理 make 命令所产生的所有文件。例如


 
 
  1. SRC = $(wildcard *.c)
  2. OBJ = $(patsubst %.c, %.o, $(SRC))
  3. ALL: hello.out
  4. hello. out: $(OBJ)
  5. gcc $< -o $@
  6. $(OBJ): $(SRC)
  7. gcc -c $< -o $@
  8. clean:
  9. -rm -rf $(OBJ) hello.out

这样我们就可以使用 clean 命令来清理生成的文件了:


 
 
  1. $ ls
  2. hello.c hello.o hello.out Makefile
  3. $ make clean
  4. rm -rf hello.o hello.out
  5. $ ls
  6. hello.c Makefile

 

2. 伪目标 .PHONY

上面我们写了一个 clean 语句,使得我们执行 “make clean” 命令的时候,可以清理我们生成的文件。

但是假如还存在一个文件名就是 clean 文件,那么我们再执行 “make clean” 命令的时候就只是显示


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

解决方法就是我们使用伪目标,这样就可以避免出现上面的问题了,例如:


 
 
  1. SRC = $(wildcard *.c)
  2. OBJ = $(patsubst %.c, %.o, $(SRC))
  3. ALL: hello.out
  4. hello. out: $(OBJ)
  5. gcc $< -o $@
  6. $(OBJ): $(SRC)
  7. gcc -c $< -o $@
  8. clean:
  9. -rm -rf $(OBJ) hello.out
  10. . PHONY: clean ALL

通常,我们也会把 ALL 也设置为伪目标。 

makefile 实例分析 Makefile 语法分析 第一部分 VERSION = 2# 给变量VERSION赋值 PATCHLEVEL = 6# 给变量PATCHLEVEL赋值 SUBLEVEL = 22# 给变量SUBLEVEL赋值 EXTRAVERSION = .6# 给变量EXTRAVERSION赋值 NAME = Holy Dancing Manatees, Batman!# 给变量NAME赋值 # *DOCUMENTATION*# To see a list of typical targets execute "make help"# More info can be located in ./README# Comments in this file are targeted only to the developer, do not# expect to learn how to build the kernel reading this file. # Do not:# o use make's built-in rules and variables#    (this increases performance and avoid hard-to-debug behavour);# o print "Entering directory ...";MAKEFLAGS += -rR --no-print-directory# 操作符“+=”的作用是给变量(“+=”前面的MAKEFLAGS)追加值。# 如果变量(“+=”前面的MAKEFLAGS)之前没有定义过,那么,“+=”会自动变成“=”;# 如果前面有变量(“+=”前面的MAKEFLAGS)定义,那么“+=”会继承于前次操作的赋值符;# 如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符# 在执行make时的命令行选项参数被通过变量 “MAKEFLAGS”传递给子目录下的make程序。# 对于这个变量除非使用指示符“unexport”对它们进行声明,它们在整个make的执行过程中始终被自动的传递给所有的子make。# 还有个特殊变量SHELL与MAKEFLAGS一样,默认情况(没有用“unexport”声明)下在整个make的执行过程中被自动的传递给所有的子make
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值