是否可以生成没有制表符的有效makefile?

是否可以生成没有制表符的有效makefile?,makefile,tabs,whitespace,spaces,Makefile,Tabs,Whitespace,Spaces,在我的系统(Mac OS X)上,make似乎要求makefile在每个命令行的内容前面有一个制表符,否则会抛出语法错误 在创建或编辑Makefiles时,这是一个麻烦,因为我的编辑器一直设置为所有空间 你能生成没有制表符的有效makefile吗?这是make的语法奇怪之处/要求,它与Mac OS X无关。不幸的是,如果你要使用make,你对此无能为力 编辑:GNU Make现在支持自定义配方前缀。看 你不是第一个不喜欢make这方面的人。引述: Dennis的Makefile的问题是,当他添加

在我的系统(Mac OS X)上,
make
似乎要求makefile在每个
命令
行的内容前面有一个制表符,否则会抛出语法错误

在创建或编辑Makefiles时,这是一个麻烦,因为我的编辑器一直设置为所有空间


你能生成没有制表符的有效makefile吗?

这是
make
的语法奇怪之处/要求,它与Mac OS X无关。不幸的是,如果你要使用
make
,你对此无能为力

编辑:GNU Make现在支持自定义配方前缀。看

你不是第一个不喜欢
make
这方面的人。引述:

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

“那又怎样?”你问,“这有什么不对?”

它本身没有什么问题。只是当你考虑其他编程工具如何在UNIX中工作时,使用标签作为语法的一部分就像绿色贝雷帽中的一个弹弓陷阱:来自堪萨斯的可怜的孩子是约翰韦恩前面的一个步行点,看不到绊脚石。毕竟,在堪萨斯州的玉米田里,没有绊倒电线可供警惕。砰


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

有一种复杂的方法可以让一个没有制表符的有效makefile

如果将makefile更改为读取:

target: dependencies
    command1
    command2
如果能成功的话。如果您希望在多行上显示,则可以执行以下操作:

target: dependencies; command1; command2

凌乱,但它可以工作。

在vim的插入模式中,可以使用
Ctrl-v
插入文字选项卡,即使您已将tab键设置为插入空格。当然,这并不能回答您的问题,但可能是避免需要文字选项卡的可用方法的替代方法。

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

target: dependencies; \
command1; \
command2

我也在努力解决这个问题,这个问题为我解决了。传播好话

自从最初提出这个问题以来,GNU Make的一个版本已经发布,允许您使用Tab以外的字符作为前缀字符:

新的特殊变量:.RECIPEPREFIX允许您重置配方 从默认(选项卡)到其他内容的介绍字符。这个 此变量值的第一个字符是新配方介绍 性格如果变量设置为空字符串,则再次使用TAB。 可任意设置和复位;配方将在以下情况下使用激活的值: 它们首先被解析。要检测此功能,请检查$(.RECIPEPREFIX)的值


这项功能是在2010年7月发布的GNU Make 3.82中添加的(在这个问题最初的提问日期六个月后)。由于这已经过去了三年,而且从那以后也发生了变化,所以很可能其他品牌的口味都跟随了GNU品牌

如果您想使用空格,我就可以使用它

autocmd FileType make setlocal noexpandtab

如果正在使用,可以将以下行添加到
.editorconfig
文件中,以强制IDE在
生成文件中使用制表符而不是空格进行缩进:

.RECIPEPREFIX +=
在ubuntu中:vi生成文件 用制表符替换空间(或其他任何您想要的内容):


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

,直到GNU达到4.2

工作

中描述了此操作有效的原因


自GNU制作4.3以来(于2020年1月19日发布)

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

您可以使用

.RECIPEPREFIX +=
.RECIPEPREFIX:=$(.RECIPEPREFIX)

,其中
是单个空格。虽然
$(.RECIPEPREFIX)
被扩展为空值,但这不需要让GNU使ignore
。请注意,此代码即使在比版本4.3更旧的GNU Make上也能正常工作。

使用Make的人首先要了解的是tabs的问题-我从来没有发现这是一个真正的问题。@Neil,我也没有说我同意UHH,我只是说有些人不喜欢它。:-)似乎是使用cmake的好插件。这并不是make语法中唯一令人沮丧的奇怪之处。我刚刚发现(请参见
.RECIPEPREFIX
)。下面的一个答案也提到了这一点,应该标记为“正确”,而不是我的。这不是什么大问题,但很烦人。每一次。这确实很烦人,而且在线性时间内也很烦人。升级到支持
。RECIPEPREFIX
的Make版本可能是最好的方法。然而,由于我不想这样做,我最终使用了基于此的解决方案。第1行:
目标:\
,第2行:[四个空格缩进]后跟
;命令
哪个版本的make支持此功能?这在GNU Make 4.1.GNU Make 4.1中不起作用,为x86_64-pc-linux-GNU构建的GNU Make 4.1很抱歉,但它确实起作用,需要提到的是,这个变量需要在Make文件本身内部声明(前缀点不容易发现),至少在版本4.2中,这应该起作用。在
.RECIPEPREFIX
的解释中说,“如果变量为空(默认情况下),则该字符为标准制表符。”这意味着默认情况下定义了该变量。通过使用
ifeq($(origin.RECIPEPREFIX),未定义)
进行确认。因为
+=
:%s/<space chars>/^I/g
:%s/        /^I/g
.RECIPEPREFIX +=
.RECIPEPREFIX := $(.RECIPEPREFIX)<space>