Nedir
.PHONY Makefile'de mi demek istiyorsun? Ben geçtim buama bu çok karmaşık.
Birisi bana basit terimlerle açıklayabilir mi?
Nedir
.PHONY Makefile'de mi demek istiyorsun? Ben geçtim buama bu çok karmaşık.
Birisi bana basit terimlerle açıklayabilir mi?
Varsayılan olarak, Makefile hedefleri "dosya hedefleri" dir - bunlar başka dosyalardan dosyalar oluşturmak için kullanılır. Hedefin bir dosya olduğunu varsayar ve bu da Makefiles yazısını göreceli olarak kolaylaştırır:
foo: bar create_one_from_the_other foo bar
Ancak, bazen Makefile'nizin dosya sisteminde fiziksel dosyaları temsil etmeyen komutları çalıştırmasını istersiniz. Bunun iyi örnekleri, "temiz" ve "tüm" ortak hedeflerdir. Durum böyle değil, ama sen Mayıs ayı potansiyel olarak adlandırılmış bir dosya var
clean ana dizininizde. Böyle bir durumda Make varsayılan olarak çünkü şaşkın olacaktır
clean hedef bu dosyayla ilişkilendirilir ve Make, yalnızca dosya bağımlılıklarına göre güncel görünmediğinde çalıştırılır.
Bu özel hedefler denir sahte ve açıkça, Dosyaları ile ilişkili olmadıklarını söyleyebilirsiniz.
.PHONY: clean clean: rm -rf *.o
şimdi
make clean adında bir dosya varsa bile beklendiği gibi çalışacak
clean.
Make açısından, sahte bir hedef sadece her zaman güncel olmayan bir hedeftir, bu yüzden ne zaman istersen
make <phony_target>, dosya sisteminin durumundan bağımsız olarak çalışır. Bazı ortak
make genellikle sahte olan hedefler şunlardır:
all,
install,
clean,
distclean,
TAGS,
info,
check.
Var olduğunu varsayalım
install Makefile'de çok yaygın olan hedef. Yaparsan değil kullanım
.PHONYve adında bir dosya
install Makefile ile aynı dizinde bulunur, sonra
make install yapacağım hiçbir şey değil. Bunun nedeni, kuralı, "adlandırılmış dosyayı oluşturmak için bu türden bir reçete yürütmek" anlamına gelir.
install". Dosya zaten orada olduğundan ve bağımlılıkları değişmediğinden hiçbir şey yapılmayacak.
Ancak eğer
install PHONY'yi hedefle, make aracının hedefin kurgusal olduğunu ve yapmanın gerçek dosyayı oluşturmasını beklememesi gerektiğini söyler. Bu yüzden bu olup olmadığını kontrol etmez
install dosya var, yani: a) dosya mevcutsa ve b) eklenmesi durumunda davranışı değiştirilmez
stat() çağrılmayacak.
Genellikle Makefile'deki hedef isimle aynı ada sahip bir çıktı dosyası üretmeyen tüm hedefler PHONY olmalıdır. Bu genellikle şunları içerir:
all,
install,
clean,
distclean, ve bunun gibi.
NOT: Make aracı makefile okur ve bir kuralda ':' sembolünün her iki tarafındaki dosyaların zaman damgalarını kontrol eder.
Bir 'test' dizininde aşağıdaki dosyalar bulunur:
prerit@vvdn105:~/test$ ls hello hello.c makefile
Makefile'de bir kural şöyle tanımlanır:
hello:hello.c cc hello.c -o hello
Şimdi 'merhaba' dosyasının 'merhaba.c' dosyasından sonra oluşturulan bazı verileri içeren bir metin dosyası olduğunu varsayalım. Bu nedenle 'merhaba' ('merhaba') 'in zamanlama (veya yaratma) zaman damgası' merhaba.c'ninkinden daha yeni olacaktır. Bu yüzden komut satırından 'merhaba' yapalım, şöyle yazdırılır:
make: `hello' is up to date.
Şimdi 'hello.c' dosyasına erişin ve içine kod sözdizimini veya mantığını etkilemeyen ve daha sonra kaydedip çıkılan beyaz boşluklar ekleyin. Şimdi, merhaba.c'nin değişiklik zaman damgası, 'merhaba'dan daha yenidir. Şimdi 'merhaba yap' diye çağırırsanız, komutları şu şekilde çalıştırır:
cc hello.c -o hello
Ve 'merhaba' dosyası (metin dosyası) yeni bir ikili dosya 'merhaba' ile (yukarıdaki derleme komutunun sonucu) üzerine yazılacaktır.
Makefile'de .PHONY'yi kullanırsak
.PHONY:hello hello:hello.c cc hello.c -o hello
ve sonra 'merhaba yap', 'merhaba' isimli pwd'de herhangi bir dosya mevcutsa ve her seferinde komutu yürütürse göz ardı eder.
Şimdi makefile'de hiçbir hedef bağımlılığın bulunmadığını varsayalım:
hello: cc hello.c -o hello
ve 'merhaba' dosyası pwd 'testinde zaten mevcut, daha sonra' merhaba yap 'her zaman şöyle görünür:
make: `hello' is up to date.
.PHONY: install
Bir dosya adı olmayan bir yapı hedefidir.
En iyi açıklama GNU kullanım kılavuzunun kendisidir: 4.6 Sahte Hedefler bölümü.
.PHONY make'den biri Özel Yerleşik Hedef İsimleri. İlgilendiğiniz başka hedefler var, bu yüzden bu referansları gözden geçirmeye değer.
Bir .PHONY hedefini göz önünde bulundurmanın zamanı geldiğinde, tarifi kendi tarifini yürütecek Bu ada sahip bir dosya bulunup bulunmadığına bakılmaksızın koşulsuz olarak son değişiklik zamanı.
Ayrıca ilginizi çekebilir Standart hedefler gibi
all ve
clean.
Fiziksel bir hedef başka bir fiziksel hedefe bağlı olan sahte hedefe bağlı olduğunda, ".PHONY" ifadesinin önemli bir zorlu muamelesi de vardır:
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2
TARGET2'yi güncellediyseniz TARGET1'in TARGET1'e göre bayat sayılması gerektiğini, böylece TARGET1'in yeniden oluşturulmasını beklersiniz. Ve gerçekten bu şekilde çalışıyor.
Zor olan bölüm TARGET2 değil TARGET1'e karşı bayat - bu durumda TARGET1'in yeniden oluşturulmasını beklememelisiniz.
Bu şaşırtıcı bir şekilde işe yaramaz çünkü: sahte hedef zaten çalıştı (sahte hedefler normalde yaptığı gibi), bu demektir ki sahte hedef güncellendi. Ve bu yuzden TARGET1, sahte hedefe karşı bayat olarak kabul edilir.
Düşünmek:
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
Bununla oynayabilirsiniz:
Bu fileallun, sahte bir hedef yoluyla dolaylı olarak dosya1'e bağlı olduğunu görebilirsiniz. her zaman Bu bağımlılık nedeniyle yeniden inşa edilir. Bağımlılığı değiştirirseniz
fileall itibaren
filefwd için
fileşimdi
fileall her seferinde yeniden inşa edilmez, ancak sadece bağımlı hedeflerden herhangi biri bir dosya olarak ona karşı batarsa.
Sık sık varsayılan hedefin ateş etmemesini söylemek için kullanırım.
superclean: clean andsomethingelse blah: superclean clean: @echo clean %: @echo catcher $@ .PHONY: superclean
PHONY olmadan
make superclean ateş
clean,
andsomethingelse, ve
catcher superclean; ama PHONY ile,
make superclean ateş etmeyecek
catcher superclean.
Anlatmak için endişelenmenize gerek yok
clean Hedef PHONY, çünkü tamamen sahte değil. Temiz dosyayı asla üretmese de, ateş etme emirleri vardır, bu yüzden nihai bir hedef olduğunu düşünün.
Ancak
superclean Hedef gerçekten sahte, bu yüzden yapmak için depsler sağlayan başka bir şey ile onu yığmaya çalışacağız
superclean hedef - bu diğer içerir
superclean hedefler ve
% hedef.
Hiç bir şey söylemediğimizi unutmayın.
andsomethingelse veya
blahBöylece açıkça yakalayıcıya giderler.
Çıktı şuna benzer:
$ make clean clean $ make superclean clean catcher andsomethingelse $ make blah clean catcher andsomethingelse catcher blah