Ich habe einige (alte) Posts im Internet gesehen, in denen es darum ging, Unterstützung für vorkompilierte Header in CMake zusammen zu hacken. Sie scheinen alle ein bisschen überall zu sein und jeder hat seine eigene Art, es zu tun. Was ist derzeit der beste Weg, dies zu tun?
c++
visual-studio
gcc
cmake
precompiled-headers
Klebrig
quelle
quelle
Ich benutze das folgende Makro, um vorkompilierte Header zu generieren und zu verwenden:
Nehmen wir an, Sie haben eine Variable $ {MySources} mit all Ihren Quelldateien. Der Code, den Sie verwenden möchten, ist einfach
Der Code würde auch auf Nicht-MSVC-Plattformen weiterhin einwandfrei funktionieren. Ziemlich ordentlich :)
quelle
list( APPEND ... )
Außenseite des Schließensendif()
. Gesamten Code hier: pastebin.com/84dm5rXZ/Yu
und/FI
Argumente, sie sollten sein${PrecompiledHeader}
und nicht${PrecompiledBinary}
./YuC:/foo/bar.h
Zum Beispiel werden Sie gezwungen, entweder das/FpC:/foo/bar.h
Flag zu übergeben oder#include <C:/foo/bar.h>
als erste include-Anweisung oben in alle Ihre .cpp-Dateien zu setzen. MSVC führt einen Zeichenfolgenvergleich der#include
Argumente durch und prüft nicht, ob es auf dieselbe Datei verweist, für die es angegeben wurde/Yu
. Ergo#include <bar.h>
wird nicht funktionieren und Fehler C2857 ausgeben.CMake hat gerade Unterstützung für PCHs erhalten. Es sollte in der kommenden Version 3.16 verfügbar sein, die am 01.10.2019 erscheinen soll:
https://gitlab.kitware.com/cmake/cmake/merge_requests/3553
Es gibt derzeit Diskussionen über die Unterstützung der gemeinsamen Nutzung von PCHs zwischen Zielen: https://gitlab.kitware.com/cmake/cmake/issues/19659
Unter https://blog.qt.io/blog/2019/08/01/precompiled-headers-and-unity-jumbo-builds-in-upcoming-cmake/ steht ein zusätzlicher Kontext (Motivation, Zahlen) zur Verfügung.
quelle
Hier ist ein Code-Snippet, mit dem Sie vorkompilierte Header für Ihr Projekt verwenden können. Fügen Sie Ihrer CMakeLists.txt Folgendes hinzu
myprecompiledheaders
und ersetzen Sie siemyproject_SOURCE_FILES
entsprechend:quelle
with set( CMAKE_AUTOMOC ON )
.myprecompiledheader.cpp
das zuerst kompiliert wird? Aus diesem Snippet geht hervor, dass es zuletzt kompiliert wird. Vielleicht ist es das, was die Verzögerung verursacht.myprecompiledheader.h
enthält nur die häufigsten STL-Header, die mein Code verwendet.Am Ende habe ich eine angepasste Version des Larsm-Makros verwendet. Durch die Verwendung von $ (IntDir) für den pch-Pfad werden vorkompilierte Header für Debug- und Release-Builds getrennt.
quelle
Angepasst von Dave, aber effizienter (legt Zieleigenschaften fest, nicht für jede Datei):
quelle
abc
in deinem Beispiel?Wenn Sie das Rad nicht neu erfinden möchten, verwenden Sie entweder Cotire, wie in der oberen Antwort angegeben, oder einen einfacheren - cmake-vorkompilierten Header hier . Um es zu verwenden, fügen Sie einfach das Modul hinzu und rufen Sie auf:
quelle
CMake 3.16 führte die Unterstützung für vorkompilierte Header ein. Es gibt einen neuen CMake-Befehl,
target_precompile_headers
der alles unter der Haube erledigt, was Sie brauchen. Weitere Informationen finden Sie in der Dokumentation: https://cmake.org/cmake/help/latest/command/target_precompile_headers.htmlquelle
Ein Beispiel für die Verwendung eines vorkompilierten Headers mit cmake und Visual Studio 2015
"stdafx.h", "stdafx.cpp" - vorkompilierter Headername.
Fügen Sie Folgendes in die Root-cmake-Datei ein.
Fügen Sie Folgendes in die Projekt-cmake-Datei ein.
"src" - ein Ordner mit Quelldateien.
quelle
IMHO ist der beste Weg, PCH für das gesamte Projekt festzulegen, wie von Martjno vorgeschlagen, kombiniert mit der Fähigkeit, PCH für einige Quellen bei Bedarf zu ignorieren (z. B. generierte Quellen):
Wenn Sie also ein Ziel MY_TARGET und eine Liste der generierten Quellen IGNORE_PCH_SRC_LIST haben, gehen Sie einfach wie folgt vor:
Dieser Ansatz ist getestet und funktioniert einwandfrei.
quelle
Wenn Builds auf einem Quad-Core-Computer jedes Mal mehr als 10 Minuten dauern, wenn Sie eine einzelne Zeile in einer der Projektdateien ändern, werden Sie aufgefordert, vorkompilierte Header für Windows hinzuzufügen. Unter * nux würde ich nur ccache verwenden und mir darüber keine Sorgen machen.
Ich habe in meiner Hauptanwendung und einigen der von ihr verwendeten Bibliotheken implementiert. Bis jetzt funktioniert es großartig. Eine Sache, die auch benötigt wird, ist, dass Sie die pch-Quell- und Header-Datei erstellen müssen und in der Quelldatei alle Header enthalten, die vorkompiliert werden sollen. Ich habe das 12 Jahre lang mit MFC gemacht, aber ich habe ein paar Minuten gebraucht, um mich daran zu erinnern.
quelle
Am saubersten ist es, die vorkompilierte Option als globale Option hinzuzufügen. In der vcxproj-Datei wird dies als angezeigt
<PrecompiledHeader>Use</PrecompiledHeader>
und nicht für jede einzelne Datei.Dann müssen Sie die
Create
Option zur Datei StdAfx.cpp hinzufügen. Folgendes benutze ich:Dies ist getestet und funktioniert für MSVC 2010 und erstellt eine MyDll.pch-Datei. Es stört mich nicht, welcher Dateiname verwendet wird, daher habe ich mich nicht bemüht, ihn anzugeben.
quelle
Da die vorkompilierte Header-Option für RC-Dateien nicht funktioniert, musste ich das von Jari bereitgestellte Makro anpassen.
Bearbeiten: Die Verwendung dieser vorkompilierten Header reduzierte die Gesamtaufbauzeit meines Hauptprojekts von 4 Minuten 30 Sekunden auf 1 Minute 40 Sekunden. Das ist für mich eine wirklich gute Sache. Im Precompile-Header befinden sich nur Header wie boost / stl / Windows / mfc.
quelle
Geh nicht mal dorthin. Vorkompilierte Header bedeuten, dass Sie bei jeder Änderung eines der Header alles neu erstellen müssen . Sie haben Glück, wenn Sie ein Build-System haben, das dies erkennt. Meistens schlägt Ihr Build nur fehl, bis Sie feststellen, dass Sie etwas geändert haben, das vorkompiliert wird, und daher eine vollständige Neuerstellung durchführen müssen. Sie können dies größtenteils vermeiden, indem Sie die Header vorkompilieren, von denen Sie absolut sicher sind, dass sie sich nicht ändern. Dann geben Sie jedoch auch einen großen Teil des Geschwindigkeitsgewinns auf.
Das andere Problem ist, dass Ihr Namespace an vielen Stellen, an denen Sie die vorkompilierten Header verwenden würden, mit allen Arten von Symbolen verschmutzt wird, die Sie nicht kennen oder die Sie nicht interessieren.
quelle