Skip to main content

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.