Pertanyaan Apa tujuan dari .PHONY di makefile?


Apa yang terjadi .PHONY berarti dalam Makefile? Saya telah melalui ini, tapi itu terlalu rumit.

Bisakah seseorang menjelaskannya kepada saya dalam istilah sederhana?


1207
2018-01-27 09:08


asal


Jawaban:


Secara default, target Makefile adalah "target file" - mereka digunakan untuk membuat file dari file lain. Buat asumsi targetnya adalah file, dan ini membuat tulisan Makefile relatif mudah:

foo: bar
  create_one_from_the_other foo bar

Namun, terkadang Anda ingin Makefile menjalankan perintah yang tidak mewakili file fisik dalam sistem file. Contoh bagus untuk ini adalah target umum "bersih" dan "semua". Peluangnya bukan ini masalahnya, tetapi Anda mungkin berpotensi memiliki file bernama clean di direktori utama Anda. Dalam kasus seperti itu, Make akan bingung karena secara default clean target akan dikaitkan dengan file ini dan Make hanya akan menjalankannya ketika file tersebut tidak tampak diperbarui berkaitan dengan dependensinya.

Target-target khusus ini disebut palsu dan Anda dapat secara eksplisit memberi tahu bahwa mereka tidak terkait dengan file, misalnya:

.PHONY: clean
clean:
  rm -rf *.o

Sekarang make clean akan berjalan seperti yang diharapkan bahkan jika Anda memiliki file bernama clean.

Dalam hal Make, target palsu hanyalah target yang selalu kedaluwarsa, jadi kapan pun Anda bertanya make <phony_target>, itu akan berjalan, independen dari keadaan sistem file. Sebagian umum make target yang sering palsu adalah: all, install, clean, distclean, TAGS, info, check.


1341
2018-01-27 09:11



Anggap saja sudah install target, yang sangat umum di makefiles. Jika kamu melakukan tidak menggunakan .PHONY, dan sebuah file bernama install ada di direktori yang sama dengan Makefile, lalu make install akan melakukan tidak ada. Ini karena Make menafsirkan aturan untuk mengartikan "jalankan resep semacam itu dan itu untuk membuat file bernama install". Karena file sudah ada, dan dependensinya tidak berubah, tidak ada yang akan dilakukan.

Namun jika Anda membuatnya install target PHONY, itu akan memberi tahu alat make bahwa target adalah fiktif, dan yang membuat seharusnya tidak mengharapkannya untuk membuat file yang sebenarnya. Oleh karena itu tidak akan memeriksa apakah install file ada, artinya: a) perilakunya tidak akan diubah jika file memang ada dan b) ekstra stat() tidak akan dipanggil.

Umumnya semua target di Makefile Anda yang tidak menghasilkan file output dengan nama yang sama dengan nama target harus PHONY. Ini biasanya termasuk all, install, clean, distclean, dan seterusnya.


636
2017-08-26 10:54



CATATAN: Alat make membaca makefile dan memeriksa waktu modifikasi-perangko dari file di kedua sisi simbol ':' dalam aturan.

Contoh

Di direktori 'test' berikut file yang hadir:

prerit@vvdn105:~/test$ ls
hello  hello.c  makefile

Dalam makefile aturan didefinisikan sebagai berikut:

hello:hello.c
    cc hello.c -o hello

Sekarang asumsikan bahwa file 'hello' adalah file teks yang berisi beberapa data, yang dibuat setelah file 'hello.c'. Jadi modifikasi (atau pembuatan) cap waktu 'hello' akan lebih baru daripada 'hello.c'. Jadi ketika kita akan memanggil 'make hello' dari command line, itu akan dicetak sebagai:

