insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
.PHONY : clean
clean :
rm edit $(objects)
Makefile里有
1、显式规则
2、隐晦规则
3、变量的定义
4、文件指示
5、注释 #
include
当前目录下:a.mk、b.mk、c.mk、foo.make、e.mk、f.mk
bar=e.mk f.mk
include foo.make *.mk $(bar)
等价于:
include foo.make a.mk b.mk c.mk e.mk f.mk
make会在当前目录下首先寻找,如果当前目录下没有找到,那么,make还会在下面的几个目录下找:
1、如果make执行时,有“-I”或“--include-dir”参数,那么make就会在这个参数所指定的目录下去寻找。
2、如果目录
-include
1、读入所有的Makefile。
2、读入被include的其它Makefile。
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。
targets : prerequisites ; command
或者
targets : prerequisites
command
objects := $(wildcard *.o)
VPATH
我的目录结构如下:
ctest
|
|--hello.c
|--Makefile
|--printf2.h
|--sub
|--printf2.c
//*****printf2.h****
void printf2(void);
//*****printf2.c***
#include
void printf2(void)
{
printf("I am printed by printf2\n");
}
//*****hello.c****
#include
#include "printf2.h"
int main(void)
{
printf2();
return 1;
}
//makefile
VPATH=./sub
hello : hello.o printf2.o
gcc -o hello hello.o printf2.o
hello.o : hello.c printf2.h
用下面的Makefile结构会好一些:
PROG = hello
OBJS = hello.o printf2.o
RM = rm -f
VPATH=./sub
all:$(PROG)
hello:$(OBJS)
$(CC) $(CFLAGS) $(CPPFLAGS) $^ $(LDFLAGS) -o $@
hello.o:hello.c printf2.h
clean:
$(RM) $(PROG) $(OBJS)
或者
VPATH=./sub
hello : hello.o printf2.o
gcc -o hello hello.o printf2.o
printf2.o : printf2.c
gcc -c $ <
hello.o : hello.c printf2.h
gcc -c hello.c
用: 分隔 VPATH = src:../headers
vpath
1、vpath
为符合模式
2、vpath
清除符合模式
3、vpath
清除所有已被设置好了的文件搜索目录。
vpath %.c foo
vpath % blish
vpath %.c bar
其表示“.c”结尾的文件,先在“foo”目录,然后是“blish”,最后是“bar”目录
vpath %.c foo:bar
vpath % blish
而上面的语句则表示“.c”结尾的文件,先在“foo”目录,然后是“bar”目录,最后才是“blish”目录。
静态模式
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
等价:
foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o
*********************************************
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte-compile $<
自动生成依赖性
cc -M main.c
其输出是:
main.o : main.c defs.h
如果你使用GNU的C/C++编译器,你得用“-MM”参数,不然,“-M”参数会把一些标准库的头文件也包含进来。
我们可以写出[.c]文件和[.d]文件的依赖关系,并让make自动更新或自成[.d]文件,并把其包含在我们的主Makefile中,这样,我们就可以自动化地生成每个文件的依赖关系了。
%.d: %.c
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< >; $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ >; $@; \
rm -f $@.$$$$
如果make执行时,带入make参数“-n”或“--just-print”或“--dry-run” 或“--recon”,那么其只是显示命令,但不会执行命令
“-t” 或“--touch” 这个参数的意思就是把目标文件的时间更新,但不更改目标文件。
make参数“-s”或“--slient”则是全面禁止命令的显示。
make的参数的是“-k”或是“--keep-going”,这个参数的意思是,如果某规则中的命令出错了,那么就终目该规则的执行,但继续执行其它规则。
“-w”或是“--print-directory”会在make的过程中输出一些信息,让你看到目前的工作目录。
当你使用“-C”参数来指定make下层Makefile时,“-w”会被自动打开的。如果参数中有“-s”(“--slient”)或是“--no-print-directory”,那么,“-w”总是失效的。
“-f”或是“--file”参数 指定Makefile make -f hchen.mk 如果在make的命令行是,不只一次地使用了“-f”参数,那么,所有指定的makefile将会被连在一起传递给make执行。
“-q” 或“--question” 这个参数的行为是找目标的意思,也就是说,如果目标存在,那么其什么也不会输出,当然也不会执行编译,如果目标不存在,其会打印出一条出错信息。
subsystem:
cd subdir && $(MAKE)
其等价于:
subsystem:
$(MAKE) -C subdir
如果你要传递变量到下级Makefile中,那么你可以使用这样的声明:
export
如果你不想让某些变量传递到下级Makefile中,那么你可以这样声明:
unexport
定义命令包
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef
foo.c : foo.y
$(run-yacc)
“=”号 右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值。
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
echo $(foo)
:=前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。如果是这样:
y := $(x) bar
x := foo
那么,y的值是“bar”,而不是“foo bar”。
ifeq (0,${MAKELEVEL})
cur-dir := $(shell pwd)
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif
高级使用
foo := a.o b.o c.o
bar := $(foo:.o=.c)
$(bar)”的值是“a.c b.c c.c
//*****************
objects = main.o foo.o bar.o utils.o
objects += another.o
//****************
override如果有变量是通过make的命令行参数设置的,那么Makefile中对这个变量的赋值会被忽略
override
目标变量
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
$(CC) $(CFLAGS) prog.o foo.o bar.o
prog.o : prog.c
$(CC) $(CFLAGS) prog.c
foo.o : foo.c
$(CC) $(CFLAGS) foo.c
bar.o : bar.c
$(CC) $(CFLAGS) bar.c
不管全局的$(CFLAGS)的值是什么,在prog目标,以及其所引发的所有规则中(prog.o foo.o bar.o的规则),$(CFLAGS)的值都是“-g”
模式变量
%.o : CFLAGS = -O
libs_for_gcc = -lgnu
normal_libs =
foo: $(objects)
ifeq ($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
ifdef
如果变量
time00 于 2010-11-26 11:08:10发表:
收藏备用
gllw915 于 2010-10-29 16:40:59发表:
先收藏之,慢慢研究
xidianwxm 于 2010-01-02 20:16:07发表:
谢谢