何时在Makefile中使用空格或制表符?

何时在Makefile中使用空格或制表符?,makefile,Makefile,我正在创建一个使用条件if和ifneq的makefile。 我注意到如果我使用if,那么接下来的几行应该用空格缩进 if [-d "$$d" ]; then <space><space><space> echo "file found"; fi; if[-d“$$d”];然后 回显“找到文件”; fi; 但是如果我使用ifneq命令,那么接下来的几行必须用制表符缩进 ifneq ($(strip $(USE_FILE)),NO) <tab>ec

我正在创建一个使用条件if和ifneq的makefile。 我注意到如果我使用if,那么接下来的几行应该用空格缩进

if [-d "$$d" ]; then
<space><space><space> echo "file found";
fi;
if[-d“$$d”];然后
回显“找到文件”;
fi;
但是如果我使用ifneq命令,那么接下来的几行必须用制表符缩进

ifneq ($(strip $(USE_FILE)),NO)
<tab>echo "file not to be used"
endif
ifneq($(strip$(USE_FILE)),否)
echo“不使用的文件”
恩迪夫

空间和标签根本不重要。但是为什么在makefile中,空格和制表符是不同的呢?

你必须理解,一个makefile实际上是用两种完全不同的“语言”编写的,在一个文件中

配方(运行编译器、echo等的命令)是用shell脚本语法编写的

配方中没有的makefile的其余部分是用makefile语法编写的

为了让make区分配方和非配方之间的区别,它使用了制表符。因此,假设以TAB开头的行是配方的一部分(因此它们是shell脚本并传递给shell进行解析),而不以TAB开头的行不能是配方的一部分(因此它们不能是shell脚本:它们必须是make语法)

在您的示例中,
if[-d…
是shell语法。如果它出现在一个生成文件中,那么它必须是一个配方的一部分,因此前面必须有一个选项卡;如果make试图将其解释为生成文件语法,那么它将是一个错误。
ifneq
是一个生成文件语法:如果shell试图将其解释为一个shell脚本,那么它将是一个语法错误,因此它不能是reci的一部分pe和前面不能有选项卡

缩进的所有其他用法都是可选的且不相关的(例如,在上面的第一个示例中,您说“下一行应该用空格缩进”;这只是一种约定,无论您是否缩进,脚本的工作方式都完全相同)


现在,有一些细节变得棘手:反斜杠转义换行符、规则上下文等。但是如果您坚持所有配方行都用制表符缩进,而没有非配方行用制表符缩进的规则,那么就可以了。

通过设置make
SHELL
变量,您可以选择让配方由完整的与标准system shell完全不同的程序,并且使用完全不同的语言编写配方。但是配方仍然必须用制表符缩进!从GNU make 3.82开始,您可以使用
.RECIPEPREFIX
变量将配方前缀的值从制表符更改为任何其他(单个)字符。