我们之前说过 makefile 是一种脚本语言程序,那么程序便会有相应的语法。在 makefile 中支持条件判断语句,可以根据条件的值来决定 make 的执行,也可以比较两个不同变量或者变量和常量值。需要注意的是:条件判断语句只能用于控制 make 实际执行的语句;但是,不能控制规则中命令的执行过程。格式如下
条件判断语句的语法如下
那么在 makefile 中都有哪些的条件判断关键呢?
关键字 |
功能 |
ifeq | 判断参数是否相等,相等为 true,否则为 false |
ifneq | 判断参数是否不相等,不相等为 true,否则为 false |
ifdef |
判断变量是否有值,有值为 true,否则为 false |
ifndef |
判断变量是否没有值,没有值为 true,否则为 false |
下来我们还是以代码为例来进行说明
.PHONY : test var1 := A var2 := $(var1) var3 := test : ifeq ($(var1),$(var2)) @echo "var1 == var2" else @echo "var1 != var2" endif ifneq ($(var2),) @echo "var2 is NOT empty" else @echo "var2 is empty" endif ifdef var2 @echo "var2 is NOT empty" else @echo "var2 is empty" endif ifndef var3 @echo "var3 is empty" else @echo "var3 is NOT empty" endif
我们来看看编译结果
我们看到编译出错了,原因就是因为 ifeq 是规则而不是命令,所以它前面一定是空格而不是 Tab 键。下来我们换成空格来看看
我们看到编译已经通过了,而且也正常运行结束。变量 var2 就取的是 变量 var1 的值,因此在第一个它们的比较相等时肯定会输出相等;第二个用 var2 和空字符进行比较,那么 var2 肯定不为空;第三个就直接用 ifdef 关键字来进行判断 var2 是否存在了;最后一个 var3 肯定为空了。根据一些前辈们的经验,总结以下的几条规则:a> 条件判断语句之前可以有空格,但不能有 Tab 字符('\t');b> 在条件语句中不要使用自动变量([email protected],$^,$<);c> 一条完整的条件语句必须位于同一个 makefile 中;d> 条件判断类似于 C 语言中的宏,预处理阶段有效,执行阶段无效;e> make 在加载 makefile 时,首先计算表达式的值(赋值方式不同,计算方式不同),根据判断语句的表达式决定执行的内容。
那么我们来看看下面的代码输出相同吗?
.PHONY : te var1 := var2 := $(var1) var3 = var4 = $(var3) test : ifdef var1 @echo "var1 is defined" else @echo "var1 is NOT defined" endif ifdef var2 @echo "var2 is defined" else @echo "var2 is NOT defined" endif ifdef var3 @echo "var3 is defined" else @echo "var3 is NOT defined" endif ifdef var4 @echo "var4 is defined" else @echo "var4 is NOT defined" endif
我们看着两个没啥差别,结果应该是一样的,都是输出的是空的。我们来看看编译结果
那么我们看到前三个是空的,var4 竟然不为空。我们来仔细看下,在 var1 和 var2 的定义中都是直接赋值(:=);而 var3 和 var4 是递归赋值(=)。在编译器看来 var4 是有值的,只不过在编译阶段不确定它的值究竟是什么而已。我们在下面加上 var3 = A,给 var3 一个具体的值,试试看效果是不是一样的。
效果是一样的。因此我们在 makefile 中不推荐递归赋值的这种写法,容易造成误解。通过对条件判断语句的学习,总结如下:1、条件判断根据条件的值来决定 make 的执行;2、条件判断可以比较两个不同变量或者变量和常量值;3、条件判断再预处理阶段有效,执行阶段无效;4、条件判断不能控制规则中命令的执行过程。
欢迎大家一起来学习 makefile 语言,可以加我QQ:243343083。
原文地址:http://blog.51cto.com/12810168/2129556