target: dependencies
command1
command2
在我的系统 (Mac OS X) 上,
make
似乎要求 Makefile 在每个 command
行的内容之前有一个制表符,否则它会抛出语法错误。
这在创建或编辑 Makefile 时很烦人,因为我将我的编辑器设置为一直都是空格。
你能制作没有制表符的有效 Makefile 吗?
这是
make
的语法异常/要求,它与 Mac OS X 无关。不幸的是,如果您要使用 make
,您将无能为力。
编辑:GNU Make 现在支持自定义配方前缀。见这个答案。
你不是第一个讨厌
make
这方面的人。引用Unix Haters'Handbook:
Dennis 的Makefile 的问题在于,他在添加注释行时,无意中在第2 行开头的制表符前插入了一个空格。制表符是Makefiles 语法中非常重要的一部分。所有命令行(在我们的示例中以 cc 开头的行)都必须以制表符开头。在他做出改变后,第 2 行没有,因此出现错误。
“那又怎样?”你问,“那有什么问题?”
它本身没有任何问题。只是当你考虑其他编程工具在 Unix 中的工作方式时,使用制表符作为语法的一部分就像绿色贝雷帽中的那些橡皮筋陷阱之一:来自堪萨斯州的可怜的孩子在约翰韦恩面前的步行点并且没有'看不到绊线。毕竟,在堪萨斯州的玉米田里没有需要提防的绊线。哇!
自从最初提出这个问题以来,发布了一个 GNU Make 版本,允许您使用 Tab 以外的其他字符作为前缀字符。 来自邮件列表公告:
新的特殊变量:.RECIPEPREFIX 允许您重置配方 从默认 (TAB) 到其他内容的介绍字符。这 这个变量值的第一个字符是新配方介绍 特点。如果变量设置为空字符串,则再次使用 TAB。 可随意设置和重置;食谱将使用值 active when 他们首先被解析。要检测此功能,请检查 $(.RECIPEPREFIX) 的值。
此功能已添加到 2010 年 7 月发布的 GNU Make 3.82 中(此问题的原始提问日期后六个月)。因为从那时起已经过去了三年并且发生了变化,所以其他 Make 风格很可能已经跟随 GNU Make。
有一个复杂的方法来获得一个没有制表符的有效 makefile。
如果您将 makefile 更改为:
target: dependencies; command1; command2
如果可行。如果你想要它在多行上,那么你可以这样做:
target: dependencies; \
command1; \
command2
凌乱,但它有效。
如果您的配置文件中有 vimrc,您可以添加此行以防止 vim 更改为空格:
autocmd FileType make setlocal noexpandtab
我也为此苦苦挣扎,这为我解决了。传播好话!
如果您正在使用 EditorConfig,您可以将以下行添加到您的
.editorconfig
文件中,以强制您的 IDE 使用制表符缩进而不是 Makefile
中的空格:
[Makefile]
indent_style = tab
在 vim 的插入模式下,即使您已将 tab 键设置为插入空格,也可以使用
Ctrl-v <TAB>
插入文字制表符。当然,这不会回答您的问题,但可能是避免需要文字标签的可用方法的替代方法。
直到 GNU Make 4.2
Steven Penny 的回答 有效。
.RECIPEPREFIX +=
这个作品的原因在我的评论中描述。
自 GNU Make 4.3(2020 年 1 月 19 日发布)
+=
运算符的行为已以向后不兼容的方式改变。如果左操作数为空值,则不再添加空格。
你可以改用
.RECIPEPREFIX := $(.RECIPEPREFIX)<space>
,其中
<space>
是一个空格。虽然 $(.RECIPEPREFIX)
被扩展为一个空值,但这是为了不让 GNU Make 忽略 <space>
。请注意,此代码甚至适用于版本 4.3 之前的 GNU Make。
(对于本质上相同但更具可读性的解决方案,请参阅@milahu 的评论。)
在 ubuntu 中:vi Makefiles 用制表符(或任何其他你想要的)替换空格:
:%s/<space chars>/^I/g
对于 ex,用制表符替换 8 个空格:
:%s/ /^I/g
注意:^I用tab键插入,不是^和I字符:D
不便携。某些风格的 make 绝对需要制表符。另一个更喜欢制表符而不是空格的原因:-)