次の方法で共有


C++ header-units.json のリファレンス

このファイルには header-units.json 、次の 2 つの目的があります。

  • 指定時 /translateInclude にヘッダー単位に変換できるヘッダー ファイルを指定します。
  • 重複するシンボルを最小限に抑えて、ビルドのスループットを向上させます。

このファイルは、含まれているヘッダー ファイルと同じディレクトリに存在する必要があります。 このファイルは、いずれか/scanDependenciesまたは/sourceDependencies:directives一緒に指定されている場合/translateIncludeにのみ使用されます。

理由

一部のヘッダー ファイルは、ヘッダー ユニットに安全に変換できません。 コマンド ラインで定義されていないマクロに依存するヘッダー ファイル、またはヘッダーに含まれるヘッダー ファイルで定義されていないヘッダー ファイルは、ヘッダー ユニットに変換できません。

ヘッダーが他のヘッダーを含めるかどうかに影響するマクロを定義している場合、安全に変換することはできません。 たとえば、 a.hすべて同じディレクトリ内にある場合 b.h 、次 macros.hのようになります。

// a.h

#include "macros.h" // #defines MACRO=1
#ifdef MACRO
#include "b.h"
#endif

header-units.jsonこのディレクトリには、次を含b.ha.hめることができますが、含まれませんmacros.hheader-units.jsonこの例は次のようになります。

{
    "Version": "1.0",
    "BuildAsHeaderUnits": [
        // macros.h should not be listed
        "a.h",
        "b.h"         
     ] 
}

このheader-units.jsonファイルに一覧表示できない理由macros.hは、スキャン フェーズ中にヘッダー ユニット (.ifc) がまだmacros.hコンパイルされていない可能性があるためです。 その場合、 MACRO コンパイル時 a.h には定義されません。 b.hつまり、依存関係a.hの一覧には表示されません。 依存関係の一覧に含まれていないため、ビルド システムでは、ファイルに一覧表示されているにもかかわらず、ヘッダー ユニット b.hheader-units.json ビルドされません。

この問題を回避するために、別のヘッダー ファイル内のマクロに依存関係がある場合、そのマクロを定義するヘッダー ファイルは、ヘッダー ユニットにコンパイルできるファイルの一覧から除外されます。 このように、マクロを定義するヘッダー ファイルは通常#includeMACROのファイルとして扱われ、依存関係の 1 つとして含まれて一覧表示されるようにb.h表示されます。

重複するシンボルの防止

また header-units.json 、重複したシンボルを使用せずにヘッダー ユニットを自動的に作成できるため、このファイルも重要です。 これは、次に示す header-units.jsonファイルの "アトミック" ヘッダー ユニットを作成することによって行われます。 インポートされたヘッダー ユニットには、ヘッダー ファイルの変換中に処理されたさまざまな #include ディレクティブの重複したシンボルは含まれません。

たとえば、両方に共通のヘッダー ファイルを含む 2 つのヘッダー ファイルがあるとします。 両方のヘッダー ファイルは、同じソース ファイルに含まれています。

// a.h
#include "b.h"
 
// c.h
#include "b.h"
 
// Source.cpp
import "a.h";
import "c.h";

コンパイラが 、b.hおよびコンパイルされたヘッダー ユニットに対a.hしてc.hヘッダー ユニットをビルドし、b.h.ifcc.h.ifcそれぞれのヘッダー ユニットa.h.ifcに含まれるすべての型b.hが含まれる場合。 両方a.hc.hSource.cppインポートするコンパイルでは、コンパイラが型を重複b.h除去する必要があり、ビルドのパフォーマンスに影響します。

ただし、ディレクトリにb.h存在header-units.json/translateInclude、指定されている場合は、次の処理が行われます。

  1. コンパイラによって生成された依存関係スキャン ファイル内のヘッダー ユニット インポートのスキャン a.hc.h 一覧 b.h
  2. ビルド システムは依存関係スキャン ファイルを読み取り、最初にビルド b.h.ifc することを決定します。
  3. その後、ビルド システムがコンパイルa.h用のコマンド ラインに追加/headerUnitb.h.ifcされ、.c.h コンパイラを呼び出してヘッダー ユニット a.h.ifcc.h.ifc. /translateInclude指定され/headerUnit for b.h.ifc、指定され、c.h.ifca.h.ifc型が含b.hまれていないため、生成されたヘッダー ユニットに重複はありません。

[スキーマ]

headerunits.json標準テンプレート ライブラリ (STL) ヘッダー用のファイルがあります。 ビルド システムはそれを使用して、STL ヘッダー ファイルとその依存関係のヘッダー ユニットを作成するかどうかを決定します。 STL ヘッダー ファイルがリストにない場合、ヘッダー ユニットとしてインポートするのではなく、通常の #include ファイルとして扱われます。

Visual Studio の header-units.json インストール ディレクトリの下にファイルが表示されます。 例: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json

ファイルは header-units.json スキーマ バージョンで始まり、その後にヘッダー単位に組み込むことができるヘッダーのファイル名の配列が続きます。

スキーマでは、次に示すようにコメントもサポートされています。

{
    "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
        ...
}

規則の検索

コンパイラは、処理中のヘッダー ファイルと同じディレクトリでこのファイルを検索します。 ライブラリがサブディレクトリに編成されている場合、各サブディレクトリには独自のファイルが必要です header-units.json

関連項目

チュートリアル: STL ライブラリをヘッダ ーユニットとしてインポートする
チュートリアル: Visual C++ プロジェクトでヘッダー ユニットをビルドしてインポートする