Udostępnij za pośrednictwem


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.hwartoś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.hbrakuje 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.helementów , b.h i c.h, a następnie skompilowane jednostki a.h.ifcnagłówka , b.h.ifci 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:

  1. Skanowanie a.h elementów i c.h wyświetla je b.h jako import jednostki nagłówka w plikach skanowania zależności generowanych przez kompilator.
  2. System kompilacji odczytuje pliki skanowania zależności i określa, czy należy go skompilować b.h.ifc jako pierwszy.
  3. Następnie system kompilacji dodaje /headerUnit element do b.h.ifc wierszy poleceń do kompilowania a.h i c.h. Wywołuje kompilator, aby skompilować jednostki a.h.ifc nagłówka i c.h.ifc. Ponieważ /translateInclude jest określony i /headerUnit for b.h.ifc jest również określony, a.h.ifc i c.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++