globals
CommandExecutorConfig
def CommandExecutorConfig(
*,
local_enabled: bool.type,
remote_enabled: bool.type,
remote_cache_enabled: [None, bool.type] = None,
remote_execution_properties: "" = None,
remote_execution_action_key: "" = None,
remote_execution_max_input_files_mebibytes: [None, int.type] = None,
remote_execution_queue_time_threshold_s: [None, int.type] = None,
remote_execution_use_case: "" = None,
use_limited_hybrid: bool.type = False,
allow_limited_hybrid_fallbacks: bool.type = False,
allow_hybrid_fallbacks_on_failure: bool.type = False,
use_windows_path_separators: bool.type = False,
use_persistent_workers: bool.type = False,
allow_cache_uploads: bool.type = False,
max_cache_upload_mebibytes: [None, int.type] = None,
experimental_low_pass_filter: bool.type = False,
remote_output_paths: [None, str.type] = None
) -> "command_executor_config"
Contains configurations for how actions should be executed
.type
attribute
Produces "command_executor_config"
Details
local_enabled
: Whether to use local execution for this execution platform. If both remote_enabled and local_enabled areTrue
, we will use the hybrid executorremote_enabled
: Whether to use remote execution for this execution platformremote_cache_enabled
: Whether to query RE cachesremote_execution_properties
: Properties for remote execution for this platformremote_execution_action_key
: A component to inject into the action key This should typically used to inject variability into the action key so that it's different across e.g. build modes (RE uses the action key for things like expected memory utilization)remote_execution_max_input_files_mebibytes
: The maximum input file size (in bytes) that remote execution can supportremote_execution_queue_time_threshold_s
: The maximum time in seconds we are willing to wait in the RE queue for remote execution to start running our actionremote_execution_use_case
: The use case to use when communicating with REuse_limited_hybrid
: Whether to use the limited hybrid executorallow_limited_hybrid_fallbacks
: Whether to allow fallbacksallow_hybrid_fallbacks_on_failure
: Whether to allow fallbacks when the result is failure (i.e. the command failed on the primary, but the infra worked)use_windows_path_separators
: Whether to use Windows path separators in command line argumentsuse_persistent workers
: Whether to use persistent workers for local execution if they are availableallow_cache_uploads
: Whether to upload local actions to the RE cachemax_cache_upload_mebibytes
: Maximum size to upload in cache uploadsexperimental_low_pass_filter
: Whether to use the experimental low pass filterremote_output_paths
: How to express output paths to RE
ConfigurationInfo
def ConfigurationInfo(
*,
constraints: {"target_label": "ConstraintValueInfo"},
values: {str.type: str.type}
) -> ConfigurationInfo.type
Provider that signals that a rule contains configuration info. This is used both as part of defining configurations (platform()
, constraint_value()
) and defining whether a target "matches" a configuration or not (config_setting()
, constraint_value()
)
.type
attribute
Produces "ConfigurationInfo"
Details
Provides a number of fields that can be accessed:
constraints: {"target_label": "ConstraintValueInfo"}
- fieldvalues: {str.type: str.type}
- field
ConstraintSettingInfo
def ConstraintSettingInfo(
*,
label: "target_label"
) -> ConstraintSettingInfo.type
Provider that signals that a target can be used as a constraint key. This is the only provider returned by a constraint_setting()
target.
.type
attribute
Produces "ConstraintSettingInfo"
Details
Provides a number of fields that can be accessed:
label: "target_label"
- field
ConstraintValueInfo
def ConstraintValueInfo(
*,
setting: "ConstraintSettingInfo",
label: "target_label"
) -> ConstraintValueInfo.type
Provider that signals that a target can be used as a constraint key. This is the only provider returned by a constraint_value()
target.
.type
attribute
Produces "ConstraintValueInfo"
Details
Provides a number of fields that can be accessed:
setting: "ConstraintSettingInfo"
- fieldlabel: "target_label"
- field
DefaultInfo
def DefaultInfo(
default_output: "" = None,
default_outputs: "" = None,
other_outputs: "" = [],
sub_targets: {str.type: ""} = {}
) -> DefaultInfo.type
A provider that all rules' implementations must return
.type
attribute
Produces "DefaultInfo"
Details
In many simple cases, this can be inferred for the user.
Example of a rule's implementation function and how these fields are used by the framework:
# //foo_binary.bzl
def impl(ctx):
ctx.action.run([ctx.attrs._cc[RunInfo], "-o", ctx.attrs.out.as_output()] + ctx.attrs.srcs)
ctx.action.run([
ctx.attrs._strip[RunInfo],
"--binary",
ctx.attrs.out,
"--stripped-out",
ctx.attrs.stripped.as_output(),
"--debug-symbols-out",
ctx.attrs.debug_info.as_output(),
])
return [
DefaultInfo(
sub_targets = {
"stripped": [
DefaultInfo(default_outputs = [ctx.attrs.stripped, ctx.attrs.debug_info]),
],
},
default_output = ctx.attrs.out,
]
foo_binary = rule(
impl=impl,
attrs={
"srcs": attrs.list(attrs.source()),
"out": attrs.output(),
"stripped": attrs.output(),
"debug_info": attrs.output(),
"_cc": attrs.dep(default="//tools:cc", providers=[RunInfo]),
"_strip_script": attrs.dep(default="//tools:strip", providers=[RunInfo])
)
def foo_binary_wrapper(name, srcs):
foo_binary(
name = name,
srcs = src,
out = name,
stripped = name + ".stripped",
debug_info = name + ".debug_info",
)
# //subdir/BUCK
load("//:foo_binary.bzl", "foo_binary_wrapper")
genrule(name = "gen_stuff", ...., default_outs = ["foo.cpp"])
# ":gen_stuff" pulls the default_outputs for //subdir:gen_stuff
foo_binary_wrapper(name = "foo", srcs = glob(["*.cpp"]) + [":gen_stuff"])
# Builds just 'foo' binary. The strip command is never invoked.
$ buck build //subdir:foo
# builds the 'foo' binary, because it is needed by the 'strip' command. Ensures that
# both the stripped binary and the debug symbols are built.
$ buck build //subdir:foo[stripped]
Provides a number of fields that can be accessed:
sub_targets: {str.type: "provider_collection"}
- A mapping of names toProviderCollection
s. The keys are used when resolving theProviderName
portion of aProvidersLabel
. These collections can contain, and actually /must/ contain aDefaultInfo
provider. However, nested label syntax is not supported. That is,cell//foo:bar[baz]
is valid,cell//foo:bar[baz][quz]
is not.default_outputs: ["artifact"]
- A list ofArtifact
s that are built by default if this rule is requested explicitly, or depended on as as a "source".other_outputs: ["artifact"]
- A list ofArtifactTraversable
. The underlyingArtifact
s they define will be built by default if this rule is requested, but not when it's depended on as as a "source".ArtifactTraversable
can be anArtifact
(which yields itself), orcmd_args
, which expand to all their inputs.
ExecutionPlatformInfo
def ExecutionPlatformInfo(
*,
label: "",
configuration: "",
executor_config: ""
) -> ExecutionPlatformInfo.type
Provider that signals that a target represents an execution platform.
Provides a number of fields that can be accessed:
label: "target_label"
- label of the defining rule, used in informative messagesconfiguration: "ConfigurationInfo"
- The configuration of the execution platformexecutor_config: "command_executor_config"
- The executor config
ExecutionPlatformRegistrationInfo
def ExecutionPlatformRegistrationInfo(
*,
platforms: "",
fallback: "" = _
) -> ExecutionPlatformRegistrationInfo.type
Provider that gives the list of all execution platforms available for this build.
Provides a number of fields that can be accessed:
platforms: ["ExecutionPlatformInfo"]
- fieldfallback: ""
- field
ExternalRunnerTestInfo
def ExternalRunnerTestInfo(
type: "",
command: "" = None,
env: "" = None,
labels: "" = None,
contacts: "" = None,
use_project_relative_paths: "" = None,
run_from_project_root: "" = None,
default_executor: "" = None,
executor_overrides: "" = None,
local_resources: "" = None
) -> ExternalRunnerTestInfo.type
Provider that signals that a rule can be tested using an external runner. This is the Buck1-compatible API for tests.
.type
attribute
Produces "ExternalRunnerTestInfo"
Details
Provides a number of fields that can be accessed:
test_type: str.type
- A Starlark value representing the type of this test. This is of type str.typecommand: [[str.type, ""]]
- A Starlark value representing the command for this test. The external test runner is what gives meaning to this command. This is of type [[str.type, "_arglike"]]env: {str.type: ""}
- A Starlark value representing the environment for this test. Here again, the external test runner is what will this meaning. This is of type {str.type: _arglike}labels: [str.type]
- A starlark value representing the labels for this test. This is of type [str.type]contacts: [str.type]
- A starlark value representing the contacts for this test. This is largely expected to be an oncall, though it's not validated in any way. This is of type [str.type]use_project_relative_paths: [bool.type]
- Whether this test should use relative paths. The default is not to. This is of type [bool.type]run_from_project_root: [bool.type]
- Whether this test should run from the project root, as opposed to the cell root. The default is not to. This is of type [bool.type]default_executor: "command_executor_config"
- Default executor to use to run tests. This is of type CommandExecutorConfig. If none is passed we will default to the execution platform.executor_overrides: {str.type: "command_executor_config"}
- Executors that Tpx can use to override the default executor. This is of type {str.type: CommandExecutorConfig}local_resources: {str.type: [None, "LocalResourceInfo"]}
- Mapping from a local resource type to a corresponding provider. Required types are passed from test runner. If the value for a corresponding type is omitted it means local resource should be ignored when executing tests even if those are passed as required from test runner.
InstallInfo
def InstallInfo(installer: "label", files: {str.type: ""}) -> InstallInfo.type
A provider that can be constructed and have its fields accessed. Returned by rules.
Provides a number of fields that can be accessed:
installer: "label"
- fieldfiles: {str.type: "artifact"}
- field
LocalResourceInfo
def LocalResourceInfo(
*,
source_target: "",
setup: "",
resource_env_vars: ""
) -> LocalResourceInfo.type
A provider that can be constructed and have its fields accessed. Returned by rules.
.type
attribute
Produces "LocalResourceInfo"
Details
Provides a number of fields that can be accessed:
source_target: "label"
- Configured target that is providing this local resource.setup: "cmd_args"
- Command to run to initialize a local resource. Running this command writes a JSON to stdout. This JSON represents a pool of local resources which are ready to be used. Example JSON would be: { "pid": 42, "resources": [ {"socket_address": "foo:1"}, {"socket_address": "bar:2"} ] } Where '"pid"maps to a PID of a process which should be sent SIGTERM to release the pool of resources when they are no longer needed.
"resources"maps to the pool of resources. When a local resource from this particular pool is needed for an execution command, single entity will be reserved from the pool, for example
{"socket_address": "bar:2"}and environment variable with name resolved using mapping in
resource_env_varsfield and
"socket_address"` key will be added to execution command.resource_env_vars: {str.type: str.type}
- Mapping from environment variable (appended to an execution command which is dependent on this local resource) to keys in setup command JSON output.
PlatformInfo
def PlatformInfo(
*,
label: str.type,
configuration: "ConfigurationInfo"
) -> PlatformInfo.type
A provider that can be constructed and have its fields accessed. Returned by rules.
.type
attribute
Produces "PlatformInfo"
Details
Provides a number of fields that can be accessed:
label: str.type
- fieldconfiguration: "ConfigurationInfo"
- field
RunInfo
def RunInfo(args: "" = []) -> RunInfo.type
Provider that signals that a rule is runnable
.type
attribute
Produces "RunInfo"
Details
Provides a number of fields that can be accessed:
args: "cmd_args"
- The command to run, stored as CommandLine
TemplatePlaceholderInfo
def TemplatePlaceholderInfo(
unkeyed_variables: "" = {},
keyed_variables: "" = {}
) -> TemplatePlaceholderInfo.type
A provider that is used for expansions in string attribute templates
.type
attribute
Produces "TemplatePlaceholderInfo"
Details
String attribute templates allow two types of user-defined placeholders, "unkeyed placeholders"
like $(CXX)
or $(aapt)
and "keyed placeholders" that include a target key like
$(cxxppflags //some:target)
. The expansion of each of these types is based on the
TemplatePlaceholderInfo
providers.
"keyed placeholders" are used for the form $(<key> <target>)
or $(<key> <target> <arg>)
. In both cases
the lookup will expect a TemplatePlaceholderInfo
in the providers of <target>
. It will then lookup
<key>
in the keyed_variables (call this the value
). There are then four valid possibilities:
- no-arg placeholder, an arg-like
value
: resolve tovalue
- no-arg placeholder, a dictionary
value
: resolve tovalue["DEFAULT"]
- arg placeholder, a non-dictionary
value
: this is an error - arg placeholder, a dictionary
value
: resolve tovalue[<arg>]
"unkeyed placeholders" are resolved by matching to any of the deps of the target. $(CXX)
will resolve
to the "CXX" value in any dep's TemplateProviderInfo.unkeyed_variables
Fields:
- unkeyed_variables: A mapping of names to arg-like values. These are used for "unkeyed placeholder" expansion.
- keyed_variables: A mapping of names to arg-like values or dictionary of string to arg-like values. These are used for "keyed placeholder" expansion.
Provides a number of fields that can be accessed:
unkeyed_variables: ""
- fieldkeyed_variables: ""
- field
WorkerInfo
def WorkerInfo(exe: "" = []) -> WorkerInfo.type
Provider that signals that a rule is a worker tool
.type
attribute
Produces "WorkerInfo"
Details
Provides a number of fields that can be accessed:
exe: "cmd_args"
- field
WorkerRunInfo
def WorkerRunInfo(*, worker: "WorkerInfo", exe: "" = []) -> WorkerRunInfo.type
Provider that signals that a rule can run using a worker
.type
attribute
Produces "WorkerRunInfo"
Details
Provides a number of fields that can be accessed:
worker: "WorkerInfo"
- fieldexe: "cmd_args"
- field
__internal__
__internal__: "struct"
attrs
attrs: "attrs"
cmd_args
def cmd_args(
*args,
delimiter: str.type = _,
format: str.type = _,
prepend: str.type = _,
quote: str.type = _
) -> "cmd_args"
The cmd_args
type is created by this function and is consumed by ctx.actions.run
. The type is a mutable collection of strings and artifact values. In general, command lines, artifacts, strings, RunInfo
and lists thereof can be added to or used to construct a cmd_args
value.
.type
attribute
Produces "cmd_args"
Details
The arguments are:
*args
- a list of things to add to the command line, each of which must be coercible to a command line. Further items can be added withcmd.add
.format
- a string that provides a format to apply to the argument. for example,cmd_args(x, format="--args={}")
would prepend--args=
beforex
, or ifx
was a list, before each element inx
.delimiter
- added between arguments to join them together. For example,cmd_args(["--args=",x], delimiter="")
would produce a single argument to the underlying tool.prepend
- added as a separate argument before each argument.quote
- indicates whether quoting is to be applied to each argument. The only current valid value is"shell"
.
dedupe
def dedupe(val: "") -> ""
Remove duplicates in a list. Uses identity of value (pointer), rather than by equality. In many cases you should use a transitive set instead.
get_base_path
def get_base_path() -> str.type
get_base_path()
can only be called in BUCK
files, and returns the name of the package. E.g. inside foo//bar/baz/BUCK
the output will be bar/baz
.
This function is identical to package_name
.
get_cell_name
def get_cell_name() -> str.type
get_cell_name()
can be called from either a BUCK
file or a .bzl
file, and returns the name of the cell where the BUCK
file that started the call lives.
For example, inside foo//bar/baz/BUCK
the output will be foo
.
If that BUCK
file does a load("hello//world.bzl", "something")
then
the result in that .bzl
file will also be foo
.
glob
def glob(include: [str.type], *, exclude: [str.type] = []) -> [str.type]
The glob()
function specifies a set of files using patterns. Only available from BUCK
files.
A typical glob
call looks like:
glob(["foo/**/*.h"])
This call will match all header files in the foo
directory, recursively.
You can also pass a named exclude
parameter to remove files matching a pattern:
glob(["foo/**/*.h"], exclude = ["**/config.h"])
This call will remove all config.h
files from the initial match.
The glob()
call is evaluated against the list of files owned by this BUCK
file.
A file is owned by whichever BUCK
file is closest above it - so given foo/BUCK
and
foo/bar/BUCK
the file foo/file.txt
would be owned by foo/BUCK
(and available from
its glob
results) but the file foo/bar/file.txt
would be owned by foo/bar/BUCk
and not appear in the glob result of foo/BUCK
, even if you write glob(["bar/file.txt"])
.
As a consequence of this rule, glob(["../foo.txt"])
will always return an empty list of files.
Currently glob
is evaluated case-insensitively on all file systems, but we expect
that to change to case sensitive in the near future.
host_info
def host_info() -> struct.type
The host_info()
function is used to get the current OS and processor architecture on the host. The structure returned is laid out thusly:
struct(
os=struct(
is_linux=True|False,
is_macos=True|False,
is_windows=True|False,
is_freebsd=True|False,
is_unknown=True|False,
),
arch=struct(
is_aarch64=True|False,
is_arm=True|False,
is_armeb=True|False,
is_i386=True|False,
is_mips=True|False,
is_mips64=True|False,
is_mipsel=True|False,
is_mipsel64=True|False,
is_powerpc=True|False,
is_ppc64=True|False,
is_x86_64=True|False,
is_unknown=True|False,
),
)
implicit_package_symbol
def implicit_package_symbol(name: str.type, default: "" = _) -> ""
load_symbols
def load_symbols(symbols: {str.type: ""}) -> None
Used in a .bzl
file to set exported symbols. In most cases just defining the symbol as a top-level binding is sufficient, but sometimes the names might be programatically generated.
It is undefined behaviour if you try and use any of the symbols exported here later in the same module, or if they overlap with existing definitions. This function should be used rarely.
oncall
def oncall(name: str.type) -> None
Called in a BUCK
file to declare the oncall contact details for all the targets defined. Must be called at most once, before any targets have been declared. Errors if called from a .bzl
file.
package
def package(
*,
inherit: bool.type = False,
visibility: [str.type] = [],
within_view: [str.type] = []
) -> None
package_name
def package_name() -> str.type
package_name()
can only be called in BUCK
files, and returns the name of the package. E.g. inside foo//bar/baz/BUCK
the output will be bar/baz
.
provider
def provider(
*,
doc: str.type = "",
fields: [[str.type], {str.type: str.type}]
) -> "provider_callable"
Create a "provider"
type that can be returned from rule
implementations. Used to pass information from a rule to the things that depend on it. Typically named with an Info
suffix.
GroovyLibraryInfo(fields = [
"objects", # a list of artifacts
"options", # a string containing compiler options
])
Given a dependency you can obtain the provider with my_dep[GroovyLibraryInfo]
which returns either None
or a value of type GroovyLibraryInfo
.
For providers that accumulate upwards a transitive set is often a good choice.
read_config
def read_config(section: str.type, key: str.type, default: "" = _) -> ""
Read a configuration from the nearest enclosing .buckconfig
of the BUCK
file that started evaluation of this code.
As an example, if you have a .buckconfig
of:
[package_options]
compile = super_fast
Then you would get the following results:
read_config("package_options", "compile") == "super_fast"
read_config("package_options", "linker") == None
read_config("package_options", "linker", "a_default") == "a_default"
In general the use of .buckconfig
is discouraged in favour of select
,
but it can still be useful.
read_package_value
def read_package_value(key: str.type) -> [None, str.type]
Read value specified in the PACKAGE
file.
Returns None
if value is not set.
read_root_config
def read_root_config(
section: str.type,
key: str.type,
default: [None, str.type] = None
) -> [None, str.type]
Like read_config
but the project root .buckconfig
is always consulted, regardless of the cell of the originating BUCK
file.
regex_match
def regex_match(regex: str.type, str: str.type) -> bool.type
Test if a regular expression matches a string. Fails if the regular expression is malformed.
As an example:
regex_match("^[a-z]*$", "hello") == True
regex_match("^[a-z]*$", "1234") == False
repository_name
def repository_name() -> str.type
Like get_cell_name()
but prepends a leading @
for compatibility with Buck1. You should call get_cell_name()
instead, and if you really want the @
, prepend it yourself.
rule
def rule(
*,
impl: "",
attrs: {str.type: "attribute"},
cfg: "" = _,
doc: str.type = "",
is_configuration_rule: bool.type = False,
is_toolchain_rule: bool.type = False
) -> "rule"
Define a rule. As a simple example:
def _my_rule(ctx: "context") -> ["provider"]:
output = ctx.actions.write("hello.txt", ctx.attrs.contents, executable = ctx.attrs.exe)
return [DefaultInfo(outputs = [output])]
MyRule = rule(impl = _my_rule, attrs = {
"contents": attrs.string(),
"exe": attrs.option(attrs.bool(), default = False),
})
rule_exists
def rule_exists(name: str.type) -> bool.type
Check if the target with name
has already been defined, returns True
if it has.
Note that this function checks for the existence of a target rather than a rule. In general use of this function is discouraged, as it makes definitions of rules not compose.
select
def select(d: "") -> "selector"
select_equal_internal
def select_equal_internal(left: "", right: "") -> bool.type
Tests that two selects are equal to each other. For testing use only.
select_map
def select_map(d: "", func: "") -> ""
Applies a mapping function to a selector. See [StarlarkSelector::select_map].
select_test
def select_test(d: "", func: "") -> bool.type
Applies a test function to a selector. See [StarlarkSelector::select_test].
sha256
def sha256(val: str.type) -> str.type
Computes a sha256 digest for a string. Returns the hex representation of the digest.
sha256("Buck2 is the best build system") == "bb99a3f19ecba6c4d2c7cd321b63b669684c713881baae21a6b1d759b3ec6ac9"
soft_error
def soft_error(category: str.type, message: str.type) -> None
Produce an error that will become a hard error at some point in the future, but for now is a warning which is logged to the server. In the open source version of Buck2 this function always results in an error.
Called passing a stable key (must be snake_case
and start with starlark_
,
used for consistent reporting) and an arbitrary message (used for debugging).
As an example:
soft_error(
"starlark_rule_is_too_long",
"Length of property exceeds 100 characters in " + repr(ctx.label),
)
transition
def transition(
*,
impl: "",
refs: {str.type: str.type},
attrs: [str.type] = _,
split: bool.type = False
) -> "transition"
transitive_set
def transitive_set(
args_projections: {str.type: ""} = _,
json_projections: {str.type: ""} = _,
reductions: {str.type: ""} = _
) -> "transitive_set_definition"
warning
def warning(x: str.type) -> None
Print a warning. The line will be decorated with the timestamp and other details, including the word WARN
(colored, if the console supports it).
If you are not writing a warning, use print
instead. Be aware that printing
lots of output (warnings or not) can be cause all information to be ignored by the user.
write_package_value
def write_package_value(
key: str.type,
value: "",
*,
overwrite: bool.type = False
) -> None
Set the value to be accessible in the nested PACKAGE
files.