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

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

  • が指定されている場合に /translateInclude 、ヘッダー単位に変換できるヘッダーファイルを指定します。
  • 重複するシンボルを最小化すると、ビルドのスループットが向上します。

このファイルは、インクルードされているヘッダーファイルと同じディレクトリに存在する必要があります。 このファイルは、がまたは /sourceDependencies:directives と共に指定されて /scanDependencies いる場合に /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.h を含むことができますが、は含める a.h ことはできません macros.h 。 この例のは、 header-units.json 次のようになります。

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

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

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

重複するシンボルの防止

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

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

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

コンパイラが、、およびの a.h ヘッダー単位を構築した場合、コンパイル済みのヘッダー単位 a.h.ifcb.h.ifc 、、および c.h.ifc には、それぞれの型 b.h が含まれ c.h ます。 b.hc.h の両方 a.h をインポートするコンパイル Source.cpp では、コンパイラが型を重複除去 b.h する必要があります。これは、ビルドのパフォーマンスに影響を与えます。

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

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

スキーマ

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++ プロジェクトでヘッダー ユニットをビルドしてインポートする