参考文章
makefile基础规则
1 个规则
目标:依赖条件
(一个tab缩进)命令 #命令行必须以[Tab]字符开始
*目标的时间必须晚于依赖条件的时间,否则,更新目标
*依赖条件如果不存在,找寻新的规则去产生依赖条件。
*ALL:指定 makefile 的终极目标。
2 个函数:
src = $(wildcard ./*.c): 用于进行文件匹配,匹配当前工作目录下的所有.c 文件。将文件名组成列表,赋值给变量 src。如 : src = add.c sub.c div1.c
obj = $(patsubst %.c, %.o, $(src)): 用于内容的替换,将参数3中,包含参数1的部分,替换为参数2。如 : obj = add.o sub.o div1.o
clean: (没有依赖)
-rm -rf $(obj) a.out “-” #作用是,删除不存在文件时,不报错。顺序执行结束。
3 个自动变量:
$@: 在规则的命令中,表示规则中的目标。
$^: 在规则的命令中,表示所有依赖条件。
$<: 在规则的命令中,表示第一个依赖条件。如果将该变量应用在模式规则中,它可将依赖条件列表中的依赖依次取出,套用模式规则。
符号
= 最基本的赋值
make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。如下:例子中,y的值将会是 xyz bar ,而不是 foo bar 。
x = foo
y = $(x) bar
x = xyz
:= 覆盖之前的值
表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。相当于C语言的宏定义。
如下:y的值将会是 foo bar ,而不是 xyz bar 了。
x := foo
y := $(x) bar
x := xyz
?= 如果没有被赋值过就赋予等号后面的值
+= 添加等号后面的值
$/ makefile中路径中的斜杠表示。
\ 分解较长的行。
一个较长的行可以用反斜线\分解为多行,这样可以是Makefile清晰容易阅读。注意:反斜线\后不能有空格
CDEBUG = -g
CFLAGS = $(CDEBUG) -I. -I$(srcdir) $(DEFS) \
-DDEF_AR_FILE=\"$(DEF_AR_FILE)\" \
-DDEFBLOCKING=$(DEFBLOCKING)
LDFLAGS = -g
% 匹配一个或者多个字符
vpath %.h ../inc #“%.h”表示所有以“.h”结尾的文件
vpath %c ../src #“%.c”表示所有以“.c”结尾的文件
- 忽略命令的执行错误
- 忽略命令执行错误,若下面有命令会继续执行
@ 避免显示出命令本身
makefile会把将要执行的命令行在命令执行前输出到屏幕上,使用@可以避免显示出命令本身。如下代码:
@echo 正在编译…
echo 正在编译…
则$make后显示
正在编译…
echo 正在编译…
[tab]键
所有命令行必须以[tab]字符开始,但并不是所有的以[tab]键出现行都是命令行。make程序会把出现在第一条规则之后的所有以[tab]字符开始的行都作为命令行来处理。
通配符 * 和 %
*是应用在系统中的,当要对文件系统中的文件进行查找替换时,使用*
%是应用在这个Makefile文件中的,当要对makefile文件中某一类变量进行操作时,用%
命令选项变量
Makefile中,所有命令都应该使用变量定义,在规则中使用此命令时,通过相应的变量的引用来实现命令的调用。
如:定义变量CC = gcc,规则中可使用$(CC)来引用gcc。
在命令变量后面添加“FLAGS”来命名这个选项变量。
如:CFLAGS是c编译器(命令变量为CC)的命令行选项变量;LDFLAGS是命令”ld“(命令变量LD)的选项变量。
CFLAGS
表示用于 C 编译器的选项。指定头文件(.h文件)的路径。
如:CFLAGS=-I/usr/include -I/path/include。安装一个包时会在安装路径下建立一个include目录。
LDFLAGS
表示用于 C++ 编译器的选项。gcc 等编译器会用到的一些优化参数,也可以在里面指定库文件的位置。
用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安装一个包都几乎一定的会在安装目录里建立一个lib目录。
LIBS
告诉链接器要链接哪些库文件。如LIBS = -lpthread -liconv
模式规则:
%.o:%.c
gcc -c $< -o %@
静态模式规则:
$(obj):%.o:%.c
gcc -c $< -o %@
伪目标:
.PHONY: clean ALL