Bu Unix için olduğundan, yürütülebilir dosyaların herhangi bir uzantısı yoktur.
Dikkat edilmesi gereken bir şey root-config
, doğru derleme ve bağlantı bayraklarını sağlayan bir yardımcı programdır; ve root'a karşı uygulamalar oluşturmak için doğru kütüphaneler. Bu, yalnızca bu dokümanın orijinal kitlesi ile ilgili bir ayrıntı.
Beni bebeğim yap
ya da İlk Yaptığın Asla Unutmazsın
Make ve basit bir makefile yazma hakkında giriş
Marka Nedir? Neden Önemsemeliyim?
Make adlı araç derleme bağımlılığı yöneticisidir. Yani, yazılım projenizi kaynak dosyalar, nesne dosyaları, kütüphaneler, başlıklar vb. Bir koleksiyondan hangi sırayla almak için hangi komutların yürütülmesi gerektiğini bilmekle ilgilenir. - bazıları değişmiş olabilir Son zamanlarda --- ve programın doğru bir güncel sürümüne dönüştürmek.
Aslında, Make'ı başka şeyler için de kullanabilirsiniz, ama bunun hakkında konuşmayacağım.
Önemsiz Makefile
: Eğer içeren bir dizin olduğunu varsayalım tool
tool.cc
tool.o
support.cc
support.hh
ve support.o
hangi bağlıdır root
ve adı verilen bir programa derlenmiş gerekiyordu tool
ve siz (mevcut demektir kaynak dosyaları üzerinde hack ettik varsayalım tool
artık güncel olan) ve istediğiniz programı derleyin.
Bunu kendiniz yapmak için
Bunlardan birini support.cc
veya support.hh
daha yeni olup olmadığını kontrol edin support.o
ve eğer böyle bir komut çalıştırın
g++ -g -c -pthread -I/sw/include/root support.cc
Bunlardan birini support.hh
veya tool.cc
daha yeni olup olmadığını kontrol edin tool.o
ve eğer böyle bir komut çalıştırın
g++ -g -c -pthread -I/sw/include/root tool.cc
Bundan tool.o
daha yeni olup olmadığını kontrol edin tool
ve eğer böyle bir komut çalıştırın
g++ -g tool.o support.o -L/sw/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint \
-lPostscript -lMatrix -lPhysics -lMathCore -lThread -lz -L/sw/lib -lfreetype -lz -Wl,-framework,CoreServices \
-Wl,-framework,ApplicationServices -pthread -Wl,-rpath,/sw/lib/root -lm -ldl
Uf! Ne kadar zor! Hatırlanması gereken çok şey var ve hata yapma şansı var. (BTW-- burada gösterilen komut satırlarının ayrıntıları yazılım ortamımıza bağlıdır. Bunlar bilgisayarımda çalışır.)
Elbette, her seferinde üç komutu da çalıştırabilirsiniz. Bu işe yarar, ancak önemli bir yazılım parçasına iyi ölçeklenmez (MacBook'umda sıfırdan derlemek 15 dakikadan fazla süren DOGS gibi).
Bunun yerine şöyle bir dosya yazabilirsiniz makefile
:
tool: tool.o support.o
g++ -g -o tool tool.o support.o -L/sw/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint \
-lPostscript -lMatrix -lPhysics -lMathCore -lThread -lz -L/sw/lib -lfreetype -lz -Wl,-framework,CoreServices \
-Wl,-framework,ApplicationServices -pthread -Wl,-rpath,/sw/lib/root -lm -ldl
tool.o: tool.cc support.hh
g++ -g -c -pthread -I/sw/include/root tool.cc
support.o: support.hh support.cc
g++ -g -c -pthread -I/sw/include/root support.cc
ve make
komut satırına yazmanız yeterlidir. Hangi yukarıda gösterilen üç adım otomatik olarak gerçekleştirecektir.
Buradaki girintisiz satırlar "target: bağımlılıklar" biçimine sahiptir ve bağımlılıklardan herhangi biri hedeften daha yeniyse ilişkili komutların (girintili satırlar) çalıştırılmasını sağlayın . Yani bağımlılık satırları, çeşitli dosyalarda değişikliklere uyum sağlamak için nelerin yeniden oluşturulması gerektiğinin mantığını tanımlar. support.cc
Değişiklik varsa bu support.o
yeniden inşa edilmelidir, ancak tool.o
yalnız bırakılabilir. Ne zaman support.o
değişiklikler tool
yeniden inşa edilmelidir.
Her bağımlılık satırıyla ilişkili komutlar bir sekme ile ayarlanır (aşağıya bakın) hedefi değiştirmelidir (veya en azından değişiklik süresini güncellemek için ona dokunmalıdır).
Değişkenler, Yerleşik Kurallar ve Diğer Hediyeler
Bu noktada, makefile'ımız basitçe yapılması gereken işi hatırlamaktır, ancak yine de ihtiyaç duyulan her bir komutu tümüyle bulmamız ve yazmamız gerekiyordu. Bu şekilde olmak zorunda değil: Make, değişkenler, metin düzenleme işlevleri ve bunu bizim için çok daha kolaylaştırabilecek bir dizi yerleşik kural içeren güçlü bir dildir.
Değişken Yap
Bir make değişkenine erişim sözdizimi $(VAR)
.
Bir Make değişkenine atama sözdizimi: VAR = A text value of some kind
(veya VAR := A different text value but ignore this for the moment
).
Değişkenlerimizi, makefile'ımızın bu geliştirilmiş sürümü gibi kullanabilirsiniz:
CPPFLAGS=-g -pthread -I/sw/include/root
LDFLAGS=-g
LDLIBS=-L/sw/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint \
-lPostscript -lMatrix -lPhysics -lMathCore -lThread -lz -L/sw/lib -lfreetype -lz \
-Wl,-framework,CoreServices -Wl,-framework,ApplicationServices -pthread -Wl,-rpath,/sw/lib/root \
-lm -ldl
tool: tool.o support.o
g++ $(LDFLAGS) -o tool tool.o support.o $(LDLIBS)
tool.o: tool.cc support.hh
g++ $(CPPFLAGS) -c tool.cc
support.o: support.hh support.cc
g++ $(CPPFLAGS) -c support.cc
Bu biraz daha okunabilir, ancak yine de çok fazla yazmayı gerektirir
İşlev Yap
GNU make, dosya sisteminden veya sistemdeki diğer komutlardan bilgiye erişmek için çeşitli işlevleri destekler. Bu durumda biz ilgilenen edilir $(shell ...)
argüman (lar) ın çıkışına genişler ki, ve $(subst opat,npat,text)
tüm örneklerini değiştirir hangi opat
ile npat
metinde.
Bundan faydalanmak bize:
CPPFLAGS=-g $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)
SRCS=tool.cc support.cc
OBJS=$(subst .cc,.o,$(SRCS))
tool: $(OBJS)
g++ $(LDFLAGS) -o tool $(OBJS) $(LDLIBS)
tool.o: tool.cc support.hh
g++ $(CPPFLAGS) -c tool.cc
support.o: support.hh support.cc
g++ $(CPPFLAGS) -c support.cc
yazması daha kolay ve daha okunabilir.
Dikkat edin
- Her nesne dosyası ve son yürütülebilir dosya için bağımlılıkları açıkça belirtiyoruz
- Her iki kaynak dosya için de derleme kuralını açıkça yazmak zorunda kaldık
Örtük ve Örüntü Kuralları
Genellikle tüm C ++ kaynak dosyalarının aynı şekilde ele alınmasını bekleriz ve Make bunu belirtmek için üç yol sağlar:
- sonek kuralları (GNU markasında kullanılmayan kabul edilir, ancak geriye dönük uyumluluk için saklanır)
- örtük kurallar
- kalıp kuralları
Örtük kurallar yerleşiktir ve bunlardan birkaçı aşağıda ele alınacaktır. Desen kuralları aşağıdaki gibi belirtilir
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
yani, "otomatik" değişken $<
ilk bağımlılığın adına genişlediğinde , komut dosyaları gösterilen komut çalıştırılarak C kaynak dosyalarından oluşturulur .
Yerleşik Kurallar
Make, bir projenin çok basit bir makefile tarafından derlenebileceği anlamına gelen bir dizi yerleşik kurala sahiptir.
C kaynak dosyaları için yerleşik GNU markası, yukarıda gösterilen dosyadır. Benzer şekilde, C ++ kaynak dosyalarından bir kurala sahip nesne dosyaları oluştururuz $(CXX) -c $(CPPFLAGS) $(CFLAGS)
.
Tek nesne dosyaları kullanılarak bağlanır $(LD) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
, ancak bizim durumumuzda çalışmaz, çünkü birden fazla nesne dosyasını bağlamak istiyoruz.
Yerleşik Kurallar Tarafından Kullanılan Değişkenler
Yerleşik kurallar, tüm kuralları yeniden yazmadan yerel ortam bilgilerini (ROOT dosyalarının nerede bulunacağı gibi) belirtmenize izin veren bir dizi standart değişken kullanır. Bizim için ilginç olma olasılığı en yüksek olanlar:
CC
- kullanılacak C derleyicisi
CXX
- kullanılacak C ++ derleyicisi
LD
- kullanılacak bağlayıcı
CFLAGS
- C kaynak dosyaları için derleme bayrağı
CXXFLAGS
- C ++ kaynak dosyaları için derleme bayrakları
CPPFLAGS
- C ve C ++ tarafından kullanılan c-önişlemcisinin bayrakları (genellikle komut satırında tanımlanan dosya yollarını ve sembolleri içerir)
LDFLAGS
- bağlayıcı bayrakları
LDLIBS
- bağlanacak kütüphaneler
Temel Makefile
Yerleşik kurallardan yararlanarak, makefile'ımızı aşağıdakileri basitleştirebiliriz:
CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)
SRCS=tool.cc support.cc
OBJS=$(subst .cc,.o,$(SRCS))
all: tool
tool: $(OBJS)
$(CXX) $(LDFLAGS) -o tool $(OBJS) $(LDLIBS)
tool.o: tool.cc support.hh
support.o: support.hh support.cc
clean:
$(RM) $(OBJS)
distclean: clean
$(RM) tool
Ayrıca, özel eylemleri gerçekleştiren birkaç standart hedef ekledik (kaynak dizini temizlemek gibi).
Make argümanı olmadan çağrıldığında, dosyada bulunan ilk hedefi (bu durumda tümü) kullandığını, ancak make clean
bu durumda nesne dosyalarını kaldırmayı sağlayan hedefi de adlandırabileceğinizi unutmayın .
Hala bağımlılıkları kodlanmış.
Bazı Gizemli Gelişmeler
CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)
SRCS=tool.cc support.cc
OBJS=$(subst .cc,.o,$(SRCS))
all: tool
tool: $(OBJS)
$(CXX) $(LDFLAGS) -o tool $(OBJS) $(LDLIBS)
depend: .depend
.depend: $(SRCS)
$(RM) ./.depend
$(CXX) $(CPPFLAGS) -MM $^>>./.depend;
clean:
$(RM) $(OBJS)
distclean: clean
$(RM) *~ .depend
include .depend
Dikkat edin
- Artık kaynak dosyalar için bağımlılık satırları yok!?!
- .Depend ve depends ile ilgili garip bir sihir var
- Bunu yaparsanız
make
o zaman ls -A
size adlı bir dosya göreceksiniz .depend
yapmak bağımlılık hatları gibi bakmak şeyleri içerir
Diğer Okumalar
Hataları ve Tarihsel Notları Tanıyın
Make için giriş dili boşluklara duyarlıdır. Özellikle, bağımlılıkları izleyen eylem çizgileri bir sekme ile başlamalıdır . Ancak bir dizi boşluk aynı görünebilir (ve sekmeleri sessizce boşluklara dönüştürecek veya tam tersi olan editörler vardır), bu da doğru görünen ve hala çalışmayan bir Make dosyasıyla sonuçlanır. Bu, erken bir hata olarak tanımlandı, ancak ( hikaye gidiyor ) düzeltilmedi, çünkü zaten 10 kullanıcı vardı.
(Bu, fizik lisansüstü öğrencileri için yazdığım bir wiki yayınından kopyalandı.)