2016-08-30 2 views
0

Ich brauche Hilfe, um ein richtiges Makefile (unterstützende inkrementelle Kompilierung) für mehrere .hpp und .cpp-Dateien zu erstellen.Schreibe Makefile für .cpp und .hpp C++

Ich habe nach Informationen gesucht, wie man ein richtiges Makefile erstellt, aber ich bin nicht wirklich sicher, wie man es macht.

Ich habe die folgenden Dateien: 2048.cpp, game.cpp, game.hpp, gameutils.cpp, gameutils.hpp, menu.cpp, menu.hpp, saveandback.cpp, saveandback.hpp und tile.hpp

Im Moment bin ich mit den folgenden Make-Datei:

all: 2048.cpp tile.hpp menu.hpp menu.cpp gameutils.hpp gameutils.cpp saveandback.hpp saveandback.cpp game.hpp game.cpp 
    g++ -g -W -Wall --pedantic -DNDEBUG 2048.cpp -o power 

clean: 
    $(RM) power 

Dank für Ihre Hilfe danken.

+2

Die Bereitstellung von Headern sieht übermäßig aus. Was ist deine Frage? – alexeykuzmin0

+0

Wie man es richtig schreibt. –

+0

@CAB meine Hausaufgaben basieren nicht auf dem Erstellen eines Makefiles, aber ich muss einen zur Verfügung stellen, da ich nicht wirklich freundlich darauf bin, deshalb frage ich Sie, ob Sie mir helfen können. Ich habe viele Dokumente darüber geschrieben, wer Makefiles schreiben soll, aber es bietet mir nicht viel Hilfe. Aber danke, ich werde mir das GNU Build System ansehen. –

Antwort

5

Vorbehalt: Ich habe seit einiger Zeit kein make mehr verwendet, daher kann ich bei POSIX vs. GNU-make-spezifische Sachen ein wenig eingerostet sein. Es kann auch neue Funktionen in den letzten Jahren geben, die mir nicht bekannt sind. Bitte zögern Sie nicht, Korrekturen vorzunehmen. Auch das meiste stammt aus dem Gedächtnis.

Es gibt ein paar Dinge aus Ihrem Wissen fehlt hier eingestellt, dass man eine anständige Make-Datei erstellen können, die nur Dinge neu kompiliert, wenn nötig:

  • Generic Rules - diese verwendet werden können, eine generische zur Verfügung zu stellen Regel zum Erstellen eines Dateinamens mit einem Suffix aus einem anderen. Z.B. Folgendes definiert für die Erstellung von beliebigen * .o von seinem entsprechenden * CPP eine Regel:

    %.o: %.cpp 
        stuff 
    

    In POSIX machen diese Regeln tatsächlich angegeben werden als:

    .cpp.o: 
        stuff 
    

    ich GNU Syntax bin mit unten, aber Sie können (und möchten vielleicht) mit der POSIX-Syntax ersetzen (wenn Sie sie auslassen und die impliziten Regeln verwenden, siehe unten).

  • Automatic Variables

    • $< wird an den Eingang der Regel erweitern.
    • [email protected] wird auf das Ziel der Regel erweitern.
  • Variablen - Sie können Variablen deklarieren und sie Werte geben, zum Beispiel:

    SOURCES=2048.cpp gameutils.cpp saveandback.cpp 
    

    Etc.

  • Text ersetzen - Sie können Textersetzungsfunktionen verwenden Suffixe zu ersetzen, zB:

    OBJECTS=$(SOURCES:.cpp=.o) 
    

    Wird OBJECTS gleich SOURCES gesetzt, aber mit der .cpp ist zu .o geändert.

  • Multiple Rules - Wenn mehrere Regeln für das gleiche Ziel angegeben sind, werden ihre Voraussetzungen zusammengeführt.

  • Phony Targets

Putting, dass alle zusammen, um Ihnen einen Start bekommen, Kopf Abhängigkeiten Weglassen jetzt:

SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 

power: $(OBJECTS) 
    g++ $(OBJECTS) -o [email protected] 

%.o: %.cpp 
    g++ -c $< -o [email protected] 

Und es ist traditionell eine all Regel zu definieren, die ein Schwindler ist Ziel, da es eigentlich keine Datei namens "all" gibt:

.PHONY: all 
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 

all: power 

power: $(OBJECTS) 
    g++ $(OBJECTS) -o [email protected] 

%.o: %.cpp 
    g++ -c $< -o [email protected] 

Jetzt haben Sie tatsächlich einige default rules bereits, einschließlich einer für %.o: %.cpp, und auch es hat einige default variables. So können Sie die oben auf das reduzieren, wenn Sie möchten (persönlich ziehe ich es ausdrücklich Regeln zu spezifizieren, aber das ist nur meine Meinung):

.PHONY: all 
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 

all: power 

power: $(OBJECTS) 
    $(CXX) $(CXXFLAGS) $(OBJECTS) -o [email protected] 

Jetzt, da für Ihre Header, unter Berücksichtigung der mehrere Regeln Sache, Sie können einfach diese Voraussetzungen von Hand anhand hinzufügen auf ihrem enthält, zum Beispiel:

.PHONY: all 
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 

all: power 

power: $(OBJECTS) 
    $(CXX) $(CXXFLAGS) $(OBJECTS) -o [email protected] 

2048.o: menu.hpp game.hpp 
menu.o: menu.hpp 
game.o: game.hpp 

Und so weiter. Sie wollen wahrscheinlich auch eine „saubere“ Regel eine andere Pseudoziel, und es schadet nicht, Ihren Namen der Binärdatei in einer Variablen zu setzen, da Sie es an einigen Stellen verwendet werden, zB:

.PHONY: all clean 
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 
BINARY=power 

all: $(BINARY) 

clean: 
    $(RM) $(BINARY) $(OBJECTS) 

$(BINARY): $(OBJECTS) 
    $(CXX) $(CXXFLAGS) $(OBJECTS) -o [email protected] 

Und tatsächlich, wenn Sie Übergeben Sie -MM zu gcc es wird Makefile Abhängigkeiten automatisch für Sie basierend auf den Includes der Quelldatei generieren. Details und ein Beispiel finden Sie unter here.

+0

Vielen Dank für Ihre Hilfe :) –

+2

Das ist eine nette, gründliche Antwort! Auf die Gefahr hin, sich noch weiter zu verlängern, wäre es besser, wenn Sie bei Make's $ '(LINK.cpp) $^$ (LOADLIBES) $ (LDLIBS) -o $ @' landeten - also ganz in der Nähe, wo Sie sind, aber so bereit für die nächsten Schritte des Fragestellers ... –

Verwandte Themen