Referencia C++ header-units.json
El archivo header-units.json
tiene dos fines:
- Especifique qué archivos de encabezado se pueden trasladar a unidades de encabezado cuando se especifica
/translateInclude
. - Minimice los símbolos duplicados para aumentar el rendimiento de la compilación.
Este archivo debe de estar en el mismo directorio que el archivo de encabezado incluido. Este archivo solo se usa cuando /translateInclude
se especifica con /scanDependencies
o /sourceDependencies:directives
.
Análisis razonado
Algunos archivos de encabezado no se pueden trasladar con seguridad a unidades de encabezado. Los archivos de encabezado que dependen de las macros que no están definidas en la línea de comandos o que no están definidas en los archivos de encabezado incluidos por el encabezado, no se pueden trasladar a unidades de encabezado.
Si un encabezado define las macros que afectan a si se incluyen otros encabezados, no se puede trasladar con seguridad. Por ejemplo, considerando que a.h
, b.h
y macros.h
, están en el mismo directorio:
// a.h
#include "macros.h" // #defines MACRO=1
#ifdef MACRO
#include "b.h"
#endif
El header-units.json
este directorio puede contener a.h
y b.h
, pero no macros.h
. El header-units.json
para este ejemplo sería parecido a esto:
{
"Version": "1.0",
"BuildAsHeaderUnits": [
// macros.h should not be listed
"a.h",
"b.h"
]
}
El motivo macros.h
por el que no se puede enumerar en este archivo header-units.json
es porque, durante la fase de examen, es posible que la unidad de encabezado (.ifc
) todavía no se compile para macros.h
. En ese caso, MACRO
no se definirá cuando se compile a.h
. Esto significa que b.h
faltará en la lista de dependencias de a.h
. Dado que no está en la lista de dependencias, el sistema de compilación no compilará una unidad de encabezado para b.h
a pesar de que se muestre en el header-units.json
archivo.
Para evitar este problema, cuando hay una dependencia de una macro en otro archivo de encabezado, el archivo de encabezado que define la macro se excluye de la lista de archivos que se pueden compilar en una unidad de encabezado. De este modo, el archivo de encabezado que define la macro se trata como normal #include
y MACRO
estará visible para que b.h
se incluya y aparezca como una de las dependencias.
Evitar los símbolos duplicados
El archivo header-units.json
también es importante porque permite la creación automática de unidades de encabezado sin símbolos duplicados. Para ello, crea unidades de encabezado "atómicas" para los archivos listados en header-units.json
. Las unidades de encabezado importadas no contienen los símbolos duplicados de las distintas directivas #include
que se han procesado al trasladar el archivo de encabezado.
Por ejemplo, considere dos archivos de encabezado que incluyan un archivo de encabezado común. Los dos archivos de encabezado están incluidos en el mismo archivo de código fuente:
// a.h
#include "b.h"
// c.h
#include "b.h"
// Source.cpp
import "a.h";
import "c.h";
Si el compilador compila las unidades de encabezado para a.h
, b.h
y c.h
, entonces las unidades de cabecera compiladas a.h.ifc
, b.h.ifc
y c.h.ifc
contienen cada una todos los tipos de b.h
. Compilar Source.cpp
que importa tanto a.h
como c.h
, requeriría que el compilador desduplique los tipos b.h
, lo que afectaría al rendimiento de la compilación.
Pero si hay un header-units.json
elemento en el b.h
directorio y /translateInclude
se especifica, se produce lo siguiente:
- El examen de
a.h
yc.h
enumerab.h
como una importación de unidad de encabezado en los archivos de examen de dependencias generados por el compilador. - El sistema de compilación lee los archivos de examen de dependencias y determina primero compilar
b.h.ifc
. - Entonces, el sistema de compilación agrega
/headerUnit
parab.h.ifc
a las líneas de comandos para compilara.h
yc.h
. Llama al compilador para compilar las unidades de encabezadoa.h.ifc
yc.h.ifc
. Dado que se especifica/translateInclude
y también/headerUnit for b.h.ifc
,a.h.ifc
yc.h.ifc
no contendrá los tiposb.h
, por lo que no habrá ninguna duplicación en las unidades de encabezado generadas.
Esquema
Hay un archivo headerunits.json
para los encabezados de la Biblioteca de plantillas estándar (STL). El sistema de compilación lo usa para determinar si se crea una unidad de encabezado para un archivo de encabezado STL y para sus dependencias. Si el archivo de encabezado de STL no está en la lista, se trata como #include
normal en lugar de importarlo como una unidad de encabezado.
Puede ver el archivo header-units.json
en el directorio de instalación de Visual Studio. Por ejemplo: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json
El archivo header-units.json
comienza con la versión del esquema, seguida de una matriz de nombres de archivo para los encabezados que se pueden integrar en las unidades de encabezado.
El esquema también admite los comentarios, como se muestra aquí:
{
"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
...
}
Buscar reglas
El compilador busca este archivo en el mismo directorio que el archivo de encabezado que se está procesando. Si la biblioteca se organiza en subdirectorios, cada subdirectorio necesita su propio archivo header-units.json
.
Consulte también
Tutorial: Importación de bibliotecas STL como unidades de encabezado
Tutorial: Compilación e importación de unidades de encabezado en proyectos de Visual C++