摘要
本文件說明「建構變數」的實作方式: Fuchsia 建構系統,可用於建構「檢測服務」或 針對主機和裝置二進位檔進行特別最佳化的版本。
讀取器必須熟悉 GN toolchain() 執行個體 ,且應閱讀下列文件:
建構變數總覽
Fuchsia 版本定義了數種建構變數類型,例如:
asan
和ubsan
變化版本可用來建構具有下列功能的機器碼: Clang 的 Address Sanitizer 分別為未定義的行為 Sanitizer。 甚至有asan-ubsan
變化版本同時結合了這兩種變數。coverage
變數是用來使用 Clang 的機器碼建構機器碼 啟用檢測型剖析功能,支援程式碼涵蓋率 集合。profile
變數也會用於建構檢測程式碼。 而是支援設定檔導向最佳化功能thinlto
和lto
變化版本可用來建構具有下列功能的二進位檔: 已啟用連結時間最佳化功能。gcc
變數是用來建構 Zircon 的特定部分 採用 GCC 編譯器的核心,而不是 Clang (這非常實用) 歸納出巧妙的機器程式碼產生問題 以的重要方式顯示核心)。release
和debug
變化版本,提供覆寫的變數 預設編譯模式,這個選項取決於args.gn
中的is_debug
建構設定變數。特殊需求的幾個其他變體,全都定義 遵循慣例,在
//build/config/BUILDCONFIG.gn
檔案中 詳見本文件其他部分
一般來說,單一建構變數模型:
一組額外設定,可定義編譯器、組合器或連結器標記 。
要新增至最終的一組選用隱含依附元件 建構圖的變體二進位檔目標 (例如可執行檔、可載入的) 甚至共用程式庫)
以「asan」為例建構變數,可用於 啟用 Clang 的 Address Sanitizer 支援功能。於 練習,使用 Address Sanitizer 建構 Fuchsia 執行程式 enabled 需要 (最低):
將
-fsanitize=address
標記同時傳遞至 Clang 編譯器和連接器 。 C 程式庫)。Asan 執行階段 (
libclang_rt.asan.so
) 可在執行階段使用, 以及本身的依附元件 (例如libc++.so
、libc++abi.so
和libunwind.so
二進位檔)。
基礎和變化版本工具鍊
建構變數一律套用至特定的「基礎」工具鍊
提供變化版本本身的預設設定。
這項操作會建立新的 GN toolchain() 執行個體。
稱為「變化版本工具鍊」,而且有專屬的 root_out_dir
。例如:
//build/toolchain:host_x64
是用於建構的基礎工具鍊 主機二進位檔,且root_out_dir
為${root_build_dir}/host_x64
。//build/toolchain:host_x64-ubsan
是建立的變化版本工具鍊 套用ubsan
變化版本,而其root_out_dir
${root_build_dir}/host_x64-ubsan
。//build/toolchain/fuchsia:x64
是預設工具鍊 (當指定目標時 x64 型裝置),用來建構 Fuchsia 使用者層級二進位檔。因為 預設值與root_build_dir
相同。root_out_dir
//build/toolchain/fuchsia:x64-asan
是由 將asan
變化版本套用至預設工具鍊。目前時間:root_out_dir
將會是${root_build_dir}/x64-asan
。
一般來說,//${tc_dir}:${tc_name}-${variant}
會是
將 ${variant}
變化版本套用至基底建立的變化版本工具鍊
名為 //${tc_dir}:${tc_name}
的工具鍊,而其 root_out_dir
一律為 ${root_build_dir}/${tc_name}-${variant}
。
如果基本工具鍊有shlib 工具鍊, 那麼所有的變化版本工具鍊也會一起使用。最後,單一變化版本 可套用至多個基本工具鍊
例如 //build/toolchain:host_x64-asan
和
//build/toolchain/fuchsia:x64-asan
是已建立的變化版本工具鍊
將相同的 asan
變化版本套用至用於
建構主機和 Fuchsia 裝置二進位檔。
後者也會有 //build/toolchain/fuchsia:x64-asan-shared
用來產生以 ELF 為基礎的共用程式庫的 shlib 工具鍊。
必須在建構作業中使用 clang_toolchain_suite()
定義基礎工具鍊
或 zircon_toolchain_suite()
。兩個範本最後都會呼叫 variant_toolchain_suite()
實作魔法,視需要自動建立變化版本工具鍊。
工具鍊和變化版本標記
Fuchsia 版本中的每個基本工具鍊可以有多個標記;
是任意形式字串,說明工具鍊的屬性。例如:
"kernel"
標記用於表示使用工具鍊建構核心
因為沒有 C 程式庫、沒有標準 C++,所以這點非常重要
資料庫以及一些對特定目標很重要的限制條件
定義)。
所有有效工具鍊標記的清單都位於
//build/toolchain/toolchain_tags.gni
。
同樣地,每個變化版本定義都有多個標記描述屬性
變數的個別內容。舉例來說,"instrumentation"
標記用於
表示這個變化版本會建立可執行執行階段的機器程式碼
檢測設備 (例如消毒液或分析器)
如要查看所有有效變化版本標記及其說明文件,請參閱
//build/toolchain/variant_tags.gni
。
建立變化版本工具鍊時,全域 toolchain_variant.tags
值
包含從基本工具鍊沿用的標記,以及沿用而來的標記
工具鍊變數例項化
建構系統在需要時,只會建立變數工具鍊。
工具鍊和變化版本的可能組合有很多種
而且一次建立所有這些項目會使 gn gen
的運作速度明顯變慢。
建構系統會決定 根據下列條件建立的工具鍊變化版本:
顯示的變化版本選取器清單
select_variant
全域變數。變化版本描述元名稱清單 呼叫 SDK 中的
enable_variants
引數variant_toolchain_suite()
範本。通常用於強制啟用 很少變體。select_variant
例如,用於建構 C 程式庫的工具鍊 ASan 和 UBSan 變化版本 一律會啟用,因為建構核心 Fuchsia IDK 時需要這些資訊 (請參閱
//zircon/system/ulib/c/BUILD.gn
)。顯示在
exclude_variant_tags
敬上variant_toolchain_suite()
的引數。通常可用來排除 避免將變化版本套用至指定基礎工具鍊例如,系統啟動載入程式會排除含有
"instrumented"
的變化版本 標記,因為您無法執行掃毒程式或剖析執行階段 同時啟動裝置 (請參閱 `//
變化版本描述元
變體描述元是一個 GN 範圍,用來說明
向建構系統提交特定建構變化版本定義方式
//build/config/BUILDCONFIG.gn
中的 known_variants
變數,以及
每個範圍都應遵循以下嚴格的結構定義:
configs
:選用的 GN 設定標籤清單,會是 自動新增到包含此變化版本的每個目標中。請注意,這份清單中每項設定
${label}
也都必須 為目標${label}_deps
,每個目標都內建在這個變化版本中 會自動依附於在多數情況下,這會是 空白group()
。remove_common_configs
:選用的 GN 設定標籤清單 從使用 這個變化版本有時這是必要的 建構系統為二進位檔設定的設定不應 特定子類的規格remove_shared_configs
:選用的 GN 設定標籤清單。 與remove_common_configs
相似,但只在 建構shared_library()
目標及其依附元件deps
:選用 GN 目標標籤清單,需 新增為隱含依附元件,並加到所有可連結目標中 使用這個變化版本建構而成name
:用來命名變化版本描述元的字串, 通常用於select_variant
。如果省略name
,configs
不得空白,並會用來產生名稱 (透過彙整 包含破折號)。tags
:用來描述屬性的任意形式字串清單 (選用) 變化版本的變化版本 (請參閱 工具鍊和子類標記。toolchain_args
:選用範圍,每個變數都定義了 此範圍內會覆寫工具鍊結構定義中的建構引數 此變數的 ID 序列host_only
和target_only
:可設為選用範圍的選用範圍 包含上述任一欄位。這些值僅適用於主機或 不同的目標 (即裝置) 工具鍊。任何欄位 也不應位於外部範圍
以下是一些例子:
單一設定的變化版本描述元範例
{
configs = [ "//build/config/lto" ]
tags = [ "lto" ]
}
上述範圍定義了名為 "lto"
的變化版本描述元 (自
範圍中沒有任何 name
鍵,名稱是推斷出
configs
中的值,而且這裡只包含單一項目)。
套用這個變化版本會新增 //build/config/lto:lto
設定。
定義於 //build/config/lto/BUILD.gn
中定義的檔案,而該檔案也應該要
包含 //build/config/lto:lto_deps
空白群組 (如果有的話)
設定沒有隱含依附元件例如:
# //build/config/lto/BUILD.gn
config("lto") {
cflags = [ "-flto" ]
asmflags = cflags
ldflags = cflags
rustflags = [ "-Clto=fat" ]
}
group("lto_deps") {
# Implicit dependencies for "lto" config.
# This is an empty group since there are none.
}
這個描述元使用 "lto"
標記來指出
變化版本已執行連結時間最佳化作業這個標記也可以
由 "thinlto"
描述元使用,而該描述元表示
另一項設定
具有多項設定的變化版本描述元範例
{
configs = [
"//build/config/sanitizers:ubsan",
"//build/config/sanitizers:sancov",
]
remove_common_configs = [ "//build/config:no_rtti" ]
tags = [
"instrumented",
"instrumentation-runtime",
"kernel-excluded",
"sancov",
"ubsan",
]
}
這會定義名為 "ubsan-sancov"
的變化版本描述元 (
名稱衍生自 configs
清單,方法是加入設定
包含破折號名稱),可用於建構能偵測
執行階段未定義的行為,收集程式碼涵蓋率
同時獲取大量資訊
請注意,這也需要 //build/config/sanitizers:ubsan_deps
還有 //build/config/sanitizers:sancov_deps
欄
隱含依附元件
使用時間:remove_common_config
,因為//build/config:no_rtti
是許多基本工具鍊的預設設定之一,但 RTTI
必須先啟用 UBSan 檢測才能正常運作。
此外,使用的代碼清單也更加詳盡。請注意,
"kernel-excluded"
標記,用於防止這個變化版本
以便套用至任何核心機器碼
包含 toolchain_args
的變化版本描述元範例
{
name = "release"
toolchain_args = {
is_debug = false
}
}
此變體描述元已明確命名,但沒有
新增任何設定或依附元件另一方面
全域建構設定變數 is_debug
將
設為 false,藉此變更
在對應的變化版本工具鍊結構定義中定義。
通用變化版本
建構系統中較不為人知的功能稱為「通用變化版本」。這些 是額外的變體描述元,可與其他已知子類結合 運作方式如下:
如果在
args.gn
中設定is_debug=false
,表示所有二進位檔 建構時使用的是最大最佳化,之後則是"debug"
變化版本描述元 是由建構定義而成這可讓您在偵錯模式下建立特定目標,前提是: 無從得知同樣地,如果
is_debug=true
(預設值),則"release"
變數 描述元是由建構定義這樣您就能使用 並視需要使用完整的最佳化功能此外,上述通用變體會與所有其他已知 自動建構變數描述元。例如:如果
is_debug=false
, 建構也會建立"asan-debug"
、"ubsan-debug"
"thinlto-debug"
等。如果is_debug=true
,則會定義"asan-release"
、"ubsan-release"
、"thinlto-release"
等。
請注意,這些變化版本描述元是由建構定義「有條件」。
根據 is_debug
的值。例如:沒有 "release"
變數及其所屬變數
組合 (通常是 is_debug=false
),且沒有 "debug"
變數及其所屬變數
is_debug=true
!
toolchain_variant
全域變數
在 BUILD.gn
或 *.gni
檔案中,全域 toolchain_variant
變數
可用來擷取 current_toolchain
的變化版本相關資訊。
這個範圍具有下列結構定義:
name
:建構變化版本描述元的名稱。這是以下項目的空字串: 基本工具鍊的結構定義,或是能協助預測的變化版本描述元的名稱 而是用於建立目前的 GNtoolchain()
執行個體。各種工具鍊內容的名稱範例:
//build/toolchain/fuchsia:x64 "" //build/toolchain/fuchsia:x64-shared "" //build/toolchain/fuchsia:x64-asan "asan" //build/toolchain/fuchsia:x64-asan-shared "asan"
base
:正式的 GN 標籤,指向基本工具鍊 (即啟用的資料庫)請注意,對於工具鍊變化版本的 shlib 工具鍊, 指向最終基本工具鍊例如://build/toolchain/fuchsia:x64 //build/toolchain/fuchsia:x64 //build/toolchain/fuchsia:x64-asan //build/toolchain/fuchsia:x64 //build/toolchain/fuchsia:x64-shared //build/toolchain/fuchsia:x64 //build/toolchain/fuchsia:x64-asan-shared //build/toolchain/fuchsia:x64
tags
:任意形式字串清單,每個字串都說明 目前的工具鍊執行個體及其變化版本。這只是 工具鍊和子類標記。instrumented
:如果tags
清單是布林值標記,會設為 true 包含"instrumentation"
標記值,方便取代 一些複雜的測試指示,例如:if (toolchain_variant.tags + [ "instrumentation" ] - [ "instrumentation" ] != toolchain_variant.tags) { # toolchain is instrumented ... }
使用:
if (toolchain_variant.instrumented) { # toolchain is instrumented ... }
is_pic_default
:在可建構的工具鍊中,為 true 的布林值 ELF 位置獨立程式碼 (PIC)。這意味著 (例如//build/toolchain/fuchsia:x64-shared
) 或 會直接產生這類程式碼 (例如//zircon/kernel/lib/userabi/userboot:userboot_arm64
)。with_shared
:如果目前工具鍊有 shlib,此佈林值為 true 用於建構 ELF 共用資料庫 (例如//build/toolchain/fuchsia:x64
) 的工具鍊 使用 or 時,請在這類工具鍊中 (例如//build/toolchain/fuchsia:x64-shared
)。configs
、remove_common_configs
、remove_shared_configs
:清單 直接擷取自目前值的config()
個項目 變化版本描述元 (如果有的話),或空白清單。deps
:列出要新增為依附元件的目標 GN 標籤清單 任何可連結的目標,繼承自變化版本描述元本身 (如果有的話)。libprefix
:如果是檢測設備,此為安裝前置字串字串 共用程式庫,否則會是空字串。詳情請參閱 toolchain variant libprefix 一節完整內容 詳細資料。exclude_variant_tags
:由變化版本選取邏輯在內部使用。 從clang_toolchain_suite()
或zircon_toolchain_suite()
沿用 呼叫或直接從目標定義呼叫。這是一種代碼清單 排除要套用至基本工具鍊或目標的變化版本,如下所示 有時是必要性suffix
:這是"-${toolchain_variant.name}"
,如果沒有名稱,則為""
。 用於內部簡化展開作業,無需符合條件。supports_cpp
:如果這個工具鍊支援 C/C++,則為true
的布林值。supports_rust
:如果這個工具鍊支援 Rust,則為true
的布林值。is_basic
:是一個布林值,如果此工具鍊由true
basic_toolchain()
範本,因此不使用任何內建範本 GN 中針對 C/C++ 和 Rust 提供支援。只有copy
或action
個目標。
這個全域變數的內容很少用於目標定義 根據目前的工具鍊內容來改變其設定。這個 尤其是在 C 程式庫、核心產物等 低階目標中 非預先建構的檢測執行階段支援。
Toolchain 變化版本 libprefix
為了能在單一檔案中混用檢測和非檢測的二進位檔 Fuchsia 套件,特殊步驟必須由建構系統執行:
使用「檢測設備」變化版本工具鍊建構的共用程式庫 必須安裝至
"lib/<variant>/"
,而不是預設的"lib/"
位置。可執行的二進位檔必須使用連結器引數 (例如
"-Wl,-dynamic-linker=<variant>/ld.so.1"
:覆寫預設值 ("ld.so.1"
,在 Fuchsia Clang 預建工具鍊二進位檔中以硬式編碼方式編寫)。模糊的建構變數是特殊情況,使用非模糊建構變數 程式庫子目錄的名稱
您可以按照以下方式定義 toolchain_variant.libprefix
變數,以便協助
可以輕鬆支援這些功能:
variant name libdir libprefix note
no variant ---> lib/ "" (default target toolchain)
thinlto ---> lib/ "" (uninstrumented)
asan-ubsan ---> lib/asan-ubsan/ "asan-ubsan/" (instrumented)
asan-fuzzer ---> lib/asan/ "asan/" (instrumented + fuzzing)
可用來判斷安裝位置為 "lib/${toolchain_variant.libprefix}"
並將連結器標記設為 "-Wl,-dynamic-linker=${toolchain_variant.libprefix}ld.so.1"
選取變化版本
Fuchsia 建構系統支援選取
以及個別目標或指定目標群組
或方法是在select_variant
建構設定檔 (args.gn
)。請參考以下範例:
# From out/default/args.gn
...
select_variant = [
{
label = [ "//src/sys/component_manager:bin" ]
variant = "release"
},
"host_asan",
"thinlto/blobfs",
"ubsan",
]
清單中的每個值都是一個運算式,稱為 變化版本選取器,可以是範圍或字串 用於設定建構作業將變化版本套用至不同目標組合的方式。
如果已定義 select_variant
而非空白清單,其值將會
用於判斷如何建立「可連結」目標,例如執行檔、
建構圖中顯示的可載入模組和共用程式庫
基本工具鍊及其所有依附元件的結構定義。
select_variant
中顯示的變化版本選取器會進行比較
並選取第一個符合目前目標的內容。
因此,上述範例意味著:
//src/sys/component/manager:bin
程式二進位檔及其依附元件 建構時應一律使用release
變化版本 (注意:這個範例 這會在gn gen
的時間為is_debug=false
時發生錯誤args.gn
檔案,因為"release"
變數不存在 在此情況下,請參閱「通用變化版本」瞭解原因)。主機二進位檔應在
"asan"
變化版本中建構。 請注意,"host_asan"
並非變化版本描述元名稱,而是 變化版本快速鍵:blobfs
程式裝置二進位檔應一律為 透過"thinlto"
變化版本建構,且會執行連結時間 以及最佳化調整所有其他裝置二進位檔都應使用
"ubsan"
變化版本建構。
變化版本選取器
變化版本選取器是可顯示在全域 select_variant
版本中的值
設定變數。供建構系統用來控制變化版本
在基本工具鍊環境中定義可連結的目標時選擇。
支援以下三種類型的值:
用來為一組指定目標定義一組比對條件的範圍。 該範圍的格式如下:
variant
:特定變化版本描述元的名稱 只有在目前目標與所有條件相符時,才會使用這個值 其他 Deployment 規格label
:如果已定義,則需提供符合資格的 GN 標籤清單 (含:
但沒有工具鍊標籤,例如//src/sys/foo:foo
)。name
:如有定義,系統會列出 GN 標籤目標名稱 (例如名稱)//src/sys/foo:bar
目標的值為「bar」。dir
:如有定義,就會列出 GN 標籤目錄路徑 (例如路徑) 的//src/sys/foo:bar
個目標為"//src/sys/foo"
)。output_name
:如果已定義,則會包含目標output_name
值的清單 (預設為target_name
)。target_type
:經過定義後,就會包含符合目標類型的字串清單。 有效值為:"executable"
、"test"
、"loadable_module"
、"shared_library"
和另外一些服務。testonly
:如果已定義,則為布林值。如果選取器比對目標為 true 只在testonly=true
。如果為 false,選取器會比對不含testonly=true
。host
:如果已定義,則為布林值。如果選取器比對 使用主機工具鍊如果為 false,則選取器會在目標工具鍊中符合。
包含簡單名稱 (例如
"asan"
) 的字串,會指向 變化版本快速指令,是現有舊項目的別名 選取器範圍值例如,
"coverage"
值等同於下列範圍:{ variant = "coverage" host = false }
字串,包含變化版本捷徑名稱和輸出名稱,並以 目錄路徑 (例如
"thintlo/blobfs"
)。這是一種便利的格式, 避免寫入對等的範圍,在先前的 範例如下:{ variant = "thinlto" host = false output_name = [ "blobfs" ] }
select_variant
清單中的選取器順序非常重要:第一個選取器
比對符合目前目標的要求,並決定了指定目標的建構方式。
變化版本快速鍵
除了變化版本描述元外,建構作業也會設定許多「快速鍵」, 為幾個硬式編碼變數選取器範圍值的已命名別名。建構會將 有幾個硬式編碼組合,並從已知變化版本清單中建立其他變數:
"host_asan"
捷徑已定義,可使用"asan"
建構主機二進位檔 子類描述元,在技術上等同於下列 選取器範圍值:# Definition for the `host_asan` variant shortcut [ { variant = "asan" host = true } ]
同樣地,
host_asan-ubsan
、host_coverage
、host_profile
也存在 以及其他幾個工具每個變化版本描述元的名稱都有對應的捷徑 專屬於裝置二進位檔例如:
"ubsan"
快速鍵等同於 加入一個選取器範圍值清單:[ { variant = "ubsan" host = false } ]
這就是在
select_variant
中使用變化版本描述元名稱的原因 只會套用至裝置的二進位檔,例如:# Applies the `ubsan` variant to device binaries, not host ones! select_variant = [ "ubsan", ]
同樣地,每個通用變數及其本身的 也會再次套用至裝置二進位檔。
也就是說,假設
args.gn
中的is_debug=true
, 下列做法會強制在版本內建構所有裝置的二進位檔 模式,而主機端仍會以偵錯模式建構。is_debug = true select_variant = [ "release" ]
等同於:
is_debug = true select_variant = [ { variant = "release" host = false } ]
如要在發布模式中強制主機二進位檔編譯, 可以使用明確範圍值,因為 定義如下:
is_debug = true select_variant = [ { variant = "release" host = true } ]
變化版本目標重新導向
variant_target()
範本
//build/config/BUILDCONFIG.gn
中定義的 variant_target()
範本
實作核心建構變數選取機制。
請勿直接從 BUILD.gn
檔案呼叫這個範本,
Fuchsia 版本定義的包裝函式範本
executable()
、loadable_module()
、shared_library()
和另外一些使用者
對應至可連結的目標 (也就是使用靜態連結建立的
連接器)。
在建構作業的每個工具鍊中,對每個目標的說明
圖表,比較 select_variant
的內容與目標
屬性 (即目標類型和幾個其他引數):
1) 計算「建構工具鍊」也就是 GN 用於建構實際二進位檔 與其依附元件
2) 如果目前的工具鍊是建構工具鍊,只需建構 再照常設定目標
3) 否則,請建立 group()
或 copy()
目標,
重新導向 (即公開依賴) 取決於建構工具鍊中的目標。
這是群組或文案,取決於細微條件
variant_target()
實作中已有的完整說明文件
但請參閱下一節的說明。
必須提供 copy()
目標,才能保留輸出位置
部分可連結目標,而 group()
會在這類情況下使用
不需要。
大多數情況下,executable()
或 loadable_module()
目標
需要 copy()
,而 shared_library()
則需要
改為 group()
可連結變化版本二進位檔的輸出位置
GN 設定語言的一大限制 有些例外,在指定的目標定義完全不知道 瞭解其依附元件這有問題 因為在許多情況下,特定目標必須知道 其依附元件或是這些輸出內容的類型 依附於依附元件
我們舉例說明這個例子:
名為
//src/my/program:bin
的executable()
目標,用於產生 名為my_program
的 Fuchsia 程式二進位檔。基於建構方式 這會產生${root_build_dir}/exe.unstripped/my_program
${root_build_dir}/my_program
和一些次要檔案 (此處忽略)。用來剖析名為
//src/my/program:verify_binary
的action()
目標 程式二進位檔檢查或擷取其資訊 (例如 然後驗證其匯入符號參照)。這個目標必須依附 第一個動作,同時找到二進位檔的輸出位置,如下所示:
action("//src/my/program:verify_imports")
script = "check-my-imports.py"
deps = [ "//src/my/program:bin" ]
inputs = [ get_label_info(deps[0], "root_out_dir") + "/my_program" ]
...
|
| deps
|
v
executable("//src/my/program:bin")
output_name = "my_program"
# outputs: [
${root_build_dir}/exe.unstripped/my_program,
${root_build_dir}/my_program,
]
在這裡,action()
可以透過以下方式猜測程式二進位檔的位置
使用 get_label_info("<label>", "root_out_dir")
做為目錄
並將 output_name
值進行硬式編碼。此舉違反了
但由於 GN 的限制,這是必要的。
啟用建構變數時,二進位檔目標的實際輸出位置
會因select_variant
而變更。如果已導入變化版本重新導向
只要使用簡單的 group()
,圖表就會變成:
action("//src/my/program:verify_imports")
script = "check-my-imports.py"
deps = [ "//src/my/program:bin" ]
inputs = [ get_label_info(deps[0], "root_out_dir") + "/my_program" ]
...
|
| deps
|
v
group("//src/my/program:bin")
|
| public_deps
|
v
executable("//src/my/program:bin(//build/toolchain/fuchsia:x64-asan")
output_name = "my_program"
# outputs: [
# ${root_build_dir}/x64-asan/exe.unstripped/my_program,
# ${root_build_dir}/x64-asan/my_program,
# ]
這個問題是頂層動作中的 inputs
值並未變更。
因此指令會嘗試在舊位置尋找程式二進位檔
(${root_build_dir}/my_program
),而非新的
(${root_build_dir}/x64-asan/my-program
)。因為建構作業會使用過時的構件
或因缺少檔案而失敗
在動作本身中剖析 select_variant
會耗費過多成本,因此解決問題
在這種情況下,可執行檔和可載入的模組目標需要 copy()
目標,而非 group()
,以確保系統會複製未移除的二進位檔
。圖表會變成:
action("//src/my/program:verify_imports")
script = "check-my-imports.py"
deps = [ "//src/my/program:bin" ]
inputs = [ get_label_info(deps[0], "root_out_dir") + "/my_program" ]
...
|
| deps
|
v
copy("//src/my/program:bin")
outputs = [ "${root_build_dir}/my_program" ]
sources = [ "${root_build_dir}/x64-asan/my_program" ]
|
| public_deps
|
v
executable("//src/my/program:bin(//build/toolchain/fuchsia:x64-asan")
output_name = "my_program"
# outputs: [
${root_build_dir}/x64-asan/exe.unstripped/my_program,
${root_build_dir}/x64-asan/my_program,
]
使用此設定時,建構作業一律會成功,且動作指令一律會 正確的二進位檔
這些作業全都會在建構作業中自動完成。最終效果是 相依項目不用考慮其依附元件是否是以 YAML 格式建構 不一定,這些結果就會仰賴輸出位置 至少對未移除的二進位路徑來說。
ELF 共用程式庫的輸出位置
TBW
特殊的 novariant
描述元
TBW
特殊的全域變數
host_toolchain
和 host_out_dir
全域變數
TBW
zircon_toolchain
變數
TBW
variant()
範本
TBW