makefilegnu-make

gnu make executes commented $(info ) within define


I cannot comment out an info line inside a define. The following makefile shows the behavior (mind the tabs)

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))

when run it prints

info inside define, not commented, parameter is: make context
info inside define, commented, parameter is: make context
info outside, not commented
info receipt target all not commented
info inside define, not commented, parameter is: receipt context
info inside define, commented, parameter is: receipt context
echo target all

I read the manual but I do not understand why the commented info in the define is not ignored but executed. What did I miss?


Solution

  • If you want to use a comment inside a define, you can use a $(comment function:

    Just replace the $(info with $(comment in your code:

    define tmpl
        $(info info inside define, not commented, parameter is: $(1))
        $(comment info inside define, commented, parameter is: $(1))
    endef
    ... everything else is the same as in your example
    

    That would give an expected output:

    info inside define, not commented, parameter is: make context
    info outside, not commented
    info receipt target all not commented
    info inside define, not commented, parameter is: receipt context
    echo target all
    

    Why the # is ignored inside the define? Because the define is actually creating a multi-line variable and

    from chapter 3.1:

    Within a define directive, comments are not ignored during the definition of the variable, but rather kept intact in the value of the variable. When the variable is expanded they will either be treated as make comments or as recipe text, depending on the context in which the variable is evaluated.

    So by defining tmpl as shown, you are commanding make to do, "define tmpl as # but do two printout with $(info first." As a result the whole tmpl is expanded to just one # and therefore ignored. Effectively your makefile is equal to

    #    // tmpl 
    
    $(info info outside, not commented)
    # $(info info outside, commented)
    
    all:
        @echo echo target $@
        $(info info receipt target $@ not commented)
    #   $(info info receipt target $@ commented)
        #  // tmpl