Saya memiliki makefile yang dibangun dan kemudian memanggil makefile lain. Karena makefile ini memanggil lebih banyak makefile yang berfungsi, itu tidak benar-benar berubah. Karena itu ia terus berpikir proyek ini dibangun dan terbaru.
dnetdev11 ~ # make
make: `release' is up to date.
Bagaimana saya memaksa makefile untuk membangun kembali target?
clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean
build = svn up ~/xxx \
$(clean) \
~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace \
$(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1) \
release:
$(build )
debug:
$(build DEBUG=1)
clean:
$(clean)
install:
cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib
Catatan: Nama dihapus untuk melindungi yang tidak bersalah
Edit: Versi Final Tetap:
clean = $(MAKE) -f xxx_compile.workspace.mak clean;
build = svn up; \
$(clean) \
./cbp2mak/cbp2mak -C . xxx_compile.workspace; \
$(MAKE) -f xxx_compile.workspace.mak $(1); \
.PHONY: release debug clean install
release:
$(call build,)
debug:
$(call build,DEBUG=1)
clean:
$(clean)
install:
cp ./source/xxx_utillity/release/xxx_util /usr/bin
cp ./dlls/Release/xxxcore.so /usr/lib
.PHONY
itu bukan satu-satunya masalah Anda, dan Anda tidak seharusnya mengedit solusi menjadi pertanyaan, atau setidaknya tidak lagi.)Jawaban:
Anda dapat mendeklarasikan satu atau lebih dari target Anda sebagai palsu .
sumber
:
, bukan hanya hasil akhir yang ingin Anda buat (mis. File biner Anda). Dalam pertanyaan,release
,debug
,clean
, daninstall
adalah target Membuat, tidakxxx_util
atauxxxcore.so
atau apa pun.The
-B
beralih ke make, yang bentuknya panjang--always-make
, mengatakanmake
untuk cap waktu mengabaikan dan membuat target yang ditentukan. Ini mungkin mengalahkan tujuan penggunaan make, tetapi mungkin itu yang Anda butuhkan.sumber
Salah satu trik yang digunakan untuk didokumentasikan dalam manual Sun
make
adalah dengan menggunakan target '.FORCE' (tidak ada). Anda bisa melakukan ini dengan membuat file, force.mk, yang berisi:Kemudian, dengan anggapan makefile Anda yang ada dipanggil
makefile
, Anda bisa menjalankan:Sejak
.FORCE
tidak ada, apa pun yang bergantung padanya akan ketinggalan zaman dan dibangun kembali.Semua ini akan berfungsi dengan versi apa pun dari
make
; di Linux, Anda memiliki GNU Make dan karenanya dapat menggunakan target .PHONY seperti yang dibahas.Ini juga layak mempertimbangkan mengapa
make
menganggap rilis terbaru. Ini bisa jadi karena Anda memilikitouch release
perintah di antara perintah yang dijalankan; itu bisa jadi karena ada file atau direktori yang disebut 'rilis' yang ada dan tidak memiliki dependensi dan juga up to date. Lalu ada alasan sebenarnya ...sumber
Orang lain menyarankan .PHONY yang pasti benar. .PHONY harus digunakan untuk aturan apa pun yang perbandingan tanggal antara input dan output tidak valid. Karena Anda tidak memiliki target formulir,
output: input
Anda harus menggunakan .PHONY untuk SEMUA dari mereka!Semua yang dikatakan, Anda mungkin harus mendefinisikan beberapa variabel di bagian atas makefile Anda untuk berbagai nama file, dan mendefinisikan aturan make nyata yang memiliki bagian input dan output sehingga Anda dapat menggunakan manfaat make, yaitu bahwa Anda hanya akan benar-benar mengkompilasi hal-hal yang perlu untuk copmile!
Edit: contoh ditambahkan. Belum diuji, tetapi ini adalah bagaimana Anda melakukannya. PHONY
sumber
.PHONY
target tidak masalah. Itu bisa di mana saja diMakefile
.Jika saya ingat dengan benar, 'make' menggunakan cap waktu (waktu modifikasi file) untuk menentukan apakah target sudah terkini atau tidak. Cara umum untuk memaksa membangun kembali adalah dengan memperbarui stempel waktu itu, menggunakan perintah 'sentuh'. Anda bisa mencoba memanggil 'sentuhan' di makefile Anda untuk memperbarui stempel waktu salah satu target (mungkin salah satu dari sub-makefile), yang mungkin memaksa Make untuk menjalankan perintah itu.
sumber
Teknik sederhana ini akan memungkinkan makefile berfungsi secara normal ketika pemaksaan tidak diinginkan. Buat target baru bernama force di akhir makefile Anda . The kekuatan target akan menyentuh file target default Anda tergantung pada. Pada contoh di bawah ini, saya telah menambahkan touch myprogram.cpp . Saya juga menambahkan panggilan rekursif untuk dilakukan . Ini akan menyebabkan target default dibuat setiap kali Anda mengetik memaksa .
sumber
make
di dalam Makefile. Gunakan$(MAKE)
sebagai gantinya.Saya mencoba ini dan itu berhasil untuk saya
tambahkan baris ini ke Makefile
simpan dan sekarang panggil
dan itu akan mengkompilasi ulang semuanya lagi
Apa yang terjadi?
1) panggilan 'baru' bersih. 'clean' do 'rm' yang menghapus semua file objek yang memiliki ekstensi '.o'.
2) 'panggilan baru' lakukan '. 'buat' lihat bahwa tidak ada file '.o', jadi itu membuat semua '.o' lagi. kemudian linker menautkan semua file .o ke satu output yang dapat dieksekusi
Semoga berhasil
sumber
new
penggunaan yang lebih baik$(MAKE)
daripadamake
Sebagai Per Rekursif Miller Membuat Dianggap Berbahaya Anda harus menghindari menelepon
$(MAKE)
! Jika Anda tunjukkan, itu tidak berbahaya, karena ini sebenarnya bukan makefile, hanya sebuah skrip pembungkus, yang mungkin juga telah ditulis di Shell. Tetapi Anda mengatakan bahwa Anda terus seperti itu pada tingkat rekursi yang lebih dalam, jadi Anda mungkin menemui masalah yang ditunjukkan dalam esai yang membuka mata itu.Tentu saja dengan GNU membuatnya sulit untuk dihindari. Dan meskipun mereka menyadari masalah ini, itu adalah cara terdokumentasi mereka dalam melakukan sesuatu.
OTOH, makepp diciptakan sebagai solusi untuk masalah ini. Anda dapat menulis file makefile Anda pada tingkat per direktori, namun semuanya ditarik bersama ke dalam tampilan penuh proyek Anda.
Tetapi warisan makefile ditulis secara rekursif. Jadi ada solusi di mana
$(MAKE)
tidak melakukan apa pun kecuali menyalurkan subrequest kembali ke proses makepp utama. Hanya jika Anda melakukan hal-hal yang mubazir atau, lebih buruk lagi, yang bertentangan di antara submake Anda, Anda harus meminta--traditional-recursive-make
(yang tentu saja merusak keunggulan makepp ini). Saya tidak tahu makefile Anda yang lain, tetapi jika itu ditulis dengan rapi, dengan makepp, pembangunan kembali yang diperlukan harus terjadi secara otomatis, tanpa perlu adanya peretasan yang disarankan di sini oleh orang lain.sumber
:
), ia akan selalu dibangun kembali jika diperlukan.Jika Anda tidak perlu mempertahankan output apa pun yang sudah berhasil dikompilasi
membangun kembali semua
sumber
Ini sebenarnya tergantung pada apa targetnya. Jika itu adalah target palsu (yaitu target TIDAK terkait dengan file), Anda harus mendeklarasikannya sebagai .PHONY.
Namun jika targetnya bukan target palsu tetapi Anda hanya ingin membangunnya kembali untuk beberapa alasan (contohnya adalah ketika Anda menggunakan makro preprocessing __TIME__), Anda harus menggunakan skema FORCE yang dijelaskan dalam jawaban di sini.
sumber
http://www.gnu.org/software/make/manual/html_node/Force-Target.html#Force-Target
sumber
Itu sudah disebutkan, tetapi saya pikir saya bisa menambahkan untuk menggunakan
touch
Jika Anda
touch
semua file sumber yang akan dikompilasi,touch
perintah mengubah cap waktu file ke waktu sistemtouch
perintah dieksekusi.Timstamp file sumber adalah apa yang
make
digunakan untuk "tahu" file telah berubah, dan perlu dikompilasi ulangMisalnya: Jika proyek itu adalah proyek c ++, maka lakukan
touch *.cpp
, lalu jalankanmake
lagi, dan buat harus mengkompilasi ulang seluruh proyek.sumber
Seperti yang ditunjukkan oleh abernier, ada solusi yang disarankan dalam manual make GNU, yang menggunakan target 'palsu' untuk memaksa membangun kembali target:
Ini akan berjalan bersih, terlepas dari dependensi lainnya.
Saya menambahkan titik koma ke solusi dari manual, jika tidak, baris kosong diperlukan.
sumber
Pada sistem Linux saya (Centos 6.2), ada perbedaan yang signifikan antara mendeklarasikan target .PHONY dan membuat ketergantungan palsu pada FORCE, ketika aturan sebenarnya membuat file yang cocok dengan target. Ketika file harus dibuat ulang setiap kali, diperlukan FORCE dependensi palsu pada file, dan .PHONY untuk dependensi palsu.
salah:
Baik:
sumber
make clean
menghapus semua file objek yang sudah dikompilasi.sumber