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 的額外字串。舉例來說,視指定的序列是 val1..val3 或為空白而定,相同的用法可在指令列中加入 --foo val1 val2 val3 --bar 或只新增 --bar

如果指令列大小超過系統允許的大小上限,這些引數可能會外洩到參數檔案中。請參閱 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。清單、元組、解碼器或目錄 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
要附加其項目的清單、元組或解碼器。
map_each callable; or None; default = None
這個函式會將每個項目轉換為零或多個字串,附加作業可進一步處理完畢。如果未提供這個參數,則會使用標準轉換。

系統會傳遞一或兩個位置引數:要轉換的項目,後面接著選用的 DirectoryExpander。只有當提供的函式屬於使用者定義 (非內建函式) 並宣告多個參數時,系統才會傳送第二個引數。

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

  • 一般來說,如果每個項目變成一個字串,函式就會傳回該字串。
  • 如果該項目完全篩除,該函式應傳回 None
  • 如果項目轉成多個字串,函式就會傳回這些字串的清單。
傳回單一字串或 None 的效果與分別傳回長度為 1 或長度 0 的清單相同。但是,這樣更有效率且易於讀取,避免在不需要建立清單時建立。

一般而言,設定 expand_directories=True 時,屬於目錄的項目會自動展開至其內容。不過,這項操作不會展開其他值中的目錄。例如,當項目是具有目錄做為欄位的結構體時,就不會展開該目錄。在這種情況下,可以套用 DirectoryExpander 引數,手動取得指定目錄的檔案。

為了避免在執行階段中意外保留大型分析階段資料結構,map_each 函式必須透過頂層 def 陳述式宣告;其預設不得為巢狀函式關閉。

警告:呼叫 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;預設值 = 無
add_all 相同。
format_each string; or None;預設值 = 無
add_all 相同。
format_joined string; or None; default = None
選用格式字串模式,已套用至彙整的字串。格式字串只能有一個「%s」預留位置。
omit_if_empty default = 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」:與「多行」相同,但這些項目是以殼層括住
  • 「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」的格式字串。如果引數溢位為參數檔案,則會替換為由此字串組成的引數,並使用參數檔案的路徑格式指定。

舉例來說,如果引數被溢位為參數檔案「params.txt」,那麼指定「--file=%s」會導致動作指令列包含「--file=params.txt」。

use_always default = False
是否一律將引數傳遞至參數檔案。如果設為 false,bazel 將根據系統和引數長度判斷引數是否需要散佈。