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

chr*_* yo 10 makefile

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

if [-d "$$d" ]; then
<space><space><space> echo "file found";
fi;
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用ifneq命令,则下一行必须通过制表符缩进.

ifneq ($(strip $(USE_FILE)),NO)
<tab>echo "file not to be used"
endif
Run Code Online (Sandbox Code Playgroud)

空间和标签根本不重要.但是如何在makefile中,空格和制表符有区别?

Mad*_*ist 17

您必须了解makefile实际上是在一个文件中用两种完全不同的"语言"编写的.

食谱(运行编译器,回声等的命令)是用shell脚本语法编写的.

不在配方中的其余makefile 是用makefile语法编写的.

为了使make能够区分配方和不是配方的东西,它使用TAB字符.因此,以TAB开头的行被假定为配方的一部分(因此它们是shell脚本并传递给shell进行解析),而不以TAB开头的行不能成为配方的一部分(因此它们不能是shell脚本:它们必须是make语法).

在您的示例中,if [ -d ...是shell语法.如果它出现在makefile中,它必须是配方的一部分,因此必须以TAB开头; 如果make试图将其解释为makefile语法,那将是一个错误. ifneq是makefile语法:如果shell试图将其解释为shell脚本,那么它将是语法错误,因此它不能成为配方的一部分,并且不能以TAB开头.

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

现在,有一些细节变得棘手:反斜杠转义的换行符,规则上下文等等但是如果你坚持使用TAB缩进所有配方行的规则并且没有非配方行用TAB缩进,那么你'没关系.

  • 通过设置 make `SHELL` 变量,您可以选择让配方由与标准系统 shell 完全不同的程序解释,并使用完全不同的语言编写配方。不过,菜谱仍然必须用制表符缩进! (2认同)
  • 从 GNU make 3.82 开始,您可以使用“.RECIPEPREFIX”变量将配方前缀的值从 TAB 更改为任何其他(单个)字符。 (2认同)