2016-12-14 5 views
0

Gibt es eine einfache Möglichkeit, ein einzelnes Rezept auf mehrere Musterregeln anzuwenden?Makefile einzelnes Rezept für mehrere Muster

Betrachten Sie diese Verzeichnisstruktur

|- src 
| - file1.cpp 
|- test 
| - file2.cpp 
| - file3.cpp 
| - metrics 
| - file4.cpp 
| - file5.cpp 

Ich möchte eine einzige Musterregel schreiben alle CPP-Dateien in dem Testverzeichnis zu kompilieren. Hier ist, was ich habe jetzt:

$(OBJS)/%.o: test/%.cpp 
    @mkdir -p $(OBJS) 
    g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 

$(OBJS)/%.o: test/metrics/%.cpp 
    @mkdir -p $(OBJS) 
    g++ $(FLAGS) $(CPPFLAGS) -I test -c $< -o [email protected] 

TEST_CPP := $(wildcard test/*.cpp) $(wildcard test/**/*.cpp) 
TEST_OBJ := $(addprefix $(OBJS)/,$(notdir $(TEST_CPP:.cpp=.o))) 

$(BIN)/testRunner: $(TEST_OBJ) 
    @mkdir -p $(BIN) 
    g++ $(FLAGS) $(CPPFLAGS) $^ $(LIBS) -o [email protected] 

Ich möchte das Rezept für die Objektdateien zu wiederholen. Ich stelle mir die Lösung wie folgt aussehen würde:

$(OBJS)/%.o: test/%.cpp 
$(OBJS)/%.o: test/metrics/%.cpp 
    @mkdir -p $(OBJS) 
    g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 

(Im Moment der objs Verzeichnis ist flach, aber, ich habe kein Problem, die Quelle Verzeichnisstruktur zu duplizieren, wenn das das Makefile vereinfacht.)

Antwort

3

Es gibt keine Möglichkeit zu tun, was Sie wollen. Die nächstgelegene Sie erhalten können, ist das Rezept in eine Variable zu setzen und dasselbe Variable in jedem Rezepte verwenden, wie folgt aus:

define BUILD_O 
     @mkdir -p $(OBJS) 
     g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 
endef 

$(OBJS)/%.o : test/%.cpp 
     $(BUILD_O) 
$(OBJS)/%.o : test/metrics/%.cpp 
     $(BUILD_O) 

Als Alternative zu, dass, weil Sie alle Ihre Objekte in das gleiche Verzeichnis hinwollen aber Quellen aus verschiedenen Verzeichnissen finden, könnten Sie VPATH statt und schreiben nur eine einzige Musterregel verwenden, wie folgt aus:

VPATH = test test/metrics 

$(OBJS)/%.o : %.cpp 
     @mkdir -p $(@D) 
     g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 

ich Ihnen dringend, drängen die Makefiles zu überarbeiten die Standardvariablennamen zu verwenden, obwohl; Verwenden Sie $(CXX), nicht g++, für den C++ - Compiler-Namen und $(CXXFLAGS), nicht $(FLAGS), für die C++ - Compiler-Optionen.

EDIT

Wenn Sie Flags anpassen, dann die normale Art und Weise, dies zu tun ist entweder durch target-specific variables oder durch constructed macro names

zielspezifische Variablen würde wie folgt aussehen:

test: $(test_targets) 
test: FLAGS += -Dtest 

production: $(production_targets) 
production: FLAGS += -Dproduction 

dann, wenn Sie make test ausführen, erhalten Sie die -Dtest hinzugefügt; Wenn Sie make production ausführen, erhalten Sie die -Dproduction hinzugefügt. Es gibt jedoch Probleme hier: Wenn Sie make myfoo.o ausführen, werden Sie diese nicht hinzugefügt (siehe die Dokumentation).

Konstruiert Makronamen würde wie folgt aussehen:

test_FLAGS = -Dtest 
production_FLAGS = -Dproduction 

rootdir = $(firstword $(subst /, ,$1)) 

VPATH = test test/metrics production production/widgets 

$(OBJS)/%.o : %.cpp 
     @mkdir -p $(@D) 
     g++ $(FLAGS) $(CPPFLAGS) $($(call rootdir,$(<D))_FLAGS) -c $< -o [email protected] 
+0

Gibt es eine Möglichkeit VPATH nur auf bestimmte Regeln anzuwenden? Angenommen, ich möchte ein anderes Flags/Bibliotheken/Includes für die "Test" .o-Dateien als für die "Produkt" .o-Dateien. Ich könnte separate Musterregeln für '$ (OBJS)/test /% .o' und' $ (OBJS)/production /% .o' einrichten; Aber gibt es dann eine Möglichkeit, Musterübereinstimmungen für .o-Dateien in '$ (OBJS)/test' auf Quellen in'/test' zu beschränken? – Zack

+0

'VPATH' ist global, aber Sie können die' vpath' Direktive wie 'vpath $ (OBJS)/test /% .o test' (und ebenfalls für die Produktion) verwenden. –

+0

Sie können 'vpath' nicht so verwenden: Das Muster in' vpath' gilt für die Liste der gesuchten Namen, nicht für die Liste der Ziele. Mit anderen Worten, Ihr Beispiel sagt make, dass es nach .o-Dateien in 'test', nicht nach' .cpp'-Dateien suchen soll. – MadScientist

Verwandte Themen