C++header-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
檔案。