lissachen
lissachen

Reputation: 229

Why are parentheses (or braces) needed in this minimal Makefile?

I am baffled why I need to echo $(VAR1) or ${VAR1} to get the output "abcd" in this Makefile:

VAR1=abcd

myTarget:
        @echo $VAR1

all: myTarget

.PHONY: all

Instead, make will echo $V (which is the empty string), and then "AR1", which is my output.

I know in bash, echo $VAR1 works to get "abcd", and my understanding is that the indented part of the code is run in bash. I'm using GNU Make 3.81.

Upvotes: 1

Views: 1117

Answers (2)

MadScientist
MadScientist

Reputation: 100856

It's needed because that's the syntax make uses to reference variables. For instance see the GNU make manual, or even the POSIX standard definition of make.

Note that makefiles are not shell scripts, and don't have the same syntax as shell scripts. Makefiles do contain shell scripts (or at least shell commands), in recipes.

By setting the variable:

VAR1 = abcd

in your makefile you're creating a make variable, not a shell variable.

A recipe (command indented by a TAB) is first parsed by make and all the make variable references are expanded. Then the result of that expansion is passed to the shell. Since you want to refer to a make variable in your recipe, you have to use the make variable reference syntax.

Upvotes: 1

jfMR
jfMR

Reputation: 24738

I know in bash, echo $VAR1 works to get "abcd", and my understanding is that the indented part of the code is what is executed by bash.

$VAR1 is expanded by make (not bash), and it is actually equivalent to expanding $(V)AR1. The resulting line after that expansion is what is executed by bash.

You need to escape the leading $ in $VAR1 to prevent make from expanding the variable. The escaping can be achieved by placing an additional $ before $VAR1, i.e.:

myTarget:
        @echo $$VAR1

This way, bash will receive the line echo $VAR1.

Upvotes: 0

Related Questions