我在用gnu make 4.1编译的makefile中有以下规则:
multiboot_check: kernel.bin
if [ $(grub2-file --is-x86-multiboot $^) -eq 0 ]; then
$(info $^: valid Multiboot Version 1 header);
else
$(error $^: invalid Multiboot Version 1 header);
fi
运行此操作时,真实和错误分支都将执行,从而导致以下输出:
kernel.bin: valid Multiboot Version 1 header
Makefile:24: *** kernel.bin: invalid Multiboot Version 1 header. Stop.
为什么会发生这种情况?有更好的方法吗?
我尝试将其放入一行,甚至将IF语句减少到[ 0 -eq 0 ]
,并且仍然执行两个分支。
您的食谱等效于:
multiboot_check: kernel.bin
# `make` directives evaluated for this target are not part of the recipe
$(info $^: valid Multiboot Version 1 header)
$(error $^: invalid Multiboot Version 1 header)
# The recipe is...
if [ -eq 0 ]; then
;
else
;
fi
首先要了解为什么make
不会像您写的那样订购线条,阅读此答案
残留食谱:
if [ -eq 0 ]; then
;
else
;
fi
对于外壳而言是句法无效的,因为UNESCAPED $(grub2-file ...)
将通过make
而不是外壳扩展,并且将一无所有。你要它是外壳的扩展,因此您需要为make
逃脱它:
$$(grub2-file...)
但是,尽管残留食谱会引起外壳语法错误,但您永远不要看到它,因为make
评估:
$(info $^: valid Multiboot Version 1 header)
$(error $^: invalid Multiboot Version 1 header)
在运行食谱之前,$(error ...)
指令终止make
在尝试执行无效的食谱之前。
校正了壳膨胀,测试:
[ $$(grub2-file --is-x86-multiboot $^) -eq 0 ]
仍然无法实现您所需的东西。该测试将确定命令grub2-file --is-x86-multiboot kernel.bin
的标准输出是否是等于0
的字符串。大概它永远不会是,你实际上是什么要确定命令的退出代码是否为0。
根据所有这些,一个更好的方法是:
multiboot_check: kernel.bin
grub2-file --is-x86-multiboot $^;
if [ $$? -eq 0 ]; then
echo "$^: valid Multiboot Version 1 header";
else
echo "$^: invalid Multiboot Version 1 header"; exit 1;
fi