What's the difference between parenthesis $() and curly bracket ${} syntax in Makefile?

32,425

Solution 1

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)

Solution 2

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.

Solution 3

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.

Solution 4

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.

Solution 5

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 !

Share:
32,425
Édouard Lopez
Author by

Édouard Lopez

Motivation I'm a quality-driven full-stack developer loving UX and devOps. Workflow include TDD and tests ; pair-programming ; code-review ; Trunk-based development ; Agile related. Languages and Tools Frontend: JS, ES6+, ReactJS, Vue.js, EmberJS, Angular, webpack/rollup ; test: unit Jest, AVA, end-to-end Cypress Backend: Python, Flask, Django, Unittest and Pytest ; DevOps: Docker/compose/Docker.py, Ansible ; Shell: bash/sh, fish, powershell test: Bats, fishtape, Pester Bonus I'm familiar with: UX (User eXperience) ; Accessibility ; Data-visualization ; IA (Information Architecture).

Updated on July 08, 2022

Comments

  • Édouard Lopez
    Édouard Lopez almost 2 years

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

  • Etan Reisner
    Etan Reisner almost 10 years
    I use the $() in make to avoid causing myself confusion (more than already exists) between make and shell variables. GNU Make documentation on variable references.
  • Keith M
    Keith M over 7 years
    Based 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.
  • lenz
    lenz about 7 years
    As pointed out in Alexandre Perrin's answer, the two syntaxes should not be mixed in the same line.
  • Norman Gray
    Norman Gray about 6 years
    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.
  • amacleod
    amacleod almost 4 years
    Some 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.
  • Teemu Ilmonen
    Teemu Ilmonen over 3 years
    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).
  • leppaott
    leppaott about 2 years
    Accidentally wrote and found $(call-function ${VARIABLE}) cleaner to read and write like in Bash.