Args

這個物件使用能夠節省記憶體的方式封裝,構成部分或所有指令列所需的資料。

動作需要一個大型指令列,其中包含從遞移依附元件中累積的值。舉例來說,連結器指令列可能針對所有連結的程式庫,列出所需的每個物件檔案。最佳做法是將這類遞移資料儲存在 depset 中,以便讓多個目標共用。然而,如果規則作者必須將這些解碼器轉換為字串清單,才能建立動作指令列,就會擊敗記憶體共用最佳化。

因此,動作建構函式除了字串之外,還接受 Args 物件。每個 Args 物件都代表一段字串和解組的串連,並可選擇轉換來操控資料。Args 物件不會在執行階段處理封裝到執行階段,也就是在計算指令列時。這樣一來,所有昂貴的複製作業都會延後到分析階段完成後。詳情請參閱最佳化效能頁面。

Args 是透過呼叫 ctx.actions.args() 建構。且能以 ctx.actions.run()ctx.actions.run_shell()arguments 參數傳遞。Args 物件的每個異動都會將值附加至最終指令列。

map_each 功能可讓您自訂項目轉換為字串的方式。如果未提供 map_each 函式,標準轉換如下:

  • 已經是字串的值會保持原樣。
  • File 物件會轉成 File.path 值。
  • 所有其他類型都會以「未指定」的方式轉換為字串。因此,您應避免將非字串或 File 類型的值傳遞至 add(),而且如果傳遞至 add_all()add_joined(),則應提供 map_each 函式。

使用字串格式 (add*() 方法的 formatformat_eachformat_joined 參數) 時,格式範本的解讀方式與字串上的 % 替代項目相同,只是範本必須有一個替換預留位置,且必須是 %s。常值百分比可能會逸出為 %%。在值轉換為字串後 (如上文所述),系統會套用格式設定。

每個 add*() 方法都有替代形式,可接受額外的位置參數;要在其餘引數之前插入「引數名稱」字串。如果是 add_alladd_joined 的序列為空白,則不會新增額外字串。舉例來說,相同的用法可以在指令列中新增 --foo val1 val2 val3 --bar 或僅加入 --bar,視指定序列包含 val1..val3 或空白而定。

如果指令列大小的成長大於系統允許的大小上限,則可將引數溢出至參數檔案。請參閱 use_param_file()set_param_file_format()

範例:假設要產生指令列:

--foo foo1.txt foo2.txt ... fooN.txt --bar bar1.txt,bar2.txt,...,barM.txt --baz
可以使用下列 Args 物件:
# foo_deps and bar_deps are depsets containing
# File objects for the foo and bar .txt files.
args = ctx.actions.args()
args.add_all("--foo", foo_deps)
args.add_joined("--bar", bar_deps, join_with=",")
args.add("--baz")
ctx.actions.run(
  ...
  arguments = [args],
  ...
)

會員

add

Args Args.add(arg_name_or_value, value=unbound, *, format=None)

在這個指令列中附加引數。

參數

參數 說明
arg_name_or_value 必要
如果傳遞兩個位置參數,系統會將此解讀為引數名稱。引數名稱是在值之前新增,不會經過任何處理。如果只傳遞一個位置參數,系統會將其解讀為 value (請參閱下方說明)。
value default = unbound
要附加的物件。系統會使用上述標準轉換,將其轉換為字串。由於這個函式沒有 map_each 參數,因此 value 應為字串或 File。您必須將清單、元組、 depset 或目錄 File 傳遞至 add_all()add_joined(),而不是使用此方法。
format string; or None; default = None
要套用至 value 字串化版本的格式字串模式。

add_all

Args Args.add_all(arg_name_or_values, values=unbound, *, map_each=None, format_each=None, before_each=None, omit_if_empty=True, uniquify=False, expand_directories=True, terminate_with=None, allow_closure=False)

在這個指令列中附加多個引數。系統會在執行階段延後處理項目。

