Dokumen resmi CMake 2.8.12 mengatakan tentangmacro
Saat dipanggil, perintah yang direkam di makro pertama-tama diubah dengan mengganti parameter formal ($ {arg1}) dengan argumen yang diteruskan, dan kemudian dipanggil sebagai perintah normal.
dan tentang function
Ketika dipanggil, perintah yang direkam dalam fungsi tersebut pertama-tama dimodifikasi dengan mengganti parameter formal ($ {arg1}) dengan argumen yang diteruskan, dan kemudian dipanggil sebagai perintah normal.
Jelas, dua kutipan hampir sama tetapi membingungkan saya. Apakah mengganti parameter pada awalnya saat memanggil fungsi seperti makro?
function
danmacro
: semantik darireturn()
: Saat digunakan dalam amacro
, Anda tidak akan kembali dari makro tetapi dari fungsi pemanggil.${ARGV}
dari dalam:macro(my_macro)
,function(my_func)
. Dan menggunakannya:set(a 123)
,my_macro("\\\${a}\\\\;\\\;;")
,my_func(\${a}\\;\;;)
. Anda akan menemukan bahwa Anda harus melarikan diri ganda semua$
,\
,;
untuk benar lulus seluruh string tidak berubah dengan perintah bersarang. Ini sebenarnya dicmake 3.14+
.Jawaban:
Saya menulis kode contoh di bawah ini:
dan hasilnya adalah:
Jadi tampaknya
arg
diberi nilaivar
saat memanggilFoo
dan${arg}
hanya string yang diganti dengan${var}
saat memanggilMoo
.Jadi menurut saya kedua kutipan di atas sangat mudah membuat orang bingung, walaupun dalam dokumen resminya juga disebutkan bahwa :
sumber
cmake --trace-expand
mencerahkanmessage("# arg in main scope = '${arg}'")
+ memanggil fungsi sebelum makro.Dengan kata lain, fungsi mendorong dan memunculkan cakupan variabel baru (variabel yang dibuat dan diubah hanya ada di fungsi), makro tidak. Namun, Anda dapat mengganti perilaku default fungsi dengan
PARENT_SCOPE
parameterset
perintah.sumber
Dokumentasi cmake yang Anda kutip sangat menyesatkan sehingga pada dasarnya salah. Ini harus diklarifikasi / diperbaiki seperti ini:
cmake --trace-expand
menunjukkan dengan tepat apa yang terjadi.Dokumen cmake 3.13.3 tidak berubah dibandingkan dengan 2.8.12 sehubungan dengan ini.
sumber
The ekspansi makro, dijawab oleh Yantao Xie benar-benar membuka mata saya!
Saya juga menemukan tutorial di bawah ini dilengkapi dengan beberapa contoh konkret, yang membantu untuk memahami konsep ruang lingkup variabel.
Dikutip dari Learn cmake dalam 15 menit :
Di CMake, Anda dapat menggunakan sepasang
function
/endfunction
perintah untuk menentukan fungsi. Ini salah satu yang menggandakan nilai numerik dari argumennya, lalu mencetak hasilnya:Fungsi berjalan dalam cakupannya sendiri. Tak satu pun dari variabel yang ditentukan dalam suatu fungsi mencemari cakupan pemanggil. Jika Anda ingin mengembalikan nilai, Anda dapat mengirimkan nama variabel ke fungsi Anda, lalu panggil
set
perintah dengan argumen khususPARENT_SCOPE
:Demikian pula, sepasang
macro
/endmacro
perintah mendefinisikan makro. Tidak seperti fungsi, makro berjalan dalam cakupan yang sama dengan pemanggilnya. Oleh karena itu, semua variabel yang ditentukan di dalam makro ditetapkan dalam cakupan pemanggil. Kita dapat mengganti fungsi sebelumnya dengan yang berikut ini:Baik fungsi maupun makro menerima sejumlah argumen yang berubah-ubah. Argumen tanpa nama diekspos ke fungsi sebagai daftar, melalui variabel khusus bernama
ARGN
.Berikut adalah fungsi yang menggandakan setiap argumen yang diterimanya, mencetak masing-masing pada baris terpisah:
sumber
Perbedaan penting lainnya antara
function()
danmacro()
adalah perilakureturn()
.Dari dokumentasi cmake return () :
Jadi karena itu diperluas pada tempatnya,
macro()
itu kembali dari pemanggil. Sementara dalam suatu fungsi, ia hanya keluar darifunction()
Contoh:
sumber
Mereka berbeda dalam hal perilakunya terkait ruang lingkup variabel. Anda dapat berpikir bahwa fungsi membuat cakupan baru dan menyalin untuk variabel, tetapi makro tidak tetapi berbagi ruang lingkup dengan induk (tempat mereka dipanggil).
Untuk detail lebih lanjut: https://levelup.gitconnected.com/cmake-variable-scope-f062833581b7
sumber