makefile mengeksekusi target lain

123

Saya memiliki makefile yang terstruktur seperti ini:

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

Saya menyadari bahwa saya secara konsisten menjalankan "make clean" diikuti dengan "clear" di terminal saya sebelum menjalankan "make all". Saya ingin memiliki terminal yang bersih sebelum saya mencoba dan menyaring kesalahan kompilasi C ++ yang buruk. Jadi saya mencoba menambahkan target ke-3:

fresh :
    rm -f *.o $(EXEC)
    clear
    make all

Ini berfungsi, namun ini menjalankan contoh kedua dari make (saya percaya). Apakah ada cara yang benar untuk mendapatkan fungsionalitas yang sama tanpa menjalankan instance make kedua?

sas4740
sumber

Jawaban:

172

Sebenarnya Anda benar: ini menjalankan contoh make yang lain. Solusi yang mungkin adalah:

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : clean clearscr all

clearscr:
    clear

Dengan memanggil make freshAnda mendapatkan cleantarget pertama , lalu clearscreenyang berjalan cleardan terakhir allyang melakukan pekerjaan.

EDIT 4 Agustus

Apa yang terjadi dalam kasus build paralel dengan -jopsi make ? Ada cara untuk memperbaiki pesanan. Dari manual make, bagian 4.2:

Namun, terkadang, Anda mengalami situasi di mana Anda ingin menerapkan urutan tertentu pada aturan yang akan dijalankan tanpa memaksa target untuk diperbarui jika salah satu aturan tersebut dijalankan. Dalam kasus tersebut, Anda ingin menentukan prasyarat khusus pesanan. Prasyarat hanya-pesanan dapat ditentukan dengan menempatkan simbol pipa (|) di daftar prasyarat: semua prasyarat di sebelah kiri simbol pipa adalah normal; semua prasyarat di sebelah kanan hanya dapat dipesan: target: normal-prasyarat | prasyarat hanya pesanan

Bagian prasyarat normal tentu saja mungkin kosong. Selain itu, Anda masih dapat mendeklarasikan beberapa baris prasyarat untuk target yang sama: mereka telah ditambahkan dengan tepat. Perhatikan bahwa jika Anda mendeklarasikan file yang sama sebagai prasyarat normal dan prasyarat hanya-pesanan, prasyarat normal akan diutamakan (karena prasyarat tersebut merupakan superset ketat dari perilaku prasyarat hanya-pesanan).

Karenanya makefile menjadi

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : | clean clearscr all

clearscr:
    clear

EDIT 5 Desember

Bukan masalah besar untuk menjalankan lebih dari satu contoh makefile karena setiap perintah di dalam tugas akan menjadi sub-shell . Tetapi Anda dapat memiliki metode yang dapat digunakan kembali menggunakan fungsi panggilan .

log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)

install:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  command1  # this line will be a subshell
  command2  # this line will be another subshell
  @command3  # Use `@` to hide the command line
  $(call log_error, "It works, yey!")

uninstall:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  ....
  $(call log_error, "Nuked!")
Dacav
sumber
6
@ sas4740: pada dasarnya semua yang mengikuti .PHONY : diperlakukan sebagai beberapa kata kunci yang selalu dieksekusi, sedangkan target non-palsu dimaksudkan sebagai file.
Dacav
apakah "Prasyarat hanya pesanan" bersyarat? untuk target t2 saya ingin pertama melakukan t0, daripada hanya jika t0 berhasil menjalankan t1, dan hanya jika keduanya berhasil menjalankan beberapa tugas di t3
fantastory
1
@fantastory, tidak, saya pikir mereka independen. t2akan bergantung pada t0, t1dan t3. Jika Anda membutuhkan ini, Anda harus meletakkan t3seperti yang dipersyaratkan oleh t2, t1sebagaimana diharuskan oleh t3dan t0sebagaimana diharuskan oleh t1. Ini berarti 3 aturan berbeda. Namun, Anda harus memverifikasi ini. Saya tidak 100% yakin.
Dacav
3
"Prasyarat hanya pesanan" adalah independen
fantastis
2
Saya tidak melihat di mana jaminan bahwa 'bersih' bekerja sebelum 'semua'? Fakta bahwa Anda menempatkannya langsung dari | tidak membuat mereka mengeksekusi secara berurutan. Ketergantungan khusus pesanan berarti bahwa target tidak perlu diperbarui setelah operasi tersebut. Ini tidak ada hubungannya dengan urutan elemen dependen ... atau?
CygnusX1
6

Jika Anda menghapus make allgaris dari target "segar" Anda:

fresh :
    rm -f *.o $(EXEC)
    clear

Anda cukup menjalankan perintah make fresh all, yang akan dieksekusi sebagai make fresh; make all.

Beberapa orang mungkin menganggap ini sebagai contoh kedua dari pembuatan, tetapi ini jelas bukan merupakan sub-contoh dari make (sebuah make inside dari make), yang tampaknya hasil dari usaha Anda.

codenaugh
sumber