【问题标题】:How to comment a line within a Makefile define directive?如何在 Makefile 定义指令中注释一行?
【发布时间】:2016-07-11 11:39:49
【问题描述】:

我想在 Makefile 的定义指令中注释一行或多行,以便在扩展指令时忽略该行。目标是放置注释行作为我的 Makefile 用户的提示,以显示定义指令中可能包含的内容的示例。该指令被扩展为一个目标。

换句话说,我想要那个 Makefile

define ECHO_FOO = 
#   @echo foo
endef

all: 
    @echo Before call
    $(ECHO_FOO)
    @echo After call

.PHONY: all

具有与此相同的行为:

define ECHO_FOO = 
endef

all: 
    @echo Before call
    $(ECHO_FOO)
    @echo After call

.PHONY: all

问题是第一个 Makefile 给了我以下错误:

process_begin: CreateProcess(NULL, #@echo foo, ...) 失败。 make (e=2): 系统找不到指定的文件。 Makefile:6:目标“全部”的配方失败 make: *** [all] 错误 2

GNU make:Makefile contents 页面声明:

在定义指令中,在定义变量期间不会忽略 cmets,而是在变量值中保持原样。扩展变量时,它们将被视为 make cmets 或配方文本,具体取决于评估变量的上下文。

但这并没有解释在哪种特定情况下 # 符号被视为制作评论或配方文本(这似乎是我遇到的问题)。

谁能告诉我如何在定义函数中将# 符号视为注释标记?

我已经尝试了以下所有行,想转义# 符号或更改缩进,但它们都没有给我正确的输出:

#@echo foo
    #@echo foo
##@echo foo
    ##@echo foo
\#@echo foo
    \#@echo foo 
/#@echo foo
    /#@echo foo 

我在 Windows 上运行 MinGW make 3.82,但我已经尝试过 make v3.82.90 和 4.1 的其他实现。

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    没有办法直接做你要求的事情。变量的内容在配方上下文中扩展,因此无论变量扩展为什么,它都将被视为配方的一部分,并且任何字符都将传递给 shell。

    请注意,您可以在 UNIX shell 和 Windows command.com 中使用 :,因为 : 是 shell no-op 运算符。您必须在其后添加一个空格,否则它将尝试运行命令:echo,这不是一个有效的命令。但是,进一步注意,shell 仍然会扩展该行!这意味着如果您使用反引号等,那么它们仍然会被扩展。另请注意,由于它是一个语句,分号将停止它。比如:

    define ECHO_FOO
    : echo hi `echo there 1>&2` ; echo bye
    endef
    
    all: ; @$(ECHO_FOO)
    

    这里,hi 不会被打印,因为 echo 命令没有运行,但是反引号仍然被扩展,所以 there 将被打印(到 stderr)并且分号结束“no-op”命令所以bye也会被打印出来。

    如果您的命令足够简单,那么 : 将起作用,但如果它们那么简单,您会想知道为什么要使用 define...

    另一种选择只是覆盖变量,而不是将其注释掉:

    define ECHO_FOO = 
       @echo foo
    endef
    
    ECHO_FOO =
    

    预计到达时间: 在 cmets 中,您确认该命令很简单。我不太明白你所说的最终用户可以扩展是什么意思,或者为什么会有所作为。

    但我的意思是,如果你有一个简单的命令,你可以写:

    ECHO_FOO = echo hi
    

    不要使用definedefine 只需要用于复杂的命令:实际上它只需要用于包含未转义换行符的命令。

    而且,如果你写:

    ECHO_FOO =# echo hi
    

    那么你正在使用 make cmets 注释掉变量的内容,而不是 shell cmets,所以它可以在任何地方工作。

    【讨论】:

    • 谢谢,它运行良好,我很高兴知道它适用于两个系统。实际上该命令很简单,但最终用户可以扩展,我一直在寻找简单的东西,因为最终用户不应该有很好的 Makefile 知识来使用我的。至少那是我的目标。
    • 它并不复杂,它是一个包含所有构建后脚本调用的指令,即从 0(默认带有注释示例)到许多。定义指令似乎是最好的解决方案,但也许这是一个糟糕的选择。
    • 我不太明白“包含所有构建后脚本”;如果您的意思是它包含一组在单个配方中运行的脚本,例如“post-script1 ; post-script2 ; post-script3”,那么它不是我上面使用的定义的“简单命令”(因为它包含多个命令),并且使用: 的第一个技巧无法阻止所有脚本运行。无论如何,希望以上信息足以让您将其应用于您的设置。干杯!
    • 是的,以上就够了,谢谢。是的,该指令可能包含一组脚本调用,但基本文件只有一个脚本调用需要注释。然后最终用户将取消注释并替换/添加他自己的脚本调用。注释只是在这里给出一个示例,并防止最终用户没有此脚本时生成错误。
    【解决方案2】:

    在 Windows 上,您可以使用 : 作为注释字符。 MS-DOS 中传统的注释关键字是REM(如“remark”)。

    【讨论】:

    • 谢谢,使用@rem 有效,但我更喜欢与操作系统无关的解决方案。我会等待,看看是否有其他解决方案,如果没有解决方案,我会接受你的。
    猜你喜欢
    • 2011-05-28
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    • 2016-01-10
    • 2015-12-23
    • 2013-06-24
    • 2010-10-05
    • 2012-01-13
    相关资源
    最近更新 更多