To refer to a variable, do either $(name) or ${name}. Now if you omit the parenthesis or the brace, like $abc, then this is interpreted as the variable $a appended to bc. Please don’t do this except for automatic variables!
To declare a variable:
varname = value
What if value itself refers to a variable? It will be expanded. The down side of this is you cannot refer to the variable itself in the value (e.g. cannot append to a variable).
Also, keep in mind the expansion occurs when evaluated. So if you make a value refer to another value, and that other value keeps changing, so will the value referring to it. At least I think that’s how it works.
(So if y=$(x), and then later x changes value, so will y).
Another way is to use := or ::=. Only the latter is a POSIX standard.
With :=, the value is set when assigned, even if the variable being referred to changes value later on.
?= means set the variable only if it is not yet set.
!= executes the RHS as a shell command and stores the resulting output. It strips the last newline if it ends in one, and converts all other newlines into spaces. Be careful if the result contains any $. I didn’t note how to take care of this.
+= appends text to the variable. It always adds a space.
There is a special form for substitutions:
${VAR:A=B} means if a word ends with A, it should replace with B. Example:
foo := a.o b.o c.o bar := $(foo:.o=.c)
It also has another substitution with % but I didn’t see the benefit.
I skipped the section on computed variable names.
Ignored override section.
Ignored the define section. It is useful when you want newlines in your variable’s value.
Occasionally, there is a difference between a variable with an empty value and a variable that was never set. Use undefine in those cases. Read for more detail.
Any variable in your environment exists as a variable in the Makefile.
By default variables are global. You can make variables that are specific to a target. Read for more details.
You can also make variables that are pattern specific. What this means is that the variables is defined for any target that matches a pattern. This way you can make a variable non-global, but not too local.
You can limit variable inheritance. Read details.
Make has some special variables. Read details.