Saya menggunakan Makefiles.
Saya memiliki target yang dipanggil run
yang menjalankan target build. Sederhana, seperti berikut ini:
prog: ....
...
run: prog
./prog
Apakah ada cara untuk menyampaikan argumen? Maka
make run asdf --> ./prog asdf
make run the dog kicked the cat --> ./prog the dog kicked the cat
Terima kasih!
Jawaban:
Saya tidak tahu cara untuk melakukan persis apa yang Anda inginkan, tetapi solusinya mungkin:
Kemudian:
sumber
$(foo)' or
$ $ foo} 'adalah referensi yang valid untuk variabel `foo '." dan hasil untuk memberikan contoh di mana hanya $ () digunakan. BaiklahPertanyaan ini sudah hampir tiga tahun, tetapi bagaimanapun juga ...
Jika Anda menggunakan GNU make, ini mudah dilakukan. Satu-satunya masalah adalah yang
make
akan menafsirkan argumen non-opsi di baris perintah sebagai target. Solusinya adalah mengubah mereka menjadi target yang tidak melakukan apa-apa, jadimake
tidak akan mengeluh:Menjalankan ini memberi:
sumber
prog foo bar --baz
make
untuk tidak menafsirkan--baz
sebagai opsi baris perintah:make -- prog foo bar --baz
. The--
berarti "semuanya setelah ini argumen, bukan pilihan".RUN_ARGS
menggunakan ini?else
cabang keifeq
dan mengatur diRUN_ARGS
sana?$(eval $(RUN_ARGS):dummy;@:)
, dengan tidak ada target dummy yang ditentukan.untuk standar make Anda bisa memberikan argumen dengan mendefinisikan makro seperti ini
kemudian gunakan seperti ini
Referensi untuk membuat NMake Microsoft
sumber
Anda dapat meneruskan variabel ke Makefile seperti di bawah ini:
Pemakaian:
atau:
Atau gunakan solusi yang disediakan oleh Beta :
Pemakaian:
sumber
TL; DR jangan mencoba melakukan ini
alih-alih membuat skrip:
dan lakukan ini:
menjawab pertanyaan yang disebutkan:
Anda dapat menggunakan variabel dalam resep
kemudian lulus tugas variabel sebagai argumen untuk dibuat
ini akan mengeksekusi
./prog arg
.tapi waspadalah terhadap jebakan. Saya akan menguraikan tentang perangkap metode ini dan metode lain lebih jauh ke bawah.
jawaban atas anggapan niat di balik pertanyaan:
asumsi: Anda ingin menjalankan
prog
dengan beberapa argumen tetapi minta dibangun kembali sebelum dijalankan jika perlu.jawabannya: buat skrip yang membangun kembali jika perlu kemudian jalankan prog dengan args
naskah ini memperjelas niatnya. ia menggunakan make untuk melakukan apa yang baik untuk: membangun. menggunakan skrip shell untuk melakukan apa yang baik untuk: pemrosesan batch.
ditambah Anda dapat melakukan apa pun yang mungkin Anda butuhkan dengan fleksibilitas penuh dan ekspresif dari skrip shell tanpa semua peringatan dari makefile.
juga sintaks panggilan sekarang praktis identik:
dibandingkan dengan:
berbeda dengan
Latar Belakang:
make tidak dirancang untuk meneruskan argumen ke target. semua argumen pada baris perintah ditafsirkan sebagai tujuan (alias target), sebagai opsi, atau sebagai penugasan variabel.
jadi jika Anda menjalankan ini:
membuat akan menafsirkan
run
danfoo
sebagai tujuan (target) untuk memperbarui sesuai dengan resep mereka.--wat
sebagai opsi untuk make. danvar=arg
sebagai tugas variabel.untuk lebih jelasnya lihat: https://www.gnu.org/software/make/manual/html_node/Goals.html#Goals
untuk terminologi lihat: https://www.gnu.org/software/make/manual/html_node/Rule-Introduction.html#Rule-Introduction
tentang metode penugasan variabel dan mengapa saya merekomendasikannya
dan variabel dalam resep
ini adalah cara yang paling "benar" dan langsung untuk menyampaikan argumen ke resep. tetapi sementara itu dapat digunakan untuk menjalankan program dengan argumen itu tentu tidak dirancang untuk digunakan seperti itu. lihat https://www.gnu.org/software/make/manual/html_node/Overriding.html#Overriding
menurut saya ini memiliki satu kelemahan besar: apa yang ingin Anda lakukan adalah menjalankan
prog
argumenarg
. tetapi bukannya menulis:kamu sedang menulis:
ini semakin canggung ketika mencoba mengoper beberapa argumen atau argumen yang mengandung spasi:
dibandingkan dengan:
Sebagai catatan, seperti inilah
prog
penampilan saya :juga perhatikan bahwa Anda tidak harus memberi
$(var)
tanda kutip di makefile:karena dengan begitu
prog
akan selalu mendapatkan hanya satu argumen:semua ini adalah mengapa saya merekomendasikan rute ini.
untuk kelengkapan berikut adalah beberapa metode lain untuk "meneruskan argumen untuk menjalankan".
metode 1:
Penjelasan super singkat: menyaring tujuan saat ini dari daftar tujuan. buat catch all target (
%
) yang tidak melakukan apa pun untuk mengabaikan tujuan lain secara diam-diam.metode 2:
Penjelasan super singkat: jika target tersebut
run
kemudian menghapus tujuan pertama dan membuat lakukan target apa-apa untuk tujuan yang tersisa menggunakaneval
.keduanya akan memungkinkan Anda untuk menulis sesuatu seperti ini
untuk penjelasan lebih lanjut, pelajari manual make: https://www.gnu.org/software/make/manual/html_node/index.html
masalah metode 1:
argumen yang dimulai dengan tanda hubung akan ditafsirkan dengan membuat dan tidak diteruskan sebagai tujuan.
solusi
argumen dengan tanda sama akan ditafsirkan dengan membuat dan tidak lulus
tidak ada solusi
argumen dengan spasi canggung
tidak ada solusi
jika sebuah argumen kebetulan
run
(sama dengan target) itu juga akan dihapusakan berjalan
./prog foo bar
sebagai gantinya./prog foo bar run
solusi mungkin dengan metode 2
jika sebuah argumen adalah target yang sah, maka itu juga akan dijalankan.
akan berjalan
./prog foo bar clean
tetapi juga resep untuk targetclean
(dengan asumsi itu ada).solusi mungkin dengan metode 2
ketika Anda salah mengetik target yang sah itu akan diam-diam diabaikan karena menangkap semua target.
hanya akan diam-diam mengabaikan
celan
.solusi adalah untuk membuat semuanya bertele-tele. jadi Anda lihat apa yang terjadi. tapi itu menciptakan banyak suara untuk keluaran yang sah.
masalah metode 2:
jika suatu argumen memiliki nama yang sama dengan target yang ada maka make akan mencetak peringatan bahwa itu sedang ditimpa.
tidak ada solusi yang saya tahu
argumen dengan tanda sama dengan masih akan ditafsirkan dengan membuat dan tidak lulus
tidak ada solusi
argumen dengan spasi masih canggung
tidak ada solusi
argumen dengan ruang istirahat
eval
mencoba membuat target melakukan apa-apa.solusi: membuat tangkapan global semua target tidak melakukan apa pun seperti di atas. dengan masalah seperti di atas bahwa ia akan lagi diam-diam mengabaikan target yang sah salah ketik.
ini digunakan
eval
untuk memodifikasi makefile saat runtime. seberapa buruk Anda dalam hal keterbacaan dan debugabilitas dan Prinsip yang paling mengejutkan .solusi: jangan lakukan ini !! 1 sebagai gantinya tulis skrip shell yang menjalankan make lalu jalankan
prog
.saya hanya diuji menggunakan gnu make. merek lain mungkin memiliki perilaku yang berbeda.
TL; DR jangan mencoba melakukan ini
alih-alih membuat skrip:
dan lakukan ini:
sumber
Berikut solusi lain yang dapat membantu dengan beberapa kasus penggunaan ini:
Dengan kata lain, pilih beberapa awalan (
test-
dalam hal ini), dan kemudian berikan nama target langsung ke program / pelari. Saya kira ini sebagian besar berguna jika ada beberapa skrip pelari yang terlibat yang dapat membuka nama target menjadi sesuatu yang berguna untuk program yang mendasarinya.sumber
$*
untuk melewati hanya bagian dari target yang cocok dengan%
.Tidak. Melihat sintaks dari halaman manual untuk GNU make
Anda dapat menentukan beberapa target, karenanya 'tidak' (setidaknya tidak dengan cara yang Anda tentukan).
sumber
Anda dapat secara eksplisit mengekstraksi setiap argumen ke-n di baris perintah. Untuk melakukan ini, Anda dapat menggunakan variabel MAKECMDGOALS, itu memegang daftar argumen baris perintah yang diberikan untuk 'make', yang ditafsirkan sebagai daftar target. Jika Anda ingin mengekstraksi argumen ke-n, Anda dapat menggunakan variabel itu dikombinasikan dengan fungsi "kata", misalnya, jika Anda ingin argumen kedua, Anda dapat menyimpannya dalam variabel sebagai berikut:
sumber
make: *** No rule to make target 'arg'. Stop.
segera ,
run: ./prog
terlihat agak aneh, karena bagian kanan harus menjadi target, jadirun: prog
terlihat lebih baik.Saya hanya menyarankan:
dan saya ingin menambahkan, bahwa argumen dapat diajukan:
make arg1="asdf" run
arg1="asdf" make run
sumber
Ini contoh saya. Perhatikan bahwa saya menulis di bawah Windows 7, menggunakan mingw32-make.exe yang datang dengan Dev-Cpp. (Saya punya c: \ Windows \ System32 \ make.bat, jadi perintahnya masih disebut "make".)
Penggunaan untuk pembersihan rutin:
Penggunaan untuk membersihkan dan membuat cadangan di mydir /:
sumber
Tidak terlalu bangga dengan ini, tetapi saya tidak ingin meneruskan variabel lingkungan jadi saya membalikkan cara untuk menjalankan perintah kaleng:
ini akan mencetak perintah yang ingin Anda jalankan, jadi evaluasi saja dalam sebuah subkulit:
sumber
Saya menemukan cara untuk mendapatkan argumen dengan tanda sama dengan (=)! Jawabannya terutama merupakan tambahan untuk jawaban @lesmana (karena ini adalah yang paling lengkap dan dijelaskan di sini), tetapi akan terlalu besar untuk menuliskannya sebagai komentar. Sekali lagi, saya ulangi pesannya: TL; DR jangan mencoba melakukan ini!
Saya membutuhkan cara untuk menangani argumen saya
--xyz-enabled=false
(karena defaultnya benar), yang kita semua tahu sekarang bahwa ini bukan target make dan karenanya bukan bagian dari$(MAKECMDGOALS)
.Sambil melihat ke semua variabel make dengan menggema
$(.VARIABLES)
saya mendapat output menarik ini:Ini memungkinkan kita untuk melakukan dua cara: memulai semuanya dengan variabel
--
(jika itu berlaku untuk kasus Anda), atau melihat ke dalam GNU membuat spesifik (mungkin tidak dimaksudkan untuk kita gunakan) variabel-*-command-variables-*-
. ** Lihat catatan kaki untuk opsi tambahan ** Dalam kasus saya, variabel ini berlaku:Dengan variabel ini kita dapat menggabungkannya dengan solusi yang sudah ada dengan
$(MAKECMDGOALS)
dan dengan mendefinisikan:dan menggunakannya dengan (secara eksplisit mencampur urutan argumen):
dikembalikan:
Seperti yang Anda lihat, kami kehilangan urutan total argumen. Bagian dengan "penugasan" -args tampaknya telah terbalik, urutan "target" -args disimpan. Saya menempatkan "penugasan" di awal, semoga program Anda tidak peduli di mana argumen itu ditempatkan.
Pembaruan: berikut membuat variabel terlihat menjanjikan juga:
sumber
Trik lain yang saya gunakan adalah
-n
bendera, yang memberitahumake
untuk melakukan lari kering. Sebagai contoh,sumber