You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GNU Make中define内注释的$(info)为何仍被执行?

为什么GNU Make的define块内注释的$(info)会执行?

先看你提供的Makefile代码:

define tmpl
  $(info info inside define, not commented, parameter is: $(1))
#  $(info info inside define, commented, parameter is: $(1))
endef

$(eval $(call tmpl,make context))

$(info info outside, not commented)
# $(info info outside, commented)

all:
    @echo echo target $@
    $(info info receipt target $@ not commented)
#   $(info info receipt target $@ commented)
    $(eval $(call tmpl,receipt context))

运行后输出里,define块内被#注释的$(info)居然也执行了,而顶层注释的$(info)却没执行,核心原因在于define块里的#不是真正的Makefile注释:

  • define的作用是定义递归展开变量,块内的所有内容都是变量的字面值——包括#字符,它只是变量内容的一部分,不会被Make当作注释处理。
  • 当用$(call)展开这个变量时,Make会优先解析变量内容里的所有内嵌函数(比如$(info)),不管函数前面有没有#。因为变量展开的逻辑是先求值所有Make函数,再输出最终文本,所以$(info)会直接执行并输出内容,之后$(eval)处理展开后的文本时,才会把#开头的行当作注释,但此时$(info)已经跑完了。
  • 而Makefile顶层的# $(info ...)不会执行,是因为Make在解析顶层代码时,只要看到行首非空白字符是#,就会直接忽略整行,根本不会去解析里面的$(info)函数。

如果要在define块内真正“注释”掉$(info)这类Make函数,不能用#,可以用以下两种方法:

  • 转义$符号:把$(info)改成$$(info),这样变量展开时不会执行函数,而是保留$$(info ...)的文本,后续不会触发执行:

    define tmpl
      $(info info inside define, not commented, parameter is: $(1))
    #  $$(info info inside define, commented, parameter is: $(1))
    endef
    
  • 用条件判断包裹:用永远不成立的条件(比如ifeq (0,1))把要注释的代码包起来,让Make直接跳过这部分的解析和展开:

    define tmpl
      $(info info inside define, not commented, parameter is: $(1))
    ifeq (0,1)
      $(info info inside define, commented, parameter is: $(1))
    endif
    endef
    

内容的提问来源于stack exchange,提问作者stefan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 16:12:32