注:这里的makefile指的是gnu makefile,可能跟其他的makefile略有不同。若有不同,我尽量提及。而且这也不算是一篇教程,只是我在用make的时候记得一些笔记。推荐看<
>。另外网上有一篇《跟我一起写makefile》也很好。
makefile规则分为三部分:目标(target)、条件(prerequisite)、命令(commands)。
target:prereq1...prereqn
commans
1.自动变量
$@:代表目标文件名
$%:The filename element of an archive member specification.
$<:条件列表中的第一个条件的文件名
$?:条件列表中所有比目标新的那些条件的文件名,以空格分割
$^:条件列表中所有条件的文件名,以空格分割。如果列表中有重复的条件,则会被删掉。
$+:跟$^类似,区别在不会去掉重复的条件。
$*:目标文件名的词干部分(去掉扩展名剩下的部分)
自动变量只能用在规则的命令部分,因为这些变量是make匹配到规则的目标和条件后才设置值的。
举个例子说明一下。假设某个工程有三个文件:cal.cpp,cal.h,test.cpp(下面再有说明时也以此为例)。makefile如下:
OBJS=test.o cal.o cal.o
TARGET=cal.exe
all:$(TARGET)
$(TARGET):$(OBJS)
@echo $@
@echo $<
@echo $^
@echo $?
@echo $+
@echo $%
@echo $*
输出为:
cal.exe
test.o
test.o cal.o
test.o cal.o
test.o cal.o cal.o
ECHO is off.
ECHO is off.
至于最后两个为什么会这样输出我还不太清楚,有清楚地麻烦告诉我一下这两个怎么用。先谢谢了。
2.模式规则
模式规则也是规则,也要满足make的规则形式,分为目标、条件、命令三个部分。只是目标、条件中的文件名的词干部分用%代替了,这个%跟shell中的*类似,代表任意长度的字符串。还以上面说得工程为例,makefile如下:
CPPFLAGS= -g
CC=g++
test:cal.o test.o
cal.o:cal.h
make的时候,输出如下内容:
g++ -g -c -o test.o test.cpp
g++ -g -c -o cal.o cal.cpp
g++ test.o cal.o -o test
这个makefile之所以能够正确被处理,是因为make内建了一些规则。例如:
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
%.o: %.cpp
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
以及
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
这些规则里面的$变量都是make的标准变量(还有上面的CPPFLAGS,CC也是。另外还有一些别的),这些标准变量有的有默认值(例如CC的默认值是cc),有的没有。make在处理makefile文件时,如果没有显式的规则,那么就会查找是否有隐式的可用规则,如果找到就会利用隐式规则来生成目标。
2.1静态模式规则
静态模式规则指的是类似下面的规则:
$(OBJECTS): %.o: %c
$(CC) -c $(CFLAGS) $< -o $@
这跟上面的模式规则类似,不同在于将规则的适用范围限制在了$(OBJECTS)。也就是只针对这些目标来应用规则。
2.2后缀规则
后缀规则是指用一个或者两个后缀连接起来作为目标,同时省略掉条件部分。如下:
.c.o:
$(COMPILE.c) $(OUTPUT_OPTION) $<
容易混淆的地方是条件后缀在前,目标后缀在后。
这跟上面的规则:
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
功能是一样的,只是为了兼容一些老的make系统。
需要注意的是,这里用到的后缀必须在已知后缀列表里面。有个专用的目标(target)——.SUFFIXES——用来设定后缀列表。例如:.SUFFIXES:.pdf .o .c 。而.SUFFIXES:(也就是后面列表为空)用来清空后缀列表。
3.自动依赖生成
还没发现这个在实际应用中有多方便,有兴趣的可以看看我开始推荐的两个文档。