Condividi tramite


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.ifcdi intestazione compilate , b.h.ifce c.h.ifc contengono tutti i tipi da b.h.c.hb.h a.h La compilazione Source.cppdi , 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:

  1. L'analisi di a.h ed c.h elenca b.h come importazione di unità di intestazione nei file di analisi delle dipendenze generati dal compilatore.
  2. Il sistema di compilazione legge i file di analisi delle dipendenze e determina prima di tutto la compilazione b.h.ifc .
  3. Il sistema di compilazione aggiunge /headerUnit quindi per b.h.ifc alle righe di comando per la compilazione a.h e c.h. Chiama il compilatore per compilare le unità a.h.ifc di intestazione e c.h.ifc. Poiché /translateInclude viene specificato e viene specificato a.h.ifc anche /headerUnit for b.h.ifc e c.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++