2017-12-26 13 views
3

Ich habe etwa 20 CPP-Dateien und und so viele .h-Dateien. Wenn ich kompilieren ichWie vermeidet man es, alle Dateien jedes Mal neu zu kompilieren?

g++ -std=c++11 main.cpp -o main 

in main.cpp ich von einigen Vorwärtsdeklarationen beginnen und dann schließe ich alle .h und CPP-Dateien.

Als Ergebnis müssen bei jeder Kompilierung alle Dateien neu kompiliert werden, was unangenehm langsam ist. Ich denke, ich würde .so und/oder .dll Dateien verwenden müssen, so dass bei der zukünftigen Kompilierung nur der geänderte Code neu kompiliert werden muss. Ich weiß nicht wirklich, wie ich das machen soll. Könntest du mir ein paar Ratschläge geben?

+0

sollten Sie ['CMake'] (https://cmake.org/) betrachten. Hier ist ein [grundlegendes Tutorial] (https://cmake.org/cmake-tutorial/). – apalomer

+2

Verwenden Sie ein Build-System; Vorschläge sind: eine der IDEs für Ihre Plattform, CMake, Make –

+7

Darüber hinaus mit einem Build-System, aufhören zu schließen Ihre cpp-Dateien. Kompilieren Sie sie zu Objektdateien und verknüpfen Sie die Objekte miteinander. Dadurch wird verhindert, dass eine Änderung an einer anderen alle (indirekt, weil sie enthalten sind) neu kompiliert werden müssen. Das heißt nicht, dass die [SCU] (https://en.wikipedia.org/wiki/Single_Compilation_Unit) Technik nicht ohne ihre Verwendung ist. Aber Sie scheinen es offensichtlich nicht zu wollen. – StoryTeller

Antwort

2

Sie möchten, dass jedes translation unit separat kompiliert wird, und Sie könnten sie sogar parallel kompilieren (z. B. mit make -j, siehe unten).

(ich bin zu raten und hoffen, dass Sie auf Linux sind und mit GCC als g++;. Adaptieren diese Antwort auf Ihre Compiler und Betriebssystem, wenn nicht)

Wenn Sie src1.cpp src2.cpp src3.cpp (jeweils mit geeigneten #include directives, wahrscheinlich mit einer gemeinsamen Header-Datei) würden Sie src1.cpp in eine kompilieren object filesrc1.ousing GCC als:

g++ -Wall -Wextra -g src1.cpp -c -o src1.o 

Die Option -Wall -Wextra fragt nach allen Warnungen und einigen zusätzlichen, und Sie möchten sie wirklich (um Ihren Code zu verbessern, um keine Warnungen zu erhalten). Die Option -g fragt nach DWARF Debugging-Informationen (zu use the gdb debugger später, und auch zu valgrind). Die Option -c erfordert nur den Übersetzungsschritt ohne Verknüpfung. Die -o src1.o erläutert die Ausgabeobjektdatei.

Ebenso werden Sie src2.cpp in src2.o

g++ -Wall -Wextra -g src2.cpp -c -o src2.o 

und src3.cpp

g++ -Wall -Wextra -g src3.cpp -c -o src3.o 

kompilieren BTW ziehe ich die kürzere .cc Suffix .cpp. Aktivieren Sie für Benchmarkzwecke optimizations in Ihrem Compiler, z. durch Zugabe von -O2 -march=native nach -g.

Schließlich möchten Sie link alle drei Objekte Dateien src1.o, src2.o und src3.o in eine myprogexecutable:

g++ -g src1.o src2.o src3.o -o myprog 

Sie können zusätzliche Optionen hinzufügen, zum Beispiel externe Bibliotheken verlinken

Beachten Sie, dass C++14 (und auch C++ 11 und sogar C++ 17) keine echte modules (im Gegensatz zu Ocaml oder Go) hat. Der Präprozessor wird also oft verwendet und Sie müssen praktisch viel Code einbinden. Zum Beispiel zieht #include <vector> mehr als zehntausend Zeilen C++ - Code aus Standard-und internen Header-Dateien auf meinem Linux/Debian-Desktop. Dies erklärt, warum C++ Compiler langsam sind, daher empfehle ich, zu kleine C++ Dateien zu vermeiden (zB eine Quelldatei von nur 100 C++ Zeilen einschließlich mehrere Header-Dateien, die in der Praxis Dutzende von C++ Zeilen aus verschiedenen internen Headern ziehen würden) . Meine Präferenz ist mehrere verwandte Funktionen (und vielleicht Klassen) in jeder .cc (oder .cpp) Quelldatei von einer oder ein paar tausend Zeilen von C++ zu definieren.

(zukünftige C++ Standards, vielleicht C++20 könnten Module in die Sprache hinzufügen, aber diese verschoben werden könnte ...)

Meine Empfehlung ist, zu lernen GNU make oder ninja zu verwenden. In der Tat benötigen Sie ein build automation Werkzeug.

Sie sollten sicherlich lernen, wie Sie Ihren Compiler in der Befehlszeile aufrufen. Lesen Sie über invoking GCC, wenn Sie g++ verwenden. Die Reihenfolge der Argumente zu g++ zählt eine große Menge.

Sie könnten Tools wie cmake oder meson verwenden, die Konfigurationsdateien generiert (für make oder ninja). Aber ich empfehle einfachere Dinge als cmake oder meson (z. B. Code Makefile von Hand und verwenden Sie einfach make). Here ist ein Beispiel für Makefile für make. Sie müssen Ihren Build-Prozess verstehen. In einigen Fällen könnten Sie während Ihres Builds einige (einfache) C++ - Dateien erzeugen (z. B. mit GNU bison oder Qt moc oder einem eigenen Skript oder Programm, das eine C++ - Datei ausgibt).

Ich glaube, ich würde .so

Nicht unbedingt verwenden müssen. .so Dateien sind freigegebene Objekte, die in gemeinsam genutzten Bibliotheken verwendet werden. Siehe this. Sie könnten (und wahrscheinlich zuerst, Sie wollen) mehrere Objektdateien haben, wie oben erklärt. Sie könnten später überlegen, Ihre eigene Software libraries zu machen, aber das lohnt sich nur für wiederverwendbaren Quellcode.

Um externe Bibliotheken zu verknüpfen, möchten Sie vielleicht sogar pkg-config (für diese Pakete, die davon wissen) verwenden, die zu den entsprechenden Erstellungsoptionen für g++ erweitert werden.

Sehen Sie auch in free software Projekte für Inspiration, und studieren Sie ihren Quellcode (einschließlich ihrer Build-Prozess).Sie finden viele von ihnen in Linux-Distributionen und unter github, sourceforge und anderswo.

+1

Das war so hilfreich. Ich fand es ein wenig schwierig, diese Art von sehr einführenden Informationen über Compilations zu bekommen, und dein leicht zu lesender Beitrag und die großzügige Menge an Links haben mir sehr geholfen. Vielen Dank –

2

... und dann schließe ich alle .h und .cpp Dateien ein.

.cpp Dateien (auch bekannt als Übersetzungseinheiten) werden nicht als enthalten soll. Sie sollten ein Skript oder eine andere Art von Build-System verwenden, das jede der Dateien separat kompiliert und alle produzierten .o Objektdateien zusammen in das ausführbare Programm verbindet.

Dies kann aktiviert werden, um zu vermeiden, alle .cpp Dateien neu zu kompilieren, wenn sie nicht von Änderungen in den Header-Dateien betroffen sind.

Verwandte Themen