2010-06-21 12 views
9

Powiedzmy mam pliki:Jak zdefiniować reguły w Makefile skompilować tylko, że pliki * .cpp, który został zmodyfikowany (i ich zależności), nie wszystkie pliki * .cpp

Libs:

  • one.cpp, one.h
  • two.cpp, two.h
  • three.cpp, three.h

Program:

  • program.cpp

Czy istnieje sposób, aby stworzyć Makefile, który będzie kompilować tylko że * .cpp, które zostały zmodyfikowane od ostatniego zestawienia?

Obecnie mam coś takiego:

SRCS = one.cpp two.cpp three.cpp 
OBJS = $(SRCS:.cpp=.o) 

all: $(OBJS) program 

.cpp.o: 
    g++ -Wall -c $< 

program: 
    g++ -Wall $(OBJS) program.cpp -o program 

clean: 
    rm -f $(OBJS) program 

I działa dobrze, ale kiedy mogę skompilować mój program, a następnie zmienić two.cpp lub two.h trzeba uruchomić "make clean" po pierwsze, dlatego, gdy i po drugie uruchomić „make” pojawia się:

Nothing to be done for 'all'. 

chciałbym zmienić mój Makefile w ten sposób, by to rozpoznać moje zmiany i skompilować ten plik i jego zależności (jeśli one.cpp wykorzystuje kod z two.cpp który został zmodyfikowany, oba pliki powinny zostać ponownie skompilowane).

Więc jeśli zmodyfikować two.cpp, zrobić należy zrobić:

g++ -Wall -c two.cpp 
g++ -Wall $(OBJS) program.cpp -o program 

Ale jeśli one.cpp wykorzystuje kod z two.cpp który został zmodyfikowany, należy shold zrobić:

g++ -Wall -c one.cpp 
g++ -Wall -c two.cpp 
g++ -Wall $(OBJS) program.cpp -o program 
+0

(Myślę, że masz na myśli 'one.cpp', a nie' first.cpp'.) – Beta

+0

Tak, powinno to być jedno.cpp. – user360872

Odpowiedz

12

Najpierw wykonujemy plików obiektowych Wymagania wstępne z plik wykonywalny. Gdy to nastąpi, Pozwól odbuduje program gdy jedna ze zmian SRC, więc nie musimy OBJS jako wyraźnej docelowa:

all: program 

program: $(OBJS) 
    g++ -Wall $(OBJS) program.cpp -o program 

Następnie udostępnić pliki nagłówkowe przesłanki obiektów, tak, że jeśli zmienić three.h, Pozwól odbuduje three.o:

$(OBJS): %.o : %.h 

I wreszcie od one.cpp wykorzystuje kod z two.cpp za pomocą two.h (mam nadzieję), wykonujemy two.ha warunek jednego .O:

one.o: two.h 

I żeby zrobić rzeczy czystsze i łatwiej utrzymać używamy zmienne automatyczne:

program: $(OBJS) 
    g++ -Wall $^ program.cpp -o [email protected] 

umieścić to wszystko razem i otrzymujemy:

SRCS = one.cpp two.cpp three.cpp 
OBJS = $(SRCS:.cpp=.o) 

all: program 

$(OBJS): %.o : %.h 

one.o: two.h 

.cpp.o: 
    g++ -Wall -c $< 

program: $(OBJS) 
    g++ -Wall $^ program.cpp -o [email protected] 

clean: 
    rm -f $(OBJS) program 

Istnieje jeszcze kilka rzeczy, które mogliśmy zrobić (np. dodanie programu do wersji OBJS), ale to wystarczy na dziś.

1

Dodaj pliki, od których zależy polecenie, są uruchamiane po prawej stronie nazwy celu.

Przykład:

default: hello.c 
    gcc -o hello.bin hello.c 

install: hello.bin 
    cp hello.bin ../ 
+0

Czy nie do tego służy '$ (OBJS)'? – JAB

+0

Powiedz mi, to twój kod. Nigdy nie użyłem zmiennych w polach zależności, ale nie ma logicznie nic, co uniemożliwiłoby działanie. – mcandre

+0

Ale to nie jest mój kod. – JAB

0

Wszystko, co musisz zrobić, to powiedzieć make że plik .o zależy pliku .cpp:

%.cpp.o: %.cpp 
    g++ -Wall -c -o [email protected] $< 
+0

To nie rozwiąże problemów zależności w plikach nagłówkowych lub obiektowych. – Beta

Powiązane problemy