2009-10-21 12 views
7

Nasz plik make kompiluje .c pliki źródłowe ze statycznym reguły wzór jak ten:w GNU make, może przesłanki w statycznym reguły wzorca mają różne przyrostki

OBJECTS = foo.o bar.o baz.o 

$(OBJECTS): %.o: %.c 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 

muszę zmienić jedną z .c pliki do pliku Objective-C .m. Wywołanie kompilatora jest takie samo dla obu typów źródeł, więc chciałbym użyć tej samej reguły i po prostu dostosować ją, aby była bardziej elastyczna. Wolę nie zmieniać zmiennej OPTIONS, ponieważ jest ona również używana do etapu łączenia itp.

Czy istnieje sposób, aby powyższa reguła była bardziej elastyczna, aby pomieścić zarówno pliki .c, jak i .m?

Dzięki

Odpowiedz

1

Niezupełnie wystarczy skopiować do

$(OBJECTS): %.o: %.m 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 
+0

To spowoduje błędy. Dla pierwszej instancji nie znaleziono plików '% .m' (błąd!), A dla drugiego - brak'% .c' (inny błąd!) –

+0

Niestety tylko przegląda, co się dzieje, jeśli nie ma. c plik wtedy nie wywoła reguły% .c – Mark

-1

Wezwanie do tego samego kompilatora jest po prostu szczęśliwy okazja. Zwykle nie kompilujesz kodu celu-c za pomocą $(CC). To po prostu wydaje się dziwne.

Ale ponieważ idziesz w trudny sposób, nie zamieszczę rozwiązania typu "zrób to sam", w którym oddzielasz cele-C od celów C na dwie różne zmienne $(OBJECTS) i tworzysz dwie reguły (które powinien naprawdę zrobić). Zbyt nudne. Zamiast tego weź hack!

OBJC_FILES:=$(subst $(wildcard *.m)) 

real_name = `(test -h $(1) && readlink $(1)) || echo $(1)` 

$(OBJECTS): %.o: %.c 
    $(GCC) $< $(C_OPTIONS) -c -o $(call real_name,[email protected]) 

$(OBJC_FILES): %.c: %.m 
    ln -s $< [email protected] 

I niech Bóg pomoże tym, którzy to utrzymują!

Przy okazji, to oczywiście nie zadziała, jeśli wygenerujesz m-pliki.

7

Możemy dodać to albo - albo zachowanie do listy rzeczy, które powinno być w stanie zrobić łatwo, ale nie jest. Oto sposób, aby to zrobić, używając "eval", aby utworzyć oddzielną regułę dla każdego obiektu.

 
define RULE_template 
$(1): $(wildcard $(basename $(1)).[cm]) 
endef 

OBJECTS = foo.o bar.o baz.o 

$(foreach obj,$(OBJECTS),$(eval $(call RULE_template,$(obj)))) 

$(OBJECTS): 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 

Zauważ, że to zależy od plików źródłowych już istniejących przed uruchomieniem Marka (foo.c lub foo.m, ale nie oba). Jeśli generujesz te źródła w tym samym kroku, to nie zadziała.

Oto mniej sprytna, solidniejsza metoda: .

 
CPP_OBJECTS = foo.o bar.o 
OBJECTIVE_OBJECTS = baz.o 
OBJECTS = $(CPP_OBJECTS) $(OBJECTIVE_OBJECTS) 

$(CPP_OBJECTS): %.o: %.c 

$(OBJECTIVE_OBJECTS): %.o: %.m 

$(OBJECTS): 
    $(CC) $< $(C_OPTIONS) -c -o [email protected] 

edit: poprawione PRZEDMIOTÓW zadania, dzięki Jonathan Leffler.

+1

Zgadzam się z bardziej niezawodną metodą - użyłbym tego. Ale OBJECTS = makro potrzebuje trochę $ (...) na RHS. –

+0

Ack! Masz rację, powinienem być bardziej ostrożny. – Beta

+0

Tworząc twój przykład (drugi) generowany jest tylko pierwszy plik foo.o. W czym problem? – BogdanSikach

Powiązane problemy