C++-header-units.json-Referenz
Die header-units.json
Datei dient zwei Zwecken:
- Geben Sie an, welche Headerdateien bei
/translateInclude
Angabe in Kopfzeileneinheiten übersetzt werden können. - Minimieren Sie doppelte Symbole, um den Builddurchsatz zu erhöhen.
Diese Datei muss sich im selben Verzeichnis wie die enthaltene Headerdatei befinden. Diese Datei wird nur verwendet, wenn /translateInclude
sie zusammen mit einem /scanDependencies
oder anderen /sourceDependencies:directives
angegeben wird.
Sinn
Einige Headerdateien können nicht sicher in Kopfzeileneinheiten übersetzt werden. Headerdateien, die von Makros abhängen, die nicht in der Befehlszeile definiert sind oder die in den Kopfzeilendateien nicht definiert sind, können nicht in Kopfzeileneinheiten übersetzt werden.
Wenn eine Kopfzeile Makros definiert, die sich darauf auswirken, ob andere Kopfzeilen enthalten sind, kann sie nicht sicher übersetzt werden. Beispiel: gegeben a.h
und b.h
macros.h
, die alle im selben Verzeichnis enthalten sind:
// a.h
#include "macros.h" // #defines MACRO=1
#ifdef MACRO
#include "b.h"
#endif
Das header-units.json
in diesem Verzeichnis kann enthalten a.h
und b.h
, aber nicht macros.h
. Dieses Beispiel ähnelt folgendem Beispiel:The header-units.json
for this example would be similar to this:
{
"Version": "1.0",
"BuildAsHeaderUnits": [
// macros.h should not be listed
"a.h",
"b.h"
]
}
Der Grund macros.h
kann in dieser header-units.json
Datei nicht aufgeführt werden, da die Kopfzeileneinheit (.ifc
) während der Überprüfungsphase möglicherweise noch macros.h
nicht kompiliert wird. In diesem Fall MACRO
wird beim Kompilieren nicht definiert a.h
. Das bedeutet, dass b.h
in der Liste der Abhängigkeiten für a.h
. Da es sich nicht in der Liste der Abhängigkeiten befindet, erstellt das Buildsystem keine Headereinheit b.h
, obwohl sie in der header-units.json
Datei aufgeführt wird.
Um dieses Problem zu vermeiden, wird die Headerdatei, die das Makro definiert, aus der Liste der Dateien ausgeschlossen, die in einer Kopfzeileneinheit kompiliert werden können, wenn es eine Abhängigkeit von einem Makro in einer anderen Headerdatei gibt. Auf diese Weise wird die Kopfzeilendatei, die das Makro definiert, normal #include
behandelt und MACRO
sichtbar, sodass b.h
es eingeschlossen und als eine der Abhängigkeiten aufgeführt wird.
Verhindern doppelter Symbole
Die header-units.json
Datei ist auch wichtig, da sie die automatische Erstellung der Kopfzeileneinheit ohne duplizierte Symbole ermöglicht. Dazu erstellen Sie "atomische" Kopfzeileneinheiten für die dateien, die in header-units.json
. Die importierten Headereinheiten enthalten keine doppelten Symbole aus den verschiedenen #include
Direktiven, die beim Übersetzen der Headerdatei verarbeitet wurden.
Ziehen Sie beispielsweise zwei Headerdateien in Betracht, die beide eine gemeinsame Headerdatei enthalten. Beide Headerdateien sind in derselben Quelldatei enthalten:
// a.h
#include "b.h"
// c.h
#include "b.h"
// Source.cpp
import "a.h";
import "c.h";
Wenn der Compiler Headereinheiten für , und , dann die kompilierten Headereinheiten a.h.ifc
, b.h.ifc
und c.h.ifc
alle Typen von b.h
.c.h
b.h
a.h
Das Kompilieren Source.cpp
, das sowohl a.h
c.h
importiert als auch , erfordert, dass der Compiler die b.h
Typen deduplizieren muss, was sich auf die Buildleistung auswirkt.
Wenn es jedoch ein header-units.json
Verzeichnis b.h
gibt und /translateInclude
angegeben ist, geschieht Folgendes:
- Der Scan von
a.h
undc.h
Listenb.h
als Headereinheit importieren sie in den Abhängigkeitsscandateien, die vom Compiler generiert werden. - Das Buildsystem liest die Abhängigkeitsscandateien und bestimmt zuerst die Erstellung
b.h.ifc
. - Anschließend fügt
/headerUnit
b.h.ifc
das Buildsystem den Befehlszeilen zum Kompilieren undc.h
Kompilierena.h
hinzu. Er ruft den Compiler auf, um die Headereinheitena.h.ifc
undc.h.ifc
. Da/translateInclude
angegeben und auch angegebena.h.ifc
wird und/headerUnit for b.h.ifc
c.h.ifc
keine Typen enthaltenb.h
, gibt es keine Duplizierung in den erzeugten Kopfzeileneinheiten.
Schema
Es gibt eine headerunits.json
Datei für die StL-Header (Standard Template Library). Das Buildsystem verwendet es, um zu bestimmen, ob eine Kopfzeileneinheit für eine STL-Headerdatei und für seine Abhängigkeiten erstellt werden soll. Wenn sich die STL-Headerdatei nicht in der Liste befindet, wird sie als normale #include
behandelt und nicht als Headereinheit importiert.
Sie können die header-units.json
Datei unter dem Installationsverzeichnis für Visual Studio anzeigen. Beispiel: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json
Die header-units.json
Datei beginnt mit der Schemaversion, gefolgt von einem Array von Dateinamen für Header, die in Kopfzeileneinheiten integriert werden können.
Das Schema unterstützt auch Kommentare, wie hier gezeigt:
{
"Version": "1.0",
"BuildAsHeaderUnits": [
// "__msvc_all_public_headers.hpp", // for testing, not production
"__msvc_system_error_abi.hpp",
"__msvc_tzdb.hpp",
"__msvc_xlocinfo_types.hpp",
"algorithm",
"any",
"array",
"atomic",
"barrier",
"bit",
"bitset",
// "cassert", // design is permanently incompatible with header units
...
}
Suchregeln
Der Compiler sucht diese Datei im selben Verzeichnis wie die verarbeitete Headerdatei. Wenn Ihre Bibliothek in Unterverzeichnissen organisiert ist, benötigt jedes Unterverzeichnis eine eigene header-units.json
Datei.
Siehe auch
Exemplarische Vorgehensweise: Importieren von STL-Bibliotheken als Headereinheiten
Exemplarische Vorgehensweise: Erstellen und Importieren von Headereinheiten in Ihren Visual C++-Projekten