Quelle est la différence entre la syntaxe entre parenthèses $ () et accolade $ {} dans Makefile?

111

Y a-t-il des différences dans l'appel de variables avec la syntaxe ${var}et $(var)? Par exemple, dans la manière dont la variable sera développée ou quoi que ce soit?

Édouard Lopez
la source

Réponses:

95

Il n'y a pas de différence - ils signifient exactement la même chose (dans GNU Make et POSIX make).

Je pense que cela a l' $(round brackets)air plus ordonné, mais c'est juste une préférence personnelle.

(D'autres réponses pointent vers les sections pertinentes de la documentation GNU Make, et notez que vous ne devriez pas mélanger les syntaxes dans une seule expression)

Norman Gray
la source
11
J'utilise $()in make pour éviter de me créer une confusion (plus que ce qui existe déjà) entre les variables make et shell. GNU Make documentation sur les références de variables .
Etan Reisner
Merci à l'utilisateur @Eloy d'avoir suggéré une extension de cette réponse, même si j'ai rejeté leur recueil en faveur de simplement noter les précieux points supplémentaires dans d'autres réponses.
Norman Gray
1
Certains outils peuvent ne pas honorer leur similitude. IntelliJ IDEA a été mis deploy: ${DEPS}en évidence comme une erreur de syntaxe pour moi, mais s'est montré deploy: $(DEPS)correct, même si les deux orthographes ont le même effet lorsqu'elles sont invoquées dans make.
amacleod le
46

Les bases de références Variable section de l' GNU makeétat de la documentation aucune différence :

Pour remplacer la valeur d'une variable, écrivez un signe dollar suivi du nom de la variable entre parenthèses ou accolades: soit $(foo)ou ${foo}est une référence valide à la variable toto.

Édouard Lopez
la source
14

Comme déjà correctement souligné, il n'y a pas de différence mais faites attention à ne pas mélanger les deux types de délimiteurs car cela peut conduire à des erreurs cryptiques comme unomadh GNU make example.

Du manuel GNU make sur la syntaxe des appels de fonction (c'est moi qui souligne):

[…] Si les arguments eux-mêmes contiennent d'autres appels de fonction ou références de variables, il est plus sage d'utiliser le même type de délimiteurs pour toutes les références; écrire $(subst a,b,$(x)), non $(subst a,b,${x}). C'est parce qu'il est plus clair et qu'un seul type de délimiteur est mis en correspondance pour trouver la fin de la référence .

Alexandre Perrin
la source
11

En fait, cela semble être assez différent:

, = ,
list = a,b,c
$(info $(subst $(,),-,$(list))_EOL)
$(info $(subst ${,},-,$(list))_EOL)

les sorties

a-b-c_EOL
md/init-profile.md:4: *** unterminated variable reference. Stop.

Mais jusqu'à présent, je n'ai trouvé cette différence que lorsque le nom de la variable dans $ {...} contient lui-même une virgule. J'ai d'abord pensé que $ {...} étendait la virgule non comme une valeur, mais il s'avère que je ne suis pas capable de le pirater de cette façon. Je ne comprends toujours pas ça ... Si quelqu'un avait une explication, je serais heureux de savoir!

unomadh
la source
Sur la base de la réponse d'Edouard, qui note que la documentation de GNU déclare qu'il n'y a pas de différence, je suppose que cela pourrait simplement être un bogue.
Keith M
8
Comme le souligne la réponse d'Alexandre Perrin, les deux syntaxes ne doivent pas être mélangées dans la même ligne.
lenz
11

Le style $ {} vous permet de tester les règles de fabrication dans le shell, si vous avez défini les variables d'environnement correspondantes, car cela est compatible avec bash.

Warren MacEvoy
la source
3

Cela fait une différence si l'expression contient des crochets non équilibrés:

${info ${subst ),(,:-)}}
$(info $(subst ),(,:-)))

->

:-(
*** insufficient number of arguments (1) to function 'subst'.  Stop.

Pour les références de variables, cela fait une différence pour les fonctions, ou pour les noms de variables qui contiennent des crochets (mauvaise idée)

Erik Carstensen
la source