Is there any differences in invoking variables with syntax ${var}
and $(var)
? For instance, in the way the variable will be expanded or anything?

- 40,270
- 28
- 126
- 178
-
1I have a vague recollection that in some early version(s) of make, only parens ($(...)) would be expanded in make and *not* braces (${...}). Variables with braces could then be used in actions where they would be expanded by the shell; the distinction might be relevant in some cases. – Chris Dodd Nov 29 '21 at 21:28
6 Answers
There's no difference – they mean exactly the same (in GNU Make and in POSIX make).
I think that $(round brackets)
look tidier, but that's just personal preference.
(Other answers point to the relevant sections of the GNU Make documentation, and note that you shouldn't mix the syntaxes within a single expression)

- 11,978
- 2
- 33
- 56
-
38I use the `$()` in make to avoid causing myself confusion (more than already exists) between make and shell variables. [GNU Make documentation on variable references](http://www.gnu.org/software/make/manual/make.html#Reference). – Etan Reisner Aug 07 '14 at 15:02
-
Thanks to user @Eloy for suggesting an expansion to this answer, even though I rejected their compendium in favour of simply noting the valuable extra points in other answers. – Norman Gray Mar 18 '18 at 19:24
-
1Some tools might not honor their sameness. IntelliJ IDEA highlighted `deploy: ${DEPS}` as a syntax error for me, but showed `deploy: $(DEPS)` as correct, even though both spellings have the same effect when invoked in `make`. – amacleod Jun 19 '20 at 04:14
-
The `ifeq` conditional requires use of round brackets for the equality check. You can't safely use curly braces on that line. As such, I would favour `$(round brackets)`. – Teemu Ilmonen Feb 02 '21 at 17:27
-
1Unfortunately, `$()` is also valid POSIX sh family syntax, for capturing the output of a shell command as a string. I do not see in the GNU make documentation where it says curly bracket macro expansion cannot be used in ifeq. – mcandre Apr 08 '23 at 02:51
The Basics of Variable References section from the GNU make
documentation state no differences:
To substitute a variable's value, write a dollar sign followed by the name of the variable in parentheses or braces: either
$(foo)
or${foo}
is a valid reference to the variable foo.

- 40,270
- 28
- 126
- 178
As already correctly pointed out, there is no difference but be be wary not to mix the two kind of delimiters as it can lead to cryptic errors like in the GNU make example by unomadh.
From the GNU make manual on the Function Call Syntax (emphasis mine):
[…] If the arguments themselves contain other function calls or variable references, it is wisest to use the same kind of delimiters for all the references; write
$(subst a,b,$(x))
, not$(subst a,b,${x})
. This is because it is clearer, and because only one type of delimiter is matched to find the end of the reference.

- 18,162
- 8
- 67
- 136

- 439
- 4
- 4
-
Accidentally wrote and found $(call-function ${VARIABLE}) cleaner to read and write like in Bash. – leppaott Apr 19 '22 at 08:40
-
1As criticism of the GNU make manual: And yet the given example works perfectly fine. All of `$(subst a,b,$(x))` and `$(subst a,b,${x})` and `${subst a,b,$(x)}` and `${subst a,b,${x}}` yield the same result. The reasoning that only one delimiter is matched makes little sense--of course if a reference starts with ( it must end with ), `$(x}` is clearly wrong, but seems irrelevant to mixing syntax for _different_ references. Barring pathological cases like unomadh's where the variable name is a comma, mixing syntax seems to work. – Mark Gates Oct 10 '22 at 10:08
The ${} style lets you test the make rules in the shell, if you have the corresponding environment variables set, since that is compatible with bash.

- 898
- 9
- 14
Actually, it seems to be fairly different:
, = ,
list = a,b,c
$(info $(subst $(,),-,$(list))_EOL)
$(info $(subst ${,},-,$(list))_EOL)
outputs
a-b-c_EOL
md/init-profile.md:4: *** unterminated variable reference. Stop.
But so far I only found this difference when the variable name into ${...} contains itself a comma. I first thought ${...} was expanding the comma not as part as the value, but it turns out i'm not able to hack it this way. I still don't understand this... If anyone had an explanation, I'd be happy to know !

- 183
- 1
- 8
-
1Based on Edouard's answer, which notes that the GNU make documentation states there's no difference, I'd guess this could just be a bug. – Keith M Jan 27 '17 at 17:43
-
13As pointed out in Alexandre Perrin's answer, the two syntaxes should not be mixed in the same line. – lenz May 08 '17 at 14:37
-
1First, obviously, don't use commas in variable names. Second, this works with all braces `${info ${subst ${,},-,${list}}_EOL}`, so it really does seem to be a bug with mixing parens and braces. – Mark Gates Oct 10 '22 at 09:52
It makes a difference if the expression contains unbalanced brackets:
${info ${subst ),(,:-)}}
$(info $(subst ),(,:-)))
->
:-(
*** insufficient number of arguments (1) to function 'subst'. Stop.
For variable references, this makes a difference for functions, or for variable names that contain brackets (bad idea)

- 634
- 4
- 14