本文摘录自《Managing Projects with GUN Make(3rd)》
本文讨论的makefile命名如下
目标:依赖
命令
--.隐含规则:当在Makefile中没有找到显示规则时,则使用隐含规则(make有许多隐含规则,这里只列了几个)
1.依赖.c文件生成同名的.o
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
2.依赖.c文件连接成同名可执行文件
%: %.c
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
3.依赖.l文件用flex生成同名的.c文件
%.c: %.l
@$(RM) $@
$(LEX.l) $< > $@
例如:
Makefile如下:
VPATH = src include
CPPFLAGS = -I include
count_words: counter.o lexer.o -lfl
count_words.o: counter.h
counter.o: counter.h lexer.h
lexer.o: lexer.h
执行make后产生如下命令
gcc -I include -c -o count_words.o src/count_words.c
gcc -I include -c -o counter.o src/counter.c
flex -t src/lexer.l > lexer.c
gcc -I include -c -o lexer.o lexer.c
gcc count_words.o counter.o lexer.o /lib/libfl.a -o count_words
rm lexer.c
--,静态规则
$(OBJECTS): %.o: %c
$(CC) -c $(CFLAGS) $< -o $@
只对$(OBJECTS)中的名字进行匹配
--.一个规则有多个目标,相当于每个目标各自有相同的依赖,多个目标是分开处理的
例如:
vpath.o variable.o: make.h config.h等同于
vpath.o: make.h config.h
variable.o: make.h config.h
--.规则不一定要一次定义,即可对规则追加依赖。
例如:
vpath.o: vpath.c make.h config.h getopt.h gettext.h dep.h
...(其他内容)
vpath.o: filedef.h hash.h job.h commands.h variable.h vpath.h
后面新出现的依赖会被追加到同一个目标后
--.Makefile的转义字符和Bourne shell的相同,即: ~, *, ?, [...], [^...]
?:匹配一个任意字符
~:展开为Home的路径
[...]:为一类字符
[~..]:为一类字符的取反
--.当转义字符出现在目标或依赖时,由make展开,当转义字符出现在命令时,由shell展开
--.make读取makefile时立即对转义字符进行展开,而shell则在执行时才展开
--.伪目标(PHONY target)总是被认为是过时的(out of date)
--.大部分Makefile都遵从的规定
Standard phony targets(标准的伪目标)
Target (目标) Function(功能)
all Perform all tasks to build the application(执行规则,生成最终的可执行程序)
install Create an installation of the application from the compiled binaries(安装可执行程序)
clean Delete the binary files generated from sources(从原代码中删除二进制文件)
distclean Delete all the generated files that were not in the original source distribution(删除所有编译产生的文件,紧保留原始源代码文件)
TAGS Create a tags table for use by editors(生成vim等编辑器可使用的TAGS)
info Create GNU info files from their Texinfo sources(产生GNU info文件)
check Run any tests associated with this application(运行测试程序)
--.自动变量只能用在命令
$@ 目标的名字
$% 库文件的成员的名字
$< 第一个依赖的名字
$? 所有比目标新的依赖的名字,多个依赖用空格分开
$^ 所有依赖的名字,多个依赖用空格分开,并删除重复的依赖
$+ 所有依赖的名字,多个依赖用空格分开,不删除重复的依赖
$* 去除前缀后目标的名字
--.VPATH变量定义文件的搜索路径,紧用于目标和依赖的搜索,如果有同名的文件则使用第一个搜索到的(用vpath会比VPATH变量更灵活)
例如:
在Makefile开头定义VPATH = src include,则make搜索路径为src, include和当前目录
例如:
在Makefile中定义
vpath %.c src
vpath %.h include
则make在src目录搜索所有.c文件,在include目录搜索所有.h文件
--,命令行中设置的变量会覆盖所有对该变量的赋值
例如:
在Makefie中有
CPPFLAGS = -I project/include
执行make CPPFLAGS=-DDEBUG时,CPPFLAGS的值将只有-DDEBUG