2017-02-16 3 views
0

Ich habe eine Binärdatei, die ich mehrmals mit verschiedenen Compiler-Flags erstellen muss. Daher habe ich ein Makefile, die so etwas wie heißt es:Makefile mehrere Ziele aus der gleichen Quelldatei, mit verschiedenen Flags

OBJECTS_A := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.a.o)) 
OBJECTS_B := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.b.o)) 
OBJECTS_C := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.c.o)) 

Ich sehe auch eine Regel die Flags für jede OBJECTS_x zu ändern:

$(OBJECTS_B): DEFINES+=-D_B 
$(OBJECTS_C): DEFINES+=-D_C 

Und das ist, wo das Problem auftritt: Wenn ich den Zustand Ziele separat, wie:

$(OBJFOLDER)/%.a.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

$(OBJFOLDER)/%.b.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

$(OBJFOLDER)/%.c.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

Alle funktioniert. wenn ich alle Regeln in einer jedoch verschmelzen, wird nur die erste ausgewertet:

$(OBJFOLDER)/%.a.o $(OBJFOLDER)/%.b.o $(OBJFOLDER)/%.c.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

Was ich auf Trockenlauf bekommen ist, dass nur $ (ObjFolder) /% ao Objekte bauen, sondern auf der Verknüpfungsregel. Jede Binärdatei benötigt ihre Objekte (und B- und C-Binärdateien können daher nicht bauen).

Irgendwelche Ideen? Vielen Dank!

+0

Ein Muster Regel mit mehreren Mustern Ziel bedeutet, genau so, wie Sie erlebt haben: es ist ein einziger Aufruf des Rezeptes erwartet _all_ die Ziele zu bauen . Es wird verwendet, wenn ein Programm mehrere Ausgabedateien erstellt. Siehe https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html (letzter Absatz) – MadScientist

Antwort

3

Sie können diese secondary expansion mit erreichen:

.SECONDEXPANSION: 
$(OBJFOLDER)/%.o: $$(basename $$*).cpp 
     $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o [email protected] 

Beachten Sie, dass dies nicht ein sehr idiomatischer Weg, dies zu tun, eine üblichere define/call/eval Combo kann verwendet werden, um Regeln zu erzeugen, wie in dem ersten Lösung:

VARIANTS=a b c 

DEFINES_FOR_a= 
DEFINES_FOR_b=-D_B 
DEFINES_FOR_c=-D_C 

define make_target = 
$$(OBJFOLDER)/%.$(1).o: %.cpp 
     $$(COMPILER) $$(CFLAGS) $$(INCFOLDER) $$(DEFINES_FOR_$(1)) -c $$< -o [email protected] 

endef 

$(eval $(foreach variant,$(VARIANTS),$(call make_target,$(variant)))) 
+0

Warum funktionieren die zielspezifischen Variablenzuweisungen nicht mehr? – MadScientist

+0

Mein schlechtes, es funktioniert ganz gut, ich habe die Antwort bearbeitet –

0

Eine andere Möglichkeit ist, Symlinks zu Ihren Quelldateien zu erstellen und diese mit verschiedenen Flags zu kompilieren. Auf diese Weise der gleiche allgemeine Muster Regel (OBJFOLDER)/%.o: %.cpp alle Ihre Ziele aufbauen kann:

OBJECTS_A := $(SOURCES:%.cpp=$(OBJFOLDER)/%.a.o) 
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.b.o) 
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.c.o) 
$(OBJECTS_B): DEFINES+=-D_B 
$(OBJECTS_C): DEFINES+=-D_C 

%.a.cpp : %.cpp 
    ln -s $< [email protected] 

%.b.cpp : %.cpp 
    ln -s $< [email protected] 

%.c.cpp : %.cpp 
    ln -s $< [email protected] 

$(OBJFOLDER)/%.o: %.cpp 
    $(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c -o [email protected] $< 
Verwandte Themen