2009-08-28 4 views
12

mamy trochę kodu C++, który musimy stworzyć plik make. Każda para .h i .C utworzyć obiekt, a następnie niektóre obiekty są połączone razem, tworząc plik wykonywalny. Całkiem standardowe rzeczy.gmake kompilować wszystkie pliki w katalogu

Ten non-gnu komenda make właśnie buduje wszystkie pliki do obiektu w katalogu

%.o:%.C 
    $(CC) $(CPFLAGS) -c $< 

Co to robi to dla każdego pliku% .c (czyli każdy plik .c) zbudować odpowiedni plik .o .

Czy ktoś wie, jak to zrobić z gmake?

Cheers

Mark

Odpowiedz

19

Przedstawiona składnia nazywana jest regułą wzoru w GNU make parlance i stanowi kamień węgielny rozwiązania. Wszystko, czego potrzebujesz, to dodać sposób, aby dynamicznie uzyskać listę plików .C. Inni pokazali rozwiązania, które wykorzystują do tego celu $(shell), ale to niepotrzebnie nieefektywne. Proponuję zamiast użyć $ (wildcard), który jest GNU make wbudowaną funkcję zaprojektowane tylko dla tego celu:

SRCS = $(wildcard *.C) 
OBJS = $(patsubst %.C,%.o,$(SRCS)) 
foo: $(OBJS) 
     $(CC) -o [email protected] $^ 

%.o: %.C 
     $(CC) $(CPFLAGS) -c $< 

Jeśli szukasz czegoś bardziej zwięzły, co następuje będzie działać zbyt:

foo: $(patsubst %.C,%.o,$(wildcard *.C)) 

Po prostu eliminuje zmienne i wykorzystuje fakt, że GNU make udostępnia domyślną regułę wzoru %.o: %.C, a także domyślną regułę łączenia pliku wykonywalnego ze zbioru obiektów. Osobiście użyłbym bardziej szczegółowej wersji, ponieważ uważam ją za łatwiejszą do przeczytania i utrzymania, ale do każdej z nich.

nadzieję, że pomoże,

Eric Melski

1

Jest przykładem pattern rule, to powinno działać dobrze w gmake. W przypadku bardzo prostych wersji tego typu możesz polegać głównie na implicit rules. Główną rzeczą, którą trzeba określić w celu chcesz zbudować i jego zależności:

CXXFLAGS:=-g -O -Iincludes 
LDFLAGS:=-lm 

SRCS:=$(shell ls *.C)   # select all .C files as source 
OBJS:=$(substr .C,.o,$(SRCS) # list the corresponding object files 

foo : $(OBJS) 

Uwaga wykorzystanie simply expanded variable operatora przypisania (:=) zamiast rekurencyjnego operatora przypisania (=), które mogą zmniejszyć ilość ponowne przetwarzanie czyni bardziej skomplikowane kompilacje.

+0

Mylisz; OP pokazuje standardową regułę wzorca, a nie regułę statycznego wzorca, i nie ma żadnego powodu, aby używać $ (powłoka) w tym miejscu, w którym $ (wieloznaczny) będzie działał bez dodatkowego obciążenia. –

+0

@Eric: Oczywiście, jeśli chodzi o regułę statycznego wzorca. Naprawiony. Używam $ (shell) dużo pomimo dodatkowego widelca, ponieważ często generalizuję polecenie. Korzystając z: = zadania, cierpię, że dodatkowo tylko raz. – dmckee

+0

możesz równie łatwo użyć: = z $ (wildcard), jeśli chcesz. –