make: `hello' is up to date.

Sekarang akses file 'hello.c' dan masukkan beberapa ruang putih di dalamnya, yang tidak mempengaruhi sintaks kode atau logika dan kemudian simpan dan berhenti. Sekarang time-stamp modifikasi hello.c lebih baru daripada 'hello'. Sekarang jika Anda memanggil 'make hello', itu akan menjalankan perintah sebagai:

cc hello.c -o hello

Dan file 'hello' (file teks) akan ditimpa dengan file biner baru 'hello' (hasil perintah kompilasi di atas).

Jika kita menggunakan .PHONY di makefile sebagai berikut:

.PHONY:hello

hello:hello.c
    cc hello.c -o hello

dan kemudian memanggil 'make hello', itu akan mengabaikan jika ada file yang ada di pwd bernama 'hello' dan menjalankan perintah setiap kali.

Sekarang anggaplah jika tidak ada ketergantungan target yang ada di makefile:

hello:
    cc hello.c -o hello

dan file 'hello' sudah ada di pwd 'test', maka 'make hello' akan selalu ditampilkan sebagai:

make: `hello' is up to date.

64
2017-09-30 14:51



.PHONY: install
  • berarti kata "install" tidak mewakili nama file dalam ini Makefile;
  • berarti Makefile tidak ada hubungannya dengan file bernama "instal" di direktori yang sama.

63
2017-08-25 22:39



Ini adalah target build yang bukan nama file.


34
2018-01-27 16:48



Penjelasan terbaik adalah GNU membuat manual itu sendiri: 4,6 bagian Target Phony.

.PHONY adalah salah satu yang membuatnya Nama-nama Target Built-in Khusus. Ada target lain yang mungkin Anda minati, jadi layak untuk membaca referensi ini.

Ketika saatnya untuk mempertimbangkan target .PHONY, make akan menjalankan resepnya   tanpa syarat, terlepas dari apakah file dengan nama itu ada atau    apa waktu modifikasi terakhirnya.

Anda mungkin juga tertarik untuk membuatnya Target Standar seperti all dan clean.


21
2018-04-03 23:49



Ada juga satu suguhan rumit penting ".PHONY" - ketika target fisik bergantung pada target palsu yang bergantung pada target fisik lain:

TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2

Anda cukup berharap bahwa jika Anda memperbarui TARGET2, maka TARGET1 harus dianggap basi terhadap TARGET1, jadi TARGET1 harus dibangun kembali. Dan itu benar-benar bekerja dengan cara ini.

Bagian yang sulit adalah ketika TARGET2 tidak basi terhadap TARGET1 - dalam hal ini Anda harus berharap bahwa TARGET1 tidak boleh dibangun ulang.

Ini mengejutkan tidak berhasil karena: target palsu tetap dijalankan (seperti biasanya target palsu), artinya itu target palsu dianggap diperbarui. Dan karena itu TARGET1 dianggap basi terhadap target palsu.

Mempertimbangkan:

all: fileall

fileall: file2 filefwd
    echo file2 file1 >fileall


file2: file2.src
    echo file2.src >file2

file1: file1.src
    echo file1.src >file1
    echo file1.src >>file1

.PHONY: filefwd
.PHONY: filefwd2

filefwd: filefwd2

filefwd2: file1
    @echo "Produced target file1"


prepare:
    echo "Some text 1" >> file1.src
    echo "Some text 2" >> file2.src

Anda dapat bermain-main dengan ini:

  • pertama lakukan 'siapkan persiapan' untuk menyiapkan "file sumber"
  • bermain-main dengan itu dengan menyentuh file tertentu untuk melihat mereka diperbarui

Anda dapat melihat bahwa semua file tergantung pada file 1 secara tidak langsung melalui target palsu - tetapi itu selalu dibangun kembali karena ketergantungan ini. Jika Anda mengubah ketergantungan dalam fileall dari filefwd untuk file, sekarang fileall tidak dibangun kembali setiap waktu, tetapi hanya ketika ada target yang bergantung yang basi terhadapnya sebagai file.


8
2018-02-11 10:11