objects := $(wildcard *.o)
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
.PHONY : clean
clean :
rm $(objects) # 或-rm或@rm
----------------------------------------------------------------
$@
表示规则中的目标文件集。
$%
仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。
$<
依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。
$?
所有比目标新的依赖目标的集合。以空格分隔。
当你希望只对更新过的依赖文件进行操作时,"$?"在显式规则中很有用,例如,假设有一个函数库文件叫"lib",其由其它几个object文件更新。那么把object文件打包的比较有效率的Makefile规则是:
lib : foo.o bar.o lose.o win.o
ar r lib $?
$^
所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
$+
这个变量很像"$^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。
----------------------------------------------------------------
sources = foo.c bar.c
sinclude $(sources:.c=.d)
# 变量$(sources)所有[.c]的字串都替换成[.d]
%.d: %.c
@set -e; rm -f $@; /
$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; /
sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; /
rm -f $@.$$$$
# main.o : main.c defs.h --> main.o main.d : main.c defs.h
----------------------------------------------------------------
make -n 或 --just-print
make -nw
The `-W' flag provides two features:
* If you also use the `-n' or `-q' flag, you can see what `make'
would do if you were to modify some files.
* Without the `-n' or `-q' flag, when `make' is actually executing
commands, the `-W' flag can direct `make' to act as if some files
had been modified, without actually modifying the files.
使用“-C”参数来指定make下层Makefile时,“-w”会被自动打开的
make -t 或 --touch
make -q 或 --question
make -s 或 --silent
make -C <dir> 或 --directory=<dir> 指定读取makefile的目录
make -i 或 --ignore-errors
make -k 或 --keep-going 及 .IGNORE目标
----------------------------------------------------------------
exec:
cd /home/hchen
pwd
与
exec:
cd /home/hchen; pwd
----------------------------------------------------------------
IMMEDIATE = DEFERRED
IMMEDIATE ?= DEFERRED
# 如果没定义
IMMEDIATE := IMMEDIATE
# 只能使用已定义好的变量
IMMEDIATE += DEFERRED or IMMEDIATE
For the append operator, `+=', the right-hand side is considered
immediate if the variable was previously set as a simple variable
(`:='), and deferred otherwise.
define IMMEDIATE
DEFERRED
endef
---------------------------------------------------------------
ifeq (0,${MAKELEVEL})
cur-dir := $(shell pwd)
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif
---------------------------------------------------------------
nullstring :=
space := $(nullstring) # end of the line
---------------------------------------------------------------
libs_for_gcc = -lgnu
normal_libs =
ifeq ($(CC),gcc)
libs=$(libs_for_gcc)
else
libs=$(normal_libs)
endif
foo: $(objects)
$(CC) -o foo $(objects) $(libs)
---------------------------------------------------------------
comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
# 把$(foo)中的空格替换成逗号,所以$(bar)的值是“a,b,c”
---------------------------------------------------------------
$(subst <from>,<to>,<text>)
$(patsubst <pattern>,<replacement>,<text>)
$(patsubst %.c,%.o,x.c.c bar.c)
$(strip <string>)
去掉<string>字串中开头和结尾的空字符
$(strip a b c )从“a b c ”得到“a b c”
---------------------------------------------------------------
$(dir <names...>)
名称:取目录函数——dir。
功能:从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”。
返回:返回文件名序列<names>的目录部分。
示例: $(dir src/foo.c hacks)返回值是“src/ ./”。
$(notdir <names...>)
名称:取文件函数——notdir。
功能:从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(“/”)之后的部分。
返回:返回文件名序列<names>的非目录部分。
示例: $(notdir src/foo.c hacks)返回值是“foo.c hacks”。
$(suffix <names...>)
名称:取后缀函数——suffix。
功能:从文件名序列<names>中取出各个文件名的后缀。
返回:返回文件名序列<names>的后缀序列,如果文件没有后缀,则返回空字串。
示例:$(suffix src/foo.c src-1.0/bar.c hacks)返回值是“.c .c”。
$(basename <names...>)
名称:取前缀函数——basename。
功能:从文件名序列<names>中取出各个文件名的前缀部分。
返回:返回文件名序列<names>的前缀序列,如果文件没有前缀,则返回空字串。
示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是“src/foo src-1.0/bar hacks”。
$(addsuffix <suffix>,<names...>)
名称:加后缀函数——addsuffix。
功能:把后缀<suffix>加到<names>中的每个单词后面。
返回:返回加过后缀的文件名序列。
示例:$(addsuffix .c,foo bar)返回值是“foo.c bar.c”。
$(addprefix <prefix>,<names...>)
名称:加前缀函数——addprefix。
功能:把前缀<prefix>加到<names>中的每个单词后面。
返回:返回加过前缀的文件名序列。
示例:$(addprefix src/,foo bar)返回值是“src/foo src/bar”。
$(join <list1>,<list2>)
名称:连接函数——join。
功能:把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数要比<list2>的多,那么,<list1>中的多出来的单词将保持原样。如果<list2>的单词个数要比<list1>多,那么,<list2>多出来的单词将被复制到<list2>中。
返回:返回连接过后的字符串。
示例:$(join aaa bbb , 111 222 333)返回值是“aaa111 bbb222 333”。
---------------------------------------------------------------
$(foreach <var>,<list>,<text>)
names := a b c d
files := $(foreach n,$(names),$(n).o)
# $(files)的值是“a.o b.o c.o d.o”。
---------------------------------------------------------------
reverse = $(2) $(1)
foo = $(call reverse,a,b)
---------------------------------------------------------------
sources = foo.c bar.c
ifneq ( $(MAKECMDGOALS),clean)
include $(sources:.c=.d)
endif
只要我们输入的命令不是“make clean”,那么makefile会自动包含“foo.d”和“bar.d”这两个makefile。
---------------------------------------------------------------
There are two reasons to use a phony target: to avoid a
conflict with a file of the same name, and to improve performance.
.PHONY: all
all: prog1 prog2 prog3 prog4
---------------------------------------------------------------
自http://www.chinaunix.net/jh/23/408225.html 及 make manual摘录