Qual è la differenza tra la sintassi della parentesi $ () e della parentesi graffa $ {} nel Makefile?


111

Ci sono differenze nell'invocare variabili con sintassi ${var}e $(var)? Ad esempio, nel modo in cui verrà espansa la variabile o altro?

Risposte:


95

Non c'è differenza - significano esattamente lo stesso (in GNU Make e in POSIX make).

Penso che sia $(round brackets)più ordinato, ma è solo una preferenza personale.

(Altre risposte indicano le sezioni pertinenti della documentazione di GNU Make e nota che non dovresti mescolare le sintassi all'interno di una singola espressione)


11
Uso il $()make per evitare di crearmi confusione (più di quanto già esiste) tra le variabili make e shell. GNU Crea documentazione sui riferimenti alle variabili .
Etan Reisner

Grazie all'utente @Eloy per aver suggerito un'espansione a questa risposta, anche se ho rifiutato il loro compendio a favore della semplice annotazione dei preziosi punti extra in altre risposte.
Norman Gray

1
Alcuni strumenti potrebbero non onorare la loro identità. IntelliJ IDEA è stato evidenziato deploy: ${DEPS}come un errore di sintassi per me, ma mostrato deploy: $(DEPS)come corretto, anche se entrambe le ortografie hanno lo stesso effetto quando invocate in make.
amacleod


14

Come già correttamente sottolineato, non vi è alcuna differenza, ma attenzione a non mischiare i due tipi di delimitatori poiché può portare a errori criptici come unomadh GNU per esempio.

Dal manuale GNU make sulla sintassi della chiamata di funzione (enfasi mia):

[…] Se gli argomenti stessi contengono altre chiamate a funzioni o riferimenti a variabili, è più saggio usare lo stesso tipo di delimitatori per tutti i riferimenti; scrivi $(subst a,b,$(x)), no $(subst a,b,${x}). Questo perché è più chiaro e perché viene trovato un solo tipo di delimitatore per trovare la fine del riferimento .


11

In realtà, sembra essere abbastanza diverso:

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

uscite

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

Ma finora ho trovato questa differenza solo quando il nome della variabile in $ {...} contiene una virgola. All'inizio pensavo che $ {...} non espandesse la virgola come parte del valore, ma si scopre che non sono in grado di hackerarlo in questo modo. Continuo a non capire ... Se qualcuno avesse una spiegazione, sarei felice di saperlo!


Sulla base della risposta di Edouard, che osserva che la documentazione di GNU make afferma che non c'è differenza, immagino che questo potrebbe essere solo un bug.
Keith M

8
Come sottolineato nella risposta di Alexandre Perrin, le due sintassi non dovrebbero essere mescolate sulla stessa riga.
lenz

11

Lo stile $ {} ti consente di testare le regole make nella shell, se hai impostato le variabili di ambiente corrispondenti, poiché è compatibile con bash.


3

Fa differenza se l'espressione contiene parentesi non bilanciate:

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

->

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

Per i riferimenti alle variabili, questo fa la differenza per le funzioni o per i nomi delle variabili che contengono parentesi (pessima idea)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.