Makefile中endif后添加无条件步骤报错及变量赋值问题咨询
Makefile条件语句与后续步骤的问题分析与解决
问题根源拆解
第一种代码的问题
你在build目标的recipe里使用了make的ifeq条件,但这里的b=yes/b=no是shell变量赋值,而非make变量赋值:
$(info)是make在解析Makefile阶段执行的,此时make变量b还是初始的空值;- 而recipe里的
b=yes仅在执行该shell命令时生效,属于shell环境变量,和make变量b完全无关,所以后续echo $(b)输出的是make变量的初始空值。
代码示例:
a = something b = build: ifeq ($(a),) b=yes else b=no endif $(info what_is_b=$(b)) @echo $(b) @echo "end of condition"
第二种代码的问题
你把ifeq放在了build:目标下但没有缩进,这会让make将其识别为全局条件语句(不属于任何目标的recipe):
endif之后的$(info)没有关联到任何目标,而后续缩进的@echo被make误认为是一个没有目标的recipe,因此抛出recipe commences before first target错误。
代码示例:
a = something b = build: ifeq ($(a),) b=yes else b=no endif $(info what_is_b=$(b)) @echo $(b) @echo "end of condition"
正确实现方式
方案1:设置make全局变量(解析时确定值)
如果要让b成为make变量,应该将条件语句放在目标之外(全局范围),这样make在解析阶段就会确定b的值,后续recipe可以直接使用:
a = something b = # 全局条件语句,解析时设置make变量b ifeq ($(a),) b=yes else b=no endif build: $(info what_is_b=$(b)) @echo $(b) @echo "end of condition"
方案2:在recipe中使用shell条件(运行时确定值)
如果需要在recipe运行时根据逻辑设置变量,应该使用shell的if语句(而非make的ifeq),注意换行要用\转义,shell变量引用要加$$转义:
a = something build: @if [ "$(a)" = "" ]; then \ b=yes; \ else \ b=no; \ fi; \ echo $$b; \ echo "end of condition"
关于endif后无条件步骤的说明
你很少看到类似案例的原因是:
- 全局条件语句之后的内容就是普通的Makefile代码(目标、变量定义等),这是常规用法但很少被单独拿出来举例;
- recipe内一般优先使用shell条件逻辑,而非make的
ifeq,因为make的ifeq在recipe中是解析时执行,而非运行时,容易和shell逻辑混淆。
内容的提问来源于stack exchange,提问作者gilex
相关产品推荐
相关产品推荐

