2012-10-28 11 views
7

die Verzeichnisstruktur meines C++ Projekt ist
alle CPP-Dateien Kompilieren Make-Datei unter MinGW mit

/.. 
    makefile  <- the makefile is in root 
    /include  <- subdirectory that has to be included while compiling 
    /obj   <- target place for all *.o and final executable 
    /src   <- sources 

Und meine aktuelle Make-Datei ist:

CC=g++ 
CFLAGS=-c -Wall -std=c++11 

INC=-Iinclude 
SRC=src 
TGT=obj 

all: myapp 

myapp: myapp.o 
    $(CC) $(TGT)/myapp.o -o $(TGT)/myapp 

myapp.o: 
    $(CC) $(CFLAGS) $(INC) $(SRC)/myapp.cpp -o $(TGT)/myapp.o 

clean: 
    rm -rf $(TGT) 
    mkdir $(TGT) 

Das für meine erste Datei gearbeitet. Ich bin ein kompletter Makefile-Neuling - bitte helfen Sie mir, alle Dateien unter dem Verzeichnis /src zu kompilieren und sie mit einer ausführbaren Datei in /obj Verzeichnis zu verknüpfen.

die Make-Datei hat unter Windows zu arbeiten, ich bin mit MinGW und MSYS

Antwort

5

eine Liste der Quelldateien hinzufügen:

SOURCES = $(wildcard $(SRC)/*.cpp) 

und eine Liste der entsprechenden Objektdateien:

OBJS = $(addprefix $(TGT)/, $(notdir $(SOURCES:.cpp=.o))) 

und die ausführbare Ziel:

$(TGT)/myapp: $(OBJS) 
    $(CXX) $(LDFLAGS) $(OBJS) -o [email protected] 

Die Regel zum Erstellen der Objekte:

$(TGT)/%.o: $(SRC)/%.cpp 
    $(CXX) $(CXXFLAGS) -c $< -o [email protected] 

Nun müssen Sie die Optionen für die g angeben sind ++:

INCLUDES = -Iinclude 
CXXFLAGS = -Wall -std=c++11 $(INCLUDES) 

Und alles zusammen:

SRC=src 
TGT=obj 
INCLUDES = -Iinclude 
CXXFLAGS = -Wall -std=c++11 $(INCLUDES) 
SOURCES = $(wildcard $(SRC)/*.cpp) 
OBJS = $(addprefix $(TGT)/, $(notdir $(SOURCES:.cpp=.o))) 

$(TGT)/%.o: $(SRC)/%.cpp 
    $(CXX) $(CXXFLAGS) -c $< -o [email protected] 

$(TGT)/myapp: $(OBJS) 
    $(CXX) $(LDFLAGS) $(OBJS) -o [email protected] 

Es ist wichtig, dass vor $(CXX) ... es muss eine „Tab sein "Charakter, keine Leerzeichen.

+0

Kann der '-Idir' Teil parametriert werden? Ihre Lösung scheint prägnant zu sein. Zwei Dinge, die geändert werden sollten: Das make-Skript sollte sowohl die '* .o' als auch die endgültige ausführbare Datei in das TGT-Verzeichnis stellen ... – emesx

+0

Was meinst du mit parametrisiert? Sie können es in eine separate Variable einfügen und diese Variable natürlich zu 'CXXFLAGS' hinzufügen. Siehe geänderte Antwort. –

+1

@elmes Bitte versuchen Sie das modifizierte 'Makefile', das ich für das separate Zielverzeichnis angepasst habe. –

1

können Sie VPATH for separating source and object files verwenden:

src/myapp.c 
obj/Makefile 

Nehmen Sie Ihre vorhandenen Makefile, es in obj/ bewegen, lassen Sie Verweise auf $(TGT) und $(SRC) und füge folgendes hinzu:

VPATH=../src 

Beachten Sie, dass wenn Sie ar e versucht zu tun multi-architecture builds, VPATH is not ideal.


BTW, Sie Kapital nicht auf builtin rules.Wo haben Sie

CC=g++ 
CFLAGS=-c -Wall -std=c++11 
myapp: myapp.o 
    $(CC) $(TGT)/myapp.o -o $(TGT)/myapp 

myapp.o: 
    $(CC) $(CFLAGS) $(INC) $(SRC)/myapp.cpp -o $(TGT)/myapp.o 

Sie könnten stattdessen verwenden:

CXXFLAGS=-Wall -std=c++11 
CXXFLAGS+=$(INC) 
LDLIBS+=-lstdc++ 

myapp: myapp.o 

Also, alles zu summieren, Ihr neues obj/Makefile sollte wie folgt aussehen:

VPATH=../src 
INC=-I../include 
CXXFLAGS=-Wall -std=c++11 
CXXFLAGS+=$(INC) 
LDLIBS+=-lstdc++ 

myapp: myapp.o 

Sie können Erstellen Sie einen weiteren Makefile von obj/, um bei Bedarf in diesen neuen zu rekursieren:

all: obj/myapp 

obj/myapp: 
    mklink obj/Makefile ../Makefile 
    $(MAKE) --directory=obj/ 
+0

Wie ich schon sagte, ich bin neu bei Makefiles. Können Sie ein Arbeitsbeispiel erstellen, das zu dem in der Frage beschriebenen Szenario passt? – emesx

+0

ok, das einzige, was im Beispiel fehlt, ist der VPATH. Hier bitteschön. –

+0

aber warum muss das Makefile in dem 'obj' Verzeichnis liegen .. es ist kein guter Ort, um es zu behalten, da ich das Verzeichnis leicht löschen möchte – emesx

Verwandte Themen