Makefile

来源:互联网 发布:网络安全法考试题库 编辑:程序博客网 时间:2024/05/16 04:49

makefile关系到了整个工程的编译规则,它带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

Makefile的规则:
target ... : prerequisites ...
command
...
...
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令)

 

Makefile可以定义变量:var = value,以后通过$(var)访问var变量。
可以通过.PHONY申明一个目标为“伪目标”,伪目标永远比它依赖的文件旧。也就是说make伪目标时必然会重新生成所有依赖目标。
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
可以通过include将其他Makefile文件包含到指定位置,include的语法是:include <filename>;
如果你的当前环境中定义了环境变量MAKEFILES,那么,make会把这个变量中的值做一个类似于include的动作。这个变量中的值是其它的Makefile,用空格分隔。只是,它和include不同的是,从这个环境变中引入的Makefile的“目标”不会起作用,如果环境变量中定义的文件发现错误,make也会不理。


make支持三种通配符:“*”,“?”和“[...]”。这是和Unix的B-Shell是相同的。“~”表示当前用户的$HOME目录。
Makefile文件中的特殊变量“VPATH”保存了make的搜索路径。
Makefile的规则中的目标可以不止一个,其支持多目标,$@保存了目标的集合;同样,规则的依赖文件也可以不止一个,$<保存了依赖文件的集合。
对于内容为多行数据的变量,可以采用define定义,例如:
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef

 

变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。如果你要使用真实的“$”字符,那么你需要用“$$”来表示。make的变量定义支持变量向后解析,例如:
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
echo $(foo)
执行make all后,将打印Huh?


为了防止这样的递归解析,可以使用:=强制变量内容不向后解析。另外,还有?=表示仅当对象没有值时才给他赋值。

$(var:a=b)表示将变量var中的a全部替换成b,如var=xadac,则返回xbdbc
$(var:%a=b%c)表示将变量var进行模式替换,如var=xxxa,则返回bxxxc
var+=x表示将x附加到变量var后面,如var=x,则执行后var=xx

如果命令是命令行设置的,则必须在赋值语句前加override关键字,否则赋值会被忽略。

 

条件表达式的格式是:
<conditional-directive>;
<text-if-true>;
else
<text-if-false>;
endif
其中conditional-directive可以是ifeq,ifneq,ifdef,ifndef

 

make调用函数的格式是:${<function> <arguments>}。各个参数之间用,隔开。

字符串处理函数
$(subst <from>,<to>,<text>):将text中的from替换成to
$(patsubst <pattern>,<replacement>,<text>):将text按照pattern模式替换成replacement
$(strip <string>):去除string两端的空格
$(findstring <find>,<in>):在in中查找字符串find,如果找到则返回find,否则返回空字符串。
$(filter <pattern...>,<text>):按模式pattern过滤文本text,保留符合模式的文本
$(filter-out <pattern...>,<text>):按模式pattern过滤文本text,保留符合模式的文本
$(sort <list>):将list中的文本结合按字母顺序升序排列
$(word <n>,<text>):取出text的第n个单词
$(wordlist <s>,<e>,<text>):取出text中从s到e的字符串,其中s和e都是数字
$(words <text>):统计text的单词个数
$(firstword <text>):取text的第一个单词

 

文件名操作函数
$(dir <names...>):取name中的目录名
$(notdir <names...>):取name中的文件名
$(suffix <names...>):取name中的后缀名
$(basename <names...>):取name中的前缀名
$(addsuffix <suffix>,<names...>):将前缀suffix加到names的前面
$(join <list1>,<list2>):将list1对应单词加到list2对应单词的后面

 

$(foreach <var>,<list>,<text>):对于list中的每个单词,都赋给var一次,然后调用text表达式,将text表达式的返回值用空格隔开,作为foreach的返回值。
$(if <condition>,<then-part>,<else-part>):当条件condition满足时,执行then-part,否则执行else-part。

$(call <expression>,<parm1>,<parm2>,<parm3>...):expression是一个包含诸如$(1),$(2),$(3),...的表达式,这些特殊符号会依次被parm1,parm2,parm3,...等替代,函数的返回值为expression替换后的内容.

$(origin <variable>):获取变量的来源,未定义为undefined,默认的定义为default,环境变量为environment,Makefile中定义的是file,命令行定义的为command line,override指示符重新定义的为override,命令运行中的自动化变量为automatic。

$(shell <command>):在shell中执行command命令,将其输出结果作为函数返回值。

$(error <text ...>):产生一个致命错误,其错误内容为text。
$(warning <text ...>):产生一个警告,其警告内容为text。

 

make命令执行后有三个退出码:0,表示成功执行;1,如果make运行时出现任何错误,其返回1;2,如果你使用了make的“-q”选项,并且make使得一些目标不需要更新,那么返回2。

 

make参数:
-n,--just-print,--dry-run,--recon:打印规则及其连带规则,但不执行
-t,--touch:更新目标文件时间,即将目标文件标记为已编译过状态
-q,--question:找寻目标,如果不存在则打印一条出错信息,否则什么都不做
-W <file>,--what-if=<file>,--assume-new=<file>:需要在后面跟随一个源文件,make会根据规则推导来运行依赖于这个文件的命令

-b,-m:忽略与其他版本的兼容性
-B,--always-make:重编译所有目标
-C,--directory=<dir>:指定m读取makefile的目录
--debug[=<options>]:输出调试信息,其中的options取值可以是:
 a:所有调试信息
 b:简单调试信息,不输出不需要重编译的目标
 v:在b的级别上,输出哪个makefile被解析,不需要重编译的依赖文件或者依赖目标
-d:等于--debug=a
-e,--environment-overrides:指定环境变量的值覆盖makefile中定义的变量的值
-f=<file>,--file=<file>,--makefile=<file>:指定需要执行的makefile
-h,--help:显示帮助信息
-i,--ignore-errors:执行时忽略所有错误
-I <dir>,--include-dir=<dir>:指定搜索目录
-j [<jobsnum>],--jobs[=<jobsnum>]:同时运行命令的个数
-k,--keep-going:出错也不停的运行
-l <load>,--load-average[=<load>],--max-load[=<load>]:指定make运行命令的负载
-o <file>,--old-file=<file>,--assum-old=<file>:不重新生成<file>,即时其依赖文件新于它
-p,--print-data-base:输出makefile中的所有数据,包括所有的规则和变量
-r,--no-buildin-rules:禁止使用任何隐含规则
-R,--no-buildin-variabes:禁止任何使用在变量上的隐含规则
-s,--silent,--quiet:不输出任何信息
-S,--no-keep-going,--stop:取消-k选项的作用
-v,--version:输出make的版本信息
-w,--printf-directory:输出运行makefile之前和之后的信息
--no-print-directory:禁止-w选项
--warn-undefined-variables:发现未定义变量时输出警告信息

 

GNU make支持模式规则,例如:
%.o : %.c ; <command ......>;
为一条模式规则,定义所有的.o文件依赖于相应的.c文件,规则是command。command中可以包含$@指定当前目标,$<指定当前依赖文件

make支持的自动化变量有:
$@:表示规则中的目标文件集
$%:仅当目标在函数库文件中,表示目标成员名,否则为空
%<:依赖目标中的第一个目标名字,如果是模式规则,则是符合模式的一系列文件的文件集
$?:所有比目标新的依赖目标集,空格分隔
$^:去重复后的所有依赖目标的集合
$+:不去重复的所有依赖目标的集合
$*:表示模式规则中%及其之前的部分
可以在以上规则后加D或F,分别表示目录部分和文件部分。如$(@D)表示$@的目录部分