跟我一起学Makefile
2014-07-21 13:47
246 查看
Makefile介绍:
make命令属于gnu工具(gcc,g++,gdb,make,cvs,patch,diff,binutils等),make命令会在当前目录下按顺序查找文件“Makefile”、“makefile”、“GNUmakefile”,也可以使用其他的名字来书写Makefile,需要再make后面使用
“-f”、“-file”参数来指定文件名,如:make -f Make.Linux;每条规则中的命令和操作系统 Shell的命令行是一致的。make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非 命令是紧跟在依赖规则后面的分号后的。在命令行之间中的空格或是空行会被忽略,但是如果该空格或空行是以Tab键开头的,那么make会认为其是一个空命令。
GNU的make工作时的执行步骤入下:(想来其它的make也是类似)
1)、读入所有的Makefile。
2)、读入被include的其它Makefile。
3)、初始化文件中的变量。
4)、推导隐晦规则,并分析所有规则。
5)、为所有的目标文件创建依赖关系链。
6)、根据依赖关系,决定哪些目标要重新生成。
7)、执行生成命令。
一、自动化变量:
$^:代表所有依赖的文件
$@:代表目标
$<:代表第一个依赖的文件
大多说的c/c++编译器都支持一个”-M“的选项,即自动寻找文件中依赖的头文件,如果使用的是GNU的c/c++编译器,需要使用”-MM“参数,否则”-M“会将
标准库的头文件包含进来
二、静态模式与多目标
<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>
targets定义了一系列的目标文件,可以有通配符。是目标的一个集合。
target-parrtern是指明了targets的模式,也就是的目标集模式。
prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目标的定义。
例1:展开:
obj
= foo.o bar.o foo.o:foo.c
all:
$(obj) $(CC) -c $(CFLAGS) foo.c -o foo.o
$(obj):
%.o : %.c =>
bar.o: bar.c
$(CC)
-c $(CFLAGS) $< -o $@ $(CC) -c $(CFLAGS) bar.c -o bar.o
注:上面的例子中,指明了我们的目标从$object中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o
bar.o”,也就是变量
$object集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo
bar”,并为其加下“.c”的后缀,于是,我们的依赖目标
就是“foo.c bar.c”。
例2:
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
注:$(filter
%.o,$(files))表示调用Makefile函数,过滤”$filter“集合,只要其中模式为"%.o"的内容
三、 清空目标文件的规则:
每个Makefile中都应该有一个清空目标文件(.o)的规则,这不仅便于重新编译,也很利于保持文件的清洁;
1、clean:
rm edit $(obj)
2、更为稳健的方式
.PHONY: clean
clean:
-rm edit $(obj)
.PHONY表示clean是一个“伪目标”在行前面加上 “-”表示即使出问题,略过,仍要继续后面的操作。clean 最好放在Makefile的最后。”make
clean" 将清除所有被清除的文件。”cleanobj“ 和 ”cleandiff“这两个伪目标有点像子程序。可以通过输入”make cleanall“和 ”make cleanobj“以
及”makediff“来达到清除不同类文件的目的
三、引用其他Makefile
1)include <filename> #filename 可以是当前操作系统Shell的文件模式(可以保含路径和通配符)
如: include foo.mk
注:在include前面可以有一些空字符,但是绝不能是[Tab]键开始。
三、在规则中引用通配符
和shell相同make支持“*”,“?”,“[...]”三个通配符。
obj = *.o #表示obj的值为"*.o",并不是所有的 .o文件,如果想代表所有的.o文件则 obj = $(wildcard *.o)
注:在Makefile中的命令,必须要以[Tab]键开始,Makefile第一次编译的错误不会为致命错误,会在整个
Makefile编译结束,再次重新编译错误位置,如果还未通过则生成致命错误
4、shell函数 (:来自 《跟我一起写Makefile》)
shell函数与其他函数不同,它的参数应该就是linux命令。shell函数把执行操作系统命令后的输出作为函数返回值。如:
contents:=$(shell cat foo) 或者 files:=$(shell echo *.c)
注意,这个函数会生成一个shell程序执行命令,所以你要注意其运行性能,如果在Makefile中有比较复杂的规则,并且大量使用该函数,那么对于你的系统性能是有害的
特别的是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想象的多得多。
make命令属于gnu工具(gcc,g++,gdb,make,cvs,patch,diff,binutils等),make命令会在当前目录下按顺序查找文件“Makefile”、“makefile”、“GNUmakefile”,也可以使用其他的名字来书写Makefile,需要再make后面使用
“-f”、“-file”参数来指定文件名,如:make -f Make.Linux;每条规则中的命令和操作系统 Shell的命令行是一致的。make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非 命令是紧跟在依赖规则后面的分号后的。在命令行之间中的空格或是空行会被忽略,但是如果该空格或空行是以Tab键开头的,那么make会认为其是一个空命令。
GNU的make工作时的执行步骤入下:(想来其它的make也是类似)
1)、读入所有的Makefile。
2)、读入被include的其它Makefile。
3)、初始化文件中的变量。
4)、推导隐晦规则,并分析所有规则。
5)、为所有的目标文件创建依赖关系链。
6)、根据依赖关系,决定哪些目标要重新生成。
7)、执行生成命令。
一、自动化变量:
$^:代表所有依赖的文件
$@:代表目标
$<:代表第一个依赖的文件
大多说的c/c++编译器都支持一个”-M“的选项,即自动寻找文件中依赖的头文件,如果使用的是GNU的c/c++编译器,需要使用”-MM“参数,否则”-M“会将
标准库的头文件包含进来
二、静态模式与多目标
<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>
targets定义了一系列的目标文件,可以有通配符。是目标的一个集合。
target-parrtern是指明了targets的模式,也就是的目标集模式。
prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目标的定义。
例1:展开:
obj
= foo.o bar.o foo.o:foo.c
all:
$(obj) $(CC) -c $(CFLAGS) foo.c -o foo.o
$(obj):
%.o : %.c =>
bar.o: bar.c
$(CC)
-c $(CFLAGS) $< -o $@ $(CC) -c $(CFLAGS) bar.c -o bar.o
注:上面的例子中,指明了我们的目标从$object中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o
bar.o”,也就是变量
$object集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo
bar”,并为其加下“.c”的后缀,于是,我们的依赖目标
就是“foo.c bar.c”。
例2:
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
注:$(filter
%.o,$(files))表示调用Makefile函数,过滤”$filter“集合,只要其中模式为"%.o"的内容
三、 清空目标文件的规则:
每个Makefile中都应该有一个清空目标文件(.o)的规则,这不仅便于重新编译,也很利于保持文件的清洁;
1、clean:
rm edit $(obj)
2、更为稳健的方式
.PHONY: clean
clean:
-rm edit $(obj)
.PHONY表示clean是一个“伪目标”在行前面加上 “-”表示即使出问题,略过,仍要继续后面的操作。clean 最好放在Makefile的最后。”make
clean" 将清除所有被清除的文件。”cleanobj“ 和 ”cleandiff“这两个伪目标有点像子程序。可以通过输入”make cleanall“和 ”make cleanobj“以
及”makediff“来达到清除不同类文件的目的
三、引用其他Makefile
1)include <filename> #filename 可以是当前操作系统Shell的文件模式(可以保含路径和通配符)
如: include foo.mk
注:在include前面可以有一些空字符,但是绝不能是[Tab]键开始。
三、在规则中引用通配符
和shell相同make支持“*”,“?”,“[...]”三个通配符。
obj = *.o #表示obj的值为"*.o",并不是所有的 .o文件,如果想代表所有的.o文件则 obj = $(wildcard *.o)
注:在Makefile中的命令,必须要以[Tab]键开始,Makefile第一次编译的错误不会为致命错误,会在整个
Makefile编译结束,再次重新编译错误位置,如果还未通过则生成致命错误
4、shell函数 (:来自 《跟我一起写Makefile》)
shell函数与其他函数不同,它的参数应该就是linux命令。shell函数把执行操作系统命令后的输出作为函数返回值。如:
contents:=$(shell cat foo) 或者 files:=$(shell echo *.c)
注意,这个函数会生成一个shell程序执行命令,所以你要注意其运行性能,如果在Makefile中有比较复杂的规则,并且大量使用该函数,那么对于你的系统性能是有害的
特别的是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想象的多得多。
相关文章推荐
- 跟我一起写Makefile:MakeFile介绍
- 跟我一起写 Makefile(十二)
- 跟我一起写 Makefile(五)
- 跟我一起写 Makefile(九)
- 跟我一起学Makefile
- 跟我一起写Makefile(1)
- 跟我一起写 Makefile——1.3 Makefile 介绍
- 跟我一起写Makefile:MakeFile介绍
- 跟我一起写 Makefile(六)
- 跟我一起写 Makefile
- 跟我一起写 Makefile
- 跟我一起写 Makefile(九)
- 跟我一起写makefile 学习笔记
- 跟我一起写 Makefile(一)
- 跟我一起写 Makefile(二)
- 跟我一起学写Makefile-Lesson 3
- 跟我一起写 Makefile
- 跟我一起写makefile-4(书写命令)
- 跟我一起写 Makefile(二)
- 跟我一起写 Makefile(十)