2

Is it possible to display variables outside rules using GNU Make?

Consider the following Makefile:

x = foo bar baz

ifdef x
    @echo $(x)
endif

This results in Makefile:4: *** commands commence before first target. Stop.

However, if I add a rule, it works:

x = foo bar baz

ifdef x
t:
    @echo $(x)
endif

Is it really necessary to add rules for outputting variables for debugging, etc.?

Bonus:

Why does the removal of ifdef result in Makefile:3: *** missing separator. Stop.?

x = foo bar baz

@echo $(x)

2 Answers 2

3

ehm, possible, but useless.

You must understand that a Makefile is not like a shell script. A Makefile specifies targets and what must be done to make those targets. If you keep that in mind, the execution of a spurious command in the Makefile becomes a conceptual problem. When is that command going to be executed? There is no target that would trigger that command.

You could:

MY_VAR := $(shell ls)

all:
    @echo MY_VAR IS $(MY_VAR)

Note that I assumed GNU make. This will execute ls for you and puts the output in MY_VAR. But that is a hack that should be avoided.

You can also try a extra target

extra: 
     @echo $(x)

and add that as pre-req for all other targets.

As for the bonus: it is because the line @echo $(x) has no separator. At this point in the file, make would expect a target with a : and there is no : on that line. (there are other possibilities, like a new variable assignment etc. of course)

1
  • 1
    Thanks. I don’t really see why your first example provides any value w.r.t the question (e.g., debugging purposes)? The “separator” part of the error message confuses me, indeed make could also have complained about a missing = for a variable definition?
    – Shuzheng
    Jun 11, 2021 at 12:16
2

GNU make has a feature for doing exactly that and it is called $(info ....).

You could place the following line outside of a rule and GNU make will execute it:

$(info variable x = $x))

And if you find yourself doing this sort of a task repeatedly, you can abstract it away in a macro and call it where ever needed:

make -f - <<\eof

dumpvar = $(info variable `$1' value is >>>$($1)<<<)

ssl_enable = NO
$(call dumpvar,ssl_enable)

.PHONY: all
all:;@:
eof

It will display the following on stout:

variable `ssl_enable' value is >>>NO<<<
4
  • Excellent! Thank you. In general, can make functions always be called outside rules, like $(info …)? Not just on the LHS of variable definitions? I like to think of $(info …) as make’s version of echo.
    – Shuzheng
    Jun 13, 2021 at 16:40
  • Yes , you can call the functions outside rules. In fact , the rule section is the shell script zone where make executes the shell utilities to build the target.
    – guest_7
    Jun 13, 2021 at 18:05
  • What feature of bash are you using for <<\eof? I have never seen the usage of "\" in that context. I see that by removing it, bash attempts all kinds of substitutions, which leads to errors.
    – Shuzheng
    Jun 14, 2021 at 13:07
  • The backslash turns off all kinds of substitutions and is like a single quoted heredoc.
    – guest_7
    Jun 14, 2021 at 18:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .