以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。
日常使用 Makefile 编译文件时,可能会遇到需要分条件执行的情况。比如在一个工程文件中可编译的源文件很多,但是它们的类型是不相同的,所以编译文件使用的编译器也是不同的。手动去编文件显然是不可行的,而make 提供条件判断来解决这样的问题。Makefile 中使用条件控制可以做到处理的灵活性和高效性。
下面是条件判断中使用到的一些关键字:
关键字 | 功能 |
---|---|
ifeq | 判断参数是否不相等,相等为 true,不相等为 false。 |
ifneq | 判断参数是否不相等,不相等为 true,相等为 false。 |
ifdef | 判断是否有值,有值为 true,没有值为 false。 |
ifndef | 判断是否有值,没有值为 true,有值为 false。 |
一、ifeq 和 ifneq
条件判断的使用方式如下:
ifeq (ARG1, ARG2) ifeq 'ARG1' 'ARG2' ifeq "ARG1" "ARG2" ifeq "ARG1" 'ARG2' ifeq 'ARG1' "ARG2"
实例:
libs_for_gcc= -lgnu normal_libs= foo:$(objects) ifeq ($(CC),gcc) #括号和关键字之间要使用空格分隔,两个参数之间要使用逗号分隔$(CC) -o foo $(objects) $(libs_for_gcc) else$(CC) -o foo $(objects) $(noemal_libs) endif
条件语句中使用到三个关键字“ifeq”、“else”、“endif”。其中:“ifeq”表示条件语句的开始,并指定一个比较条件(相等)。括号和关键字之间要使用空格分隔,两个参数之间要使用逗号分隔。参数中的变量引用在进行变量值比较的时候被展开。“ifeq”下面的命令是条件满足的时候执行的,条件不满足忽略;“else”下面的命令表示当条件不满足的时候执行的部分,不是所有的条件语句都要执行此部分;“endif”是判断语句结束标志。
其实 "ifneq" 和 "ifeq" 的使用方法是完全相同的,只不过是满足条件后执行的语句正好相反。
上面的例子可以换一种更加简介的方式来写:
libs_for_gcc= -lgnu normal_libs= ifeq($(CC),gcc)libs=$(libs_for_gcc) elselibs=$(normal_libs) endif foo:$(objects)$(CC) -o foo $(objects) $(libs)
二、ifdef 和 ifndef
它们的主要功能是判断变量的值是不是为空,使用方式如下:
ifdef VARIABLE-NAME
实例1
bar = foo = $(bar) all: ifdef foo@echo yes else@echo no endif#变量“foo”的定义是“foo = $(bar)” #虽然变量“bar”的值为空,但是“ifdef”的判断结果为真,所以结果是yes
实例 2:
foo= all: ifdef foo@echo yes else@echo no endif#打印的结果是 "no",因为foo确实为空
执行 make 可以看到实例 1打印的结果是 "yes" ,实例 2打印的结果是 "no" 。
在实例 1 中,变量“foo”的定义是“foo = $(bar)”,虽然变量“bar”的值为空,但是“ifdef”的判断结果为真。
这种方式判断变量的值是否为空显然不行,因此当我们需要判断一个变量的值是否为空的时候需要使用“ifeq" 而不是“ifdef”。
注意:在 make 读取 Makefile 文件时,才计算表达式的值,并根据表达式的值决定判断语句中的哪一个部分作为此 Makefile 所要执行的内容。因此在条件表达式中不能使用自动化变量,因为自动化变量在规则命令执行时才有效(或者说自动化变量只能用在规则的命令中?)。更不能将一个完整的条件判断语句分卸在两个不同的 Makefile 的文件中。