makefile语法
special variables特殊变量
Archive file
makefile中的规则
例子:
foo.o : foo.c defs.h
cc -c -g foo.c
会去比较foo.o新还是foo.c和defs.h新,如果是后者,就会执行第二行的语句,更新foo.o
规则的语法格式
targets : prerequisites
recipe
…
或者
targets : prerequisites ; recipe
recipe
…
通配符和Archive members都可以作为target,一般来说一条规则对应一个targets,但是也有一条规则对应多个target的情况。
recipe是由tab字符或者是.RECIPEPREFIX定义的字符起头,需要遵循特定规则.
对于很长的一行可以使用一个反斜杠分割成多行。
规则的作用有两个:1.target什么时候是过期的;2. 在需要的时候如何去更新他们。
判断时候过期的标准是由prerequisites决定的(可以是通配符或者是Archive文件)。
Prerequisites的类型
分两类
- 普通的prerequisites,主要是做了两个声明:
- recipe的执行顺序,在执行target的recipe之前,会执行该target所有prerequisites的recipe
- 声明了一个强依赖关系,一旦prerequisites比target要新,就要重新生成target
使用普通的prerequisites,得到结果是,如果有任何一个prerequisites被更新了,那么都会重新更新target。
- order-only prerequisites:放在这个list中的prerequisites时间戳更新不会导致target被更新,仅按顺序执行一次。
存在这样的情况,你想把你生成的target放在一个独立的目录下,但是该目录在执行make之前还没有被创建。
因为在目录下对文件的操作会改变时间戳,有可能会导致依赖它的target被更新。要避免这种情况,可以将目录设置为order-only prerequisites。
使用的格式:
targets : normal-prerequisites | order-only-prerequisites
例子:
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir $(OBJDIR)
在这个例子中执行顺序只这样的
- 先创建objdir目录
- 生成’.o’文件,添加到objdir目录下(objdir时间戳比’.o’文件要新,但是不会重新更新’.o’文件)
Wildcard characters通配符
官方资料
和Bourne shell中的通配符语法,作用一样。
一些使用例子:
- 在recipe中可以直接使用
clean :
rm -f *.o
- 在target和prerequisites中都可以直接使用
print: *.c
lpr -p $?
touch print
- 在变量中不能直接使用,需要配合wildcard函数
objects = *.o #这里objects就是"*.0"
objects := $(wildcard *.o) #这里objects就是当前目录下的所有.o文件
一些通用方法
在一个目录中编译c语言文件
objects := $(patsubst %.c,%.o,$(wildcard *.c))
foo : $(objects)
cc -o foo $(objects)
搜索其他目录的源文件
General Search:指定每个prerequisites的搜索路径
使用VPATH指定make需要搜索的目录,如果当前目录下没有找到需要文件,就会到VPATH列出的目录中找。
例子:
VPATH = src:../headers # ':'是分隔符,包含两个目录src和../headers
foo.o : foo.c
上面的recipe等价于下面的
foo.o : src/foo.c
Selective Search:为特定类指定搜索路径
使用vpath指令。
格式:
vpath pattern directories #pattern是用来匹配文件的,directories是这些文件所在的目录
vpath pattern #清除针对pattern匹配到的文件的vpath配置
vpath #清除所有的vpath配置
例子:
- 所有的.h文件都在…/headers中找
vpath %.h ../headers
- 所有的.c文件,先在foo目录下找,然后在blish目录中找,最后在bar目录下找。
vpath %.c foo
vpath % blish
vpath %.c bar
- 先在foo目录下找,然后在bar目录下找,最后在blish目录下找
vpath %.c foo:bar
vpath % blish