Share via


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:directivesangegeben 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.hund b.hmacros.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.hnicht 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.ifcund c.h.ifc alle Typen von b.h.c.hb.ha.h Das Kompilieren Source.cpp, das sowohl a.hc.himportiert 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:

  1. Der Scan von a.h und c.h Listen b.h als Headereinheit importieren sie in den Abhängigkeitsscandateien, die vom Compiler generiert werden.
  2. Das Buildsystem liest die Abhängigkeitsscandateien und bestimmt zuerst die Erstellung b.h.ifc .
  3. Anschließend fügt /headerUnitb.h.ifc das Buildsystem den Befehlszeilen zum Kompilieren und c.hKompilieren a.h hinzu. Er ruft den Compiler auf, um die Headereinheiten a.h.ifc und c.h.ifc. Da /translateInclude angegeben und auch angegeben a.h.ifc wird und /headerUnit for b.h.ifcc.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 normal #include behandelt, anstatt sie als Kopfzeileneinheit zu importieren.

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