處理過程大多是在要附加的引數清單上進行,如下所示:

  1. 每個目錄 File 項目都會替換為該目錄中包含的所有 File 以遞迴方式取代。
  2. 如果指定 map_each,該值會套用至每個項目,而產生的字串清單會串連以形成初始引數清單。否則,初始引數清單即是每個項目套用標準轉換的結果。
  3. 清單中的每個引數都會有 format_each 的格式 (如果有的話)。
  4. 如果 uniquify 為 true,系統會移除重複的引數。第一次出現是留下的。
  5. 如果指定 before_each 字串,系統會將該字串以新引數插入清單中的每個現有引數之前。這樣就能有效將在此點附加的引數數量加倍。
  6. 除了清單空白且 omit_if_empty 為 true (預設值) 以外,引數名稱和 terminate_with 會分別插入做為第一個和最後一個引數 (如有指定)。
請注意,空字串是有效引數,必須遵循上述所有處理步驟。

參數

參數 說明
arg_name_or_values 必要
如果傳遞兩個位置參數,系統會將此解讀為引數名稱。新增的引數名稱在 values 之前沒有任何處理。如果 omit_if_empty 為 true (預設值),且未附加其他項目 (正如 values 為空白或已篩選其所有項目),則不會新增這個引數名稱。如果只傳遞一個位置參數,系統會將其解讀為 values (請參閱下方說明)。
values sequence; or depset; default = unbound
將附加項目的清單、元組或 depset。
map_each callable; or None; default = None
可將每個項目轉換為零或多個字串的函式,這個函式可以先處理再附加。如果未提供此參數,系統會採用標準轉換。

函式會傳遞一或兩個位置引數:要轉換的項目,然後是選用的 DirectoryExpander。只有在提供的函式是由使用者定義 (非內建) 並宣告多個參數時,才會傳遞第二個引數。

回傳值的類型取決於要為項目產生的引數數量:

  • 在一般情況下,每個項目成為一個字串時,函式應傳回該字串。
  • 如果項目必須遭到徹底篩除,函式應傳回 None
  • 如果該項目變成多個字串,則函式會傳回這些字串的清單。
傳回單一字串或 None,效果等同於傳回長度為 1 或長度 0 的清單。但比較有效率且易於讀取,避免在不需要的地方建立清單。

一般來說,設定 expand_directories=True 時,目錄項目會自動擴展至內容。不過,這不會展開其他值中包含的目錄,例如項目是將目錄當做欄位的結構時。在這種情況下,可套用 DirectoryExpander 引數,手動取得指定目錄的檔案。

為避免意外將大型分析階段資料結構保留至執行階段,您必須透過頂層 def 陳述式宣告 map_each 函式;這可能不是巢狀函式預設關閉狀態。

警告:呼叫 map_each 期間執行的 print() 陳述式不會產生任何可見的輸出內容。

format_each string; or None; default = None
選用格式字串模式,套用至 map_each 函式傳回的每個字串。格式字串只能有一個「%s」預留位置。
before_each string; or None; default = None
在附加每個從 values 衍生的引數之前附加的選用字串。
omit_if_empty default = True
如果為 true,如果沒有從 values 衍生的引數可附加,則系統會封鎖所有後續處理程序,且指令列將維持不變。如果為 false,即使有其他引數,系統仍會附加引數名稱和 terminate_with (如有提供)。
uniquify default = False
如果設為 true,系統會省略從 values 衍生的重複引數。系統只會保留每個引數的第一次出現次數。由於依附元件已省略重複項目,因此通常不需要這項功能,不過如果 map_each 針對多個項目發出相同的字串,這項功能就能派上用場。
expand_directories default = True
如果設為 true,values 中的所有目錄都會展開為平面檔案清單。這項操作會在系統套用 map_each 前發生。
terminate_with string; or None; default = None
要附加在所有其他引數後方的選用字串。如果 omit_if_empty 為 true (預設值),且未附加其他項目 (與 values 空白或所有項目都經過篩選時一樣),系統不會新增這個字串。
allow_closure default = False
如果設為 true,則允許在 map_each 等函式參數中使用閉包。通常不需要執行這項作業,而且可能會使將大型分析階段的資料結構保留至執行階段。

