Build APIs
ExecutionPlatformInfo
def ExecutionPlatformInfo(
*,
label: target_label,
configuration: ConfigurationInfo,
executor_config: command_executor_config,
) -> ExecutionPlatformInfo
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 messages -
configuration: ConfigurationInfo
- The configuration of the execution platform -
executor_config: command_executor_config
- The executor config
ExecutionPlatformRegistrationInfo
def ExecutionPlatformRegistrationInfo(
*,
platforms: list[ExecutionPlatformInfo],
fallback = None,
) -> ExecutionPlatformRegistrationInfo
Provider that gives the list of all execution platforms available for this build.
Provides a number of fields that can be accessed:
-
platforms: list[ExecutionPlatformInfo]
- field -
fallback: typing.Any
- field
InstallInfo
def InstallInfo(
installer: label,
files: dict[str, artifact],
) -> InstallInfo
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
- field -
files: dict[str, artifact]
- field
Provider
Provider: type
anon_rule
def anon_rule(
*,
impl: typing.Callable[[typing.Any], list],
attrs: dict[str, attribute],
doc: str = "",
artifact_promise_mappings: dict[str, typing.Callable[[typing.Any], list]],
) -> def(**kwargs: typing.Any) -> None
Define an anon rule, similar to how a normal rule is defined, except with an extra artifact_promise_mappings
field. This is a dict where the keys are the string name of the artifact, and the values are the callable functions that produce the artifact. This is only intended to be used with anon targets.
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.
dynamic_actions
def dynamic_actions(
,
impl: typing.Callable[", actions: actions, **kwargs: typing.Any", list[provider]],
attrs: dict[str, DynamicAttrType],
) -> DynamicActionCallable
Create new dynamic action callable. Returned object will be callable, and the result of calling it can be passed to ctx.actions.dynamic_output_new
.
get_base_path
def get_base_path() -> str
get_base_path()
can only be called in buildfiles (e.g. BUCK files) or PACKAGE files, and returns the name of the package. E.g. inside foo//bar/baz/BUCK
the output will be bar/baz
. E.g. inside foo//bar/PACKAGE
the output will be bar
.
This function is identical to package_name
.
get_cell_name
def get_cell_name() -> str
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: list[str] | tuple[str, ...],
*,
exclude: list[str] | tuple[str, ...] = [],
) -> list[str]
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(..)
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,
default = ...,
)
load_symbols
def load_symbols(
symbols: dict[str, typing.Any],
) -> 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, /) -> 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 = False,
visibility: list[str] | tuple[str, ...] = [],
within_view: list[str] | tuple[str, ...] = [],
) -> None
package_name
def package_name() -> str
package_name()
can only be called in buildfiles (e.g. BUCK files) or PACKAGE files, and returns the name of the package. E.g. inside foo//bar/baz/BUCK
the output will be bar/baz
. E.g. inside foo//bar/PACKAGE
the output will be bar
.
provider
def provider(
*,
doc: str = "",
fields: list[str] | tuple[str, ...] | dict[str, typing.Any],
) -> 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.
provider_field
def provider_field(ty, /, *, default = ...) -> ProviderField
Create a field definition object which can be passed to provider
type constructor.
read_config
def read_config(
section: str,
key: str,
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_oncall
def read_oncall() -> None | str
Called in a BUCK
file to retrieve the previously set oncall
, or None
if none has been set. It is an error to call oncall
after calling this function.
read_package_value
def read_package_value(key: str, /)
Read value specified in the PACKAGE
file.
Returns None
if value is not set.
read_parent_package_value
def read_parent_package_value(
key: str,
/,
)
Read a package value defined in a parent PACKAGE
file.
This function can only be called in a Package context.
Returns None
if value is not set.
read_root_config
def read_root_config(
section: str,
key: str,
default: None | str = None,
/,
) -> None | str
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,
str: str,
/,
) -> bool
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
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: typing.Callable[[context], promise | list[provider]],
attrs: dict[str, attribute],
cfg: transition = ...,
doc: str = "",
is_configuration_rule: bool = False,
is_toolchain_rule: bool = False,
uses_plugins: list[PluginKind] | tuple[PluginKind, ...] = [],
) -> def(**kwargs: typing.Any) -> None
Define a rule. As a simple example:
def _my_rule(ctx: AnalysisContext) -> list[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,
) -> bool
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: dict[str, typing.Any],
/,
) -> selector
select_equal_internal
def select_equal_internal(
left,
right,
/,
) -> bool
Tests that two selects are equal to each other. For testing use only. We simply compare their string representations.
select_map
def select_map(d, func, /)
Maps a selector.
Each value within a selector map and on each side of an addition will be passed to the mapping function. The returned selector will have the same structure as this one.
Ex:
def increment_items(a):
return [v + 1 for v in a]
select_map([1, 2] + select({"c": [2]}), increment_items) == [2, 3] + select({"c": [3]})
select_test
def select_test(d, func, /) -> bool
Test values in the select expression using the given function.
Returns True, if any value in the select passes, else False.
Ex:
select_test([1] + select({"c": [1]}), lambda a: len(a) > 1) == False
select_test([1, 2] + select({"c": [1]}), lambda a: len(a) > 1) == True
select_test([1] + select({"c": [1, 2]}), lambda a: len(a) > 1) == True
set_cfg_constructor
def set_cfg_constructor(
*,
stage0,
stage1,
key: str,
aliases = None,
extra_data = None,
) -> None
Register global cfg constructor.
This function can only be called from the repository root PACKAGE
file.
Parameters:
stage0: The first cfg constructor that will be invoked before configuration rules are analyzed.
stage1: The second cfg constructor that will be invoked after configuration rules are analyzed.
key: The key for cfg modifiers on PACKAGE values and metadata.
aliases: The aliases map to use for input modifiers.
extra_data: Some extra data that may be used by set_cfg_constructor
implementation that is
custom to our implementation and may not be used in other context like open-source.
set_starlark_peak_allocated_byte_limit
def set_starlark_peak_allocated_byte_limit(
value: int,
/,
) -> None
Set the peak allocated bytes during evaluation of build ctx. Err if it has already been set
sha256
def sha256(
val: str,
/,
) -> str
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,
message: str,
/,
*,
quiet: bool = ...,
stack: bool = ...,
) -> 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: typing.Callable[", platform: PlatformInfo, refs: struct(..), attrs: struct(..) = ...", dict[str, PlatformInfo] | PlatformInfo],
refs: dict[str, str],
attrs: list[str] | tuple[str, ...] = ...,
split: bool = False,
) -> transition
transitive_set
def transitive_set(
*,
args_projections: dict[str, typing.Callable[[typing.Any], typing.Any]] = ...,
json_projections: dict[str, typing.Callable[[typing.Any], typing.Any]] = ...,
reductions: dict[str, typing.Callable[[list, typing.Any], typing.Any]] = ...,
) -> transitive_set_definition
warning
def warning(x: str, /) -> 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,
value,
/,
*,
overwrite: bool = False,
) -> None
Set the value to be accessible in the nested PACKAGE
files.
If any parent PACKAGE
value has already set the same key
,
it will raise an error unless you pass overwrite = True
,
in which case it will replace the parent value.