2009-12-30 13 views
6

Jestem nowicjuszem w Makefiles i g ++, i mam problem z generowaniem zależności plików projektu za pomocą flagi -MM. Zamieszczam plik Makefile, którego używam do rozpatrzenia. Proszę spojrzeć.Problem generujący zależności w Makefile przy użyciu -MM

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] 

Próbowałem kilka opcji i wiele razy. Szukałem go, szukałem rozwiązania, ale nie mogłem go znaleźć.

Czy używa się flagi "-MM" do generowania zależności z odpowiednią opcją? Jeśli nie, zaproponuj mi właściwy sposób generowania zależności. Chciałem wygenerować zależności automatycznie, ponieważ mój projekt będzie miał wiele różnych plików. Myślałem, że jest lepszą opcją niż ręczne zapisywanie zależności.

Są to błędy Dostaję

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. 

Z góry dzięki.

+0

Co to znaczy "DEPS = $ (OBJS:%. O =%. D)"? Dlaczego czasami używasz ": =", a czasami "="? –

+0

Tworzy DEPS z nazwami obiektów w katalogu obiektów. Właśnie testuję z opcjami "=" i ": =", ale nie znam dokładnej różnicy b/w je – Jabez

Odpowiedz

8

Wygląda na to, że próbujesz wygenerować plik zależności (nazwany * .d, według reguł pliku makefile) dla każdego pliku .cpp. To nie jest moje zrozumienie, w jaki sposób używany jest plik zależności.

Użyj opcji -M, aby wygenerować pojedynczy plik zależności dla projektu, a następnie dołącz plik zależności.

DEPS = $(OUR_DIR)/make.dep 

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

include $(DEPS) 

edit Plik zależność powinna również zależeć od nagłówków

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

gdzie HEADER_TARGET jest określone tak samo jak SOURCE_TARGET. W ten sposób, gdy plik nagłówkowy zostanie zmieniony, plik zależności zostanie odbudowany.

+1

Dziękuję mcdave, to bardzo dobra sztuczka Myślę, że Generowanie pojedynczego pliku jest lepsze niż generowanie wielu ... Jeszcze raz dziękuję – Jabez

+1

Chcę tylko zwrócić uwagę, że '-MM' wyklucza nagłówki systemowe (mniej lub bardziej), co prawdopodobnie powoduje, że kompilacja jest szybsza, ponieważ istnieje mniej plików do 1) sprawdzenia 2) procesu budowania listy zależności. przykład stwórz foo.cpp z jakimś stl zawiera i uruchom 'g ++ -M foo.cpp', aby zobaczyć, jak wypluwa listę blisko 100 zależności, z których żadna nigdy się nie zmienia, a wszystkie z nich będą musiały sprawdzić każdą kompilację. –

+0

@Robert: Dzięki za podpowiedź - nie wiedziałem o tym i zaktualizuję pliki Makefile, aby były bardziej wydajne! – mcdave

3

Dla początkujących robisz egzotyczne rzeczy. Powinieneś zacząć prosty i używać tylko kodu w Makefile, który w 100% rozumiesz i którym ufasz. Nawet w dużym projekcie z setkami plików nie będziesz spędzać wiele czasu na utrzymaniu pliku Makefile.

Zmienne przypisane za pomocą: = są natychmiast rozszerzane - wszystkie wartości $ (VAR) są podstawiane do wartości zmiennej podczas przypisywania. Zmienne przypisane za pomocą = są rozszerzane, gdy są używane, więc mogą np. Odwoływać się do zmiennych, które nie są jeszcze zdefiniowane.

Flaga -MM dla g ++ wygeneruje linię zależności pliku Makefile, np. foo.o: foo.cc foo.hh, ale nigdy nie znalazłem tego użytecznego. Miałem fałszywy cel "zależności", który wygenerował pojedynczy plik zależności. Twój pomysł na zrobienie paczki * .d z tymi zależnościami może działać, ale skończysz z dużą ilością tych plików.

Błąd, który otrzymujesz, pochodzi z g ++, a nie z make. Dzieje się tak, ponieważ używasz $ (DEPS) tak, jakby był to pojedynczy plik, gdy jest to cała lista plików * .d. Co się dzieje, jest to linia:

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

zostanie rozszerzony:

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

mcdave właśnie pisał kod użyłem, aby wygenerować plik zależności.Można też przejść do pojedynczego pliku stylu zależność lub zmienić polecenie -MM do tego:

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

Można również naprawić -include oświadczenie, ponieważ nie sądzę, że obsługuje listę plików do zawierać.

+0

Dziękuję Ken, używam teraz pojedynczego pliku zamiast wielu różnych plików. Dziękuję, mówiąc diff b/w "=" i ": =", które z pewnością mi bardzo pomaga. – Jabez

Powiązane problemy