¿Cuál es la diferencia entre la sintaxis entre paréntesis $ () y corchetes $ {} en Makefile?

110

¿Hay alguna diferencia al invocar variables con sintaxis ${var}y $(var)? Por ejemplo, ¿en la forma en que se expandirá la variable o algo así?

Édouard López
fuente

Respuestas:

95

No hay diferencia: significan exactamente lo mismo (en GNU Make y en POSIX make).

Creo que se $(round brackets)ve más ordenado, pero eso es solo una preferencia personal.

(Otras respuestas apuntan a las secciones relevantes de la documentación de GNU Make y tenga en cuenta que no debe mezclar las sintaxis en una sola expresión)

Norman Grey
fuente
11
Utilizo $()in make para evitar causarme confusión (más de la que ya existe) entre las variables make y shell. GNU Make documentación sobre referencias variables .
Etan Reisner
Gracias al usuario @Eloy por sugerir una expansión a esta respuesta, aunque rechacé su compendio a favor de simplemente señalar los valiosos puntos adicionales en otras respuestas.
Norman Gray
1
Es posible que algunas herramientas no respeten su similitud. IntelliJ IDEA se destacó deploy: ${DEPS}como un error de sintaxis para mí, pero se mostró deploy: $(DEPS)como correcto, aunque ambas ortografías tienen el mismo efecto cuando se invoca make.
amacleod
45

La sección Conceptos básicos de referencias de variables de la GNU makedocumentación no indica diferencias :

Para sustituir el valor de una variable, escriba un signo de dólar seguido del nombre de la variable entre paréntesis o corchetes: bien $(foo)o ${foo}es una referencia válida para la variable foo.

Édouard López
fuente
13

Como ya se señaló correctamente, no hay diferencia, pero tenga cuidado de no mezclar los dos tipos de delimitadores, ya que puede llevar a errores crípticos como unomadh GNU make example.

Del manual GNU make sobre la sintaxis de llamadas a funciones (el énfasis es mío):

[…] Si los argumentos en sí contienen otras llamadas a funciones o referencias a variables, es mejor usar el mismo tipo de delimitadores para todas las referencias; escribir $(subst a,b,$(x)), no $(subst a,b,${x}). Esto se debe a que es más claro y a que solo se hace coincidir un tipo de delimitador para encontrar el final de la referencia .

Alexandre Perrin
fuente
11

En realidad, parece ser bastante diferente:

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

salidas

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

Pero hasta ahora solo encontré esta diferencia cuando el nombre de la variable en $ {...} contiene una coma. Primero pensé que $ {...} estaba expandiendo la coma no como parte del valor, pero resulta que no puedo hackearlo de esta manera. Sigo sin entender esto ... Si alguien tuviera una explicación, ¡estaría feliz de saberlo!

unomadh
fuente
Según la respuesta de Edouard, que señala que la documentación de GNU make dice que no hay diferencia, supongo que esto podría ser solo un error.
Keith M
7
Como se señaló en la respuesta de Alexandre Perrin, las dos sintaxis no deben mezclarse en la misma línea.
lenz
11

El estilo $ {} le permite probar las reglas de creación en el shell, si tiene configuradas las variables de entorno correspondientes, ya que es compatible con bash.

Warren MacEvoy
fuente
3

Hace una diferencia si la expresión contiene corchetes no balanceados:

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

->

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

Para referencias de variables, esto marca la diferencia para funciones o para nombres de variables que contienen corchetes (mala idea)

Erik Carstensen
fuente