Apa perbedaan antara sintaks tanda kurung $ () dan kurung kurawal $ {} dalam Makefile?

111

Apakah ada perbedaan dalam memanggil variabel dengan sintaks ${var}dan $(var)? Misalnya, bagaimana variabel akan diperluas atau apa?

Édouard Lopez
sumber

Jawaban:

95

Tidak ada perbedaan - artinya sama persis (di GNU Make dan di POSIX make).

Saya pikir itu $(round brackets)terlihat lebih rapi, tapi itu hanya preferensi pribadi.

(Jawaban lain menunjuk ke bagian yang relevan dari dokumentasi GNU Make, dan perhatikan bahwa Anda tidak boleh mencampur sintaks dalam satu ekspresi)

Norman Grey
sumber
11
Saya menggunakan $()in make untuk menghindari kebingungan (lebih dari yang sudah ada) antara variabel make dan shell. GNU Membuat dokumentasi tentang referensi variabel .
Etan Reisner
Terima kasih kepada pengguna @Eloy karena menyarankan perluasan jawaban ini, meskipun saya menolak ringkasan mereka hanya dengan mencatat poin tambahan yang berharga di jawaban lain.
Norman Grey
1
Beberapa alat mungkin tidak menghormati kesamaannya. IntelliJ IDEA disorot deploy: ${DEPS}sebagai kesalahan sintaks untuk saya, tetapi ditampilkan deploy: $(DEPS)sebagai benar, meskipun kedua ejaan memiliki efek yang sama saat dipanggil make.
amacleod
46

The Dasar-dasar dari Variabel Referensi bagian dari GNU makenegara dokumentasi tidak ada perbedaan :

Untuk mengganti nilai variabel, tulis tanda dolar diikuti dengan nama variabel dalam tanda kurung atau tanda kurung: salah satu $(foo)atau ${foo}merupakan referensi yang valid ke variabel foo.

Édouard Lopez
sumber
14

Seperti yang telah ditunjukkan dengan benar, tidak ada perbedaan tetapi berhati-hatilah untuk tidak mencampur dua jenis pembatas karena dapat menyebabkan kesalahan samar seperti contoh GNU unomadh .

Dari GNU buat manual tentang Fungsi Panggilan Sintaks (penekanan milik saya):

[…] Jika argumen itu sendiri berisi pemanggilan fungsi lain atau referensi variabel, sebaiknya gunakan jenis pembatas yang sama untuk semua referensi; tulis $(subst a,b,$(x)), bukan $(subst a,b,${x}). Ini karena lebih jelas, dan karena hanya satu jenis pembatas yang cocok untuk mencari akhir acuan .

Alexandre Perrin
sumber
11

Sebenarnya, ini terlihat cukup berbeda:

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

keluaran

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

Tapi sejauh ini saya hanya menemukan perbedaan ini ketika nama variabel menjadi $ {...} mengandung koma sendiri. Saya pertama kali mengira $ {...} memperluas koma bukan sebagai bagian dari nilainya, tetapi ternyata saya tidak dapat meretasnya dengan cara ini. Saya masih tidak mengerti ini ... Jika ada yang punya penjelasan, saya akan senang mengetahuinya!

unomadh
sumber
Berdasarkan jawaban Edouard, yang mencatat bahwa dokumentasi GNU menyatakan tidak ada perbedaan, saya kira ini hanya bug.
Keith M
8
Seperti yang ditunjukkan dalam jawaban Alexandre Perrin, kedua sintaks tersebut tidak boleh dicampur dalam baris yang sama.
Lenz
11

Gaya $ {} memungkinkan Anda menguji aturan make di shell, jika Anda memiliki variabel lingkungan yang sesuai yang disetel, karena itu kompatibel dengan bash.

Warren MacEvoy
sumber
3

Ini membuat perbedaan jika ekspresi mengandung tanda kurung yang tidak seimbang:

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

->

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

Untuk referensi variabel, ini membuat perbedaan untuk fungsi, atau untuk nama variabel yang mengandung tanda kurung (ide buruk)

Erik Carstensen
sumber