Bagaimana saya bisa membatalkan eksekusi make / makefile berdasarkan variabel makefile yang tidak disetel / dihargai?
Saya datang dengan ini, tetapi hanya berfungsi jika penelepon tidak secara eksplisit menjalankan target (yaitu make
hanya berjalan ).
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
Saya pikir sesuatu seperti ini akan menjadi ide yang bagus, tetapi tidak menemukan apa pun di manual make:
ifndef MY_FLAG
.ABORT
endif
Jawaban:
TL; DR : Gunakan
error
fungsinya :Perhatikan bahwa garis tidak boleh diindentasi. Lebih tepatnya, tidak ada tab yang harus mendahului garis-garis ini.
Solusi umum
Jika Anda akan menguji banyak variabel, ada baiknya mendefinisikan fungsi bantu untuk itu:
Dan inilah cara menggunakannya:
Ini akan menghasilkan kesalahan seperti ini:
Catatan:
Pemeriksaan sebenarnya dilakukan di sini:
Ini mencerminkan perilaku
ifndef
kondisional, sehingga variabel yang didefinisikan sebagai nilai kosong juga dianggap "tidak terdefinisi". Tapi ini hanya berlaku untuk variabel sederhana dan variabel rekursif kosong secara eksplisit:Seperti yang disarankan oleh @VictorSergienko dalam komentar, perilaku yang sedikit berbeda mungkin diinginkan:
Dan:
Pemeriksaan spesifik target
Dimungkinkan juga untuk memperluas solusi sehingga seseorang dapat memerlukan variabel hanya jika target tertentu dipanggil.
$(call check_defined, ...)
dari dalam resepCukup pindahkan cek ke dalam resep:
Tanda terkemuka
@
mematikan perintah yang bergema dan:
merupakan perintah aktual, sebuah shell no-op stub .Menampilkan nama target
Itu
check_defined
fungsi dapat ditingkatkan untuk juga output nama sasaran (disediakan melalui$@
variabel):Jadi, sekarang cek yang gagal menghasilkan output yang diformat dengan baik:
check-defined-MY_FLAG
target khususSecara pribadi saya akan menggunakan solusi sederhana dan mudah di atas. Namun, misalnya, jawaban ini menyarankan menggunakan target khusus untuk melakukan pemeriksaan yang sebenarnya. Orang bisa mencoba menggeneralisasi itu dan mendefinisikan target sebagai aturan pola implisit:
Pemakaian:
Perhatikan bahwa
check-defined-BAR
terdaftar sebagai pesanan saja|...
prasyarat ( ).Pro:
Cons:
make -t
(lihat Alih-alih Melaksanakan Resep ) akan mencemari direktori root Anda dengan banyakcheck-defined-...
file. Ini adalah kelemahan menyedihkan dari kenyataan bahwa aturan pola tidak dapat dinyatakan.PHONY
.Saya percaya, keterbatasan ini dapat diatasi dengan menggunakan beberapa
eval
sulap ekspansi sihir dan sekunder , meskipun saya tidak yakin itu layak.sumber
make --version
sebagai langkah pertama.Gunakan fungsi shell
test
:Pemakaian:
sumber
checkforsomething
target yang hanya memilikitest
di dalamnya dan membuatfoo
tergantung pada itu, dan 2) saya mengubah cek@if test -z "$(something)"; then echo "helpful error here"; exit 1; fi
sebagai gantinya. Itu memberi saya kemampuan untuk menambahkan kesalahan yang bermanfaat, dan memungkinkan saya untuk membuat nama target baru sedikit lebih mengindikasikan apa yang salah.Makefile:5: *** missing separator. Stop.
test -n "$(something) || (echo "message" ; exit 1)
menghindari yang eksplisitif
.Anda dapat menggunakan IF untuk menguji:
Hasil:
sumber
[
adalah alias untuk perintahtest
, jadi ini adalah jawaban yang sama dengan @Messa di atas. Ini lebih kompak, dan termasuk pembuatan pesan kesalahan.Gunakan penanganan kesalahan shell untuk variabel tidak disetel (perhatikan ganda
$
):Jika Anda memerlukan pesan kesalahan khusus, tambahkan setelah
?
:sumber
Untuk kesederhanaan dan singkatnya:
Dengan output:
sumber