Dokumentacja header-units.json języka C++
Plik header-units.json
służy do dwóch celów:
- Określ, które pliki nagłówka można przetłumaczyć na jednostki nagłówka po
/translateInclude
określeniu. - Zminimalizować zduplikowane symbole, aby zwiększyć przepływność kompilacji.
Ten plik musi znajdować się w tym samym katalogu co dołączony plik nagłówka. Ten plik jest używany tylko wtedy, gdy /translateInclude
jest określony razem z elementem /scanDependencies
lub /sourceDependencies:directives
.
Uzasadnienie
Niektóre pliki nagłówkowe nie mogą być bezpiecznie tłumaczone na jednostki nagłówka. Pliki nagłówkowe, które są zależne od makr, które nie są zdefiniowane w wierszu polecenia lub które nie są zdefiniowane w plikach nagłówka zawartych w nagłówku, nie można przetłumaczyć na jednostki nagłówka.
Jeśli nagłówek definiuje makra, które mają wpływ na to, czy inne nagłówki są uwzględniane, nie można go bezpiecznie przetłumaczyć. Na przykład podane a.h
wartości , b.h
i macros.h
, które znajdują się w tym samym katalogu:
// a.h
#include "macros.h" // #defines MACRO=1
#ifdef MACRO
#include "b.h"
#endif
Element header-units.json
w tym katalogu może zawierać elementy a.h
i b.h
, ale nie macros.h
. W header-units.json
tym przykładzie będzie to podobne do następującego:
{
"Version": "1.0",
"BuildAsHeaderUnits": [
// macros.h should not be listed
"a.h",
"b.h"
]
}
Przyczyną macros.h
, dla którego nie można wymienić tego header-units.json
pliku, jest to, że w fazie skanowania jednostka nagłówka (.ifc
) może nie zostać jeszcze skompilowana dla elementu macros.h
. W takim przypadku MACRO
nie będzie definiowany podczas a.h
kompilowania. Oznacza to b.h
, że na liście zależności dla elementu a.h
brakuje elementu . Ponieważ nie znajduje się ona na liście zależności, system kompilacji nie skompiluje jednostki nagłówka, b.h
mimo że jest on wymieniony w header-units.json
pliku.
Aby uniknąć tego problemu, gdy istnieje zależność od makra w innym pliku nagłówka, plik nagłówka definiujący makro jest wykluczony z listy plików, które można skompilować w jednostce nagłówka. Dzięki temu plik nagłówka definiujący makro jest traktowany jako normalny #include
i MACRO
będzie widoczny, tak aby b.h
został uwzględniony i wymieniony jako jeden z zależności.
Zapobieganie zduplikowanym symbolom
Plik header-units.json
jest również ważny, ponieważ umożliwia automatyczne tworzenie jednostek nagłówka bez zduplikowanych symboli. W tym celu należy utworzyć jednostki nagłówka "niepodzielne" dla plików wymienionych w pliku header-units.json
. Zaimportowane jednostki nagłówka nie zawierają zduplikowanych symboli z różnych #include
dyrektyw, które zostały przetworzone podczas tłumaczenia pliku nagłówka.
Rozważmy na przykład dwa pliki nagłówkowe, które zawierają wspólny plik nagłówka. Oba pliki nagłówków są dołączane przez ten sam plik źródłowy:
// a.h
#include "b.h"
// c.h
#include "b.h"
// Source.cpp
import "a.h";
import "c.h";
Jeśli kompilator skompilował jednostki nagłówka dla a.h
elementów , b.h
i c.h
, a następnie skompilowane jednostki a.h.ifc
nagłówka , b.h.ifc
i c.h.ifc
będą zawierać wszystkie typy z .b.h
Kompilowanie Source.cpp
, które importuje zarówno , a.h
jak i c.h
, wymagałoby, aby kompilator deduplikował b.h
typy, co miałoby wpływ na wydajność kompilacji.
Jeśli jednak istnieje header-units.json
element w b.h
katalogu i /translateInclude
zostanie określony, wystąpią następujące czynności:
- Skanowanie
a.h
elementów ic.h
wyświetla jeb.h
jako import jednostki nagłówka w plikach skanowania zależności generowanych przez kompilator. - System kompilacji odczytuje pliki skanowania zależności i określa, czy należy go skompilować
b.h.ifc
jako pierwszy. - Następnie system kompilacji dodaje
/headerUnit
element dob.h.ifc
wierszy poleceń do kompilowaniaa.h
ic.h
. Wywołuje kompilator, aby skompilować jednostkia.h.ifc
nagłówka ic.h.ifc
. Ponieważ/translateInclude
jest określony i/headerUnit for b.h.ifc
jest również określony,a.h.ifc
ic.h.ifc
nie będzie zawieraćb.h
typów, więc nie będzie żadnych duplikacji w wygenerowanych jednostkach nagłówka.
Schemat
headerunits.json
Istnieje plik nagłówków standardowej biblioteki szablonów (STL). System kompilacji używa go do określenia, czy utworzyć jednostkę nagłówka dla pliku nagłówka STL i dla jego zależności. Jeśli plik nagłówka STL nie znajduje się na liście, jest traktowany jako normalny #include
, zamiast importować go jako jednostkę nagłówka.
Plik można wyświetlić header-units.json
w katalogu instalacyjnym programu Visual Studio. Na przykład: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json
.
Plik header-units.json
rozpoczyna się od wersji schematu, a następnie tablicy nazw plików nagłówków, które mogą być wbudowane w jednostki nagłówków.
Schemat obsługuje również komentarze, jak pokazano poniżej:
{
"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
...
}
Reguły wyszukiwania
Kompilator szuka tego pliku w tym samym katalogu co przetwarzany plik nagłówkowy. Jeśli biblioteka jest zorganizowana w podkatalogi, każdy podkatalog potrzebuje własnego header-units.json
pliku.
Zobacz też
Przewodnik: importowanie bibliotek STL jako jednostek nagłówka
Przewodnik: kompilowanie i importowanie jednostek nagłówków w projektach Visual C++