129
target: dependencies
    command1
    command2

在我的系统(Mac OS X)上,make似乎要求 Makefile 在每command行内容之前有一个制表符,否则会引发语法错误。

这在创建或编辑 Makefile 时很烦人,因为我将编辑器设置为所有空间的所有时间。

你能制作没有制表符的有效 Makefile 吗?

4

10 回答 10

133

makemake.

编辑:GNU Make 现在支持自定义配方前缀。看到这个答案

您不是第一个不喜欢make. 引用Unix Haters 的手册

Dennis 的 Makefile 的问题在于,他在添加注释行时,无意中在第 2 行开头的制表符之前插入了一个空格。制表符是 Makefile 语法中非常重要的一部分。所有命令行(在我们的示例中以 cc 开头的行)必须以制表符开头。在他进行更改后,第 2 行没有,因此出现错误。

“所以呢?” 你问:“这有什么问题?”</p>

它本身没有任何问题。只是当您考虑其他编程工具在 Unix 中如何工作时,使用制表符作为语法的一部分就像绿色贝雷帽中的那些 pungee 棒陷阱之一:来自堪萨斯州的可怜的孩子正走在约翰韦恩面前并且没有'看不到绊线。毕竟,堪萨斯州的玉米田没有绊线需要提防。哇!

于 2010-01-25T09:19:04.520 回答
67

自从最初提出这个问题以来,已经发布了一个 GNU Make 版本,它允许您使用除Tab前缀字符之外的其他内容。从邮件列表公告

新的特殊变量:.RECIPEPREFIX 允许您将配方介绍字符从默认 (TAB) 重置为其他内容。该变量值的第一个字符是新配方介绍字符。如果变量设置为空字符串,则再次使用 TAB。可随意设置和复位;recipes 将在第一次解析时使用 active 值。要检测此功能,请检查 $(.RECIPEPREFIX) 的值。

此功能是在 2010 年 7 月发布的 GNU Make 3.82 中添加的(在此问题的原始提问日期后六个月)。由于它已经过去了三年并且自那以后发生了变化,因此其他 Make 风格很可能已经跟随 GNU Make。

于 2014-02-20T21:36:49.380 回答
54

有一个没有标签的有效生成文件的复杂方式。

如果您将 makefile 更改为:

target: dependencies; command1; command2

如果会工作。如果你想要它不止一行,那么你可以这样做:

target: dependencies; \
command1; \
command2

凌乱,但它的工作原理。

于 2010-12-11T22:39:33.237 回答
36

如果您的配置文件中有 vimrc,您可以添加此行以防止 vim 更改为空格:

autocmd FileType make setlocal noexpandtab

我也在为此苦苦挣扎,这为我解决了这个问题。传播好话!

于 2013-10-14T02:20:49.023 回答
21

如果您想使用空格,这对我有用

.RECIPEPREFIX +=

例子

于 2014-10-05T07:08:12.487 回答
14

如果您使用的是EditorConfig,则可以将以下行添加到.editorconfig文件中,以强制您的 IDE 使用制表符而不是空格来缩进Makefile

[Makefile]
indent_style = tab
于 2017-02-28T13:45:03.500 回答
13

在 vim 的插入模式下,可以使用Ctrl-v <TAB>插入文字制表符,即使您已将制表键设置为插入空格。当然,这并不能回答您的问题,但可能是避免需要文字标签的可用方法的替代方法。

于 2013-08-15T19:59:26.457 回答
9

直到 GNU Make 4.2

史蒂文彭尼的回答有效。

.RECIPEPREFIX +=

我的评论中描述了这个工作的原因。


自 GNU Make 4.3(2020 年 1 月 19 日发布)

运算符的行为+=已以向后不兼容的方式更改。如果左操作数为空值,则不再添加空格。

您可以改为使用

.RECIPEPREFIX := $(.RECIPEPREFIX)<space>

,其中<space>是一个空格。虽然$(.RECIPEPREFIX)被扩展为一个空值,但这需要不要让 GNU Make 忽略<space>。请注意,此代码甚至适用于版本低于 4.3 的 GNU Make。

于 2020-02-23T14:20:00.187 回答
2

在 ubuntu 中: vi Makefiles 用制表符替换空格(或任何你想要的):

:%s/<space chars>/^I/g

例如,用制表符替换 8 个空格:

:%s/        /^I/g

请注意:^I使用制表键插入,而不是^I字符:D

于 2020-01-14T08:28:25.300 回答
-5

不便携。某些风格的 make 绝对需要制表符。另一个更喜欢制表符而不是空格的原因:-)

于 2010-01-25T09:19:14.707 回答