Informazioni di riferimento sulle header-units.json C++
Il header-units.json
file ha due scopi:
- Specificare quali file di intestazione possono essere convertiti in unità di intestazione quando
/translateInclude
viene specificato. - Ridurre al minimo i simboli duplicati per aumentare la velocità effettiva di compilazione.
Questo file deve trovarsi nella stessa directory del file di intestazione incluso. Questo file viene usato solo quando /translateInclude
viene specificato insieme /scanDependencies
a o /sourceDependencies:directives
.
Spiegazione
Alcuni file di intestazione non possono essere convertiti in modo sicuro in unità di intestazione. I file di intestazione che dipendono da macro non definite dalla riga di comando o che non sono definiti nei file di intestazione inclusi nell'intestazione, non possono essere convertiti in unità di intestazione.
Se un'intestazione definisce macro che influiscono sul fatto che siano incluse altre intestazioni, non può essere tradotta in modo sicuro. Ad esempio, dato a.h
, b.h
e macros.h
, che si trovano tutti nella stessa directory:
// a.h
#include "macros.h" // #defines MACRO=1
#ifdef MACRO
#include "b.h"
#endif
in header-units.json
questa directory può contenere a.h
e b.h
, ma non macros.h
. L'oggetto header-units.json
per questo esempio sarà simile al seguente:
{
"Version": "1.0",
"BuildAsHeaderUnits": [
// macros.h should not be listed
"a.h",
"b.h"
]
}
Il motivo macros.h
per cui non è possibile elencare questo header-units.json
file è che durante la fase di analisi, l'unità di intestazione (.ifc
) potrebbe non essere ancora compilata per macros.h
. In tal caso, MACRO
non verrà definito quando a.h
viene compilato. Ciò significa che b.h
non sarà presente nell'elenco delle dipendenze per a.h
. Poiché non è presente nell'elenco delle dipendenze, il sistema di compilazione non creerà un'unità di intestazione per b.h
nonostante sia elencata nel header-units.json
file.
Per evitare questo problema, quando si verifica una dipendenza da una macro in un altro file di intestazione, il file di intestazione che definisce la macro viene escluso dall'elenco di file che possono essere compilati in un'unità di intestazione. In questo modo il file di intestazione che definisce la macro viene considerato come normale #include
e MACRO
sarà visibile in modo che b.h
sia incluso e elencato come una delle dipendenze.
Prevenzione dei simboli duplicati
Il header-units.json
file è importante anche perché consente la creazione automatica dell'unità di intestazione senza simboli duplicati. A tale scopo, creare unità di intestazione "atomic" per i file elencati in header-units.json
. Le unità di intestazione importate non contengono simboli duplicati dalle varie #include
direttive elaborate durante la conversione del file di intestazione.
Si considerino ad esempio due file di intestazione che includono entrambi un file di intestazione comune. Entrambi i file di intestazione sono inclusi nello stesso file di origine:
// a.h
#include "b.h"
// c.h
#include "b.h"
// Source.cpp
import "a.h";
import "c.h";
Se il compilatore ha compilato unità di intestazione per , e , le unità a.h.ifc
di intestazione compilate , b.h.ifc
e c.h.ifc
contengono tutti i tipi da b.h
.c.h
b.h
a.h
La compilazione Source.cpp
di , che importa sia a.h
e c.h
, richiede al compilatore di deduplicare i b.h
tipi, che influirebbero sulle prestazioni di compilazione.
Tuttavia, se nella directory è presente un header-units.json
b.h
oggetto e /translateInclude
viene specificato , si verifica quanto segue:
- L'analisi di
a.h
edc.h
elencab.h
come importazione di unità di intestazione nei file di analisi delle dipendenze generati dal compilatore. - Il sistema di compilazione legge i file di analisi delle dipendenze e determina prima di tutto la compilazione
b.h.ifc
. - Il sistema di compilazione aggiunge
/headerUnit
quindi perb.h.ifc
alle righe di comando per la compilazionea.h
ec.h
. Chiama il compilatore per compilare le unitàa.h.ifc
di intestazione ec.h.ifc
. Poiché/translateInclude
viene specificato e viene specificatoa.h.ifc
anche/headerUnit for b.h.ifc
ec.h.ifc
non conterràb.h
tipi, quindi non ci sarà alcuna duplicazione nelle unità di intestazione prodotte.
Schema
È disponibile un headerunits.json
file per le intestazioni STL (Standard Template Library). Il sistema di compilazione lo usa per determinare se creare un'unità di intestazione per un file di intestazione STL e per le relative dipendenze. Se il file di intestazione STL non è presente nell'elenco, viene considerato come normale #include
anziché importarlo come unità di intestazione.
È possibile visualizzare il header-units.json
file nella directory di installazione per Visual Studio. Ad esempio: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json
Il header-units.json
file inizia con la versione dello schema, seguita da una matrice di nomi file per le intestazioni che possono essere incorporate in unità di intestazione.
Lo schema supporta anche i commenti, come illustrato di seguito:
{
"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
...
}
Cerca regole
Il compilatore cerca questo file nella stessa directory del file di intestazione in fase di elaborazione. Se la libreria è organizzata in sottodirectory, ogni sottodirectory necessita di un proprio header-units.json
file.
Vedi anche
Procedura dettagliata: Importare librerie STL come unità di intestazione
Procedura dettagliata: Compilare e importare unità di intestazione nei progetti Visual C++