转载 http://blog.youkuaiyun.com/haoel/article/details/2886
http://blog.youkuaiyun.com/ruglcc/article/details/7814546/
Makefile:
规则:
target... : prerequisites ...
command
...
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)伪目标.
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令)
声明变量: objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o
x := foo
y := $(x) bar
x := later
result:
y := foo bar
x := later
值得一提的是,这种方法,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量
还有一个比较有用的操作符是“?=”,
FOO ?= bar
其含义是,如果FOO没有被定义过,那么变量FOO的值就是“bar”,如果FOO先前被定义过,那么这条语将什么也不做,其等价于:
ifeq ($(origin FOO), undefined)
FOO = bar
endif
使用变量: $(objects) 变量也可以赋值给变量
make自动推导: GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中.
伪目标:一般情况下,一个伪目标不作为另一个目标的依赖。当一个伪目标没有作为任何目标的依赖时,我们只能通过make命令来明确指定它为make的终极目标,
来执行它所在规则所定义的命令。还有一个特别的伪目标——all,如果我们在一个目录下创建多个可执行程序,我们可以将所有程序的重建规则在一个makefile中描述。
In terms of Make, a phony target is simply a target that is always out-of-date, so whenever you ask make <phony_target>, it will run, independent from the state of the file system.
Some common make targets that are often phony are: all, install, clean, distclean, TAGS, info, check.
phony 在WIKI的意思:Fraudulent 欺骗 ; fake 伪造; having a misleading appearance 误导性的样子.
exp:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
rm edit $(objects)
把clean定义成伪目标,就算存在clean文件,make clean也会正常运行。
Makefile中的%标记和系统通配符*的区别在于,*是应用在系统中的,%是应用在这个Makefile文件中的。
特殊符号:
“$”表示执行一个Makefile的函数
$@:目标的名字
$^:构造所需文件列表所有所有文件的名字
$<:构造所需文件列表的第一个文件的名字
$?:构造所需文件列表中更新过的文件
exp:
1 test1.o:test1.c
2 gcc -o $@ $<
$@:就是test1.o
$<:就是test1.c
1 test1.o:test1.c head.c
2 gcc -o $@ $^
$^:就是test1.c head.c
$(subst 要被替换的字符串,用来替换的字符串,被处理的字符串):
exp:
$(subst .c,.o,test1.c test2.c)
就会得到test1.o test2.o
$(wildcard 寻找的文件):
exp:
$(wildcard *.c)
就等于找到系统中所有后缀为.c的文件,返回成以空格隔开的一整行字符
例如:test1.c test2.c test3.c 这样
$(basename 文件名):
取得文件的名字(去掉后缀的意思)
exp:
$(basename test1.c)
就会取得test1
把目录下所有文件都编译的命令。
all:$(subst .c,.o,$(wildcard *.c))
%.o:%.c
gcc -o $@ $<
嵌套执行make:先进入“subdir”目录,然后执行make命令。
subsystem:
cd subdir && $(MAKE)
其等价于:
subsystem:
$(MAKE) -C subdir