为什么 Make 不允许缩进“if”语句?

Lon*_*TP5 5 gnu-make

当我试图读取带有嵌套逻辑的 makefile 时,这是我身边的一个不断刺痛的问题,Make不允许缩进if语句。为什么会这样,是否有解决此限制的好方法,并且仍然具有可读的 makefile?

更新:我现在意识到这个问题是基于一个错误的前提,但我相信把它留在这里对任何犯了和我一样的错误的人来说都是有价值的。

Lon*_*TP5 10

感谢其他人的帮助,我现在意识到我的问题是在错误的前提下提出的。Makefile 绝对允许缩进的 if 语句,或者更准确地说是缩进的条件语句。他们不允许的 - 至少是开箱即用的 - 是选项卡条件。这是因为,默认情况下,Make将制表符解释为特别有意义的字符。几乎任何以制表符开头的行都被解释为配方的一部分。因此,任何不打算成为配方一部分的行(例如条件语句)不应制表符开头。

至于回答我的问题中询问为什么他们选择以这种方式使用制表符的部分,我还没有找到答案。也许设计者打算谨慎使用条件语句。

至于解决方法,我将在这里尝试描述一些解决方法。

如果您没有显示空白字符的编辑器,第一个解决方案会非常痛苦,但如果您这样做,最简单的方法可能就是添加一些空格来缩进非配方代码。但这是一个相当黑客的解决方法,而且可能是不明智的。

另一个解决方案(由 @Stefan Becker 提供)是将特殊变量,设置.RECIPEPREFIX为制表符以外的字符。这是我尝试过的示例:

.RECIPEPREFIX := >
# Now, all recipes will begin with the > character rather than a tab.

things = something another_thing something_else nothing
nothing = true

something: another_thing something_else
# See how each line of a recipe now begins with >.
# You can see I also added a tab after the >. 
# These tabs doesn't mean anything to Make; it's just for readability.
>   $(info Making $@.)
>   @touch $@

another_thing:
>   $(info Making $@.)
    # See also how lines like comments can be tabbed, 
    # but no longer add anything meaningful to recipes.
>   @touch $@

something_else:
>   $(info Making $@.)
>   @touch $@
    # And just to prove the situation with conditionals is resolved...
    # See how the @touch command begins with the new RECIPEPREFIX 
    # but the conditionals don't.
    ifeq ($(nothing),true)
>       $(info Also making nothing, because nothing is true.)
>       @touch nothing
    endif

.PHONY: everything_clean
everything_clean:
>   $(info Cleaning up everything.)
>   rm -f $(things)
Run Code Online (Sandbox Code Playgroud)

值得记住的一件事是配方行必须以 new开头RECIPEPREFIX。也就是说,这样的事情是行不通的

something: another_thing something_else
# Remember that the RECIPEPREFIX must come first. 
# Indenting your recipe lines first and then using the RECIPEPRIFX will not work.
    >$(info Making $@.)
    >@touch $@
Run Code Online (Sandbox Code Playgroud)