makefile 多目标
一个规则中可以有多个目标,规则所定义的命令对所有目标有效。
多目标意味着所有的目标具有相同的依赖文件,多目标通常用在一下两种情况:
仅需要一个描述依赖关系的规则,不需要在规则中命令、例如:
kbd.o command.o files.o:command.h
这个规则实现了同时给三个目标文件制定一个依赖文件
对于多个具有类似重建命令的目标。重建这些目标的命令不需要完全相同。因为可以在命令行中使用自动环变量“$@”来引用具体的目标,完成重建,
例如:
big output littleoutput :text.g
generate text.g -$(subs output,,$@)>$@
这个等价于:
bigoutput :text.g
generate text.g -big >bigoutput
littleoutput :text.g
generate text.g -little >littleoutput
例子中的“generate”根据命令行参数来决定输出文件的类型。使用make的字符串处理函数“subst”来根据目标产生对应的命令行选项。
虽然在多目标的规则中,可以根据不同目标使用不同的命令(在命令行中使用自动化变量$@)。但是,多目标规则并不能做到根据目标文件自动改变依赖文件(像上边例子中使用自动化变量$@改变规则的命令一样)。需要实现这个目的是,要用到make的静态模式。
多规则:
多规则不同于多目标,这个指的是一个文件作为多个规则的目标。
对于一个多规则的目标,重建此目标的命令只能出现在一个规则中(可以是多条命令)。如果多个规则同时给出重建此目标的命令,make使用最后一个规则中所定义的命令,同时提示错误信息。
makefile通常存在一个变量,就像我们以前提到的“objects”,它定义为所有需要变异生成.o文件的列表,当这些.o文件在其源文件所包含的头文件config.h发生变化之后能够自动的被重建,我们可以使用多目标的方式来书写makefile:
objects=foo.o bar.o
foo.o:defs.h
bar.o:defs.h test.h
$(objects):config.h
这样做的好处是:我们可以再源文件增加或删除包含头文件以后不用修改已经存在的makefile的规则,只需要增加或者删除某一个.o文件依赖的头文件。这种方式很简单也很方便。对于一个大的工程来说,这样做的好处显而易见。我们也可以通过一个变量来增加目标的依赖文件,使用make命令来定义某一个目标的依赖头文件,例如:
extradeps=$(objects):$(extradeps)
程序的意思是我们如果执行“make extradeps=foo.h”那么“foo.h”将作为所有的.o 文件的依赖文件,但是如果只执行make的话,就没有指定任何文件作为.o文件的依赖文件。
Makefile文件条件语句的三个关键字:
1.ifeq 表示条件语句的开始,并指定了一个比较条件(相等)。之后是用圆括号括包围的。使用逗号“,”分割的两个参数,和关键字“ifeq”用空格分开,参数中的变量引用在进行变量值比较时被展开。“ifeq”之后就是当满足条件make需要执行的,条件不满足时忽略。
2.“else”之后就是当天剑不满足是执行部分。
3.“endif”表示一个条件语句的结束,任何一个条件表达式都必须以“endif”结束
关键字“ifneq”
此关键字是用来判断参数是否不相等,格式为:
ifneq(ARG1,ARG2)
关键字 “ifdef”
关键字“ifdef”用来判断一个变量是否已经定义。格式为:
ifdef VARIABLE-NAME
如果变量VARIABLE-NAME的值非空,那么表达式为真。
对于indef需要说明的是:ifdef只是测试一个变量是否有值,不会对变量进行替换展开来判断变量的值是否为空。
比如说 :
bar =
foo =$(bar)
ifdef foo 就是为真的,因为它内部有值
而 indef bar 是返回false的,因为,他是空值。
关键字 “ifndef”实现的功能和“ifdef”相反。
在条件表达式中不能使用自动化变量,自动化变量在规则命令执行时才有效。