细数makefile遇到的那些坑

细数makefile遇到的那些坑

1号坑:

在这里插入图片描述
不好意思放错了,再来!!

示例1:

.PHONY: all

A=hello

ifeq($(A), hello)
    INFO=true
else
    INFO=false
endif

all:
	@echo "result: $(INFO)"

执行结果:

$ make
Makefile:5: *** 缺失分隔符。 停止。

错误原因:
第5行:ifeq( 之间应该有空格

2号坑:

示例2:

.PHONY: all

ifeq ($(A), hello)
	INFO=true
else
	INFO=false
endif

all:
	@echo "result: $(INFO)"

执行结果:

$ make A=hello
result:

可以看到,INFO未能赋值成功。并且示例中 INFO 赋值语句中 INFO 变量没有语法高亮。

错误原因:
INFO赋值的两条语句前面应该使用空格,而不是tab键。

在写非recipe的时候,缩进应该使用空格而非TAB。在写makefile中的recipe时,因为实际上我们写的是希望shell执行的语句,所以使用的是shell syntax。而make识别recipe的方式就是缩进使用TAB。而其他时候,比如上面的例子中,我们并非在写recipe,这时候syntax应该按照makefile风格来写,所以应当使用空格来缩进。

摘自:https://zhuanlan.zhihu.com/p/145439685

总结:
经过测试发现,按照示例1中方式,将 A=hello 放在Makefile中,即使 INFO 赋值的两条语句前面使用tab键,执行 make 命令发现还是可以正确输出 result: true 的。比较奇怪。不过遇到这种情况,还是使用空格吧。

3号坑

示例3:

.PHONY: all

A=hello

ifeq ($(A), "hello")
    INFO=true
else
    INFO=false
endif

all:
	@echo "result: $(INFO)"

执行结果:

$ make 
result: false

错误原因:
语句 ifeq ($(A), "hello") 中第2个参数 "hello" 不能使用双引号。或者,变量 A 赋值语句应该为:A="hello"。根本原因在于,比较时 "hello" 才是真正的字符串,而不是 hello

4号坑

示例4:

.PHONY: all

A=hello 

ifeq ($(A), hello)
    INFO=true
else
    INFO=false
endif

all:
	@echo "result: $(INFO)"

执行结果:

$ make 
result: false

错误原因:
语句A=hello 后面多了一个空格。错误根因与示例3一致,该语句导致变量 A 的实际值是 hello ,而不是 hello

5号坑

示例5:

.PHONY: all

ifeq ($(A), "hello")
    INFO=true
else
    INFO=false
endif

all:
	@echo "result: $(INFO)"

执行结果:

$ make A="hello"
result: false
$
$ make A=hello
result: false

错误原因:
语句 ifeq ($(A), "hello") 应该修改为 ifeq ($(A), hello)
我猜测,是因为执行语句 make A="hello"make A=hello 都是在shell环境下。shell环境下赋值语句 A="hello"A=hello 是等价的,实际 A 的值都是 hello

6号坑

示例6:

.PHONY: all

A=hello

ifeq ($(A), hello)
	echo "A = hello"
else
	echo "A != hello"
endif

all:
	@echo "result: $(INFO)"

执行结果:

$ make
Makefile:6: *** 配方在第一个目标前开始。 停止。

错误原因:
我描述不太好,大概意思是 echo 是shell语句,只能在目标中使用。下面是正确写法:

正确写法:
示例6-2:

.PHONY: all

A=hello

all:
	@echo "result: $(INFO)"

ifeq ($(A), hello)
	echo "A = hello"
else
	echo "A != hello"
endif

正确写法执行结果:

$ make
result: 
echo "A = hello"
A = hello

7号坑

示例7:

.PHONY: all

A=hello

ifeq ($(A), hello)
    echo "A = hello"
else
    echo "A != hello"
endif

all:
	@echo "result: $(INFO)"

执行结果:

$ make
Makefile:6: *** 缺失分隔符。 停止。

乍一看,示例6示例7 代码代码是一样的,为什么报错不一样。
实际上,示例6 条件分支中的两个 echo 语句前面是tab键;示例7 条件分支中的两个 echo 语句前面是空格

8号坑

示例8:

.PHONY: all

A=hello

all:
	@echo "result: $(INFO)"

ifeq ($(A), hello)
    echo "A = hello"
else
    echo "A != hello"
endif

执行结果:

$ make
Makefile:9: *** 缺失分隔符。 停止。

错误原因:
示例8 代码和 6号坑 中的正确写法示例6-2非常像,区别在于示例8 中最后两个echo语句前面是空格,而示例6-2最后两个echo语句前面是tab键。根因: echo 是shell语句,需要在目标中才能使用,并且makefile的目标中使用shell语句,需要在语句前使用tab缩进。

9号坑

示例9:

.PHONY: all

A=hello

all:
	@echo "result: $(INFO)"

	ifeq ($(A), hello)
		echo "A = hello"
	else
		echo "A != hello"
	endif

执行结果:

$ make
result: 
ifeq (hello, hello)
/bin/sh: -c: 行 0: 未预期的符号“hello,”附近有语法错误
/bin/sh: -c: 行 0: `ifeq (hello, hello)'
make: *** [Makefile:7:all] 错误 1

错误原因:
ifeqelseendif 前面使用了tab缩进。
makefile的目标中,使用tab缩进来表示该条语句是shell语句。然而,ifeqelseendif 是makefile的条件判断语法,不是shell语句,因此不能在ifeqelseendif 前面使用tab缩进,可是使用空格缩进,或者按照6号坑 中的正确写法示例6-2写法,不进行缩进。

猜你喜欢

转载自blog.csdn.net/ljz0929/article/details/123153846