A:B
cmd1
B:C
cmd2
如果B比A新但C不比B新,则只会执行cmd1,不会执行cmd2.
.PHONY : clean
clean :
如果目标与文件夹同名,目标又没有依赖,则会一直提示 XX is up to date .可以用.PHONY 指明是目标而不是文件。
objects=*.o 并不会展开
objects:=$(wildcard *.o) 展开得到所有的.o 文件
静态模式
objects=aa.o bb.o
all:$(objects)
$(objects):%.o:%.c
cc -c $< -o $@
$(objects):%.o:%.c 表示$(objects)中满足%.o匹配作为目标并依赖与%.c
%.d: %.c
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< >$@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g'< $@.$$$$ > $@; \
rm -f $@.$$$$
set -e表示,如果某个命令的返回参数非0,那么整个程序立刻退出
由于$是makefile特殊符号,一个$要用$$得到,$$$$表示当前进程号每个shell命令的进程号通常是不同的,为了每次调用
时得到的进程号相同,必须把这4行放在一条命令中,这里用分号把它们连接成一条命令
变量的部分替换:
$(var:a=b)
将var中a结尾内容天换为b
foo:=a.o b.o c.o
$(foo:.o=.c)
则foo为a.c b.c c.c
静态模式:
bar:=$(foo:%.o=%.c)
将变量的值再当成变量:
x=y
y=z
z=u
a:=$($($(x)))
则a=u
目标变量即局部变量:
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
$(CC) $(CFLAGS) prog.o foo.obar.o
prog.o : prog.c
$(CC) $(CFLAGS) prog.c
foo.o : foo.c
$(CC) $(CFLAGS) foo.c
bar.o : bar.c
$(CC) $(CFLAGS) bar.c
在这个示例中,不管全局的$(CFLAGS)的值是什么,在 prog 目标,以及其所引发的所
有规则中(prog.o foo.o bar.o 的规则),$(CFLAGS)的值都是“-g”
在这个示例中,不管全局的$(CFLAGS)的值是什么,在 prog 目标,以及其所引发的所
有规则中(prog.o foo.o bar.o 的规则),$(CFLAGS)的值都是“-g”
模式变量及匹配的目标变量:
%.o : CFLAGS = -O
a.mk b.mk $(bar)=biso bash
include *.mk $(bar)
include 会将变量直接展开 上边相当include a.mk b.mk biso bash
如果路径不是以/开头,也就是不是绝对路径,则1:再命令行 “-I “ “--include-dir 找
2:依次找/usr/gnu/include” “/usr/local/include”和“/usr/include
如果没找到,会提示warning,继续读取makefile,知道最后还没找到则会抛出error
-include 可以用来忽略错误
MAKEFILES环境变量,用于指定再读取makefile前就读取的make文件:跟include的差别:
1:不会作为终极目标
2:找不到不会报错
MAKEFILE_LIST 各种方式读取的mk文件
$(word $(worlds $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) 得到最后一个mk文件。
.VARIABLES 所有的全局变量
---makefile 文件的重建跟重载其他makefile
依赖---目标
依赖目标可以有多个,第一个作为终极目标。 以点开头的.PHONY 或者模式目标%.c: 不能作为终极目标
依赖可以有多个,其中依赖两种: AA:BB | CC BB更新会重新生成AA CC更新只有在AA不存在的情况下才会重新生产AA 可以没有BB类型依赖,
依赖可以追加: AA:BB
cmd1
AA:CC
cmd2
等价于 AA:BB CC
cmd2
print: *.java
@echo "$?"
@touch print
$? 指所有更新的依赖
4.5.3 目录搜索路径
VPATH
vpath %.h ../headers
%.h 表示当前目录没有%.h ,再到../headers下搜索 这些.h文件仅限于makefile中.h文件 .c文件中的不是,这个需要再gcc 的-I选项中找。
$^ 代表所有目标依赖,包含路径 解决目录搜索问题
$@ 代表所有目标,包含路径
$< 代表所有目标依赖第一个,包含路径 可以去掉头文件,头文件只是目标更新起作用
$? 指所有更新的依赖
$* 静态模式中所有的茎
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc -c $(CFLAGS) $< -o $@
4.12 静态模式
bigoutput littleoutput : %output : text.g
generate text.g -$* > $@
$* 代表big little
环境变量
CURDIR 当前make目录
cd subdir && $(MAKE) 这个时候CURDIR=subdir
SHELL默认是 /bin/sh