1.makefile书写规则:
规则包括两个部分:依赖关系和生成目标的方法
makefile中第一条规则中的目标将被确立为最终目标,其他的目标都是被这个目标所连带出来的,如果第一条规则中的目标有很多个,那么,第一个目标灰成为最终目标。
main.o:main.c main.h
cc -g main.c //说明如何生成main.o这个文件
上面例子说明:main.o依赖于main.c和 main.h生产的目标。main.c和main.h是目标所依赖的源文件。
文件的依赖关系发生条件:1.main.o文件不存在
2.main.c和mian.h文件的日期要比main.o的文件日期要新。
规则告诉make两件事,文件的依赖关系和如何成成目标文件
=========================================================================================================================
2.在规则中使用通配符:
make支持三个通配符:“*”,“?”,“[...]”
扩展知识:
wildcard:扩展通配符(通配符(wildcard)用来指定一组符合条件的文件名)
notdir:去除路径
patsubst:替换通配符
--------------------------------------------------------------------------------------------------------------------------------------------------------------
例子:
在test目录下,建立a.c和b.c两个文件,在sud目录下,建立sa.c和sb.c两个文件。建立一个简单的Makefile:
src = $(wildcard *.c ./sub/*.c) #将./下和./sub目录下的所有的.c文件,全部展开
dir = $(notdir $(src)) #将./和./sub目录下的.c文件去掉路径名。
obj = $(patsubst %.c,%.o,$(dir))#将./和./sub目录下的全部.c文件替换成.o文件
all:
@echo "src的打印结果是:$(src)"
@echo "dir的打印结果是:$(dir)"
@echo "obj的打印结果是:$(obj)"
@echo "××××××××打印完毕××××××××××"
打印结果:
src的打印结果是:a.cb.c ./sub/sa.c ./sub/sb.c
dir的打印结果是:a.cb.c sa.c sb.c
obj的打印结果是:a.ob.o sa.o sb.o
××××××××打印完毕××××××××××
用函数wildcard得到当前目录下的所有c语言源程序文件名的方法 SRC=$(wildcard *.c)
如果还要要获得子目录sub下的文件,则可写成:SRC=$(wild *c) $(wildcard ./sub/*.c )
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
正常情况下make会先打印每一条命令语句,然后再执行,这叫回声。在语句前面加上"@",关闭回声。就像上面几句echo语句前加了@,所以没有打印语句。
==========================================================================================================================
3.模式匹配符
Make命令允许对文件名进行类似于正则运算的匹配。主要用到的匹配符“%”。
---------------------------------------------------------------------------------------------------------------------------------------------------
例如:如果当前目录下的有main.c和 foo.c两个文件,现在要将他们编译为对应的对象文件。
%.o : %.c
相当于:
main.o : main.c
foo.o : foo.c
------------------------------------------------------------------------------------------------------------------------------------------------------
使用匹配符%,可以将大量同类型的文件,只用一条规则就完成构建
==========================================================================================================================
4.变量和赋值符
Makefile一共提供了四个赋值运算符:=、:=、?=、+=。
= :在执行时扩展,允许递归扩展
:= :在定义时扩展
?= :只有在该变量为空时才设置值
+= :将值追加到变量的尾端
Makefile允许使用等号自定义变量。在调用时要用 $()括起来。在调用shell变量时美元符号前,再加一个美元符号,这是因为Make命令会对美元符号转义。
例如:
a= hello world
test:
@echo $(a)
@echo $$HOME
输出结果:
hello world
/home/ubuntu
==========================================================================================================================
5.内置变量
Make命令提供一系列内置变量。$(CC)指向当前使用的编译器,$(MAKE)指向当前使用的make工具
===========================================================================================
6.自动变量
1.$@ :指当前目标,Make命令当前构建的那个目标。
例如:
a.txt b.txt:
touch $@
运行结果:
在当前目录下创建了a.txt 和b.txt两个文件。
所以上面的相当于:
a.txt:
touch a.txt
b.txt:
touch b.txt
2.$< :指代第一个前置条件
例如:a: b c 那么$<指代a
3.$^ : 指代所有的前置条件
例如:a: b c 那么$<指代a b
4.$? :指代比目标更新的所有前置条件,之间以空格分隔.
例如:a: b c 如果b的时间比a的时间新。那么$?指代b
5.$* :指代匹配符%匹配的部分
例如:%匹配a.txt中的a,那么$*指代a
6.$(@D)和$(@F) : $(@D):指向$@的目录
$(@F):指向$@的文件名
例如:$@指代 test/a.c 则:$(@D)指代test $(@F)指代a.c
7.$(>D)和$(>F) :$(>D):指向$>的目录
$(>F):指向$>的文件名