2009-12-30 16 views
6

Makefiles ve g ++ konusunda yeniyim ve proje dosyalarının bağımlılığını -MM bayrağı kullanarak oluştururken bir sorunla karşılaşıyorum. Makefile'ı senin için düşündüğüm için gönderiyorum. Lütfen bir bak. Makefile'de -MM ile ilgili bağımlılıklar oluşturma sorunu

OUTPUT_ROOT := output/ 
SOURCE_ROOT := source/ 

TITLE_NAME := TestProj 

SOURCES := \ 
MyFile.cpp \ 
stdAfx.cpp \ 
Main.cpp \ 

OUT_DIR := $(OUTPUT_ROOT) 

OUT_O_DIR := $(OUT_DIR) 

OBJS = $(SOURCES:%.cpp=$(OUT_O_DIR)%.o) 
DEPS = $(OBJS:%.o=%.d) 
DIRS = $(subst /,/,$(sort $(dir $(OBJS)))) 
SOURCE_TARGET = $(SOURCES:%.cpp=$(SOURCE_ROOT)%.cpp) 
OUTPUT_TARGET = $(OUT_DIR)$(TITLE_NAME) 

#--------------------------------------------------------------------- 
# executables 
#--------------------------------------------------------------------- 
MD := mkdir -p 
RM := rm 
CC := g++ 

#--------------------------------------------------------------------- 
# rules 
#--------------------------------------------------------------------- 
.PHONY: clean directories objects title 

all: directories objects title 

directories: 
@$(MD) $(DIRS) 

clean: 
$(RM) -rf $(OUT_DIR) 

$(OBJS): $(SOURCE_TARGET) 
@$(CC) -c $< -o [email protected] 

$(DEPS): $(SOURCE_TARGET) 
@$(CC) -c -MM $< > $(DEPS) 

-include $(DEPS) 

objects:$(OBJS) $(DEPS) 

title: $(OBJS) 
@$(CC) $< -o [email protected] 

Ben çeşitli seçenekler ve sooo defalarca denedik. Çözüme baktım ama bulamadım.

Bağımlılıkları doğru seçenek oluşturmak için "-MM" bayrağını kullanıyor musunuz? Eğer değilse lütfen bağımlılıkları üretmenin doğru yolunu öner. Bağımlılıkları otomatik olarak oluşturmak istedim çünkü projem çok sayıda dosyaya sahip olacak. Elle bağımlılığı elle yazmaktan daha iyi bir seçenek olduğunu düşündüm.

Bu

i peşin

g++: stdAfx.d: No such file or directory 
g++: Main.d: No such file or directory 
make: *** No rule to make target `stdAfx.d', needed by `objects'. Stop. 

Teşekkür alıyorum hatalardır.

+0

"DEPS = $ (OBJS:%. O =%. D)" nedir? Ve neden bazen ': =' ve bazen '=' kullanıyorsunuz? –

+0

Nesne dizinindeki nesnelerin isimleri ile DEPS oluşturuyor. Ben sadece '=' ve ': =' seçenekleri ile test ediyorum, ama tam farkını bilmiyorum b/w onları – Jabez

cevap

8

Her .cpp dosyası için bir bağımlılık dosyası oluşturmaya çalışıyorsunuz (makefile kurallarınız tarafından * .d olarak adlandırılır). Bu bir bağımlılık dosyasının nasıl kullanıldığına dair bir anlayış değil.

Projeniz için tek bir bağımlılık dosyası oluşturmak için -M seçeneğini kullanın ve sonra bağımlılıklar dosyasını ekleyin.

DEPS = $(OUR_DIR)/make.dep 

$(DEPS): $(SOURCE_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

include $(DEPS) 

düzenlemek Kişisel bağımlılık dosyası da başlıklarını

HEADER_TARGET SOURCE_TARGET aynı tanımlanır
$(DEPS): $(SOURCE_TARGET) $(HEADER_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

bağlı olmalıdır. Bu şekilde, bir başlık dosyası değiştirildiğinde, bağımlılık dosyası yeniden oluşturulur.

+1

Teşekkür ederim mcdave, thats çok iyi bir hile.Ben tek bir dosya oluşturma çok üreten daha iyidir ... Tekrar teşekkürler – Jabez

+1

Sadece -MM'nin sistem başlıklarını (daha fazla veya daha az) hariç tutması gerektiğini belirtmek isterim. örnek bazı stl ile foo.cpp oluşturmayı içerir ve 'g ++ -M foo.cpp' dosyasını çalıştırmak için 100 bağımlılığa yakın bir listeyi tükettiğini görürsünüz, bunların hiçbiri değişmez, bunların hepsi her bir yapı üzerinde kontrol etmek zorunda kalır. –

+0

@Robert: Bahşiş için teşekkürler - Ben bunu bilmiyordum ve onları daha verimli hale getirmek için benim makefiles güncellemek! – mcdave

3

Yeni başlayanlar için egzotik bir şeyler yapıyorsunuz. Basit bir şekilde başlamalı ve Makefile'de yalnızca% 100'ü anladığınız ve güvendiğiniz kodu kullanın. Yüzlerce dosya içeren büyük bir projede bile Makefile'yi korumak için fazla zaman harcamazsınız.

Şu şekilde atanan değişkenler: = hemen genişletilir - atama sırasında tüm $ (VAR) değerleri değişken değerine değiştirilir. = Ile atanan değişkenler, kullanıldıkları zaman genişletilir, böylece henüz tanımlanmamış değişkenlere atıfta bulunurlar.

g ++ için -MM bayrağı bir Makefile bağımlılık çizgisi oluşturacaktır, örn. foo.o: foo.cc foo.hh, ama asla bulamadım. Tek bir bağımlılık dosyası oluşturan sahte bir "bağımlılık" hedefi vardı. Bu tek hat bağımlılıkları ile bir sürü * .d dosyası oluşturma fikriniz işe yarayabilir, ancak bu dosyaların çoğuna sahip olursunuz.

Aldığınız hata, g ++ dosyasından değil. Bunun nedeni, * .d dosyalarının tüm listesi olduğunda tek bir dosyaymış gibi $ (DEPS) kullanıyorsunuzdur.

@$(CC) -c -MM $< > $(DEPS) 

genişletilmiş alır:

g++ -c -MM MyFile.cpp > MyFile.d stdAfx.d Main.cpp 

mcdave sadece bir bağımlılık dosyası oluşturmak için kullandık kodu yayınlanmıştır Ne olur bu çizgidir.Ayrıca ben dosyaların bir listesini destekler sanmıyorum çünkü Include ifadeyi düzeltmek gerekebilir

@$(CC) -MM $< > [email protected] 

: Ya tek bağımlılık dosyası biçimine geçme veya bu şekilde -MM komutunu değiştirebilir Dahil etmek.

+0

Teşekkürler Ken, artık çok sayıda dosya yerine tek bir dosya kullanıyorum. Diyelim ki, b/w '=' ve ': =', bu bana çok yardımcı olur. – Jabez

İlgili konular