C++ 標頭 units.json 參考
檔案 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
,但不能 macros.h
包含 a.h
。 header-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.h
和 c.h
的標頭單位,則編譯的標頭單位 a.h.ifc
、 b.h.ifc
和 c.h.ifc
都會包含 來自 b.h
的所有型別。 Source.cpp
編譯 會同時匯 a.h
入 和 c.h
,會要求編譯器重復資料刪除類型,這會影響建置 b.h
效能。
但是,如果 目錄中有 header-units.json
b.h
,而且 /translateInclude
已指定 ,則會發生下列情況:
a.h
在編譯器所產生的相依性掃描檔案中,將 和c.h
清單列為b.h
標頭單位匯入。- 建置系統會讀取相依性掃描檔案,並決定先建置
b.h.ifc
。 - 然後,建置系統會將 的
b.h.ifc
新增/headerUnit
至用於編譯a.h
和c.h
的命令列。 它會呼叫編譯器來建置標頭單位a.h.ifc
和c.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
檔案。
另請參閱
意見反映
https://aka.ms/ContentUserFeedback。
即將推出:我們會在 2024 年淘汰 GitHub 問題,並以全新的意見反應系統取代並作為內容意見反應的渠道。 如需更多資訊,請參閱:提交及檢視以下的意見反映: