This RFC proposes to extend buck2 Starlark with package-local values.
DevX people want to have some per-directory configuration files, accessible from Starlark macros.
For example, a project NNN may want to switch to building using LLVM 15 by default. End users would want to have an easy instruction how to do that, after DevX people provided instructions and infrastructure for that.
What we have now
Currently, in fbcode, we have
get_modes symbol is registered in per-package implicit symbols,
This symbol can be accessed from macros using implicit_package_symbol function.
get_modes functions are package-local, but all
BUILD_MODE.bzl files need to
be registered in global buckconfig, which is not ideal.
Proposed per-package properties can replace
BUCK file, buck2 will evaluate all
PACKAGE files in the
same directory and all parent directories. Absent
PACKAGE files are treated as
PACKAGE files are executed sequentially from the root directory
to the current directory (but unrelated
PACKAGE files can be executed in
PACKAGE files sequentially provides additional
guarantees, for example, attempt to override a property (unless explicitly
requested) should fail with Starlark call stack.
PACKAGE file is evaluated at most once (like
PACKAGE files may load arbitrary
BUCK-specific functions called
bzl files (like rule functions) are available, but calling functions from
PACKAGE files is an error. This way,
bzl files are evaluated only once
regardless of whether they are loaded from
PACKAGE files have a global function:
PACKAGE file API
overwrite: bool = False,
Name is a string which must contain exactly one dot symbol (just to enforce code style).
Value is an arbitrary Starlark value, for example, an integer, a list of integer, a struct or a function.
False (default), attempt to overwrite per-package value
defined in parent
PACKAGE file will fail.
Written values are frozen when
PACKAGE file evaluation is finished.
write_package_value symbol exists in
bzl globals, and it can be called
bzl file in context of
PACKAGE evaluation, but calling
write_package_file is an error on context of
PACKAGE file logically invalidates the
BUCK file of this package,
BUCK files of subpackages. However,
evaluation may track which package-local values were accessed and only
BUCK files which were potentially affected (similarly to how we do
it with buckconfigs, with individual properties being projection keys).
BUCK file API
BUCK files (and
bzl files included from
BUCK files) have a global
This function returns the nearest value registered per package, or
such value does not exist.
This function is available in
bzl files, but attempt to call this function in
PACKAGE file evaluation results in an error. This restriction can
be lifted in the future.
Per-package values are not accessible as global symbols in
BUCK files. We
may reconsider it in the future.
PACKAGE files may call