参数

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。
一个对象,用于以节省内存的方式封装构建部分或全部命令行所需的数据。

操作经常需要一个大型命令行,其中包含从传递依赖项中累积的值。例如,链接器命令行可能会列出正在链接的所有库所需的每个对象文件。最佳做法是将此类传递数据存储在 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。列表、元组、deset 或目录 File 必须传递给 add_all()add_joined(),而不是此方法。
format string; or None;默认值 = None
将应用于字符串化版本的 value 的格式字符串模式。

添加全部

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;默认值 = None
一个函数,将每个项目转换为零个或多个字符串,这些字符串可以在附加之前进一步处理。如果未提供此参数,则系统会使用标准转换。

向其传递一个或两个位置参数:要转换的项,后跟可选的 DirectoryExpander。仅当所提供的函数为用户定义的(非内置)且声明了多个参数时,系统才会传递第二个参数。

返回值的类型取决于要为相应项生成的参数数量:

  • 在常见情况下,当每项内容转换为一个字符串时,函数应返回该字符串。
  • 如果商品被完全滤除,该函数应返回 None
  • 如果该项变为多个字符串,该函数会返回这些字符串的列表。
返回单个字符串或 None 与分别返回长度为 1 或长度为 0 的列表具有相同的效果。不过,避免创建不需要的列表,更高效、更易读。

通常,当 expand_directories=True 已设置时,属于目录的项会自动展开到其内容。但是,这不会展开包含在其他值中的目录,例如,当项是具有目录作为字段的结构体时。在这种情况下,DirectoryExpander 参数可用于手动获取指定目录的文件。

为避免在执行阶段意外保留大型分析阶段数据结构,必须由顶级 def 语句声明 map_each 函数;默认情况下,它不能是嵌套函数闭包。

警告:在调用 map_each 期间执行的 print() 语句不会产生任何可见的输出。

format_each string; or None;默认值为 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 的重复参数。系统只会保留每个参数的首次出现。通常不需要此功能,因为 Depset 已经省略了重复项,但如果 map_each 为多个项发出相同的字符串,此功能会很有用。
expand_directories default = True
如果为 true,则 values 中的任何目录都将展开为平面文件列表。此操作发生在应用 map_each 之前。
terminate_with string; or None;默认值为默认值 None
附加到所有其他参数后的可选字符串。如果 omit_if_empty 为 true(默认值),并且未附加任何其他项(当 values 为空或过滤了所有项时,则不会添加此字符串)。
allow_closure default = False
如果为 true,则允许在 map_each 等函数参数中使用闭包。这通常没有必要,并且存在将大型分析阶段数据结构保留到执行阶段的风险。

加入联接

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;默认值 = None
add_all 相同。
format_each string; or None;默认值 = None
add_all 相同。
format_joined string; or None;默认值 = 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”相同,但这些项带有 shell 引号
  • "flag_per_line": 与“multiline”相同,但 (1) 只有参数(以 '--' 开头)会写入参数文件;(2) 标记的值(如果有)会用 '=' 分隔符在同一行中写入。这是 Abseil 标志库的预期格式。

如果不调用,格式默认为“shell”。

使用参数文件

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

将参数溢出到参数文件,用指向参数的指针替换它们。如果您的参数可能超出了系统的命令长度限制,请使用此选项。

为了提高效率,Bazel 可能会选择在执行期间省略将参数文件写入输出树。如果您要调试操作并想检查参数文件,请将 --materialize_param_files 传递给 build。

参数

参数 说明
param_file_arg 必需
包含单个“%s”的格式字符串。如果参数溢出至参数文件,则这些参数将被替换为由此字符串格式化的参数字符串。

例如,如果参数泄漏到参数文件“params.txt”中,则指定 "--file=%s" 会导致操作命令行包含 "--file=params.txt"。

use_always default = False
是否始终将参数溢出到参数文件。如果为 false,bazel 将根据您的系统和参数长度来决定是否需要参数传播。