2012-12-27 19 views
6

Makefile s için yeniden kullanılabilir kod yazmanın en iyi yolu nedir? Ben görevler (task03) yeni ailesini eklemek istediğiniz ŞimdiYeniden kullanılabilir kod yazmak için en iyi yöntem

.PHONY: all task01-all task01-clean task01-run task02-all task02-clean task02-run 

all: task01-all task02-all 

############################################################################### 
task01-all: task01-clean task01 task01-run 

task01-clean: 
    rm task01 task01.{exi,o} -f 

task01: 
    compiler task01.ext -O2 --make 

task01-run: 
    ./task01 

############################################################################### 
task02-all: task02-clean task02 task02-run 

task02-clean: 
    rm task02 task02.{exi,o} -f 

task02: 
    compiler task02.ext -O2 --make 

task02-run: 
    ./task02 

ve ben, tüm bölümü CopyPaste bunun için s/02/03/ yapıp .PHONY bölümüne ekleyin gerekir - bu: Varsayalım

Ben bir Makefile var gürültülü, iğrenç ve doğru değil.

Bundan nasıl kurtulabilirim? Tek bir satıra yeni görev grubu eklemek için güzel bir mekanizmaya sahip olmak için şablonlarla tüm görevleri yeniden tanımlayabilir miyim?

cevap

9

, nasıl göründüğünü (Make GNU içinde kalıp kurallarını nasıl kullanılacağına dair bir örnek vereyim .PHONY hedefinden bahsetmişken kullandığınız gibi. Yaptığınız en Bağımlılık denetimi herhangi kullanmıyorsanız Ancak, bir kabuk ile bunu daha basit olabilecek - gibi bir şey:

#!/bin/sh 
TASKS="task01 task02 task03" 

for i in $TASKS; do 
    rm $i $i.ext $i.o -f; 
    compiler $i.ext -O2 --make; 
    ./$i; 
done 

Ama Yapmak ilkesini genişletmek için, başka bir sorun var mücadele etmek. Formun Hatları:

task01-all: task01-clean task01 task01-run 

ön koşulları oluşturmak ne sırayla yapın söyleme - hepsi task01-all inşa girmeden önce yapılması gereken sadece bu. Bunun yerine, çalıştırılacak her adım ondan önceki adımlara bağlı olmalıdır. Böyle bir şey: % ile

TASKS=task01-run task02-run task03-run 

.PHONY: all $(TASKS) $(TASKS:run=clean) 

all: $(TASKS) 

$(TASKS:run=clean): %-clean: 
    rm $* $*.ext $*.o -f 

%: %.ext | %-clean 
    compiler $< -O2 --make 

$(TASKS): %-run: % 
    ./$< 

kurallar "desen kuralları" denilen ve farklı hedefler için yeniden yazma aynı kural birden çok kez önlemek için harika bir araç olduğunu edilir. Bir uyarı, Make'in normalde .PHONY hedefine ilişkin kurallarını kontrol etmemesidir; Bunu, bu kuralların hedefler listesi ve ikinci bir kolon (örneğin, $(TASKS):) ile önekleyerek bunu açıkça yapmasını söyleriz.

task01-run numaralı telefondan task01 numaralı telefon hattına ihtiyaç duyduğumuzdan, hedeflerini % numaralı telefondan edinebilirsiniz. Ayrıca, Makefile'niz her seferinde temiz çalıştırmak istediğinizi gösterir, bu yüzden %'u %-clean'a bağımlı hale getiririz. %-clean aslında herhangi bir çıktı üretmediğinden, bunu "yalnızca sipariş" bağımlılığı yapıyoruz - Make bir zaman damgası veya herhangi bir şey aramayacak, sadece kuralını ilk kez çalıştırdıktan sonra % kural. "Sipariş sadece" bağımlılıkları sonra yerleştirilir bir |:

%: %.ext | %-clean 

bunu yapmak en önemli güçlerinden biri o tekrarlanması gerekmez işi tekrarlayarak kalmayarak zamandan tasarruf olmasıdır belirtmekte yarar var - yani onu Bağımlılıklar hedeften daha yeni ise, yalnızca bir kural çalıştırır.Daha sonra bir kural ekleyebilir

%: %.ext 
    compiler $< -O2 --make 

sadece %-clean hedeflerin tümünü çalıştırmak için: Yani, sadece yeni % daha compiler $< -O2 --make %.ext eğer çalıştırmak yapmak neden olur %-clean olan bağımlılığı, kapalı bırakabilir

.PHONY: all $(TASKS) $(TASKS:run=clean) clean 

clean: $(TASKS:run=clean) 

Son şey: Tariflerde bazı özel değişkenler kullanıyorum. [email protected], oluşturulmakta olan hedefi gösterir. $< ilk bağımlılık anlamına gelir. $*, bir desen kuralının "gövdesini" (yani, % ile eşleşen parça) kısaltmasıdır.

+0

Güzel açıklamalar. Teşekkürler! –

+0

"|" için bir örnek sağlama iyiydi teşekkürler. –

2

neyi aradığım gibi görünüyor: Makefile içinde yeniden kullanılabilir kod yazmadan hakkındadır soruya yana

ALLS=task01-all task02-all 
BUILDS=${ALLS:-all=-build} 
CLEANS=${ALLS:-all=-clean} 
RUNS=${ALLS:-all=-run} 

.PHONY: all $(ALLS) $(CLEANS) $(BUILDS) $(RUNS) 

all: $(ALLS) 

############################################################################### 
$(ALLS): $(CLEANS) $(BUILDS) $(RUNS) 

$(CLEANS): 
     rm ${@:-clean=} ${@:-clean=}.{ext,o} -f 

$(BUILDS): 
     compiler ${@:-build=}.ext -O2 --make 

$(RUNS): 
     ./${@:-run=} 
İlgili konular