在用GNUmak4.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当我运行它时,执行true和false分支,从而得到以下输出:
kernel.bin: valid Multiboot Version 1 header
Makefile:24: *** kernel.bin: invalid Multiboot Version 1 header. Stop.为什么会发生这种事?有更好的办法吗?
我尝试把它放到一行中,甚至将if语句还原为[ 0 -eq 0 ],它仍然执行两个分支。
发布于 2017-04-21 08:15:11
您的菜谱相当于:
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不按您所写的顺序排列行,请阅读this answer
剩余配方:
if [ -eq 0 ]; then \
; \
else \
; \
fi在语法上对shell无效,因为未转义的$(grub2-file ...)将由make而不是shell展开,并且将展开为空。您希望它是一个shell扩展,所以您需要为make转义它。
$$(grub2-file...)但是,虽然剩余的菜谱会引发shell语法错误,但您从未见过它,因为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; \
fihttps://stackoverflow.com/questions/43533256
复制相似问题