add_joined

Args Args.add_joined(arg_name_or_values, values=unbound, *, join_with, map_each=None, format_each=None, format_joined=None, omit_if_empty=True, uniquify=False, expand_directories=True, allow_closure=False)

使用分隔符串連多個值,藉此將引數附加至這個指令列。系統會在執行階段延後處理項目。

處理程序與 add_all() 類似,但從 values 衍生的引數清單會合併成單一引數,就和由 join_with.join(...) 一樣,然後使用指定的 format_joined 字串範本格式化。與 add_all() 不同,before_eachterminate_with 參數在項目合併為單一引數時通常不實用。

如果篩選後沒有可彙整到引數的字串,且 omit_if_empty 為 true (預設值),系統就不會執行任何處理作業。否則,如果沒有可彙整的字串,但 omit_if_empty 為 false,已彙整的字串會是空字串。

參數

參數 說明
arg_name_or_values 必要
如果傳遞兩個位置參數,系統會將此解讀為引數名稱。引數名稱是在 values 之前新增,沒有任何處理。如果 omit_if_empty 為 true (預設值),且沒有衍生自 values 可彙整的字串 (如果 values 空白或已篩選其所有項目),則不會新增這個引數。如果只傳遞一個位置參數,系統會將其解讀為 values (請參閱下方說明)。
values sequence; or depset; default = unbound
將彙整其項目的清單、元組或補償組。
join_with 必要
分隔符號字串,用於彙整從套用 map_eachformat_each 取得的字串,方式與 string.join() 相同。
map_each callable; or None; default = None
add_all 相同。
format_each string; or None; default = None
add_all 相同。
format_joined string; or None; default = None
套用至已聯結字串的選用格式字串模式。格式字串只能有一個「%s」預留位置。
omit_if_empty default = True
如果為 true,如果沒有可彙整的字串 (因為 values 空白或遭篩選的所有項目),系統會封鎖所有後續處理,且指令列不會變更。若為 false,即使沒有可彙整的字串,系統仍會附加兩個引數:引數名稱後面接著空字串 (這是零字串的邏輯彙整)。
uniquify default = False
add_all 相同。
expand_directories default = True
add_all 相同。
allow_closure default = False
add_all 相同。

set_param_file_format

Args Args.set_param_file_format(format)

設定參數檔案的格式 (如有使用)

參數

參數 說明
format 必填
必須是以下其中一個值:
  • 「multiline」:每個項目 (引數名稱或值) 都會一字不漏地寫入參數檔案,並在參數後方加上換行字元。
  • 「shell」:與「multiline」相同,但項目是以殼層引號括住
  • 「flag_per_line」:和「multiline」相同,但 (1) 僅有的旗標 (開頭為「--」) 會寫入參數檔案中;且 (2) 旗標的值 (如有) 會寫入同一行,並以「=」分隔符撰寫。這是 Abseil 旗標程式庫預期的格式。

如未呼叫,格式會預設為「shell」。

use_param_file

Args Args.use_param_file(param_file_arg, *, use_always=False)

將引數溢出至參數檔案,並替換成參數檔案的指標。引數可能過大,不符合系統指令長度限制時使用。

為了提高執行效率,Bazel 可能會選擇移除參數檔案至輸出樹狀結構。如要對動作進行偵錯,並想檢查參數檔案,請將 --materialize_param_files 傳遞至建構作業。

參數

參數 說明
param_file_arg 必要
只有單一「%s」的格式字串。如果引數溢出在參數檔案中,則這些引數會替換為由此字串組成的引數,該字串會採用參數檔案的路徑格式。

舉例來說,如果 args 外洩至參數檔案「params.txt」,則指定「--file=%s」會導致動作指令列包含「--file=params.txt」。

use_always default = False
是否要一律將引數溢出至參數檔案。如果設為 false,Bazel 會根據您的系統和引數長度,決定是否需要溢出引數。