分享方式:


C++ 標頭 units.json 參考

檔案 header-units.json 有兩個用途:

  • 指定指定時 /translateInclude ,哪些標頭檔可以轉譯成標頭單位。
  • 將重複的符號降到最低,以增加建置輸送量。

這個檔案必須與包含的標頭檔位於相同的目錄中。 只有在與 或 /sourceDependencies:directives 一起 /scanDependencies 指定時 /translateInclude ,才會使用此檔案。

基本原理

某些標頭檔無法安全地轉譯為標頭單位。 相依于命令列上未定義的宏,或未在標頭包含之標頭檔中定義的標頭檔,無法轉譯為標頭單位的標頭檔。

如果標頭定義會影響是否包含其他標頭的宏,則無法安全地轉譯。 例如,給定 a.h 的 、 b.hmacros.h ,全都位於相同的目錄中:

// a.h

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

header-units.json此目錄中的 可以包含 和 b.h ,但不能 macros.h 包含 a.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.h ,儘管它列在檔案中 header-units.json

為了避免這個問題,當另一個標頭檔中的宏相依性時,定義宏的標頭檔會從可編譯為標頭單位的檔案清單中排除。 如此一來,定義宏的標頭檔會被視為一般 #include ,而且 MACRO 將可見, b.h 以便包含並列為其中一個相依性。

防止重複的符號

檔案 header-units.json 也很重要,因為它允許自動建立標頭單位,而不需要重複的符號。 其方式是建立中 header-units.json 所列檔案的「不可部分完成」標頭單位。 匯入的標頭單位不包含轉譯標頭檔時所處理之各種 #include 指示詞的重複符號。

例如,請考慮兩個標頭檔,這兩個標頭檔都包含通用標頭檔。 這兩個標頭檔都包含在相同的原始程式檔中:

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

如果編譯器建 a.h 置 、 b.hc.h 的標頭單位,則編譯的標頭單位 a.h.ifcb.h.ifcc.h.ifc 都會包含 來自 b.h 的所有型別。 Source.cpp編譯 會同時匯 a.h 入 和 c.h ,會要求編譯器重復資料刪除類型,這會影響建置 b.h 效能。

但是,如果 目錄中有 header-units.jsonb.h ,而且 /translateInclude 已指定 ,則會發生下列情況:

  1. a.h在編譯器所產生的相依性掃描檔案中,將 和 c.h 清單列為 b.h 標頭單位匯入。
  2. 建置系統會讀取相依性掃描檔案,並決定先建置 b.h.ifc
  3. 然後,建置系統會將 的 b.h.ifc 新增 /headerUnit 至用於編譯 a.hc.h 的命令列。 它會呼叫編譯器來建置標頭單位 a.h.ifcc.h.ifc 。 因為 /translateInclude 已指定 ,而且 /headerUnit for b.h.ifc 也會指定 a.h.ifc ,而且 c.h.ifc 不會包含 b.h 類型,因此產生的標頭單位中不會有任何重複專案。

結構描述

標準範本庫 (STL) 標頭有檔案 headerunits.json 。 建置系統會使用它來判斷是否要建立 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++ 專案中建置和匯入標頭單位