diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/404.html b/404.html new file mode 100644 index 000000000000..a8ee152f7d4d --- /dev/null +++ b/404.html @@ -0,0 +1,20 @@ + + + + + +Page Not Found | Buck2 + + + + + + + + +
+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+ + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 000000000000..e9f120a02324 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +buck2.build \ No newline at end of file diff --git a/_src/.gitignore b/_src/.gitignore new file mode 100644 index 000000000000..0aebda0a49b7 --- /dev/null +++ b/_src/.gitignore @@ -0,0 +1,2 @@ +/generated/ +*.generated.md diff --git a/_src/api.md b/_src/api.md new file mode 100644 index 000000000000..067c7439c277 --- /dev/null +++ b/_src/api.md @@ -0,0 +1,16 @@ +# APIs + +A lot of Buck2 is driven by Starlark APIs. While there is a +[Starlark specification](https://github.com/bazelbuild/starlark/blob/master/spec.md), +for most purposes it can be considered a subset of Python. There are three main +places you can write Starlark in Buck2: + +- In `BUCK` files, where you can define the rules. The most interesting + functions are [the rules themselves](rules), but you will often use the + [builtin Starlark functions](starlark/globals) (most of which are the same as + in Python), and a few of the [build functions](build/globals) (e.g. `glob`). +- In rule definitions, where you can use the same Starlark standard functions, + but will heavily be using the [build functions](build/globals) (e.g. `rule` + and `attrs`). +- In [BXL](../developers/bxl), where the [context type](bxl/bxl_ctx) is one of + the more important ones. diff --git a/_src/benefits.md b/_src/benefits.md new file mode 100644 index 000000000000..0968e031b99b --- /dev/null +++ b/_src/benefits.md @@ -0,0 +1,150 @@ +--- +id: benefits +title: Benefits When Compared to Buck1 +--- + + + +For reports from real users, see the [Testimonials](testimonials.fb.md), which +include Workplace posts and their full context. + + + +## Benefits for end users + +> _"`buck2 build SOME_TARGET_I_ALREADY_BUILT_BEFORE` is basically instantaneous +> and is a super delightful experience. 🙂"_ - End user experience +> +> ([source](https://fb.prod.workplace.com/groups/buck2users/posts/3030704467185914)) + +> _"Buck2 is largely faster and more memory efficient than buck1, and where I’ve +> seen counter-examples, the buck2 team quickly optimizes and fixes that.🙂"_ - +> Software Engineer feedback +> ([source](https://fb.prod.workplace.com/groups/devx.ci.bffs/posts/616830502778501)) + +For people who use Buck on a daily basis (such as using Buck build as part of +their development inner loop), switching to Buck2 provides the following +benefits: + +- **Performance** - the performance of Buck2 is better in four ways: + - **_Fast things are fast_** - in Buck1, simply typing `buck build` when there + is nothing to do can be expensive (23 seconds in some benchmarks). In Buck2, + the same build action takes 0.1 seconds. Actions that should be fast are + fast, which enables developers to use Buck more freely, without trying to + work around the build system. + - **_Slow things are faster_** - when there is real work to do, Buck2 is + significantly closer to the critical path. Benchmarks range from 5%/10s + faster for changing a header file (lots of parallel C++ computations, Buck1 + already nearly at the critical path) to 42%/145s faster (changing a Thrift + file in a large project). + - **_Users contribute to the shared cache_** - with Buck1, only trusted CI + builds write to the network cache, while with Buck2 everyone writes to the + cache through sandboxed remote execution. This increases the chance of cache + hits, saving capacity and time. + - **_CI builds go faster_** - these numbers vary day by day, but most projects + are 2-4x faster. This means spending less time waiting for CI and saving + some capacity at the same time. +- **Correctness** - in Buck2, rules are hermetic by default. Missing + dependencies are errors. These restrictions apply to both the user-written + `BUCK` files and the language rules. + - During the process of migrating to Buck2, a huge number of missing + dependencies have been fixed. However, during the same process, several + Buck1 issues were identified that are not going to be fixed in Buck1 (such + as missing headers, genrules without dependencies, and OCaml rules don’t + track all deps). The end result is that Buck2 gives the right answer more + often, cutting down on user surprises. +- **Rule features** - the rules in Buck2, especially for less commonly used + languages (such as Haskell, OCaml, and Rust) support features above and beyond + those in Buck1. + - Examples: dependencies can be given as arguments to + `prebuilt_ocaml_library`, Haskell enables the use of stub headers from C++, + and Rust has experimental pipelining support. +- **Actively developed** - the Meta build team is putting all its efforts behind + Buck2; it's vastly easier to develop than Buck1. While Buck2 is already ahead + of Buck1 in many important aspects, the difference is only going to grow with + several improvements in the pipeline. +- **Support** - Meta can provide much better support to those having + difficulties with Buck2 than to those using Buck1. + +## Benefits for Rule Authors + +If you write language-specific rules, then Buck2 is in a different league to +Buck1. + +> _"This is all rather fun! Buck2 rules are so much more hackable than +> Buck1."_ - Software Engineer feedback +> ([source](https://fb.prod.workplace.com/groups/333784157210625/posts/928214407767594)) + +There are a number of reasons why Buck2 excels for Rule Authors: + +- **Faster developer cycle** - in Buck1, the time from changing a rule to seeing + the impact is many minutes: you first have to compile Buck1, invalidate the + dependency cache (and so on), and perhaps work between multiple OSs. With + Buck2, it takes seconds, you don’t even need to restart the daemon. +- **Simple API** - Buck2 rules use a small and documented Starlark API, which is + dependency-correct by construction. In Buck1, the rules must obey a lot of + subtle side conditions with a much larger API. +- **Easier deployment** - for Buck2, deployment is just checking the rules in, + with an atomic commit changing associated macros (when required). For Buck1, + you have to make the repo work with the old and new rules and wait for a Buck + version bump to ship your changes, perhaps a few days later. +- **Low barrier to entry** - writing rules in Buck2 is vastly easier than Buck1, + significantly increasing the developer pool. This means that writing rules is + now accessible to language experts, not just Buck experts. + +## Benefits for Integrators + +For those people who integrate Buck2 into larger systems, in addition to many of +the above benefits apply, Buck2 provides the following benefits: + +- **Faster queries** - many integrators make extensive use of `buck uquery` and + `cquery`. In Buck2, these commands are **faster** and use **less memory**. + - For example, on CI target determination (a bunch of targets/queries), Buck2 + is 25% faster at P50 (moving to 40% faster at P95) with 25% less memory + (saving over 20Gb, and crossing below the 64Gb threshold). +- **Profiling** - Buck2 already ships with five types of profiling for both + loading and analysis (flame graphs, statement breakdown, heap profiles etc). + With Buck2, these tools are much more easily accessible to people not on the + Build Infra team. + + + +- **Eden friendly** - Buck2 is tuned for the Eden architecture, performing fewer + disk operations with greater parallelism. + - For example, the slowdown caused by using Eden for `targets` on `fbandroid` + is + [reduced from 300s to 80s](https://fb.workplace.com/groups/132499338763090/posts/132580122088345). +- **Better observability** - Buck2 populates many Scuba tables with information + about + [loading](https://www.internalfb.com/intern/scuba/query/?dataset=buck2_loads), + [analysis](https://www.internalfb.com/intern/scuba/query/?dataset=buck2_analyses), + [builds](https://www.internalfb.com/intern/scuba/query/?dataset=buck2_builds) + and + [errors](https://www.internalfb.com/intern/scuba/query/?dataset=buck2_action_errors), + and more. The architecture of Buck2 ensures that all important information can + be recorded in a uniform manner, enabling sensible trade-offs to be made about + what to store vs for how long. + + + +## The downside + +While there are many benefits, it would be remiss not to include a small list of +temporary issues: + +- **Stability** - Buck2 is under active development, which means the risk of + regression is correspondingly higher. There may be issues, but they will be + fixed as quickly as possible (and lessons learned) through the through Meta's + SEV-review process. +- **Corner cases** - Buck1 has been battle-tested for nearly a decade, which has + included attention to events such as error messages in unlikely corner cases. + Only time and user feedback will enable Meta to bring Buck2 to the same level. + Please share all such feedback! + + + +- **Buck2 Web UI** - there isn’t yet a working Web UI equivalent to the one + provided by Buck1. But we’re working on it and hope to share an initial + version shortly. + + diff --git a/_src/bootstrapping.md b/_src/bootstrapping.md new file mode 100644 index 000000000000..17192e3b49ce --- /dev/null +++ b/_src/bootstrapping.md @@ -0,0 +1,32 @@ +--- +id: bootstrapping +title: Bootstrapping Buck2 +--- + +# Bootstrapping Buck2 + +To generate `BUCK` files for `buck2`'s dependencies, we use +[reindeer](https://github.com/facebookincubator/reindeer). + +Note that the resulting binary will be compiled without optimisations or +[jemalloc](https://github.com/jemalloc/jemalloc), so we recommend using the +Cargo-produced binary in further development. + +First, install `reindeer` with `Cargo`: + +```sh +cargo install --locked --git https://github.com/facebookincubator/reindeer reindeer +``` + +Next, run the following to buckify dependencies: + +```sh +cd buck2/ +reindeer --third-party-dir shim/third-party/rust buckify +``` + +Build `buck2` with `buck2`: + +```sh +buck2 build //:buck2 +``` diff --git a/_src/concepts/buck_out.md b/_src/concepts/buck_out.md new file mode 100644 index 000000000000..5a76dd36f044 --- /dev/null +++ b/_src/concepts/buck_out.md @@ -0,0 +1,22 @@ +--- +id: buck_out +title: buck-out +--- + +# buck-out + +Buck2 stores build artifacts in a directory named `buck-out` in the root of your +[project](glossary.md#project). You should not make assumptions about where +Buck2 places your build artifacts within the directory structure beneath +`buck-out` as these locations depend on Buck2's implementation and could +potentially change over time. Instead, to obtain the location of the build +artifact for a particular target, you can use one of the `--show-*-output` +options with the [`buck2 build`](../../users/commands/build) or +[`buck2 targets`](../../users/commands/targets) commands, most commonly +`--show-output`. For the full list of ways to show the output location, you can +run `buck2 build --help` or `buck2 targets --help`. + +``` +buck2 targets --show-output +buck2 build --show-output +``` diff --git a/_src/concepts/buckconfig.md b/_src/concepts/buckconfig.md new file mode 100644 index 000000000000..809e8abd3dd8 --- /dev/null +++ b/_src/concepts/buckconfig.md @@ -0,0 +1,273 @@ +--- +id: buckconfig +title: .buckconfig +--- + +The root of your [project](glossary.md#project) must contain a configuration +file named `.buckconfig`. Before executing, Buck2 reads this file to incorporate +any customizations it specifies. + +## Performance impact of Buck2 configuration changes + +Because configuration settings are sometimes included in the cache keys that +Buck2 uses in its caching system, changes to Buck's configuration can invalidate +previously-built artifacts in Buck's caches. If this occurs, Buck2 rebuilds +those artifacts, which can impact your build time. + +## The .buckconfig file uses the INI file format + +The `.buckconfig` file uses the +[INI file format](http://en.wikipedia.org/wiki/INI_file). That is, it is divided +into _sections_ where each section contains a collection of key _names_ and key +_values_. The `.buckconfig` implementation supports some modifications to the +INI file format; these are discussed below. + +### Other INI file parsers + +As mentioned previously, we have extended the INI file parser that Buck2 uses to +parse configuration files. As a result, _INI file parsers provided by other +languages or libraries are often not able to parse Buck's configuration files +successfully_. + +### Dot character not supported in section names + +We do not support the use of the _dot_ character (`.`) in section names within +Buck2 configuration files. For example, the following is **not** +supported—_although Buck2 does not issue a warning or error_. + +```ini +[foo.bar] + baz=1 +``` + +Note that sometimes you might need to define your own custom sections, such as +for platform flavors for C++ or Python. These scenarios are examples of when you +should be careful not to introduce the dot character in section names. This +constraint is because Buck2 uses the dot character to delimit section names and +key names in other contexts such as the `--config` command-line parameter. + +## Character encoding + +To ensure that any character can be encoded in a `.buckconfig` key value, you +can use escape sequences to encode characters that would otherwise be +problematic. The following escape sequences are supported. + +| `\\` | backslash | +| ------------ | --------------------------------------------------- | +| `\"` | double quote | +| `\n` | newline | +| `\r` | carriage return | +| `\t` | tab | +| `\x##` | Unicode character with code point ## (in hex) | +| `\u####` | Unicode character with code point #### (in hex) | +| `\U########` | Unicode character with code point ######## (in hex) | + +## Key values as lists + +Although the standard INI format supports only key values that represent a +single item, Buck2 supports key values that represent a list of items. The +syntax is to separate the items in the list using the space (`0x20`) character. +For example, a key value for the list of command-line flags to be passed to a +compiler could be represented as a list of the flags separated by spaces: + +``` +flags = -foo -bar -baz -qux +``` + +When a key value is parsed as a list instead of a single item, the separator +character is interpreted as a separator only when it occurs _outside of double +quotes_. For example, if `flags` is a key value interpreted as a list of items +separated by spaces, then + +``` +flags = -foo "-bar \u0429" +``` + +results in the two strings: `foo` and `-bar Щ`; the space character between +`-bar` and `\u0429` is not interpreted as a separator. + +## Transclusion of values from one key to another + +Values from other keys can be transcluded into the current key using the +following syntax inside the current key value. + +``` +$(config
.) +``` + +For example, to use the `[go].vendor_path` in a custom setting: + +``` +[custom_section]custom_value = $(config go.vendor_path) +``` + +## Comments + +In addition to the semicolon (`;`), you can use the pound sign (`#`), as a +comment character in `.buckconfig`. + +## .buckconfig.local + +The root of your [project](glossary.md#project) may contain a second +configuration file named `.buckconfig.local`. Its format is the same as that of +`.buckconfig`, but settings in `.buckconfig.local` override those in +`.buckconfig`. In practice, `.buckconfig` is a version-controlled file that +contains settings that are applicable to all team members, whereas +`.buckconfig.local` is excluded from version control to allow users to define +personal settings, such as personal aliases. + +## Other initialization files + +In addition to the `.buckconfig` and `.buckconfig.local` files in the project +root, Buck2 reads configuration settings from the following additional +locations, some of which are actually directories: + +1. Directory `.buckconfig.d` located in the project root directory. +2. File `.buckconfig` and directory `.buckconfig.d` located in the current + user's home directory which, on Unix-like systems, is available from the + `HOME` environment variable or through the `~` symbol. +3. File `buckconfig` and directory `buckconfig.d` located in system directory + `/etc/`. + +Buck2 treats _any_ file—irrespective of name—in a +`.buckconfig.d`(`buckconfig.d`) directory (excluding files found in +subdirectories) as a Buck2 configuration file, provided that it adheres to +`.buckconfig` syntax. Note that a `.buckconfig.d` directory is distinct from the +similarly-named `.buckd` directory which is used by the +[Buck2 Daemon (`buckd`)](daemon.md) . For a description of how Buck2 resolves +collisions between settings in these configuration files, see the section +[**Precedence of Buck2 configuration specifications**](#precedence-of-buck2-configuration-specifications) +below. + +## Command-line control of configuration + +In addition to the above configuration files, Buck2 supports specifying +additional configuration files from the Buck2 command line using the +`--config-file` parameter. You can also specify configuration settings +_individually_ on the Buck2 command line using the `--config` (`-c`) parameter. +Furthermore, you can aggregate these settings into _flag files_ using the +`--flagfile` parameter. A flag file provides similar functionality to a +configuration file but uses a different syntax. Flag files are sometimes called +_mode files_ or _at_ (`@`) files. + +## Precedence of Buck2 configuration specifications + +The following list shows the order of precedence for how Buck2 interprets its +configuration specifications. Settings specified using a method closer to the +top of the list have higher precedence and will override those lower on the +list. For example, the `.buckconfig` file in the repo overrides a `.buckconfig` +file in the user's `HOME` directory. + +1. Configuration specified on the command line using `--config` (`-c`), + `--config-file` and `--flagfile`. Configuration specified later on the + command line overrides configuration specified earlier. +1. `.buckconfig.local` in the repo. +1. `.buckconfig` in the repo. +1. Files in a `.buckconfig.d` folder of the repo. +1. `.buckconfig.local` in user's `HOME` directory. +1. Files in a `.buckconfig.d` folder in user's `HOME` directory. +1. The global file `/etc/buckconfig` +1. Files in the global directory `/etc/buckconfig.d` + +Files in a `.buckconfig.d` (`buckconfig.d`) directory have precedence according +to the lexicographical order of their file names. Files _later_ in the +lexicographical order have precedence over files earlier in that order. + +## Configuration files can include other files + +Any of the configuration files that we've discussed so far can also include by +reference other files that contain configuration information. These included +files can contain complete `.buckconfig` sections or they can contain a group of +key name/value pairs that constitute part of a section. In this second use case, +you'll need to ensure that the _included_ file is referenced beneath the +appropriate section in the _including_ file. Because of this additional +complexity, we recommend that you include only files that contain complete +sections. **Note:** Inclusion of files is a Buck-specific extension to the INI +file parser that Buck2 uses. Therefore, if you use this feature, your Buck2 +configuration files will probably not be parsable by other more-generic INI file +parsers. The syntax to include a file is + +``` + +``` + +where _path-to-included-file_ is either a relative path from the including file +(recommended) or an absolute path from the root of the file system. You can also +specify that the file should be included only if it exists by prefixing with a +question mark (`?`). + +``` + +``` + +If you use this prefix, it is not an error condition if the file does not exist; +Buck2 just silently continues to process the rest of the configuration file. In +the following example, the `.buckconfig` file includes the file +`cxx-other-platform.include` which exists in the subdirectory +`cxx-other-platform`. The `.buckconfig` file will also include the file +`future-platform` from the directory `future-platform.include` if that file +exists. + +``` +# +# .buckconfig +# +[cxx] + cxxppflags="-D MYMACRO=\"Buck\"" + + + + +# +# cxx-other-platform.include +# +[cxx#other_platform] + cxxppflags="-D MYMACRO=\"Watchman\"" +``` + +## Sections + +Below is an incomplete list of supported buckconfigs. + +## [alias] + +This section contains definitions of [build target](build_target.md) aliases. + +``` +[alias]app = //apps/myapp:app + apptest = //apps/myapp:test +``` + +These aliases can then be used from the command line: + +``` +$ buck2 build app +$ buck2 test apptest +``` + +## [cells] + +Lists the cells that constitute the Buck2 project. Buck2 builds that are part of +this project—that is, which use this `.buckconfig`—can access the cells +specified in this section. + +``` +[cells] + buck = . + bazel_skylib = ./third-party/skylark/bazel-skylib +``` + +The string on the left-hand side of the equals sign is the _alias_ for the cell. +The string on the right-hand side of the equals sign is the path to the cell +from the directory that contains this `.buckconfig` file. It is not necessary to +include the current cell in this section, but we consider it a best practice to +do so: + +``` +buck = . +``` + +You can view the contents of this section using the `buck2 audit cell` command. + +`[repositories]` is additionally supported as a deprecated alternative name for +this section. diff --git a/_src/concepts/build_file.md b/_src/concepts/build_file.md new file mode 100644 index 000000000000..8a4279bdde20 --- /dev/null +++ b/_src/concepts/build_file.md @@ -0,0 +1,63 @@ +--- +id: build_file +title: Build File +--- + +# Build File + +A _build file_ is a file, typically named `BUCK`, that defines one or more +[build rule](build_rule.md)s. Note that you can change the name that Buck2 uses +for the build file in the `buildfile` section of `.buckconfig`. A source file in +your project can only be referenced by rules in its "nearest" build file, where +"nearest" means its closest direct ancestor in your project's file tree. (If a +source file has a build file as a sibling, then that is its nearest ancestor.) +For example, if your project had the following `BUCK` files: + +``` +java/com/facebook/base/BUCK +java/com/facebook/common/BUCK +java/com/facebook/common/collect/BUCK +``` + +Then your build rules would have the following constraints: + +- Rules in `java/com/facebook/base/BUCK` can reference any file under + `java/com/facebook/base/`. +- Rules in `java/com/facebook/common/` can reference any files under that + directory, except for those under `java/com/facebook/common/collect/`, as + those "belong" to the `BUCK` file in the `collect` directory. + +The set of source files accessible to a build file is also known as its _build +package_. The way to refer to code across build packages is to create build +rules and use `deps` to refer to that code. Going back to the previous example, +suppose code in `java/com/facebook/common/concurrent/` wants to depend on code +in `java/com/facebook/common/collect/`. Presumably +`java/com/facebook/common/collect/BUCK` has a build rule like: + +``` +java_library( + name = 'collect', + srcs = glob(['*.java']), + deps = ['//java/com/facebook/base:base',],) +``` + +Then `java/com/facebook/common/BUCK` could have a rule like: + +``` +java_library( + name = 'concurrent', + srcs = glob(['concurrent/*.java']), + deps = ['//java/com/facebook/base:base','//java/com/facebook/common/collect:collect',],) +``` + +whereas the following **would be invalid** because +`java/com/facebook/common/collect/` has its own build file, so +`//java/com/facebook/common/collect:concurrent` cannot list +`java/com/facebook/common/collect/*.java` in its `srcs`. + +``` +java_library( + name = 'concurrent', + srcs = glob(['collect/*.java', 'concurrent/*.java']), + deps = ['//java/com/facebook/base:base',],) +``` diff --git a/_src/concepts/build_rule.md b/_src/concepts/build_rule.md new file mode 100644 index 000000000000..b7b8e6472d82 --- /dev/null +++ b/_src/concepts/build_rule.md @@ -0,0 +1,164 @@ +--- +id: build_rule +title: Build Rule +--- + +# Build Rule + +A _build rule_ is a procedure for producing output files from a set of input +files in the context of a specified build configuration. Build rules are +specified in [build file](build_file.md)s—typically named BUCK. **Note:** A +build rule must explicitly specify, in its arguments, all of its required inputs +in order for Buck2 to be able to build the rule's output in a way that is +deterministic and reproducible. + +## Buck2's collection of build rules + +Buck2 comes with a collection of built-in build rules for many common build +procedures. For example, compiling Java code against the Android SDK is a common +procedure, so Buck2 provides the build rule +[`android_library`](../../api/rules/#android_library) to do that. Similarly, the +final product of most Android development is an APK, so you can use the build +rule [`android_binary`](../../api/rules/#android_binary) to create an APK. + +## Source files as inputs to build rules + +Most build rules specify source files as inputs. For example, a +[`cxx_library`](../../api/rules/#cxx_library) rule would specify `.cpp` files as +inputs. To support specifying these files, a `cxx_library` rule provides the +`srcs` argument. Some languages, such as C++, use header files as well. To +specify these, `cxx_library` provides a `headers` argument. In addition to +`srcs` and `headers`, some rules provide variants of these arguments, such as +`platform_srcs` and `platform_headers`. These arguments support groups of source +files that should be used as inputs only when building for specific platforms. + +### Package boundaries and access to source files + +In Buck2, a BUCK file defines a _package_, which corresponds _roughly_ to the +directory that contains the BUCK file and those subdirectories that do not +themselves contain BUCK files. (To learn more, see the +[Key Concepts](key_concepts.md) topic.) A rule in a BUCK file cannot specify a +source file as an input unless that source file is in that BUCK file's package. +An exception to this restriction exists for header files, but only if a rule in +the package that contains the header file _exports_ that header file using the +`exported_headers` argument. For more details, see the description for +`exported_headers` in, for example, the +[`cxx_library`](../../api/rules/#cxx_library) topic. More commonly though, the +package for a BUCK file contains all the source files required for the rules +defined in that BUCK file. Functionality in source files from other packages is +made available through the artifacts produced by the rules in the BUCK files for +those packages. For example, a [`cxx_binary`](../../api/rules/#cxx_binary) might +use the functionality in a `cxx_library` that is defined in another package. To +access that functionality, the `cxx_binary` would take that `cxx_library` as a +_dependency_. + +##### Symlinks: Use with caution if at all + +We recommend that you do _not_ use symlinks—either absolute or relative—to +specify input files to build rules. Although using symlinks in this context does +sometimes work, it can lead to unexpected behavior and errors. + +## Dependencies: Output from one rule as input to another rule + +A build rule can use the output from another build rule as one of its inputs by +specifying that rule as a _dependency_. Typically, a build rule specifies its +dependencies as a list of [build target](build_target.md)s in its `deps` +argument. However, the rule can also specify dependencies—as build targets—in +other arguments, such as `srcs`. **Example:** The output of a +[`java_library`](../../api/rules/#java_library) rule is a JAR file. If a +`java_library` rule specifies another `java_library` rule as a dependency, the +JAR file produced by the specified rule is added to the classpath for the +`java_library` that depends on it. **Example:** If a +[`java_binary`](../../api/rules/#java_binary) rule specifies a `java_library` +rule as a dependency, the JAR file for the specified `java_library` is available +on the classpath for the `java_binary`. In addition, in the case of +`java_binary`, the JAR files for any dependencies of the `java_library` rule +_are also_ made available to the `java_binary` rule—and if those dependencies +have dependencies of their own, they are added as well. This exhaustive cascade +of dependencies is referred to as the rule's _transitive closure_. + +### Required dependencies are always built first + +Buck2 guarantees that any dependencies that a rule lists that are required in +order to build that rule are built successfully _before_ Buck2 builds the rule +itself. Note though that there can be special cases—such as +[`apple_bundle`](../../api/rules/#apple_bundle)—where a rule's listed +dependencies do not actually need to be built before the rule. + +### Visibility + +In order for a build rule to take a dependency on another build rule, the build +rule on which the dependency is taken must be _visible_ to the build rule taking +the dependency. A build rule's `visibility` argument is a list of +[build target pattern](target_pattern.md)s that specify the rules that can take +that rule as a dependency. For more information about the concept of visibility +in Buck2, see the [Visibility](visibility.md) topic. + +### Dependencies define a graph + +Build rules and their dependencies define a directed acyclic graph (DAG). Buck2 +requires this graph to be acyclic to make it possible to build independent +subgraphs in parallel. + +## How to handle special cases: genrules and macros + +Although Buck2 provides a rich set of built-in build rules for developers, it is +not able to address all possible needs. As an "escape hatch," Buck2 provides a +category of generic build rules called _genrules_. With genrules, you can +perform arbitrary operations using shell scripts. The genrules supported by +Buck2 are: + +- [`genrule`](../../api/rules/#genrule) +- [`apk_genrule`](../../api/rules/#apk_genrule) +- [`cxx_genrule`](../../api/rules/#cxx_genrule) + +### Multiple output files with genrules + +In most cases, a build rule produces exactly one output file. However, with +genrules, you can specify an output _directory_ and write arbitrary files to +that directory. + +### Macros + +Finally, note that you can define functions that generate build rules. In +general, this should not be something that you need to do, but taking advantage +of this option might help you add needed functionality to Buck2's without +editing its source code. + +## String parameter macros + +It is also possible to expand references to other rules within the `cmd`, using +builtin `string parameter macros`. All build rules expanded in the command are +automatically considered to be dependencies of the `genrule()`. + +Note that the paths returned by these macros are _relative_ paths. Using +relative paths ensures that your builds are _hermetic_, that is, they are +reproducible across different machine environments. + +`$(classpath //path/to:target)` + +Expands to the transitive classpath of the specified build rule, provided that +the rule has a Java classpath. If the rule does not have (or contribute to) a +classpath, then an exception is thrown and the build breaks. + +`$(exe //path/to:target)` + +Expands a build rule that results in an executable to the commands necessary to +run that executable. For example, a `java_binary()` might expand to a call to +`java -jar path/to/target.jar` . Files that are executable (perhaps generated by +a `genrule()`) are also expanded. If the build rule does not generate an +executable output, then an exception is thrown and the build breaks. + +If the `$(exe my_dependency)` dependency should actually be built with the +target platform, use `$(exe_target my_dependency)` instead, which will stick to +the same platform as the target. + +`$(location //path/to:target)` + +Expands to the location of the output of the specified build rule. This means +that you can refer to the output without needing to be aware of how Buck is +storing data on the disk mid-build. + +``` + +``` diff --git a/_src/concepts/build_target.md b/_src/concepts/build_target.md new file mode 100644 index 000000000000..fccef48d9a77 --- /dev/null +++ b/_src/concepts/build_target.md @@ -0,0 +1,129 @@ +--- +id: build_target +title: Build Target +--- + +# Build Target + +A _build target_ is a string that identifies a build rule in your project. Build +targets are used as arguments to Buck2 commands, such as +[`buck2 build`](../../users/commands/build) and +[`buck2 run`](../../users/commands/run). Build targets are also used as +arguments to [build rules](build_rule.md) to enable one build rule to reference +another. For example, a build rule might use a build target to reference another +rule in order to specify that rule as a _dependency_. + +#### Fully-qualified build targets + +Here is an example of a _fully-qualified_ build target: + +``` +//java/com/facebook/share:ui +``` + +A fully-qualified build target has three components: + +1. The `//` prefix indicates that the subsequent path is from the _root_ of your + project. You can use the `buck2 root` command to identify the root of your + project. +2. The `java/com/facebook/share` between the `//` prefix and the colon (`:`) + indicates that the [build file](build_file.md) (usually named `BUCK`) is + located in the directory `java/com/facebook/share`. +3. The `ui` after the colon (`:`) indicates the name of the build rule within + the build file. Build rule names must be unique within a build file. By + _name_ we mean, more formally, the value of the `name` argument to the build + rule. + +Note that the name of the build file itself—usually BUCK—does _not_ occur in the +build target. All build files within a given Buck2 project must have the same +name—defined in the `[buildfile].name` entry of `.buckconfig`. Therefore, it is +unnecessary to include the name in the target. The full regular expression for a +fully-qualified build target is as follows: + +``` +[A-Za-z0-9._-]*//[A-Za-z0-9/._-]*:[A-Za-z0-9_/.=,@~+-]+ +|- cell name -| | package path | |--- rule name ----| +``` + +In Buck2, a _cell_ defines a directory tree of one or more Buck2 packages. For +more information about Buck2 cells and their relationship to packages and +projects, see the [Key Concepts](key_concepts.md) topic. **NOTE:** All target +paths are assumed to start from the root of the Buck2 project. Buck2 does not +support specifying a target path that starts from a directory below the root. +Although the double forward slash (`//`) that prefixes target paths can be +omitted when specifying a target from the command line (see **Pro Tips** below), +Buck2 still assumes that the path is from the root. Buck2 does support +_relative_ build paths, but in Buck2, that concept refers to specifying build +targets _from within_ a build file. See **Relative build targets** below for +more details. + +#### Relative build targets + +A _relative_ build target can be used to reference a [build rule](build_rule.md) +_within the same _[_build file_](build_file.md). A relative build target starts +with a colon (`:`) and is followed by only the third component (or _short name_) +of the fully-qualified build target. The following snippet from a build file +shows an example of using a relative path. + +``` +## Assume this rule is in //java/com/facebook/share/BUCK# +java_binary( + name = 'ui_jar', + deps = [## The following target path## //java/com/facebook/share:ui## is the same as using the following relative path.#':ui',],) +``` + +## Command-line Pro Tips + +Here are some ways that you can reduce your typing when you specify build +targets as command-line arguments to the `buck2 build` or `buck2 run` commands. +Consider the following example of a fully-qualified build target used with the +`buck2 build` command: + +``` +buck2 build //java/com/facebook/share:share +``` + +Although Buck2 is always strict when parsing build targets in build files, Buck2 +is flexible when parsing build targets on the command-line. Specifically, the +leading `//` is optional on the command line, so the above could be: + +``` +buck2 build java/com/facebook/share:share +``` + +Also, if there is a forward slash before the colon, it is ignored, so this could +also be written as: + +``` +buck2 build java/com/facebook/share/:share +``` + +which enables you to produce the red text shown below using tab-completion, +which dramatically reduces how much you need to type: + +``` +buck2 build java/com/facebook/share/:share +``` + +Finally, if the final path element matches the value specified after the colon, +it can be omitted: + +``` +# This is treated as //java/com/facebook/share:share. +buck2 build java/com/facebook/share/ +``` + +which makes the build target even easier to tab-complete. For this reason, the +name of the build rule for the primary deliverable in a build file is often +named the same as the parent directory. That way, it can be built from the +command-line with less typing. + +## See also + +Buck2 supports the ability to define **_aliases_ for build targets**; using +aliases can improve brevity when specifying targets on the Buck2 command line. +For more information, see the [`[alias]`](buckconfig.md#alias) section in the +documentation for [`.buckconfig`](buckconfig.md). A +[**build target pattern**](target_pattern.md) is a string that describes a set +of one or more build targets. For example, the pattern `//...` is used to build +an entire project. For more information, see the **Build Target Pattern** topic. diff --git a/_src/concepts/concept_map.md b/_src/concepts/concept_map.md new file mode 100644 index 000000000000..d786d7a2446e --- /dev/null +++ b/_src/concepts/concept_map.md @@ -0,0 +1,27 @@ +--- +id: concept_map +title: Concept Map +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +The Concept Map provides an at-a-glance overview of the relationships between +widely used Buck2 concepts. It is meant to be a tool to help those onboarding to +Buck2 to quickly gain an understanding of the Buck2 environment. + +justifyContent + + +:::note +The Concept Map is for reference only and is not intended to be 100% +accurate nor complete. + + + +The version above was created in LucidChart and is located in the +[Buck2 team folder](https://lucid.app/folder/invitations/accept/inv_c5c89718-b1cd-4b22-ae76-a47616719948). +To login into Lucidcharts, do `bunnylol lucidchart` + + + +::: diff --git a/_src/concepts/configurations.md b/_src/concepts/configurations.md new file mode 100644 index 000000000000..567e0e570bbf --- /dev/null +++ b/_src/concepts/configurations.md @@ -0,0 +1,91 @@ +--- +id: configurations +title: Configurations +--- + +For rule authors see also: [Configurations](../rule_authors/configurations.md) + +When building a target, buck always builds it in a particular "configuration." +The configuration typically includes information like the target os, target +arch, sanitizers, opt level, etc. One way to understand the effect that a +configuration has is via the `cquery` and `uquery` commands. The cquery command +will compute the appropriate configuration for a target and display a version of +that target's attributes with the configuration applied. The `uquery` command +will not apply a configuration. + +Here is a heavily trimmed version of the outpus of invoking `uquery` and +`cquery` on `//buck2/app/buck2_core:buck2_core`. + +``` +> buck2 uquery -A '"//buck2/app/buck2_core:buck2_core"' +{ + "fbcode//buck2/app/buck2_core:buck2_core": { + "buck.type": "rust_library", + "buck.package": "fbcode//buck2/app/buck2_core:TARGETS", + "name": "buck2_core", + "visibility": [ + "PUBLIC" + ], + "deps": { + "fbsource//third-party/rust:anyhow", + "fbsource//third-party/rust:arc-swap", + "fbsource//third-party/rust:blake3", + "fbsource//third-party/rust:compact_str", + "fbsource//third-party/rust:dashmap", + { + "__type": "selector", + "entries": { + "DEFAULT": [], + "ovr_config//os:windows": [ + "fbsource//third-party/rust:common-path" + ] + } + }, + { + "__type": "selector", + "entries": { + "DEFAULT": [], + "ovr_config//os:linux": [ + "fbsource//third-party/rust:nix" + ] + } + }, + }, + } +} +``` + +``` +> buck2 cquery -A '"//buck2/app/buck2_core:buck2_core"' +{ + "fbcode//buck2/app/buck2_core:buck2_core (ovr_config//platform/linux:)": { + "buck.type": "rust_library", + "buck.package": "fbcode//buck2/app/buck2_core:TARGETS", + "buck.target_configuration": "ovr_config//platform/linux:", + "buck.execution_platform": "fbcode//buck2/platform/", + "name": "buck2_core", + "visibility": [ + "PUBLIC" + ], + "deps": [ + "fbsource//third-party/rust:anyhow (ovr_config//platform/linux:)", + "fbsource//third-party/rust:arc-swap (ovr_config//platform/linux:)", + "fbsource//third-party/rust:blake3 (ovr_config//platform/linux:)", + "fbsource//third-party/rust:compact_str (ovr_config//platform/linux:)", + "fbsource//third-party/rust:dashmap (ovr_config//platform/linux:)", + "fbsource//third-party/rust:nix (ovr_config//platform/linux:)" + ] +} +``` + +The `cquery` output has additional `buck.target_configuration` and +`buck.execution_platform` attributes which tell you what the target is being +built for and what it's being built on, respectively. `uquery` doesn't have +those. + +The deps in `uquery` also have a number of selects; these indicate that the +`common-path` dependency should only be included when building for Windows, +while the `nix` dependency is needed only for Linux. In `cquery` that +distinction has been resolved; because the target has been configured for Linux, +the `nix` dependency is present and indistinguishable from any other, while the +`common-path` dependency is gone. diff --git a/_src/concepts/daemon.md b/_src/concepts/daemon.md new file mode 100644 index 000000000000..f2f93a30c9f8 --- /dev/null +++ b/_src/concepts/daemon.md @@ -0,0 +1,35 @@ +--- +id: daemon +title: Daemon (buckd) +--- + +The first time that a Buck2 command is run, Buck2 starts a daemon process for +the current project. For subsequent commands, Buck2 checks for the running +daemon process and, if found, uses the daemon to execute the command. Using the +Buck2 daemon can save significant time as it enables Buck to share cache between +Buck2 invocations. + +By default, there is 1 daemon per [project](./glossary.md#project) root, you can +run multiple daemons in the same project by specifying an +[isolation dir](./glossary.md#isolation-dir). + +While it runs, the Buck daemon process monitors the project's file system for +changes. The Buck daemon excludes from monitoring any subtrees of the project +file system that are specified in the `[project].ignore` setting of +`.buckconfig`. + +## Killing or disabling the Buck daemon + +The Buck daemon process is killed if `buck2 clean` or `buck2 kill` commands are +run. Note that they won't kill the daemon associated with custom isolation dirs. +To do that, run using the `--isolation-dir` option +(`buck2 --isolation-dir `) + + + +The Daemon is also killed when: + +- The `buck2 killall` command is run. +- A new buck2 version is available. + + diff --git a/_src/concepts/glossary.md b/_src/concepts/glossary.md new file mode 100644 index 000000000000..e29b7561659d --- /dev/null +++ b/_src/concepts/glossary.md @@ -0,0 +1,295 @@ +--- +id: glossary +title: Glossary of Terms +toc_max_heading_level: 4 +--- + +#### .buckconfig + +The root of your [project](#project) must contain a configuration file named +`.buckconfig`. Before executing, Buck2 reads this file to incorporate specified +customizations. See [.buckconfig](buckconfig.md) for more info. + +#### Action + +An individual, cacheable, ideally hermetic command that's run during the +[build](#buck-file). It takes [artifacts](#artifact) as inputs and produces +other artifacts as outputs. An example command could be `gcc -o main main.c`, +which takes the artifact `main.c` (a source file) and produces the artifact +called `main` (the compiled binary). + +#### Action digest + +Encoded [action](#action) representation. It is sent to +[remote execution](#remote-execution-re). Used among other things to retrieve +action inputs and to check for cache hits + +#### Action graph + +The dependency graph of all [actions](#action) belonging to a target: it can be +queried with `buck2 aquery`. + +#### Artifact + +A single input or output of an [action](#action). These are files that +participate as inputs or outputs of a build and can be source files or build +outputs. For more information, see the +[Artifact API](https://buck2.build/docs/api/build/Artifact/). + +#### Attribute + +Declared by a [rule](#rule) and used to express the properties of a particular +instance of a rule to create a [target](#target). For example, srcs, deps and +copts, which declare a target's source files, dependencies, and custom compiler +options, respectively. The available attributes for a target depend on its rule +type. + +#### BUCK file + +A `BUCK` file (the name is configurable, some projects use `TARGETS`) is the +main configuration file that tells Buck2 what to build, what their dependencies +are, and how to build them. Buck2 takes a `BUCK` file as input and evaluates the +file to declare [targets](#target), which are then used to create a graph of +dependencies and to derive the [actions](#action) that must be completed to +build intermediate and final software outputs. A `BUCK` file marks a directory +and any sub-directories not containing a `BUCK` file as a [package](#package). + +#### BXL + +BXL ([Buck eXtension Language](https://buck2.build/docs/developers/bxl)) scripts +are written in [Starlark](#starlark) (a restricted subset of Python) and give +integrators the ability to inspect and interact directly with the buck2 graph. + +BXL scripts can query the [action graph](#action-graph), +[configured graph](#configured-graph), and +[unconfigured graph](#unconfigured-graph). They can also create +[actions](#action) and trigger builds. + +#### Cell + +The directory tree of one or more Buck2 [packages](#package). A Buck2 build can +involve multiple cells. The cell root always contains a +[.buckconfig](#buckconfig), although the presence of a .buckconfig file doesn't +in itself define a cell. Rather, the cells involved in a build are defined at +the time Buck2 is invoked; they are specified in the .buckconfig for the Buck +[project](#project). + +#### Configuration + +Configurations consist of a set of 'constraint values' that are used to resolve +`select` [attributes](#attribute) prior to evaluating [rule](#rule) +implementations: the attribute takes the value of the first branch in the +`select` that matches the configuration. + +Configurations are instantiated by rules that produce a `PlatformInfo` +[provider](#provider). Once created, targets can receive their configuration +through a variety of mechanisms, such as: + +- Inheritance - by default, when following a dependency edge A -> B, B inherits + A's configuration. +- The `default_target_platform` attribute and `--target-platforms` command line + flag. +- [Transitions](#transition) (see below). + +Configurations allow a single target to exist in multiple variants in the +configured graph (for example, to build a given binary at differing optimization +levels or targeting different CPU architectures). + +#### Configured graph + +The configured target graph is generated by configuring target nodes in the +[unconfigured target graph](#unconfigured-graph). That is, `selects` are fully +resolved and configurations applied. The configured graph includes information +about the [configurations](#configuration) and [transitions](#transition) +involved in building targets. The same target may appear in multiple different +configurations (when printed, the configuration is after the target in +parentheses). + +#### Constraint + +A constraint represents a property that may differ across different +[target](#target) or build contexts, such as CPU architecture, the version of a +system-installed compiler, optimization level, which version of a particular +library to use, etc. + +#### Daemon + +The Daemon process lives between invocations and is designed to allow for cache +reuse between Buck2 invocations, which can considerably speed up builds. For +more information, see [Daemon (buckd)](daemon.md). + +#### Dependency + +A directed edge between two [targets](#target). A target `A` can have a +dependency on target `B`, for example, if any `dep` attribute of `A` mentions +`B`. A target's dependence on another target is determined by the +[visibility](#visibility) of the latter. + +#### Execution platform + +A type of [rule](#rule) that includes information such as what execution types a +[target](#target) supports, which can be [remote](#remote-execution-re), local, +and [hybrid](#hybrid-execution) execution. Also, whether it supports cache +uploads, which allows users to get cache hits for things that executed locally. + +#### Hybrid execution + +Allows Buck2 to race local and remote execution and get whichever finishes first +(unless there's a cache hit, then it will get output from cache). This can +provide substantial speedup by eliminating the overhead of going to +[remote execution](#remote-execution-re) when there is enough capacity to +service the build locally. + +#### Isolation dir + +Instances of Buck2 share a [daemon](#daemon) if and only if their isolation +directory is identical. The isolation directory also influences the output paths +provided by Buck2. + +#### Modifiers + +It's a modification of a constraint from the existing +[configuration](#configuration) to obtain a new configuration. They provide a +unified way to specify build settings on a [project](#project), +[target](#target), and command line level. It is intended to replace +[target platforms](#target-platform) and most use cases of +[.buckconfigs](#buckconfig). + +#### Package + +A directory that contains a Buck2 [BUCK file](#buck-file) and all source files +belonging to the same directory as the BUCK file, or any of its subdirectories +that do not contain a BUCK file themselves. + +#### Prelude + +The prelude is a unique `.bzl` file located at `prelude//prelude.bzl`. Buck2 +implicitly loads all the symbols defined in the prelude whenever it loads a +[`BUCK`](#buck-file) file. Symbols defined outside the prelude can be imported +via a `load()` statement. + +When you create a Buck2 project using `buck2 init --git`, it will contain the +same prelude used internally at Meta by Buck2 users. It is viewable at +https://github.com/facebook/buck2/tree/main/prelude. + +#### Project + +The Outermost directory where there is a [.buckconfig](#buckconfig): also known +as the [root cell](#cell). The .buckconfig for the project specifies the +[cells](#cell) that constitute the Buck2 project. Specifically, these cells are +specified in the '[cells]' section of the `.buckconfig`. All command invocations +are executed from the project root. + +#### Provider + +Data returned from a [rule](#rule) function. It's the only way that information +from this rule is available to other rules that depend on it (see +[dependency](#dependency)). For more information, see +[Providers](https://buck2.build/docs/rule_authors/writing_rules/#providers). + +#### Platform + +A named set of [constraints](#constraint), defining a specific runtime +environment. E.g. `cpu=x86_64, os=windows` + +#### Remote execution (RE) + +Distributed execution of [actions](#action) on remote workers. It can speed up +builds significantly by scaling the nodes available for parallel actions, and by +caching action outputs across Buck2 users. + +#### Rule + +A rule consists of an attribute spec and an implementation, which is a +[Starlark](#starlark) function. + +The attribute spec declares what attributes the rule expects to receive. The +rule implementation receives the [attributes](#attribute) of a [target](#target) +and the [providers](#provider) of its [dependencies](#dependency). It can +declare new [actions](#action) and [artifacts](#artifact) and must return +[providers](#provider) that can be used to pass data to its dependents or to +Buck2 itself. + +Rules are instantiated in [BUCK files](#buck-file) to declare targets and set +their attributes. The rule implementation is called when Buck2 needs its +providers, which can happen when the target is built, or when one of its +dependents is. + +As an example, the `cxx_binary` rule could be used to create a C++ binary, but +`android_binary` rule would be used to create an Android APK + +#### Starlark + +Starlark is a dialect of Python originally developed by Google for the +[Bazel build tool](https://bazel.build/rules/language). It is the configuration +language of the Buck2 build system and the language you use in `.bzl` and +[`BUCK` files](#buck-file) to define and instantiate [rules](#rule). + +There are many reasons why Meta has chosen Starlark, as detailed in +[The Rust Starlark library](https://developers.facebook.com/blog/post/2021/04/08/rust-starlark-library/) +article. + +The Buck2 project maintains and uses an open source +[Starlark interpreter in Rust](https://github.com/facebook/starlark-rust). + +#### Subtarget + +Collection of [providers](#provider) that can be accesed by name. The subtargets +can have their own subtargets as well, which can be accessed by chaining them, +e.g.: `buck2 build cell//foo:bar[baz][qux]`. + +#### Target + +An object that is defined in a [BUCK file](#buck-file). Targets represent the +buildable units of a build from the perspective of the end user. Declared by +instantiating a [rule](#rule) with attributes. A target has +[dependencies](#dependency), which are references to other targets. + +#### Target label + +The identifier for a [target](#target). Structured as +`cell_alias//path/to/package:target`, where `cell_alias//` maps to a +[cell root](#cell) path (as defined in the [./buckconfig](#buckconfig) of the +cell this target belongs to), `path/to/package` is the [package](#package) +directory that contains the [BUCK file](#buck-file) declaring the target +(relative to the mapped cell alias), and `:target` is the target's name. + +#### Target pattern + +A string that resolves to a set of [targets](#target). They can be used as +arguments to commands such as `buck2 build` and `buck2 uquery`. They can also be +used in the [visibility](#visibility) argument of a [rule](#rule). For more +information, see [Target pattern](./target_pattern.md). + +#### Target platform + +Represents the [platform](#platform) that the final output is built for residing +and executing. If buck2 is a chef, and the output is the meal, the target +platform would be the people that eat the meal. + +#### Target universe + +A set of configured targets and their transitive deps. In the context of cquery +and build in the Buck2 CLI, any literals are resolved to all matching targets +within the universe. Target universe can be passed explicitly on the Buck2 CLI +via `--target-universe`. If omitted, the target universe will be inferred by +constructing a universe using all the target literals (and their transitive +deps) within the query string for cquery. + +#### Transition + +Allows the [configuration](#configuration) to change across a +[dependency](#dependency) edge. That is, normally, if [target](#target) A +depends on target B, then if the configuration for A is X, then B is configured +using X too. By using a transition, you can produce X to configure B instead. + +#### Unconfigured graph + +A graph of [targets](#target) before [configurations](#configuration) are +applied. Can be queried via `buck2 uquery`. + +#### Visibility + +Determines whether a [target](#target) can include another [target](#target) as +its [dependency](#dependency). For more information, see +[Visibility](./visibility.md). diff --git a/_src/concepts/key_concepts.md b/_src/concepts/key_concepts.md new file mode 100644 index 000000000000..a8b7fcc4ff53 --- /dev/null +++ b/_src/concepts/key_concepts.md @@ -0,0 +1,85 @@ +--- +id: key_concepts +title: Key Concepts +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Key concepts + +Buck2 has a number of fundamental concepts: + +- A [**_build rule_**](build_rule.md) describes how to produce an output file + from a set of input files. Most build rules are specific to a particular + language or platform. For example, you would use the + [`cxx_binary`](../../api/rules/#cxx_binary) rule to create a C++ binary, but + you would use the [`android_binary`](../../api/rules/#android_binary) rule to + create an Android APK. +- A [**_build target_**](build_target.md) is a string that uniquely identifies a + build rule. It can be thought of as a URI for the build rule within the Buck2 + project. +- A [**_build file_**](build_rule.md) defines one or more build rules. In Buck2, + build files are typically named `BUCK`. A `BUCK` file is analogous to the + `Makefile` used by the Make utility. In your project, you will usually have a + separate `BUCK` file for each buildable unit of software—such as a binary or + library. For large projects, you could have hundreds of `BUCK` files. + +A Buck2 **_package_** comprises of: a Buck2 build file (a `BUCK` file), all +files—such as source files and headers—in the same directory as the `BUCK` file +or in subdirectories, provided those subdirectories do not themselves contain a +`BUCK` file. To say it another way, a `BUCK` file defines the root of a package, +but Buck2 packages might not include all their subdirectories because Buck2 +packages do not overlap or contain other Buck2 packages. For example, in the +following diagram, the BUCK file in directory `app-dir-1` defines that directory +as the root of a package—which is labeled **Package A** in the diagram. The +directory `app-dir-2` is part of Package A because it is a subdirectory of +`app-dir-1`, but does not itself contain a BUCK file. Now, consider directory +`app-dir-3`. Because `app-dir-3` contains a BUCK file it is the root of a new +package (**Package B**). Although `app-dir-3` is a subdirectory of `app-dir-1`, +it is _not_ part of Package A. Buck2 has the concept of a **_cell_**, which +defines a directory tree of one or more Buck2 packages. A Buck2 build could +involve multiple cells. Cells often correspond to repositories, but this isn't +required. The root of a Buck2 cell contains a global configuration file called +[**`.buckconfig`**](buckconfig.md). Note that although the cell root should +contain a `.buckconfig`, the presence of a `.buckconfig` file doesn't in itself +define a cell. Rather, _the cells involved in a build are defined at the time +Buck2 is invoked_; they are specified in the `.buckconfig` for the Buck2 +_project_ (see below). A Buck2 **_project_** is defined by the `.buckconfig` +where Buck2 is invoked, or if that directory doesn't contain a `.buckconfig`, +the project is defined by the `.buckconfig` in the nearest ancestor directory. +The `.buckconfig` for the project specifies the cells that constitute the Buck2 +project. Specifically, these cells are specified in the +[cells](buckconfig.md#cells) section of the `.buckconfig`. Note that the +directory tree rooted at this `.buckconfig` is automatically considered a cell +by Buck2; in other words, the project's `.buckconfig` doesn't need to specify +the project cell explicitly—although it is a good practice to do so. + +justifyContent + +### Buck2's dependency graph + +Every build rule can have zero or more dependencies. You can specify these +dependencies using, for example, the `deps` argument to the build rule. For more +information about specifying dependencies, consult the reference page for the +build rule you are using. These dependencies form a directed graph, called the +_target graph_. Buck2 requires the graph to be acyclic. When building the output +of a build rule, all of the rule's transitive dependencies are built first. This +means that the graph is built in a "bottom-up" fashion. A build rule knows only +which rules it depends on, not which rules depend on it. This makes the graph +easier to reason about and enables Buck2 to identify independent subgraphs that +can be built in parallel. It also enables Buck2 to determine the minimal set of +build targets that need to be rebuilt. + +### Multiple Buck2 projects in a single repository + +Buck2 is designed to build multiple deliverables from a single repository—that +is, a _monorepo_—rather than from multiple repositories. Support for the +monorepo design motivated Buck2's support for cells and projects. It is +Facebook's experience that maintaining all dependencies in the same repository +makes it easier to ensure that all developers have the correct version of the +code and simplifies the process of making atomic commits. + +### See also + +Take a look at the [Concept Map](concept_map.md) for a visualization of how +Buck2 concepts interact with each other. Also see the [Glossary](glossary.md). diff --git a/_src/concepts/target_pattern.md b/_src/concepts/target_pattern.md new file mode 100644 index 000000000000..59fa79665b2c --- /dev/null +++ b/_src/concepts/target_pattern.md @@ -0,0 +1,88 @@ +--- +id: target_pattern +title: Target Pattern +--- + +A _target pattern_ is a string that resolves to a set of +[targets](./glossary.md#target). A target pattern can be used as arguments to +commands, such as `buck2 build` and `buck uquery`. You can also use build target +patterns in the [visibility](./glossary.md#visibility) argument of your build +[rules](./glossary.md#rule). + +The simplest build target pattern matches the build target of the same name: + +```bash +# +# Matches //apps/myapp:app +# +//apps/myapp:app +``` + +A build target pattern that ends with a colon matches all build targets in the +build file at the preceding directory path. For example, suppose that the build +file: + +```sh +apps/myapp/BUCK +``` + +defines the rules: `app_v1` and `app_v2`, then the following build target +pattern would match both of those rules: + +```bash +# +# Matches //apps/myapp:app_v1 and //apps/myapp:app_v2 +# +//apps/myapp: +``` + +A build target pattern that ends with an ellipsis (`/...`) matches all build +targets in the build file in the directory that precedes the ellipsis and also +_all build targets in build files in subdirectories_. For example, suppose that +you have the following build files: + +```bash +apps/BUCK +apps/myapp/BUCK +``` + +then the following pattern would match all build targets in both of those files: + +```bash +# +# Matches (for example) //apps:common and //apps/myapp:app +# +//apps/... +``` + +A target pattern that does not include a `:` separator matches the target with +the same name as the last element of the path: + +```bash +# +# Matches //apps/myapp:myapp +# +//apps/myapp +``` + +Finally, target patterns can be relative to your current directory. For example: + +```bash +# +# If your current working directory is `apps`, matches //apps/myapp:myapp +# +myapp:myapp +``` + +### Build target patterns are not allowed in the deps argument + +Build target patterns cannot be used with the `deps` argument of a build rule. +Buck requires that you specify all dependencies explicitly as either +fully-qualified or relative build targets. + +### Target aliases + +Buck supports the ability to define _aliases_ for build targets; using aliases +can improve brevity when specifying targets on the Buck command line. + +To see which aliases exist, use `buck2 audit config alias`. diff --git a/_src/concepts/visibility.md b/_src/concepts/visibility.md new file mode 100644 index 000000000000..70e3bcc28414 --- /dev/null +++ b/_src/concepts/visibility.md @@ -0,0 +1,90 @@ +--- +id: visibility +title: Visibility +--- + +Visibility determines whether a [target](./glossary.md#target) can reference +another target in its [attributes](./glossary.md#attribute). In a large project, +you may want to prevent developers from 'reaching across' the project and +pulling in additional code. Reducing the visibility of targets can help prevent +that type of behavior. + +There are two types of visibility attributes available (each of which takes a +list of [target patterns](./glossary.md#target-pattern)): + +- `visibility` - determines which other targets can depend on a target. +- `within_view` - determines which other targets a target can depend on. + +Both attributes act as allowlists, with some exceptions. In general, if a target +is not listed, there may be no dependency relationship. If the `within_view` +list is empty or unset, however, its check is bypassed. Similarly, targets +defined in the same [BUCK file](./glossary.md#buck-file) always act as if they +were members of their siblings' `visibility` lists. + +There is also a special value for `visibility` attribute: `'PUBLIC'`, which +makes a build rule visible to all targets. + +In case of logically-conflicting lists, `within_view` takes precedence over +`visibility`. If `//foo:bar` defines `//hello:world` in its `visibility` list, +but `//hello:world` does not define `//foo:bar` in its `within_view` list, then +`//hello:world` may not depend on `//foo:bar`. + +## Examples + +A common library like Guava should be able to be included by any build rule: + +```java +prebuilt_jar( + name = 'guava', + binary_jar = 'guava-14.0.1.jar', + visibility = ['PUBLIC'] +) +``` + +It is common to restrict the visibility of Android resources to the Java code +that uses it: + +```java +android_resource( + name = 'ui_res', + res = 'res', + package = 'com.example', + visibility = ['//java/com/example/ui:ui'] +) +``` + +Or it may be simpler to make it visible to the entire directory in case +additional build rules are added to `java/com/example/ui/BUCK`: + +```java +android_resource( + name = 'ui_res', + res = 'res', + package = 'com.example', + visibility = ['//java/com/example/ui:'] +) +``` + +Also, it is common to limit code for testing to be visible only to tests. If you +define all of your Java unit tests in a folder named `javatests/` in the root of +your project, then you could define the following rule to ensure that only build +rules under `javatests/` can depend on JUnit: + +```java +prebuilt_jar( + name = 'junit', + binary_jar = 'junit-4.11.jar', + visibility = ['//javatests/...'] +) +``` + +Finally, restricting the view of a target can be useful for preventing +dependency creep: + +```java +java_library( + name = 'example', + visibility = ['PUBLIC',], + within_view = ['//foo:bar','//hello:world'] +) +``` diff --git a/_src/developers/architecture/buck1_vs_buck2.md b/_src/developers/architecture/buck1_vs_buck2.md new file mode 100644 index 000000000000..3129d9fc3a61 --- /dev/null +++ b/_src/developers/architecture/buck1_vs_buck2.md @@ -0,0 +1,175 @@ +--- +id: buck1_vs_buck2 +title: Buck1 vs Buck2 +--- + +## At a glance + +The following table provides an at-a-glance comparison of Buck1 and Buck2. + +| Buck1 | Buck2 | +| :---------------------------------------------- | :-------------------------------------------- | +| Build files in Starlark | Build files in Starlark | +| Macros in Starlark | Macros in Starlark | +| Rules in Java | Rules in Starlark | +| Rules and Macros are logically similar | Rules and Macros are logically similar | +| Rules and Core are not well abstracted | Rules and Core are strongly separated | +| Core in Java | Core in Rust | +| Remote Execution (RE) not well supported | All rules support remote execution by default | +| Varying degrees of incrementality / parallelism | Unified incrementality / parallelism | + +## Top-down vs Bottom-up - understanding the implications of the difference in execution models between Buck1 and Buck2 + +It is often said that Buck1 does 'top down' and Buck2 does 'bottom up' building. +This results in cases where some topics that seem conceptually trivial in Buck1 +are hard problems in Buck2, or vice versa. + +### What are the differences? + +**Scenario**: Imagine you are building A, which depends on both B and C, but +where neither B nor C have any dependencies. + +For the sake of simplicity, imagine B and C are C++ compilations (that produce +object files), and A is a link (that consumes them and produces a shared +library). + +#### Building A with Buck1 + +Following is an oversimplified view of what happens: + +- Buck1 computes the 'rulekey' for B. + - This consists of mixing together the hashes of the C++ file being compiled, + as well as all C++ compiler flags, and so on. +- Buck1 then does the same for C. +- Buck1 then computes the rulekey for A. + - This consist of mixing together the rulekeys of B and C, as well as linker + flags used by A. for example. +- Buck1 then looks up the rulekey for A in the cache. + - If there's a hit, then Buck1 downloads the output and its job done. + - If there's a cache miss, continue. +- Buck1 then queries the cache for the rulekeys of B and C: + - If there's a hit, then the output is downloaded. + - If there's a miss, then Buck1 runs the commands needed to produce the object + file that was missed. Regardless of whether those commands run locally or on + RE, Buck1 downloads the output of B and C. +- Buck1 then runs the command for A to produce the shared library. + - At this point, Buck1 may actually do another cache lookup with a different + rulekey, which is called an _input based rulekey_. This rulekey is derived + from the inputs of the action that needs executing, which at this point of + the build are known (since they were just built)! + +#### Building A with Buck2 + +In contrast, if you ask Buck2 to build A, here is what happens: + +- Buck2 produce the action to compile B and computes the hash of the action. + - This is the 'action digest', which consists of mixing the hashes of all the + inputs (such as the C++ file), as well as the command line (so, implicitly, + the compiler flags). +- Buck2 queries the action cache for the action digest hash. + - If there's a hit, Buck2 obtains the hash of the resulting object file (that + is, the output of B). + - If there's a miss, Buck2 runs the action on RE (or potentially locally) and + obtains the hash of the object file. If the action runs remotely, Buck2 will + not download the output. +- Buck2 does the same thing for C. +- Buck2 produces the action to link A. + - This consists of mixing together all the hashes of the input files (which + were retrieved earlier) and the command line to produce an action digest, + then querying the cache and potentially running the action. +- Once Buck2 produces A (again, on RE), then, since this output was requested by + the user (unlike the intermediary outputs B and C), Buck2 downloads A. + +### Some implications + +#### Rulekeys vs Action digests + +The closest thing to Buck1’s rulekey in Buck2 is the action digest, but they are +very different! + +Since it’s a product of the (transitive) inputs of an action, the (default) +rulekey can be computed without running anything or querying any caches. +However, the action digest cannot: it requires the actual inputs of an action, +which means you need to build all the dependencies first. + +This means that: + +- In Buck1, you can ask for rulekeys for a target. +- In Buck2, you’d have to run the build first then ask for the action digests + (this is what the `buck2 log what-ran` would show you). + +#### Buck2 queries many more caches + +- Buck1 will not descend further down a tree of dependency when it gets a cache + hit. +- Buck2 will always walk up all your dependencies, regardless of whether you get + cache hits or not. + +#### Materialization + +- When Buck1 gets a cache miss, it downloads the outputs. +- Buck2, by contract, does not download outputs as part of a build (this is + called 'deferred materialization'). + - Note that Buck2 does download the outputs if the user asked for them (that + is, they were the targets the user put on the command line). + +### Second-order implications + +#### Non-determinism + +Non-determinism in a build affects Buck2 and Buck1 differently. One scenario +that often works fine in Buck1 but can work catastrophically bad in Buck2 is a +codegen step, driven by a Python binary. + +In certain configurations/modes, Python binaries are non-deterministic, because +they are +(XARs)[https://engineering.fb.com/2018/07/13/data-infrastructure/xars-a-more-efficient-open-source-system-for-self-contained-executables/] +(eXecutable ARchives) and that is always non-deterministic, which is bad! + +- In Buck1, that doesn’t really matter, because you can get a cache hit on the + codegen output without ever visiting the XAR (as long as the input files + haven’t changed). +- In Buck2, you need the XAR to check the action cache for the codegen step. + - However, binaries are often not cached in certain configurations/modes, so + your XAR isn’t cached. + - Therefore, since your XAR build is non-deterministic, you’ll always miss in + the action cache and the codegen step will always have to run in every + build. + +It can get worse! If the Python binary produces non-deterministic codegen, then +the entire build might become uncacheable. + +#### Cache misses don’t necessarily propagate + +Say that, in Buck2, you’re trying to build a chain of actions like codegen -> +compile -> link. + +Even if your codegen step isn’t cached (say, because its action inputs are +non-deterministic as mentioned above), as long as the codegen output is +deterministic, you can still get cache hits from compile and link steps. + +#### Hybrid execution + +If you squint, you’ll note that Buck1’s build could be viewed as 'local first', +whereas Buck2’s would be better viewed as 'remote first': + +- When Buck1 builds something remotely or gets a cache hit, the outputs are + always downloaded. +- When Buck2 builds something remotely or gets a cache hit, the outputs are + never downloaded. + +In turn, this has some important implications: + +- When Buck1 builds something locally, the inputs are always already present. +- When Buck2 builds something locally, the inputs have to be downloaded, unless + they were built locally (which if you’re doing any RE, is usually not the + case), or if another command caused them to be downloaded. + +This means that, in Buck1, running something locally when you have spare +resources is usually a no-brainer, because it’s always ready to go, and you’ll +save on not having to download the output from RE (though you might have to +upload the output if you need to run actions depending on it later). + +On the flip side, with Buck2, that’s not necessarily the case. To run an action +locally, you need to download inputs that you might otherwise not have needed, +which will tax your network connection. diff --git a/_src/developers/architecture/buck2.md b/_src/developers/architecture/buck2.md new file mode 100644 index 000000000000..90438a76590e --- /dev/null +++ b/_src/developers/architecture/buck2.md @@ -0,0 +1,190 @@ +--- +id: buck2 +title: Architectural Model +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +## High-level Overview + +Buck2 is a build system whose core is written in Rust. Starlark, which is a +deterministic, immutable version of Python, is used to extend the Buck2 build +system, enabling Buck2 to be language-agnostic. + +The high-level flow starts with a user creating a build file (a `BUCK` file) +containing one or more targets, which is specified by the target label, its +inputs (sources, attributes, configurations, and dependencies), and the type of +macro or rule to use. + +Briefly, a macro is a wrapper around a rule, which runs necessary commands to +generate what’s needed for a target (for example, for a `cxx_binary` target, +generate the header map and run necessary `clang` commands). Macros can be used +to reduce boilerplate code for users (such as to supply the same set of +attributes for a rule for all targets). Macros and rules are both written in +Starlark and are specified by input sources, attributes, and the implementation +function. + +If the target type is a macro, then the macro will fill in some details (for +example, for a `cxx_binary` target, these are the compilation, debug flags to +use, this is the `clang` to use). If the target type is a rule, then the macro +layer is skipped altogether. + +This is all orchestrated by the core, which performs operations such as +executing Buck2 CLI args, generating/updating the dependency graph (which +contains the configured target nodes, unconfigured target nodes, action nodes, +among other types of nodes that all allow for incrementality and execution), and +materializing the artifacts. The core is written in Rust. + +The following diagram shows the high-level overview. + +justifyContent + +The Buck2 CLI runs in a client process, which sends commands to the Buck2 daemon +via gRPC. The daemon goes through several phases after receiving a request from +the client: **evaluation, configuration, analysis, execution, and +materialization** (see [Execution Model](#execution-model), below). When using +`buck2 test`, there is a final stage for **testing**. Note that these are the +phases that a build goes through, but they are not always sequential. + +After finishing all phases, the daemon will send the response back to the client +via gRPC. + +## Execution Model + +The following diagram shows the Execution Model, which consists of 5 phases and +states. + +justifyContent + +Each of the phases and states shown in the Execution Model, are detailed in the +following sub-sections. + +### State 0 - Build Files + +Build files (commonly referred to as `BUCK` files, their default name) are the +main input to Buck2 and are syntactically Python. + +Each build file is uniquely identified by the directory in which it's located. +Since all build files have the same name, there cannot be two build files in the +same directory. This is usually represented as the relative path from the root +of the project (the directory where the .buckconfig file is). + +Each build file has a set of targets. These describe the things the user wants +Buck2 to know about. Each target has a type and a set of named attributes, +including at least a name (also known as the label) identifying it. Additional +attributes depend on the type of the target. + +### Phase A: Evaluation + +First, Buck2 evaluates a build file, and then constructs an unconfigured target +graph. + +Buck2 performs directory listings to discover packages, then evaluates the build +files that were found, expands any macros detected into their underlying rules, +and then will take rule attributes and convert them from Starlark to Rust types +to construct a target node, and insert it into the unconfigured target graph, +which is a smaller portion of Buck2’s larger dependency graph. The target node +consists of a reference to rule implementation, and the set of attributes and +sources. + +The result of evaluation is a list of targets read from the build file mapped to +a target node in Buck2 unconfigured target graph. + +### State 1 - Unconfigured Target Graph is generated + +At this point, the unconfigured target graph is available for the next stage of +transformation, which is to configure the target nodes within the graph. + +### Phase B: Configuration + +At the end of evaluation, the target nodes are not yet configured. Configuration +means applying a list of constraints (such as resolving selects to specify the +right CPU) to make sure the target can be run where it needs to. This is also +known as target platform resolution, and can be configured within the target, +the buckconfig, propagated from dependencies, or passed into the CLI. After +applying configurations, the target nodes are transformed into configured target +nodes within the Buck2 configured target graph, which is a smaller portion of +Buck2’s larger dependency graph. + +### State 2 - Configured Target Graph is generated + +At this point, the configured target graph is available for the analysis stage +to generate the action graph. + +### Phase C: Analysis + +In the analysis phase, Buck2 constructs a context object (ctx) which contains +relevant information (such as attributes pulled from the configuration stage), +all converted into Starlark types and made available to the rule. For example, +the target’s dependencies are turned into a `ProviderCollection`, source files +are converted into `StarlarkArtifacts`, and String attributes are turned into a +`StarlarkString`. This ctx object is backed by Buck2’s dependency graph for +computation and rules use it to tell Buck2 to run actions, create dynamic +actions, or create new files. + +The rule will return a list of providers, which is data that the rule wants to +expose to its dependents (that is, can flow through the dependency graph), such +as output artifact information (such as file paths and file hashes). Providers +could be actions, source files, or attributes. Within the returned list, +DefaultInfo always needs to be returned, which indicates what the default +outputs are. Some other common built-in providers include RunInfo, TestInfo, and +InstallInfo. + +The end result is a list of providers and actions (inserted into the action +graph) that Buck2 needs to execute to produce the desired outputs, known as +'bound artifacts'. + +### State 3 - Action Graph and Providers are generated + +At this point, the action graph and providers are available to be processed by +the execution stage. + +### Phase D: Execute + +Execution is where Buck2 takes all the providers (input files from the targets, +args from the command line), runs the actions, and then outputs the computed +results. The critical path is the theoretical lower bound for the duration of a +build, which are the slowest set of actions. + +Buck2 can be run locally or on remote execution, or in a hybrid manner. + +For each action, a digest is created which is a hash of an action's command and +all its inputs. Buck2 then checks if there is a result cached within RE for an +action with a given digest. + +If there is a cache hit, Buck2 does not need to run the command for the action. +Instead, the RE returns the output action digest. This digest can be used to +download the actual output artifacts at a later time. This is known as the **RE +action cache**. + +If there is a cache miss, the action needs to be run either remotely or locally. +If Buck2 decides to run the action remotely, it will first upload all of the +action's inputs that are missing from the RE's content addressable storage. If +Buck2 decides to run the action locally, it will first download and materialize +in `buck-out` all of the action's inputs. These inputs might be outputs of other +actions and are stored in RE's content addressable storage but are missing on +the local machine.Only after those steps will Buck2 schedule the action for +actual execution. + +Buck2 can also decide to run local and remote execution simultaneously (a +process known as racing), and use the result of whichever action finishes first +to speed up performance. This strategy is known as **hybrid execution**." + +Materialization of action outputs (which involves downloading and placing them +in the correct location in `buck-out`) can be done immediately after the action +has finished executing. Alternatively, it can be deferred until it is actually +needed for the local execution of another action. There are various +configurations that a user can set to control how this materialization is +handled. + +### State 4 - Build outputs are generated + +At this point, the build is complete. + +If a user ran `buck2 test`, then there is a final transformation for Buck2 to +construct a command for TPX to execute the actual test. + +### Phase E: Execute tests + +For more detail on testing, review +[Test Execution](/docs/rule_authors/test_execution). diff --git a/_src/developers/architecture/buck2_telemetry.md b/_src/developers/architecture/buck2_telemetry.md new file mode 100644 index 000000000000..9cb33beaff20 --- /dev/null +++ b/_src/developers/architecture/buck2_telemetry.md @@ -0,0 +1,11 @@ +--- +id: buck2_telemetry +title: Buck2 Telemetry +--- + + +:::note +🚧   THIS PAGE IS UNDER CONSTRUCTION + + +::: diff --git a/_src/developers/bxl.md b/_src/developers/bxl.md new file mode 100644 index 000000000000..ce850e20bfe9 --- /dev/null +++ b/_src/developers/bxl.md @@ -0,0 +1,117 @@ +--- +id: bxl +title: Why BXL +--- + +## Buck2 Extension Language (BXL) + +BXL is a Starlark-based script that enables integrators to inspect and interact +with the Buck2 graph. + +Integrators are able to: + +- Write Starlark code that queries, analyzes, and builds on the Buck2 graph. +- Introspect and interact with the Buck2 graph structures natively, via + Starlark, in a safe, controlled manner. + +Introspection of the Buck2 graph can occur at the unconfigured, configured, +providers, and action stages. There are also APIs offered to allow BXL to accept +custom command line argument, output artifacts, and print results to stdout. + +BXL leverages Buck2 core's incremental +[caching](bxl_faq.md#when-is-my-bxl-script-cached). It also has support for +[running actions](bxl_common_how_tos.md#running-actions), +[dynamic outputs](bxl_dynamic_output.md), and +[anonymous targets](bxl_anon_target.md). In addition, BXL has +[profiling](bxl_common_how_tos.md#profiling-testing-and-debugging-a-bxl-script) +capabilities, and allows users to add their own [telemetry](bxl_telemetry.md) +directly within the BXL scripts. + +BXL is considered to be mostly stable, with a bit more active development here +and there. + +## When should I use BXL over Buck2 API/CLI? + +There are many overlaps between BXL and Buck2 (for example, both can run cquery +and both can build targets). It’s possible that one use case could be handled by +both BXL and Buck2. + +Following are some specific recommendations to help decide when to use BXL over +regular Buck2: + +- **Use/inspect resolved attributes that are not exposed/accessible to users via + normal Buck2 operations.** + - This includes introspecting the Starlark object of providers, analyzing the + Starlark object of a rule’s attr before and after coercing and resolution, + and introspecting intermediate query results. +- **Reduce/eliminate the need to make several Buck2 calls within your program, + such as running several subprocesses to call `cquery` several times.** + - With BXL, you can just call the BXL script once in a subprocess, potentially + reducing the amount of code you need to write in your program. For example, + if you need to call cquery and build several times, you can put that all + within a single BXL script and run `buck2 bxl` once, rather than running + `buck2 cquery` and `buck2 build` several times. +- **Reduce/eliminate the need to manually parse Buck2 output format within your + program, and any bugs that may come with manual parsing**. + - Some languages are more verbose than others when it comes to string parsing. + - BXL scripts are written in Starlark, which is basically a deterministic, + immutable Python, and are able to directly introspect Starlark objects (such + as rules and target nodes, and so on) and call methods on these objects + instead of parsing them over Buck2’s output. + +## Example Use Cases + +### Generate a project for IDE + +IDE project generation is roughly as follows: + +- Form the target graph for the project target +- Perform some filtering on the graph targets if needed. This depends on the + target's configuration. +- For each target, generate the project target metadata, including: +- compiler flags +- linker flags +- paths to generated files +- inputs and outputs for each targets +- the paths relative to some `PATH` +- Write a single file translating this metadata into a format understood by the + IDE + +An example BXL flow for generating a project for IDE might be: + +- Add some command line arguments to accept a target (or subtarget) to generate + the project +- Run analysis on the project target with a specific configuration to filter the + graph targets +- For each resulting target, inspect the providers and attributes to extract the + required metadata information. BXL has filesystem operations handle paths + within the project +- Run actions based on the linker/compiler flags, and build artifacts as needed + to generate a project +- Write a single file containing the metadata obtained from previous steps + +### Build an LSP + +A compilation database is a database containing information about which compile +options are used to build the files in a project. Language Server Protocols +(LSPs) uses the compilation database to provide language features like auto +complete, go to definition, and find all references for the user within an +IDE/editor. + +An example BXL flow for building a C++ LSP might be: + +- Add a command line argument to accept a file +- Run owners cquery in BXL to get the owning target of the file +- Run analysis on the owning target to get the desired clang flags +- Use BXL to write the clang flags to the disk in compilation database format + +### Perform graph analysis + +Some example graph analysis functionalities might be: + +- Run an analysis in BXL on a set of targets, and then inspect their providers, + and build some subtargets +- Run a uquery on some set of targets, and inspect the resulting nodes' coerced + attributes +- Run a cquery on some set of targets with a specific configuration, and inspect + the resulting nodes' attributes before and after resolution diff --git a/_src/developers/bxl_anon_target.md b/_src/developers/bxl_anon_target.md new file mode 100644 index 000000000000..4e0757099abc --- /dev/null +++ b/_src/developers/bxl_anon_target.md @@ -0,0 +1,144 @@ +--- +id: anon_targets +title: BXL and Anonymous Targets +--- + +## Anonymous targets + +[Anonymous targets](../rule_authors/anon_targets.md) are supported in BXL. +Anonymous targets are keyed by the attributes, and allow you to share/cache work +more effectively. + +You might want to use anonymous targets if there is some heavy Starlark +evaluation which can be cached, or if you want to cache local actions. + +**Note**: The context object within the anon target rule is **not** a BXL +context, but a normal rule analysis context. + +### APIs + +The `actions` object returned from `ctx.bxl_actions().actions` (equivalent of +`ctx.actions` in normal rules) has the following functions for anonymous +targets: + +- `anon_target(rule: "rule", attrs: Dict[str, Any]) -> "promise"`: generates a + single anonymous target. Return type is an unresolved `promise`. +- `anon_targets(rules: [("rule", Dict[str, Any])]) -> "promise"`: generates a + list of anonymous targets. Return type is an unresolved `promise` representing + the list of anonymous targets. +- `artifact_promise(promise: "promise") -> "promise_artifact"`: turns an + unresolved promise into a kind of artifact. See + [Convert promise to artifact](../rule_authors/anon_targets.md#convert-promise-to-artifact) + for more info on why you might want to use this. + +The resulting promise also has `map()` and `join()` functions. `map()` applies a +function to the promise's results, and `join()` turns multiple promises into a +single promise. + +To resolve promises in BXL, `bxl_ctx` has a `resolve()` function, which takes in +the analysis actions instance (`actions` object returned from +`ctx.bxl_actions().actions`) and a single promise and returns an optional +promise value, if there is one. If you intend to create multiple promises, using +`join()` to produce a single promise will allow you to resolve them concurently +with a single `resolve()` call. + +Small example: + +```python +def _my_impl(ctx): + bxl_actions = ctx.bxl_actions() # pass in relevant params to configure the execution platform resolution + actions = bxl_actions.actions + + promise1 = actions.anon_target(my_anon_rule1, my_attrs1).promise + promise2 = actions.anon_target(my_anon_rule2, my_attrs2).promise.map(my_map_function) + + joined = promise1.join(promise2) + + resolved = ctx.resolve(actions, joined) + + # do some more stuff ... +``` + +### Complete Example + +```python +## anon_bxl_rules.bzl ############ + +# Define an anonymous rule. + +MirrorInfo = provider(fields = ["mirrored_attrs"]) + +# Anonymous rule which writes some silly output, and also mirrors all attributes received +def _mirror_impl(ctx: "context") -> ["provider"]: + out = ctx.actions.declare_output("my_output") + ctx.actions.write(out, "my_content") + return [DefaultInfo(default_outputs = [out]), MirrorInfo(mirrored_attrs = ctx.attrs)] + +my_mirror_rule = rule(impl = _mirror_impl, attrs = { + "false": attrs.bool(), + "int": attrs.int(), + "list_string": attrs.list(attrs.string()), + "string": attrs.string(), + "true": attrs.bool(), +}) + +# Will be used in a map function in my_script.bxl below +StringInfo = provider(fields = ["my_string"]) + +## my_script.bxl ############ + +load(":anon_bxl_rules.bzl", "MirrorInfo", "StringInfo", "my_mirror_rule") + +def _anon_target_example(ctx): + bxl_actions = ctx.bxl_actions() + actions = bxl_actions.actions + + # Attrs to pass into the anonymous target. An anonymous target is defined by the hash of its attributes + my_attrs = { + "false": False, + "int": 42, + "list_string": ["a", "b", "c"], + "string": "foo-bar-string", + "true": True, + } + + # A function to be applied to the promise (result of anon target), producing a promise with the resulting value. + def my_function(providers): + # Do something with the attrs. In this example, we are validating that the attrs are what we expect. + mirrored_fields = providers[MirrorInfo].mirrored_attrs + assert_eq(mirrored_fields.true, True) + assert_eq(mirrored_fields.false, False) + assert_eq(mirrored_fields.int, 42) + assert_eq(mirrored_fields.string, "foo-bar-string") + assert_eq(mirrored_fields.list_string, ["a", "b", "c"]) + + outputs = providers[DefaultInfo].default_outputs + # These are the providers this target returns + return [DefaultInfo(default_outputs = outputs), StringInfo(my_string = "map function succeeded!")] + + # Create an anonymous target by passing in "my_attrs" into "my_mirror_rule", and returns providers. + # Specifically, it returns "DefaultInfo" and "MirrorInfo", as defined in "my_mirror_rule" + # Then, we map the result to "my_function", which does some validation + promise = actions.anon_target(my_mirror_rule, my_attrs).promise.map(my_function) + + # Resolving the promise returns a "provider_collection", which was defined by "my_function" above. + # `DefaultInfo` is at index 0, `StringInfo` is at index 1 + promise_result = ctx.resolve(actions, promise) + + ensured = ctx.output.ensure(promise_result[0].default_outputs[0]) + # should print out location of the output, which contains the "my_content" string as defined in anon_bxl_rules.bzl above + ctx.output.print(ensured) + + # should print out "map function succeeded!" + ctx.output.print(promise_result[1].my_string) + +def assert_eq(a, b): + if a != b: + fail("Expected {} == {}".format(a, b)) + +anon_target_example = bxl_main( + impl = _anon_target_example, + cli_args = { + }, +) +``` diff --git a/_src/developers/bxl_basics.md b/_src/developers/bxl_basics.md new file mode 100644 index 000000000000..ffe0358b6d08 --- /dev/null +++ b/_src/developers/bxl_basics.md @@ -0,0 +1,107 @@ +--- +id: bxl_basics +title: BXL Basics +--- + +This page is a primer on common BXL functionalities and data types. Ramping up +in BXL may be challenging without much prior knowledge of Buck2 building blocks +(ex: targets, configurations, queries), so please take a look at the +[Concepts](../concepts/concept_map.md) documentation before reading on. + +## Common BXL functionalities + +### Build + +You can build targets within BXL with +[`ctx.build()`](../../api/bxl/bxl_ctx/#bxl_ctxbuild). The result is a +[`bxl_build_result`](../../api/bxl/bxl_build_result), which has `artifacts()` +and `failures()` functions that provide iterators to the artifacts or failures, +respectively. You can pass in a single target or target pattern to build. + +### Analysis + +You can run analysis on targets within BXL via +[`ctx.analysis()`](../../api/bxl/bxl_ctx/#bxl_ctxanalysis). Analysis means to +evaluate the underlying rule implementation for the inputted targets, and +produce the providers that the rule defined for the target. A common workflow is +to inspect the resulting providers, and perhaps ensure parts of these providers +or run actions using information from the providers (see [Actions](#actions) +below). + +### Query + +Buck2 supports a couple different query types: querying the unconfigured graph +(`buck2 uquery`), the configured graph (`buck2 cquery`), or the action graph +(`buck2 aquery`). These queries are all available in BXL as well: + +- `ctx.uquery()` returns a [`uqueryctx`](../../api/bxl/uqueryctx) +- `ctx.cquery()` returns a [`cqueryctx`](../../api/bxl/cqueryctx) +- `ctx.aquery()` returns a [`aqueryctx`](../../api/bxl/aqueryctx) + +You can read more about the individual queries in the API docs. There are many +queries that are common between uquery, cquery, and aquery, but cquery and +aquery will have extra queries unique to the configured graph or the action +graph. One more thing to call out is the `eval()` query, which is a special +query that takes in the entire query as a string literal. A common use for +`eval()` is to migrate a complex query from Buck2 CLI to BXL by dropping the +entire query string directly into `eval()`. + +The query results are target sets (iterable container) of +[`unconfigured_target_node`s](../../api/bxl/unconfigured_target_node) for +uquery, [`target_node`s](../../api/bxl/target_node) for cquery, and +[`action_query_node`s](../../api/bxl/action_query_node) for aquery. Each of +these node types have accessors on their attributes. A common workflow is to run +some query in BXL, and iterate through the resulting nodes to inspect their +attributes, and use those attributes to inform further computations in BXL. + +#### Uquery + +Querying the unconfigured graph means that no configurations (such as platforms +and transitions) have been applied to the target graph yet. This means that it's +very possible that some parts of the target graph is broken due to lack of +configurations. Generally to avoid this problem, cquery may be preferred +instead. + +#### Cquery + +Querying the configured graph means that configurations have been applied to the +target graph. For cquery, we require that users use a +[target universe](../developers/bxl_target_universe.md) for their query inputs. + +#### Aquery + +Aquery is a quite different from uquery and cquery. It is used to query the +action graph, which is constructed after Buck2 runs analysis on the targets and +produces the list of providers and actions needed to build the target. + +### Actions + +You can create actions directly within the BXL API. The available action APIs +are equivalent to the ones found on the [`actions`](../../api/bxl/actions) type +for normal rules, with the caveat that +[dynamic actions](./bxl_dynamic_output.md) use the +[`bxl_ctx`](../../api/bxl/bxl_ctx) (which provides richer functionalities). + +A common workflow would be to run analysis on a target, and use some interesting +bits found in the analysis result to construct an augmented +[`cmd_args`](../../api/bxl/cmd_args) to run, and then ensure the action's output +(see below for ensuring). Also see +[Running actions](./bxl_common_how_tos.md#running-actions). + +### Ensure + +Ensuring an artifact means that you want the artifact to be materialized +(meaning, downloaded to your machine) at the end of the BXL execution. There are +two APIs for ensuring: `ctx.output.ensure()` and `ctx.output.ensure_multiple()` +(see [`bxl_output_stream`](../../api/bxl/bxl_output_stream)). As the naming +indicates, the former is for ensuring a single artifact, and the latter is for +ensuring multiple artifact-like inputs. Artifact-like inputs include +[`cmd_args`](../../api/bxl/cmd_args) (can be found when inspecting providers), +[`bxl_build_result`](../../api/bxl/bxl_build_result) (produced when building +something in BXL), or [`artifact`](../../api/bxl/artifact) (can be found when +inspecting providers, or creating your own actions). + +A common workflow is to ensure an artifact that you created via some custom +actions defined in your script, or ensuring some artifacts found in the +providers after running analysis. Also see +[What do I need to know about ensured artifacts](./bxl_faq.md#what-do-i-need-to-know-about-ensured-artifacts). diff --git a/_src/developers/bxl_common_how_tos.md b/_src/developers/bxl_common_how_tos.md new file mode 100644 index 000000000000..4bc69ce1be54 --- /dev/null +++ b/_src/developers/bxl_common_how_tos.md @@ -0,0 +1,234 @@ +--- +id: bxl_how_tos +title: Common How-Tos +--- + +## Passing in and using CLI args + +A BXL function can accept a `cli_args` attribute where args names and types are +specified to use within your script, as shown in the following example: + +Example: + +```python +def _impl_example(ctx): + # ... + pass + +example = bxl_main( + impl = _impl_example, + cli_args = { + # cli args that you want to receive from the command line + "bool_arg": cli_args.bool(), + "list_type": cli_args.list(cli_args.int()), + "optional": cli_args.option(cli_args.string()), + "target": cli_args.target_label(), + }, +) +``` + +On the command line, you can invoke the arguments as follows: + +```sh +buck2 bxl //myscript.bxl:example -- --bool_arg true --list_type 1 --list_type 2 --target //foo:bar +``` + +For BXL functions, to read the arguments, use them as attributes from the +`cli_args` attribute on the BXL `ctx` object, as follows: + +```python +def _impl_example(ctx): + my_bool_arg = ctx.cli_args.bool_arg +``` + +## Running actions + +You can create actions within BXL via the `actions_factory`. This is called once +globally then used on demand: + +```python +def _impl_example(ctx): + actions = ctx.bxl_actions().actions # call once, reuse wherever needed + output = actions.write("my_output", "out") +``` + +You will need to have +[execution platforms](../rule_authors/configurations.md#execution-platforms) +enabled for your project, or else you will get an error. You can specify the +execution platform resolution by setting named parameters when instantiating +`bxl_actions`: + +- `exec_deps` - These are dependencies you wish to access as executables for + creating the action. This is usually the same set of targets one would pass to + rule's `attr.exec_dep`. Accepts a list of strings, subtarget labels, target + labels, or target nodes. +- `toolchains` - The set of toolchains needed for the actions you intend to + create. Accepts a list of strings, subtarget labels, target labels, or target + nodes. +- `target_platform` - The intended target platform for your toolchains. Accepts + a string or target label. +- `exec_compatible_with` - Explicit list of configuration nodes (like platforms + or constraints) that these actions are compatible with. This is the + `exec_compatible_with` attribute of a target. Accepts a list of strings, + target labels, or target nodes. + +If you specify `exec_deps` or `toolchains`, you can access the resolved +`dependency` objects on the `bxl_actions` object. The `bxl_actions` object will +have `exec_deps` and `toolchains` attributes, which are `dict`s where the keys +are the unconfigured subtarget labels, and the values are the +configured/resolved `dependency` objects. + +Note that the keys of `exec_deps` and `toolchains` must be unconfigured +subtarget labels (`StarlarkProvidersLabel`), and not unconfigured target labels. +You can use `ctx.unconfigured_sub_targets(...)` or `with_sub_target()` on +`target_label` to create the label. + +```python +def _impl_example(ctx): + my_exec_dep = ctx.unconfigured_sub_targets("foo//bar:baz") # has some provider that you would use in the action + bxl_actions = ctx.bxl_actions(exec_deps = [my_exec_dep]) # call once, reuse wherever needed + output = bxl_actions.actions.run( + [ + "python3", + bxl_actions.exec_deps[my_exec_dep][RunInfo], # access resolved exec_deps on the `bxl_actions` + out.as_output(), + ], + category = "command", + local_only = True, + ) + ctx.output.ensure(output) +``` + +## Getting providers from an analysis + +After calling `analysis()`, you can get the providers collection from +`providers()`: + +```python +def _impl_example(ctx): + my_providers = ctx.analysis(my_target).providers() +``` + +## Get a specific provider from an analysis + +After calling `analysis()`, you can also get the providers collection from +`providers()` then grab whatever specific provider you need: + +```python +def _impl_example(ctx): + default_info = ctx.analysis(my_target).providers()[DefaultInfo] + ctx.output.print(default_info) +``` + +## Get a specific subtarget from an analysis + +Once you have a provider, you can get its subtargets by using the `sub_targets` +attribute on the struct to get a dict of provider labels to provider +collections: + +```python +def _impl_example(ctx): + subtarget = ctx.analysis(my_target).providers()[DefaultInfo].sub_targets["my_subtarget"] + ctx.output.print(subtarget) +``` + +## Building a subtarget + +You can use `analysis()` to get a specific subtarget from an analysis, or you +can pass in the subtarget literal directly into `ctx.build()`: + +```python +def _impl_example(ctx): + outputs = ctx.build("cell//path/to/my:target[my_subtarget]") + ctx.output.ensure_multiple(outputs) +``` + +## Getting attributes or resolved attributes efficiently on a configured target node + +If you need to use all of the attrs/resolved_attrs, then initializing the eager +variant once would be best. If you only need a few of the attrs, then +initializing the lazy variant is better. There’s not really a hard line, it +depends on the target node, and which attrs you are looking for. If performance +is key to your BXL script, the best way to determine this is to use the BXL +profiler. + +Regardless, if you use eager or lazy versions of getting attributes, you should +cache the attrs object: + +```python +def _impl_example(ctx): + my_configured_node = ctx.configured_targets(":foo") + + # call once and resue, ideally when you need most/all attrs + eager = my_configured_node.attrs_eager() + + # call once and reuse, ideally when you only need a few attrs + lazy = my_configured_node.attrs_lazy() + + # call once and reuse, ideally when you need most/all resolved attrs + resolved_eager = my_configured_node.resolved_attrs_eager(ctx) + + # call once and reuse, ideally when you only need a few resolved attrs + resolved_lazy = my_configured_node.resolved_attrs_lazy(ctx) +``` + +## Inspecting a struct + +You can use `dir(my_struct)` to inspect a struct. You can also use +`getattr(my_struct, "my_attr")` to grab individual attributes, which is +equivalent to `my_struct.my_attr`. + +These are available as part of the +[Starlark language spec](https://github.com/bazelbuild/starlark/blob/master/spec.md#dir). + +## Set addition/subtraction on a `target_set` + +There are a few BXL actions that return a `target_set` (such as a cquery +`eval()`). The `target_set` supports set subtraction and addition (you can use +`-` and `+` directly in Starlark). + +## Profiling, Testing, and Debugging a BXL script + +You can use `buck2 bxl profiler`, with various measurements, to determine where +the script is least efficient. + +To time individual pieces of the script, you can use BXL’s timestamp methods: + +```python +def _impl_example(_ctx): + start = now() # call once and reuse wherever is necessary + # do something time intensive here + end1 = start.elapsed_millis() + # do something else time intensive here + end2 = start.elapsed_millis() +``` + +BXL does not have a debugger available nor a robust testing framework for +mocking. + +- **Debug** - the main method to debug a BXL script is with print statements + (`print()` and `ctx.output.print()`). +- **Test** - the main method to test a BXL script is to actually invoke it with + required inputs then verify the outputs. + +## Getting the path of an artifact as a string + +The starlark `artifact` type encapsulates source artifacts, declared artifacts, +and build artifacts. It can be dangerous to access paths and use them in further +BXL computations. For example, if you are trying to use absolute paths for +something and end up passing it into a remotely executed action, the absolute +path may not exist on the remote machine. Or, if you are working with paths and +expecting the artifact to already have been materialized in further BXL +computations, that would also result in errors. + +However, if you are not making any assumptions about the existence of these +artifacts, you can use use +[`get_path_without_materialization()`](../../api/bxl/globals#get_path_without_materialization), +which accepts source, declared, or build aritfacts. It does _not_ accept ensured +artifacts (also see +[What do I need to know about ensured artifacts](./bxl_faq.md#what-do-i-need-to-know-about-ensured-artifacts)). + +For getting paths of `cmd_args()` inputs, you can use +[`get_paths_without_materialization()`](../../api/bxl/globals#get_paths_without_materialization), +but note this is risky because the inputs could contain tsets, which, when +expanded, could be very large. Use these methods at your own risk. diff --git a/_src/developers/bxl_dynamic_output.md b/_src/developers/bxl_dynamic_output.md new file mode 100644 index 000000000000..979b01c68552 --- /dev/null +++ b/_src/developers/bxl_dynamic_output.md @@ -0,0 +1,79 @@ +--- +id: dynamic_output +title: BXL and Dynamic Outputs +--- + +## Dynamic output + +When declaring [dynamic outputs](../rule_authors/dynamic_dependencies.md) within +a BXL script, the dynamic lambda for is created with a `bxl_ctx`, which means +that you can do things like run analysis or queries to inspect the build graph +from within the dynamic lambda. + +You may declare multiple dynamic outputs within a single BXL script, or declare +nested dynamic outputs. Dynamic outputs are run asynchronously after the BXL +evaluation. + +### Limitations + +- `ctx.output` is not available from a dynamic lambda. This means you can’t + ensure artifacts or print cached outputs within a dynamic lambda. +- Error messages from skipping incompatible targets are only emitted to the + console, and not cached in the stderr +- `build()` is not available from a dynamic lambda +- `bxl_actions` in a dynamic lambda always inherits the execution platform + resolution of the root/parent BXL. + - The expected usage of `bxl_actions` from within a dynamic lambda is to + instantiate it without any named parameters, but the `exec_deps` and + `toolchains` of the execution platform resolution are accessible, and return + the same values as the root/parent BXL +- Profiling is not hooked up to dynamic BXL context + +### Silly example + +This is a silly example of creating a dynamic output which reads some +`query_params` input, calls some BXL functions like `uquery`, +`configured_targets` to get the resolved attributes of a target node, and then +writes the attributes to an output file. + +```python +def _impl_dynamic_output(ctx): + actions = ctx.bxl_actions().actions + + # Declare some input here to read within the lambda + query_params = actions.write_json("query_params", {"rule_type": "apple_bundle", "universe": "fbcode//buck2/tests/..."}) + + # Dynamic lambda's output artifact + resolved_attrs = actions.declare_output("resolved_attrs") + + # Dynamic lambda function to be used in the dynamic_output + def my_deferred(ctx, artifacts, outputs): + + # Read the input, then do some BXL things here + + params = artifacts[query_params].read_json() + target = ctx.uquery().kind(params["rule_type"], params["universe"])[0] + node = ctx.configured_targets(target.label) + eager_attrs = node.resolved_attrs_eager(ctx) + + # Dynamic BXL context's `bxl_actions` does not take in named parameters because it inherits the exec platform resolution from the root/parent BXL. If the root BXL's `bxl_actions` were created with exec deps/toolchains, you can access them using `exec_deps` and `toolchains` attributes here + + ctx.bxl_actions().actions.write(outputs[resolved_attrs], str(eager_attrs)) + + actions.dynamic_output( + dynamic = [query_params], + inputs = [], + outputs = [ + resolved_attrs, + ], + f = my_deferred, + ) + + ctx.output.print(ctx.output.ensure(resolved_attrs).abs_path()) + +dynamic_output_example = bxl_main( + impl = _impl_dynamic_output, + cli_args = { + }, +) +``` diff --git a/_src/developers/bxl_faq.md b/_src/developers/bxl_faq.md new file mode 100644 index 000000000000..15f1d40bec2a --- /dev/null +++ b/_src/developers/bxl_faq.md @@ -0,0 +1,78 @@ +--- +id: bxl_faqs +title: FAQs +--- + +## When is my BXL script cached? + +The entire BXL script is represented as a single node on the DICE graph (Buck2’s +internal dependency graph). When the script’s input changes, the entire node is +invalidated and needs to be recomputed. For example, if a BXL function calls +uquery, then uses the result to do a cquery and then a build, if Buck2 detects +that any of the recorded calls to uquery, cquery, and build changes, then the +entire BXL script will be reran. The computations themselves (uquery, cquery, +and build) will still be incrementally evaluated via DICE, so we are not +rerunning _every_ computation entirely within the BXL. + +When the BXL script creates artifacts and ensures them, those artifacts are +cached separately in an action outside of the BXL execution. This means that the +artifacts produced by BXL are cached separately from the BXL script itself, much +like the computations within a BXL. + +During 2023, there is a plan to add finer grain incrementality to make better +use of DICE’s existing incrementality support. + +## What’s the difference between `ctx.output.print()` and `print()`? + +- `ctx.output.print()` writes items to stdout by buck2 even when the script is + cached. Items written to the output stream are considered to be the results of + a BXL script, which will be displayed to stdout by buck2 even when the script + is cached. +- `print()` is offered by Starlark via the stdlib. This prints anything you want + but won’t be provided to stdout at the end of a BXL script. These can be used + to print to stderr. NOTE: `print()` statements don't show up if the script has + been cached. + +## What do I need to know about ensured artifacts + +An `ensured_artifact` prints out the relative or absolute path via +`ctx.output.print()`, depending on if called with `abs_path()` or `rel_path`(), +but will print out `>` via `print()`. + +This is intentional because when the ensured artifact is created within BXL, it +has not been materialized yet. It will be materialized after the BXL script +finishes executing, and Buck2 core performs some additional actions after the +BXL script. + +This is a safeguard to prevent people from misusing the artifact path and +passing it into an action without the artifact having been materialized or +passing an absolute path into RE, which can actually mess up RE and render the +action not shareable across users. In addition, it makes these actions +separately cacheable from the BXL execution. + +## What is the difference between dynamic outputs and anon targets? + +Dynamic outputs are meant for +[dynamic dependencies](../rule_authors/dynamic_dependencies.md). The context +type is a `bxl_ctx`. Dynamic outputs are ran asynchronously outside of the BXL +execution. + +Anon targets are meant for sharing work betwen multiple BXLs. The context type +is a normal rule analysis `context`. Anon targets are `await`-ed inline with +your BXL function. + +## Can I mutate types returned by BXL APIs? + +The data types produced by BXL API calls are always immutable. + +## What is run synchronously vs asynchronously? + +Starlark itself is run synchronously. However, certain BXL APIs are evaluated +asynchronously. + +If you pass in multiple inputs to builds, queries, or analyses, the execution of +these API calls will be blocking, but the inputs themselves will be evaluated in +parallel within the execution. + +Ensuring artifacts, dynamic outputs, anon targets, and resolving promises will +happen _after_ the Starlark script is executed. diff --git a/_src/developers/bxl_getting_started.md b/_src/developers/bxl_getting_started.md new file mode 100644 index 000000000000..342334f41908 --- /dev/null +++ b/_src/developers/bxl_getting_started.md @@ -0,0 +1,101 @@ +--- +id: bxl_getting_started +title: Getting Started +--- + +If you are mostly unfamiliar with Buck2, take a look at +[BXL Basics](./bxl_basics.md). + +## Navigating the docs + +All BXL APIs can be found [here](../../api/bxl/globals). A good place to start +would be the [`bxl_ctx`](../../api/bxl/bxl_ctx), which contains all available +BXL functionalities. + +All [Build APIs](../../api/build/globals) are mirrored to the BXL APIs section. + +The [Starlark spec](https://github.com/bazelbuild/starlark/blob/master/spec.md) +is also a good resource for general Starlark APIs. + +## Writing a BXL + +To create a BXL, first, create a script somewhere in the repository ending in +`.bxl`. (Note that you can define a single bxl per file, or multiple BXLs per +file like in Starlark rules). + +In it, define a BXL function as follows: + +```python +def _your_implementation(ctx): + # ... + pass + +your_function_name = bxl_main( + impl = _your_implementation, + cli_args = { + # cli args that you want to receive from the command line + "bool_arg": cli_args.bool(), + "list_type": cli_args.list(cli_args.int()), + "optional": cli_args.option(cli_args.string()), + "target": cli_args.target_label(), + }, +) +``` + +This exposes `your_function_name` as a function, with whatever arguments you +defined it, so that on the command line you can invoke: + +```text +buck2 bxl //myscript.bxl:your_function_name -- --bool_arg true --list_type 1 --list_type 2 --target //foo:bar` +``` + +You can also add helpdocs to the cli args and get them to show up in cli via +`--help`: + +```python +def _your_implementation(ctx): + # ... + pass + +your_function_name = bxl_main( + impl = _your_implementation, + cli_args = { + "my_bool": cli_args.bool(True, "this will be printed as part of `--help`") + }, +) +``` + +The implementation function takes a single context as parameter (see the +documentation for [`BxlContext`](../../api/bxl/bxl_ctx)). Using it, you'll be +able to access functions that enable you to perform queries, analysis, builds, +and even create your own actions within BXL to build artifacts as part of a BXL +function. + +The primary method to return information from BXL is to either print them, or +build some artifact (for details, see the +[`OutputStream`](../../api/bxl/bxl_output_stream) documentation, available as +part of `ctx.output`). At high level, `ctx.output.print(..)` prints results to +stdout, and `ctx.output.ensure(artifact)` marks artifacts as to be materialized +into buck-out by the end of the BXL function, returning an object that lets you +print the output path via `ctx.output.print(ensured)`. + +## Running a BXL + +To run a BXL function, invoke the buck2 command: + +```text +buck2 bxl -- +``` + +Where `` is of the form `:`, +and `` are the arguments that the function accepts from the +command line. + +The documentation for a BXL function can be seen by running: + +```text + buck2 bxl -- --help` +``` + +Note that this is different from `buck2 bxl --help`, which generates the help +for the buck2 command instead of the function. diff --git a/_src/developers/bxl_target_universe.md b/_src/developers/bxl_target_universe.md new file mode 100644 index 000000000000..c13c5d9cc24e --- /dev/null +++ b/_src/developers/bxl_target_universe.md @@ -0,0 +1,121 @@ +--- +id: target_universe +title: Target Universe in BXL +--- + +## BXL cquery and target universe + +BXL cannot infer the [target universe](../concepts/glossary.md#target-universe) +like in the CLI (in most cases). BXL splits up cquery functions per function +(ex: `ctx.cquery().kind(...)`), with the exception of `ctx.cquery.eval(...)`, +which accepts literals exactly like in the CLI. For the `eval` query, target +universe is inferred exactly like the CLI. + +For all other cases, take the following query as an example: + +`buck2 cquery "rdeps(deps(//example:foo), deps(//example:bar))"` + +The target universe here should be constructed from the all the target literals +and their transitive deps, which is to say `deps(//example:foo, //example:bar)`. +When you run the query, the evaluation of `deps(//example:foo)` and +`deps(//example:bar)` nested in the `rdeps` query will happen inside the +universe resulting from `deps(//example:foo, //example:bar)`. Translating it to +BXL's individual cquery functions, and let’s say we also try to use the target +literals to construct the universe as the CLI target inference does: + +```python +from_node = ctx.cquery().deps("//example:foo") # universe would be //example:foo + +to_node = ctx.cquery().deps("//example:bar") # universe would be //example:bar + +rdeps = ctx.cquery().rdeps(from_node, to_node) # what is the universe here? +``` + +Here, the `from_node` query is actually evaluated in the wrong target universe +because we have broken up the query steps in BXL. Instead of +`deps(//example:foo)` being evaluated in `deps(//example:foo, //example:bar)`, +it’s evaluated with only `deps(//example:foo)`. It’s impossible to know that +there’s going to be an rdeps query later on that expects a different target +universe. + +### Specifying target universe in BXL cquery + +BXL cquery functions should only accept configured targets as inputs, with the +exception of `eval` and `testsof_with_default_platform`. + +BXL has a `ctx.target_universe()` function to construct a `target_universe` +object, which has a `lookup()` function to lookup the configured targets within +the target universe and return the target set. ​​The lookup functionality is +useful because sometimes a single target can appear multiple times within a +target universe. For example, if you specify a cxx toolchain using its +unconfigured target label, it will always match against all cxx toolchains in +the target universe (so at least once for target deps and once for exec deps), +since cxx toolchains may have multiple configurations. Example: + +```python +def _impl: + target_universe = ctx.target_universe(["//example:foo", "//example:bar"]) + to_node = target_universe.lookup("//example:foo") + from_node = target_universe.lookup("//example:bar") + rdeps = ctx.cquery().rdeps(to_node, from_node) +``` + +However, sometimes you might want a specific configuration instead of using all +configurations found within a target universe, in which case you could use +`ctx.configured_targets(...)` to specify the configuration. Or, sometimes you +may want to use the specific configured target nodes resulting from other BXL +calls. In these cases, you can pass the configured targets directly into cquery +functions, instead of going through target universe lookup. + +### What does the target universe tend to be in practice? + +For `owner` query, the universe would be constructed with the unconfigured +target nodes returned from `ctx.uquery().owner(...)`. Example: + +```python +def _impl: + unconfigured_owners = ctx.uquery().owner("foobar") + target_universe = ctx.target_universe(unconfigured_owners).target_set() + owners = ctx.cquery().owner("foobar", target_universe) +``` + +For everything else, the universe would usually be constructed using all target +literals found in your query. Example: + +```python +def _impl: + target_universe = ctx.target_universe("//example:foo") + inputs = target_universe.target_set() + deps = ctx.cquery().deps(inputs) +``` + +While the above guideline should work for `rdeps` as well, for `rdeps` the +universe would usually be narrowed down to the "to"/"destination" target set +argument. (This is a subset of the target universe suggested for non-`owner` +query cases). Updating the example from above: + +```python +def _impl: + target_universe = ctx.target_universe("//example:foo") # narrowed down to the "to" literals in rdeps + universe_node = target_universe.target_set() + from_node = target_universe.lookup("//example:bar") + rdeps = ctx.cquery().rdeps(universe_node, from_node) +``` + +### `keep-going` + +The configured graph can be broken for various reasons: incompatible targets +(BXL skips these automatically), visibility issues, nonexistent targets, etc. +For issues that are not incompatible targets, the `target_universe` can be +constructed with the `keep_going` flag set to `True` to skip any other errors, +and your cquery will not error out. Note that `keep_going` is only compatible +for a single string literal target or target pattern at the moment. + +```python +ctx.target_universe("//foo/...", keep_going = True) +``` + +## BXL build and target universe + +Note that BXL builds currently do not support target universe, but we intend to +add this. diff --git a/_src/developers/bxl_telemetry.md b/_src/developers/bxl_telemetry.md new file mode 100644 index 000000000000..0a4cb999ca98 --- /dev/null +++ b/_src/developers/bxl_telemetry.md @@ -0,0 +1,168 @@ +--- +id: bxl_telemetry +title: BXL Telemetry +--- + +## Telemetry + +### Emitting events from your BXL script + +In BXL, you can emit custom events via `ctx.instant_event()`, which takes in two +named parameters: + +- `id`: string, identifies your event. Helpful to identify your event when + looking through event logs. Ids do not have to be unique in a single BXL + script. +- `metadata`: dict, where keys are strings, and values are strings, bools, ints, + or lists/dicts of the mentioned types. You can put any metadata you wish here. + +Example: + +```python +def _impl(ctx): + ctx.instant_event(id = "id1", metadata = {"foo": "bar"}) + +my_script = bxl_main( + impl = _impl, + cli_args = {}, +) +``` + +Only instant events can be manually created within BXL at this time, which means +that the event represents a single point in time. If you need something similar +to spans (start and end events which encompass a range of time) for measuring +the duration of a particular section (excluding actions - see below for more +information), you could couple instant events with the global `now()` function +to measure the duration yourself: + +```python +def _impl(ctx): + instant = now() + + # do something time intensive + end = instant.elapsed_millis() + ctx.instant_event(id = "id1", metadata = {"duration": end}) + + # do something else time intensive + end = instant.elapsed_millis() + ctx.instant_event(id = "id2", metadata = {"duration": end}) + +my_script = bxl_main( + impl = _impl, + cli_args = {}, +) +``` + +**Measuring time for actions and ensuring artifacts** + +You cannot use `now()` to measure the time it takes to run actions and ensure +artifacts because these processes occur asynchronously outside of the BXL script +execution. For BXL user telemetry, we emit action events via the buck2 core +automatically. Events around ensuring the artifacts are not emitted currently, +but will be added soon. + +### User event log + +To write to your own event log when running BXL, you can run your BXL command +with the `--user-event-log` flag to tell buck2 where to write the events to. +Buck2 is aware of the following file extensions: `.json-lines`, +`json-lines.zst`, `.json-lines.gz`, and will compress the files automatically +for you depending on the extension. If the extension is not one of these, the +logs will always be written in JSONL format, uncompressed. + +Example: + +``` +buck2 bxl path//to/my_script/script.bxl:my_script --user-event-log my_file.json-lines.gz +``` + +When using this flag to write to a custom event log, it is up to you to clean up +these log files. In addition, if the same filename is used with subsequent BXL +invocations, events are always appended to the existing file contents, which is +the same behavior as `buck2 --event-log `. If you tell buck2 +to write to a compressed file, you are responsible for decompressing them. + +### Getting a user event log from a normal event log + +`buck2 log show-user` can be used to convert a normal event log (regardless of +encoding/compression) to a user event. Similar to `buck2 log show`, you can +choose the most recent invocation, or the nth invocation, or provide a path to +the normal user event log. Note that user event logs are not able to be passed +into `buck2 log show` or `buck2 log show-user`. + +### Event log output + +The first line of your event log will always be the invocation record, which +contains useful things like command line args used, working directory, etc. The +subsequent lines are either instant events and/or action events, depending on +your BXL script's contents. + +**Instant event** + +Sample: + +```python +{ + "StarlarkUserEvent": { + "id": "foo", + "metadata": { + "bool_value": true, + "string_value": "str", + "int_value": 123, + "list_value": [ + "a", + "b", + "c" + ], + "dict_value": { + "foo": "bar" + } + }, + }, + "epoch_millis": 123456789 # when the event was emitted +} +``` + +**Action event** + +```python +{ + "ActionExecutionEvent": { + "kind": "Write", # kind of action, like write or run + "name": { # name of the action, for user display. Unique within the execution of a particular target + "category": "write", # category for the action + "identifier": "my_output" # identifier for the action + }, + "duration_millis": 0, # duration of the action in millis, excluding input materialization time + "output_size": 10, # size in bytes of the action's outputs + "input_materialization_duration_millis": 0, # how long it took to materialize any inputs to the action + "execution_kind": "Simple", # how the action was executed + "owner": "cell//path/to/script.bxl:function_name" # owner of the action execution (target label, anon target label, bxl label) + }, + "epoch_millis": 123456789 # when the event was emitted +} +``` + +`execution_kind` includes: + +- Local: action was executed locally +- Remote: action was executed via a remote executor +- ActionCache: action was served by the action cache and not executed +- Simple: action is simple and executed inline within buck2 (ex: write, + symlink_dir) +- Skipped: action was not executed at all +- Deferred: action logically executed, but didn't do all the work +- LocalDepFile: action was served by the local dep file cache and not executed. +- LocalWorker: action was executed via a local worker +- NotSet: action execution kind was not set + +**Ensure artifact event** + +```python +{ + "BxlEnsureArtifactsEvent": { + "duration_millis": 0, # duration of ensuring the artifact + }, + "epoch_millis": 123456789 # when the event was emitted +} +``` diff --git a/_src/developers/options.md b/_src/developers/options.md new file mode 100644 index 000000000000..e8eada0f95ef --- /dev/null +++ b/_src/developers/options.md @@ -0,0 +1,10 @@ +# Buck 2 specific options + +Buck 2 introduces some options that don't exist in v1 and are accessed in the +root cell: + +- `project.watchman_merge_base`: defines the merge base to use for SCM-aware + queries to Watchman. This is read when the daemon starts and cannot be changed + later without a restart. +- `test.v2_test_executor`: defines the program to invoke as the test executor in + `buck test`. This is read every time a test command executes. diff --git a/_src/developers/request_for_comments.md b/_src/developers/request_for_comments.md new file mode 100644 index 000000000000..e707bfb292c1 --- /dev/null +++ b/_src/developers/request_for_comments.md @@ -0,0 +1,24 @@ +--- +id: request_for_comments +title: Request for Comments +--- + +Following are Request for Comments (RFCs) at specific stages of the lifecycle. + +### Drafts + +- [@configuration syntax](rfcs/drafts/configuration-at-syntax.md) +- [bxl actions and Build API](rfcs/drafts/bxl-actions.md) +- [Digest Kinds](rfcs/drafts/digest-kinds.md) +- [labels -> metadata attribute](rfcs/attr-metadata.md) + +### Accepted + +- [configured_alias](rfcs/configured-alias.md) +- [Buck Extension Language (BXL)](rfcs/bxl.md) +- [Bxl Support for performing analysis on targets](rfcs/bxl-analysis.md) +- [Package-local values](rfcs/package-local-values.md) + +### Implemented + +- [ProviderCollection[]](rfcs/implemented/provider-collection-at.md) diff --git a/_src/developers/starlark/spec.md b/_src/developers/starlark/spec.md new file mode 100644 index 000000000000..85b72ee9bc96 --- /dev/null +++ b/_src/developers/starlark/spec.md @@ -0,0 +1,4 @@ +# Starlark Language Specification + +The Starlark language spec can be found in the +[Bazel GitHub repository](https://github.com/bazelbuild/starlark/blob/master/spec.md). diff --git a/_src/developers/what-ran.md b/_src/developers/what-ran.md new file mode 100644 index 000000000000..2d04a2516a8f --- /dev/null +++ b/_src/developers/what-ran.md @@ -0,0 +1,87 @@ +--- +id: what-ran +title: Finding Commands That Buck2 Ran +--- + +Buck2 logs all the commands it runs. So, after you've run a build, you can query +Buck2 to get access to the exact command it used. + +To do so, do your build as normal, then run `buck2 log what-ran`. + +## What Ran output format + +This will output a table showing all the commands that were executed, and how +they were executed. + +The structure is as follows: + +```sh +REASON TARGET IDENTIFIER EXECUTOR REPRODUCER +``` + +Which should be used as follows: + +- REASON - value is either `build` (for building a thing) or `test` (for running + a test). +- TARGET - the name of the build target that declared an action. +- IDENTIFIER - depends on the target but will usually be something like a file + name or a module. +- EXECUTOR - value is either `cache`, `re` or `local`. +- REPRODUCER - how you can re-run this yourself. + +## Using the What Ran output + +Use What Ran as follows: + +- Start by identifying the command you're looking for: + - You can grep the output for a given target. + - You can then grep by identifier if necessary. For example, if you're after + C++ compilation, try grepping for the basename of your file (for example, + for `fbcode/my/stuff.cpp`, grep for `stuff.cpp`). +- Once you found it, reproduce as follows: + - If the executor was `local`, the command is in the output, so just run it. + It's expected that you'll do this from the root of your project (use + `buck2 root --kind project` to find where that is). + - If the executor was `re` or `cache`, you're provided a RE digest of the form + `HASH:SIZE`. Run `frecli cas download-action HASH:SIZE` to retrieve the + action, then follow the instructions to run it. + +## Examples + +The following ran locally: + +```bash +build fbcode//scripts/torozco/getenv:getenv-san-conf-__generated-lib__ (archive_thin libgetenv-san-conf-__generated-lib__.pic.a) local fbcode/third-party-buck/platform010/build/llvm-fb/bin/llvm-ar qcsTD buck-out/v2/gen/fbcode/d839c731f5505c62/scripts/torozco/getenv/__getenv-san-conf-__generated-lib____/libgetenv-san-conf-__generated-lib__.pic.a buck-out/v2/gen/fbcode/d839c731f5505c62/scripts/torozco/getenv/__getenv-san-conf-__generated-lib____/__objects__/san-conf.c.pic.o +``` + +To repro, you'd run: + +```bash +fbcode/third-party-buck/platform010/build/llvm-fb/bin/llvm-ar qcsTD buck-out/v2/gen/fbcode/d839c731f5505c62/scripts/torozco/getenv/__getenv-san-conf-__generated-lib____/libgetenv-san-conf-__generated-lib__.pic.a buck-out/v2/gen/fbcode/d839c731f5505c62/scripts/torozco/getenv/__getenv-san-conf-__generated-lib____/__objects__/san-conf.c.pic. +``` + +The following ran on RE: + +```bash +build fbcode//common/init:kill (cxx_compile Kill.cpp (pic)) re 97feca9d014155a80ec55fe27e6bb17f9d2f8574:94 +``` + + +To repro, you'd run: + +```bash +frecli cas download-action 97feca9d014155a80ec55fe27e6bb17f9d2f8574:94 +``` + + + +Reproducing this command will depend on the particular RE implementation you use. + + +## Expired Digests + +Note that if the action was a cache hit on RE, you might get an error when +downloading it, indicating that it's not found. If that happens, it's because +the cache entry is there but the inputs have expired. + +If this happens to you, run your build with `--upload-all-actions`. diff --git a/_src/developers/windows_cheat_sheet.md b/_src/developers/windows_cheat_sheet.md new file mode 100644 index 000000000000..13eca58d8e4c --- /dev/null +++ b/_src/developers/windows_cheat_sheet.md @@ -0,0 +1,38 @@ +--- +id: windows_cheat_sheet +title: Windows Cheat Sheet +--- + +This page contains notes and tips to assist you in understanding the different +tools used when migrating Buck2 to Windows. + +## CMD, Powershell, Bash Command Comparison + +| Bash | Powershell | CMD | What does it do | +| ------------------ | ------------------ | ---------------- | -------------------------------- | +| cd | cd | cd | Change the current directory | +| mkdir | mkdir | mkdir / md | Create a directory | +| ls | ls | dir | List contents of a directory | +| export var="value" | $env:var="value" | set var=value | To set environment variables | +| $ENV_VAR | $env:ENV_VAR | %ENV_VAR% | Read environment variable | +| echo "Hello world" | echo "Hello world" | echo Hello world | To print something on the screen | +| rm | rm | del | Delete a file | +| rm -rf | rmdir | rmdir | Delete a directory | +| cat | cat | type | Print file content to console | + +## Symlinks + +In Windows, there are two types of symlinks: file and directory. + +You can find out which type of symlink is being created using: +`dir /AL /S `. + +The command lists all of the symbolic links in the `` directory: + +- `^` is a Directory SymLink +- `^` is a File SymLink + +## Target names + +Escaping the '=' symbol on Windows is quite complicated: make sure none of the +targets being built contain this symbol as it could cause build breakages. diff --git a/_src/getting_started.md b/_src/getting_started.md new file mode 100644 index 000000000000..34cc3532dfcb --- /dev/null +++ b/_src/getting_started.md @@ -0,0 +1,250 @@ +--- +id: getting_started +title: Getting Started +--- + +## Installing Buck2 + +The latest set of `buck2` executables can be found under the +[`latest` release page](https://github.com/facebook/buck2/releases/tag/latest). + +Additionally, for each bi-monthly release there is a +[dotslash](https://dotslash-cli.com/) file that is appropriate for checkin to a +repository. This will automatically fetch the correct version and architecture +for each user, and ensures a consistent build environment for each commit in the +repo. + +To get started, first install [rustup](https://rustup.rs/), then compile the +`buck2` executable: + +```bash +rustup install nightly-2024-03-17 +cargo +nightly-2024-03-17 install --git https://github.com/facebook/buck2.git buck2 +``` + +The above commands install `buck2` into a suitable directory, such as +`$HOME/.cargo/bin`, which you should then add to your `$PATH`: + +Linux / macOS + +```sh +export PATH=$HOME/.cargo/bin:$PATH +``` + +Windows Powershell + +```powershell +$Env:PATH += ";$HOME\.cargo\bin" +``` + +With Buck2 installed, you can build projects with `buck2`! + +### Windows configuration + +Some of our rules use symlinks, which are disabled by default for non-admin +Windows users. You can fix that by +[enabling Developer Mode](https://pureinfotech.com/enable-developer-mode-windows-11/). + +## Compiling your first project + +This section covers the building of a +['hello_world' example project](https://github.com/facebook/buck2/tree/main/examples/hello_world) +that contains a simple C++ binary. If you are interested in seeing how other +languages can be built, take a look at the +[prelude example project](https://github.com/facebook/buck2/tree/main/examples/with_prelude), +which contains Rust, C++, Python, and OCaml targets. + +First, clone the buck2 repository and cd into the 'hello_world' project: + +```bash +git clone https://github.com/facebook/buck2.git +cd buck2/examples/hello_world +``` + +`buck2 init --git` is all the setup you need to start building. This will use +git submodule to pull [buck2-prelude](https://github.com/facebook/buck2-prelude) +into your project: + +```sh +buck2 init --git +``` + +To use another version control system, run `buck2 init` and manually download +[buck2-prelude](https://github.com/facebook/buck2-prelude) into `prelude` at +root. + +```sh +buck2 init +``` + +To build the entire project, run: + +Note: _Requires clang and lld to be in the path_ + +```sh +buck2 build //... +``` + +Note that this uses a +[simple C++ toolchain](https://github.com/facebook/buck2/blob/main/prelude/toolchains/cxx.bzl) +that requires a recent version of `clang` to be installed on your system. This +can be installed with any package manager (ex. `apt install clang`, +`xcode-select --install` on macOS, `choco install llvm`). After installing any +external tools or changing your `PATH`, run `buck2 kill` before running a build. + +To list all targets available in the project, run: + +```sh +buck2 targets //... +``` + +To run the main C++ binary, run: + +```sh +buck2 run //:main +``` + +The newly built binary can be found with the `--show-output` flag: + +```sh +buck2 build //:main --show-output +``` + +Output: + +```sh +Build ID: 0e890477-5b7f-4829-9ffe-662e572320a0 +Jobs completed: 3. Time elapsed: 0.0s. +BUILD SUCCEEDED +root//:main buck-out/v2/gen/root/9f4d83578bb24895/__main__/main +``` + +## Creating your first hello_world project + +This section demonstrates how to create a simple C++ 'hello_world' project. + +To get started, make a new folder for your project and cd into it. + +```sh +mkdir hello_world +cd hello_world +``` + +Next, run `buck2 init --git` to initialize the project. This command will set up +your project with `git` and pull in +[buck2-prelude](https://github.com/facebook/buck2-prelude) as a submodule. +Additionally, it will generate multiple files with default values. + +```sh +buck2 init --git +``` + +Next, add the source code `main.cpp` , + +```c++ +#include +int main() { + std::cout << "Hello from a C++ Buck2 program!" << std::endl; +} +``` + +Then, define a `cxx_binary` in the root `BUCK` file: + +```Python +# BUCK +cxx_binary( + name = "main", + srcs = ["main.cpp"], + link_style = "static", +) +``` + +If you try to build `//:main` at this point, you'll see an error about `buck2` +not being able to find `toolchains//:cxx`. + +The final step is to define the necessary toolchain targets. For that project, +you need `system_cxx_toolchain` and `system_python_bootstrap_toolchain`, which +will pick up the necessary tools (clang++, python, and so on) from the system. + +```Python +# toolchains/BUCK +load("@prelude//toolchains:cxx.bzl", "system_cxx_toolchain") +load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain") + +system_cxx_toolchain( + name = "cxx", + visibility = ["PUBLIC"], +) + +system_python_bootstrap_toolchain( + name = "python_bootstrap", + visibility = ["PUBLIC"], +) +``` + +At this point, your project should have the following files: + +```bash +$ tree -a -I "buck-out|prelude|.git" +|-- .buckconfig +|-- .gitmodules +|-- BUCK +|-- main.cpp +`-- toolchains + `-- BUCK +``` + +Now, you're ready to see the build in action. + +To build the main C++ target, run: + +```sh +buck2 build //:main +``` + +To run the main C++ target, run: + +```sh +buck2 run //:main +``` + +In summary, a `buck2` project requires: + +1. A `.buckconfig` file in the root which has a `[cells]` section listing out + [cells](https://buck2.build/docs/concepts/glossary/#cell) +2. A `prelude` directory, which contains a collection of + [rules](https://buck2.build/docs/concepts/glossary/#rule) of your choice. + `buck2 init` will pull in the + [buck2-prelude](https://github.com/facebook/buck2-prelude.git) as a git + submodule by default +3. If using the [buck2-prelude](https://github.com/facebook/buck2-prelude.git), + a `toolchains` directory that declares relevant toolchains. We provide some + basic toolchains in + [prelude/toolchains](https://github.com/facebook/buck2/tree/main/prelude/toolchains) +4. `BUCK` files that specify targets for your project + +`buck2 init --git` will generate all of these with reasonable default values. + +## Learning More + +You should now be ready to explore Buck2 for use in your own projects. You can +explore the [examples](https://github.com/facebook/buck2/tree/main/examples) +folder. Look out for more tutorials in the future. + + + +## Communication channels + +The following channels provide an insight into Buck2: + +- [Buck2 Engineering](https://fb.workplace.com/groups/buck2prototyping) - + Workplace group for discussions about what features Buck2 should have, how + it's going, status updates, and much more. +- [Buck2 Users](https://fb.workplace.com/groups/buck2users) - Workplace group + featuring questions from users and reports of bugs. +- [Buck2 Rule Authors](https://fb.workplace.com/groups/347532827186692) - + Workplace group for discussions about language-specific rules. +- [Buck2 Oncall Hub](https://www.internalfb.com/intern/monitor/oncall_profile?oncall=buck2) - + urgent tasks and escalation. + + diff --git a/_src/index.md b/_src/index.md new file mode 100644 index 000000000000..5a5e9eec5cd7 --- /dev/null +++ b/_src/index.md @@ -0,0 +1,140 @@ +--- +id: index +title: Introduction +--- + +Welcome to Buck2, a large scale, fast, reliable, and extensible build tool +developed and used by Meta. Buck2 supports a variety of languages on many +platforms. + +Buck2's core is written in [Rust](https://www.rust-lang.org/). +[Starlark](https://github.com/bazelbuild/starlark), which is a deterministic, +immutable dialect of Python, is used to extend the Buck2 build system, enabling +Buck2 to be language-agnostic. With Starlark, users can define their own custom +rules. + +Buck2 leverages the Bazel spec of +[Remote Build Execution](https://bazel.build/remote/rbe) as the primary means of +parallelization and caching, which increases the importance of idempotency (no +matter how many times an operation is performed, it yields the same result) and +hermeticity (code is sealed off from the world), giving the right results, +reliably. + +Buck2 multi-language support includes C++, Python, Java, Go, Rust, Erlang, +OCaml, and more. + +The following sub-sections contain a list of links to key points in the Buck2 +Documentation website that explain the advantages of using Buck2 for you and +your team. + +## Buck2 Documentation Website Links + +### For end users + +- [Getting Started](getting_started.md) - how to get started with using Buck2. +- [Benefits](benefits.md) - the benefits of using Buck2. + + + +- [Migration Guide](users/migration_guide.fb.md) - how to port projects from + Buck to Buck2, including the issues you might face and notable differences. +- [Buck2 and Build Observability](users/build_observability/observability.fb.md) - + how to use Buck2's datasets to analyze specific invocations or classes of + invocations. +- [Migrating builds to work VPNless](users/advanced/vpnless.fb.md) - how to + migrate builds to work without VPN or lighthouse access. + + + +### For people writing rules + +- [Writing Rules](rule_authors/writing_rules.md) - how to write rules to support + new languages. +- [Build APIs](api/build/globals) - documentation for the APIs available when + writing rules. +- [Starlark Types](https://github.com/facebook/starlark-rust/blob/main/docs/types.md) - + rules are written in Starlark (which is approximately Python), but our version + adds types. + + + +- [Rule Writing Tips](rule_authors/rule_writing_tips.fb.md) - tips for migrating + rules from Buck1 to Buck2. + + + +### For people integrating with Buck2 + +- [Extending Buck via BXL](developers/bxl.md) - powerful Starlark scripts for + introspection of Buck2's graphs. +- [Buck2 change detector](https://github.com/facebookincubator/buck2-change-detector) - + tools for building a CI that only builds/tests what has changed in diff/PR. +- [Buck2 GitHub actions installer](https://github.com/dtolnay/install-buck2) - + script to make GitHub CI with Buck2 easier. +- [Reindeer](https://github.com/facebookincubator/reindeer) - a set of tools for + importing Rust crates from crates.io, git repos etc and generating a BUCK file + for using them. +- [ocaml-scripts](https://github.com/facebook/ocaml-scripts) - scripts to + generate a BUCK file enabling the use of OCaml packages from an OPAM switch. +- [Buckle](https://github.com/benbrittain/buckle) - a launcher for Buck2 on a + per-project basis. Enables a project or team to do seamless upgrades of their + build system tooling. + +### External articles about Buck2 + +- [Introducing Buck2](https://engineering.fb.com/2023/04/06/open-source/buck2-open-source-large-scale-build-system/) - + our initial introduction when we open sourced Buck2. +- [Reddit AMA](https://old.reddit.com/r/rust/comments/136qs44/hello_rrust_we_are_meta_engineers_who_created_the/) + where the Buck2 team answered a number of questions. +- [Using buck to build Rust projects](https://steveklabnik.com/writing/using-buck-to-build-rust-projects) - + working through an initial small Rust project, by + [Steve Klabnik](https://steveklabnik.com/). Followed up by + [building from crates.io](https://steveklabnik.com/writing/using-cratesio-with-buck) + and [updating Buck2](https://steveklabnik.com/writing/updating-buck). +- [Awesome Buck2](https://github.com/sluongng/awesome-buck2) is a collection of + resources about Buck2. +- [Buck2 Unboxing](https://www.buildbuddy.io/blog/buck2-review/) is a general + review of Buck2 by [Son Luong Ngoc](https://github.com/sluongng/). +- [A tour around Buck2](https://www.tweag.io/blog/2023-07-06-buck2/) gives an + overview of Buck2 and how it differs from Bazel. + +### External videos about Buck2 + +- [Accelerating builds with Buck2](https://www.youtube.com/watch?v=oMIzKVxUNAE) + Neil talks about why Buck2 is fast. +- [Buck2: optimizations & dynamic dependencies](https://www.youtube.com/watch?v=EQfVu42KwDs) + Neil and Chris talk about why Buck2 is fast and some of the advanced + dependency features. +- [Building Erlang with Buck2](https://www.youtube.com/watch?v=4ALgsBqNBhQ) + Andreas talks about building WhatsApp with Buck2. +- [antlir2: Deterministic image bulids with Buck2](https://www.youtube.com/watch?v=Wv-ilbckSx4) + talks about layering a packaging system over Buck2. + +### External projects using Buck2 + +- [System Initiative](https://www.systeminit.com/) build their DevOps product + [using Buck2](https://nickgerace.dev/post/system-initiative-the-second-wave-of-devops/#under-the-hood), + with their own custom prelude. +- [Rust `cxx` library](https://github.com/dtolnay/cxx) has examples and tests + with a wide variety of build systems, including Buck2. +- [`ocamlrep` library](https://github.com/facebook/ocamlrep) allows for interop + between OCaml and Rust code, and can be + [built with Buck2](https://github.com/facebook/ocamlrep/blob/main/README-BUCK.md). +- [`buck2-nix`](https://github.com/thoughtpolice/buck2-nix) is an experiment to + integrate Buck2, [Sapling](https://sapling-scm.com) and + [Nix](https://nixos.org) together in a harmonious way. + +Feel free to +[send a PR](https://github.com/facebook/buck2/edit/main/docs/index.md) adding +your project. + + + +### For people developing Buck2 + +- [Basic README](https://www.internalfb.com/code/fbsource/fbcode/buck2/README.md) - + how to get started, compile Buck2 and the basic workflows. +- [Notes for Developers](developers/developers.fb.md) - more advanced workflows + and notes around debugging, profiling etc. + + diff --git a/_src/rfcs/attr-metadata.md b/_src/rfcs/attr-metadata.md new file mode 100644 index 000000000000..3f471ef6fc08 --- /dev/null +++ b/_src/rfcs/attr-metadata.md @@ -0,0 +1,51 @@ +# RFC: labels -> metadata attribute + +This RFC proposes to add new builtin per target attribute: `metadata`, as +replacement for `labels`. + +## Context: labels + +In buck1 we have `labels` builtin rule attribute, which is a list of strings. + +In buck2 we have `labels` attribute which is configured in prelude, it does not +have special meaning. + +## Context: package values + +`PACKAGE` files have a function: `write_package_value(key, value)`, where a key +is a word-dot-word string, and value is arbitrary starlark value which should be +serializable as JSON. + +## Context: metadata we use or we need + +There are several spaces where we use or need metadata to be stored in buck2 +target graph. + +- fbcode uses per-package values to switch code to new clang + ([example](https://www.internalfb.com/code/fbsource/[ef740e6f2610c64621f7547a3b46d54d32af8600]/fbcode/ownership/code_metadata/PACKAGE?lines=3)) +- testinfra wants to use `PACKAGE` values to mark a set of folders to a logical + larger project +- it is likely that per-target `metadata` attribute should be used in + [configuration factory function](cfg-modifiers/api.md). +- TD wants to declare CI trigger jobs per-target or per-package, and this logic + is to be specified in `BUCK` or `PACKAGE` files — as metadata + +## Proposal: metadata attribute + +Add builtin `metadata` attribute to all the targets. + +`metadata` has the same structure as package values: word-dot-word to arbitrary +value serializable to JSON. + +For example: + +```python +cxx_library( + name = "mylib", + metadata = { + "td.run_on_windows": True, + }, +) +``` + +Metadata attribute is not configurable (means `select` cannot be used). diff --git a/_src/rfcs/audit_visibility.md b/_src/rfcs/audit_visibility.md new file mode 100644 index 000000000000..deeaf033e0f2 --- /dev/null +++ b/_src/rfcs/audit_visibility.md @@ -0,0 +1,89 @@ +# `buck2 audit visibility` command + +## Context + +Buck has a concept of Visibility for every target. It allows users to define, +for each target, the targets it can depend on and targets that can depend on it. +Visibility is specified as an allowlist of targets/target patterns, and any +target used that falls outside of the allowlist fails visibility checking. +Visibility pattern can be specified on `visibility` and `within_view` attributes +in buildfiles and +[PACKAGE files](https://www.internalfb.com/intern/wiki/Buck-users/Key_Concepts/Package_Files/). + +Visibility is important to lots of codebase maintainers because it can be used +to keep projects from pulling in unwanted dependencies. As some examples, App +Core teams are using Buck visibility as a +[replacement to current supermodules for protecting app modularity](https://fb.prod.workplace.com/groups/2292177024436518/permalink/3112235492430663/). +Instagram's using visibility to +[protect modularity and define Link Groups used for build speed optimizations](https://fb.prod.workplace.com/groups/devx.build.bffs/posts/5169450219756775/?comment_id=5169500636418400). +There's interest from various DevX teams in using Buck visibility on +[PACKAGE files](https://www.internalfb.com/intern/wiki/Buck-users/Key_Concepts/Package_Files/) +to +[enforce repo boundaries, which will allow target determinators to migrate off of sparse profiles and onto Eden](https://fb.prod.workplace.com/groups/devx.build.bffs/posts/5169450219756775/), +although visibility in its current form is likely not fit for enforcing such +repo boundaries. Visibility has also been used to enforce +[requirements that only certain targets are allowed to depend on targets in fbcode/scripts](https://fb.workplace.com/groups/buckeng/permalink/4392940254087889/). + +For perf reasons, buck2 doesn't always enforce visibility. Instead, it only +enforces visibility on construction of the configured target graph. Visibility +checking is expensive memory-wise because it requires tracking all deps at each +node. When constructing configured target graph, this cost is already paid for +when buck2 checks transitive target compatibility. When constructing the +unconfigured target graph, however, this is costly, so we avoid checking +visibility there. (Note that buck does not allow you to specify selects in +visibility attributes.) + +In practice, this means that commands like `cquery` and `build` can enforce +visibility whereas commands like `uquery` and `targets` cannot. Having +visibility checked only on the configured target graph is problematic for 2 +reasons: + +1. Visibility is only checked on configured deps after selects are resolved, so + it's possible for a target to pass visibility checking in one configuration + but fail visibility checking in another. For example, a target may pass + visibility checking on a linux configuration but fail visibility checking on + mac configuration if it has a bad mac-only dependency. This makes visibility + enforcement more difficult because now you have to query the same graph in + both linux and mac configuration before you know that visibility is always + valid. + +2. Uquery (querying the unconfigured target graph) has better performance than + cquery (querying the configured target graph). Big-O wise, uquery scales with + O(# of targets) whereas cquery scales with O((# number of configurations) x + (# of targets)). Having a way to check visibility on unconfigured target + graph can be much cheaper than doing so on configured target graph. + +## Proposed Solution: `audit visibility` command + +It's clear that we need a way to check visibility on the unconfigured target +graph, but we don't want `buck2 uquery` and `buck2 targets` to regress in memory +use. To get the best of both worlds, I propose adding a separate command to +buck2, `buck2 audit visibility`, that will check visibility on the unconfigured +target graph. Instead of checking on construction of the unconfigured target +graph, this command will check after construction, which will avoid any memory +regression. The tradeoff is that the visibility checking won't be cached, and +rerunning `audit visibility` will rerun visibility checking on each invocation. + +## Usage and Invocation + +`buck2 audit visibility` command will take in a list of target patterns as well +as common build args like config flags and mode files as args. It will construct +the unconfigured target graph based on the **transitive deps** of those targets +and check that this graph has valid visibility. Checking transitive deps matches +the behavior of visibility checking on cquery, but we may revisit this decision +in the future if there is a need for just verifying the immediate dependencies. + +For example, an invocation to check visibility on the transitive closure of +fbobjc can be + +```shell +buck2 audit visibility fbsource//fbobjc/... +``` + +It cannot be used to check that a target has a valid visibility with respect to +targets outside of the transitive closure of its deps. For example, +`buck2 audit visibility fbcode//buck2/starlark-rust/starlark:starlark` will just +check that all transitive deps of `starlark` target (including `starlark` +target) have valid visibility with respect to each other. It will not check that +any targets that depend on `starlark` respect `starlark` target's visibility +attribute. diff --git a/_src/rfcs/bxl-analysis.md b/_src/rfcs/bxl-analysis.md new file mode 100644 index 000000000000..66f989b3631e --- /dev/null +++ b/_src/rfcs/bxl-analysis.md @@ -0,0 +1,76 @@ +# Bxl support for performing analysis on targets + +## Intro + +As Bob and I continue to build out `bxl` we want users to be able to inspect the +providers and actions for a given target label. In order to support this, we +need to be able to provide access to `AnalysisResult` via `starlark`, obtained +via a call to `RuleAnalysisCalculation::get_analysis_result`. + +## How to implement it? + +Our three principle options are as follows: + +1. `BxlContext::analyze(targetlabel: ConfiguredTargetLabelLike)`, where + `ConfiguredTargetLabelLike` accepts `ConfiguredTargetLabel`, + `ConfiguredTargetNode`, or sets and lists of these things + acceptable + strings. + +In this scenario, we attach the analysis method onto the bxl context itself, and +require that users pass in the target label-ish thing when they want to +construct an analysis result. It's a little awkward in some ways because the +analysis is more naturally a method on the argument being passed in and the +`BxlContext` is a context that is needed to perform the calculation. On the +other hand, this allows us to construct a type analogous to `TargetExpr` which +can parse from a wide variety of different `ConfiguredTarget` like things +(strings, nodes, labels, sets, ...). It also is a bit nice from an +implementational standpoint since we don't have to pass the context around +everywhere. This isn't a huge pro though, since we can stick it in the global +eval field. + +```python +result = bxl.analyze(bxl.cquery.deps("foo")) +``` + +2. `ConfiguredTargetLabel::analyze()`, `ConfiguredTargetNode::analyze()`, ... + where we carry around the `BxlContext` in the `eval` global field and + implement analysis on each type that is target label like. + +The pro of this one is that it's quite natural - you can take a +`ConfiguredStarlarkTargetLabel` and then just ... call `analyze()` on it like +you might expect to. The two downsides are that we have to propagate the context +around behind the scenes, and we'll have to provide an implementation of +`analyze` on everything that we'd like to have be able to be `analyzable`. + +```python +result = "root//bin:the_binary".analyze() +# but we don't support +"root//bin:the_binary".rdeps() + + +# instead this looks nice +nodes = ctx.cquery.deps("foo") +for n in nodes: + # since we can now do + nodes.label + nodes.attrs.field + + # similarly access analysis + nodes.analysis +``` + +3. `BxlContext::analysis(): AnalysisContext` where `AnalysisContext` exposes + `AnalysisContext::analyze(targetlabel: ConfiguredTargetLabelLike)`. + +There's not really any pros of this approach except that it's similar to the +flow for `cquery` where we return a `cqueryctx` object to call `cquery` methods +through. + +```python +result = ctx.analysis().analyze("//lib:file1") +``` + +We can also restrict the API to require that users go through `cquery` to obtain +a `ConfiguredTargetNode` prior to calling `analysis`, although we don't _have +to_. I say that we don't have to because the `get_analysis_result` method +mentioned above is configured to accept a label anyway. diff --git a/_src/rfcs/bxl.md b/_src/rfcs/bxl.md new file mode 100644 index 000000000000..fef54a08c492 --- /dev/null +++ b/_src/rfcs/bxl.md @@ -0,0 +1,276 @@ +# Buck Extension Language (BXL) + +Buck2 will allow more complex introspection and interaction with its graphs via +the `bxl` feature. BXL will be a starlark script that allows integrators to +interact with `buck` commands like build and query within starlark, creating a +sequence of operations that introspect, build, and extend the build graph. + + + +https://fb.workplace.com/groups/buck2prototyping/permalink/2404233936540759/. + + + +These are essentially custom buck operations, defined in Starlark, that still +follow the constraints of Buck2, which will enable the same level of +incrementality and caching as native buck2 operations. Furthermore, bxl will +have subscriptions enabled in the future, where based on the incrementality +tracking, buck2 can provide "updated" bxl executions when its known that its +dependencies change, and even when generated sources need to be regenerated. + +The following proposes a basic set of bxl api and building blocks that are +targeted at solving key issues for IDE integration. + +## Use Cases + +### Cpp LSP + + + +I’ve previously defined some proposed integrations +[here](https://docs.google.com/document/d/1jyehtuQ236rtwq2yyLnLmsIgBOctuAm9eoqx95TCO4I/edit). + + + +Lsp prefers to have a single buck command that given a file, returns the +corresponding compilation database. This requires a single command, i.e a bxl, +that accepts a file as input, performs `owners` queries, and uses the owning +target plus the desired file to get the clang flags, and then writes it to disk +in comp db format. It’s possible to write the same features using buck calls to +cquery, and build using subtargets to generate compilation database per file. +However, this requires lsp owners to maintain code in several locations and +languages, and parse and reserialize data. It also does not provide the same +incrementality and subscription update features of the resulting comp db that +writing this in bxl would have. Furthermore, we may explore the idea of trimming +the compilation command to only dependencies required per the file requested. +Bxl actions provides a straightforward api for adding this when writing the +actual comp db file. + +### Android LSP + +Android project requires traversing the target graph to find and java libraries, +grouping and converting them between modules or project libraries depending on +the number of references, and restructuring the graph as directory based. +Android LSP is able to take advantage of subscriptions in the future when +available, allowing developers to keep their IDE up-to-date automatically +without needing to manually regenerate the project. + +With bxl, the graph traversals can be written in starlark, allowing propagation +of information down the graph, accessing targets’ attributes to analyze +dependencies, and access providers for artifacts and action information needed +to output the project file. Project generation also performs directory listings +that buck2’s dice already performs and caches (I think, need to confirm). Bxl +poses the interesting possibility that we can expose a limited set of IO +operations that are tracked by dice so bxl can access the same cached file +operations as rest of buck2. Android project generation currently doesn’t write +project files to buck-out, which prevents it from using buck2 actions. It will +have to rely on an external script to process the graph information printed by +buck and write the actual project files. If it moves to `buck-out` based, then +it can take advantage of creating actions directly using the graph information +processed, and potentially take advantage of incremental actions api to avoid +writing the entire graph on each subsequent update. + +### iOS Project + +iOS is currently being implemented as a series of queries that are aggregated by +an external python script, that then invokes builds of subtargets. The same can +be achieved in bxl, but with the entire sequence being cacheable and +subscribable so that when the graph is updated, or even when generated files +need updating, buck2 can automatically push the updates. However, it is +uncertain whether xcode itself can make use of push updates. + + + +In +https://docs.google.com/document/d/1USZ_ZYxq45DHUFF-BAYo6zS4lAHlpvNk9uM5SBL9e-w/edit?disco=AAAAQv4gLQ0, +it was also proposed that project generation may need information to flow down +as part of the generation, which is only possible via bxl defining its own +actions. (Although, there may have been a workaround per Chatura). + + + +### Rust LSP + +(note from dbarsky@: I’m adding this at Bob’s request. Can be removed as +needed.) + +### Visual Studio Project (vsgo) + +Vsgo is a pile of python that converts buck query/buck targets output via a +variety of heuristics into inputs to a custom fork gyp which is then invoked to +generate visual studio projects for a given buck target. Having direct access to +the internals of buck would allow us to remove the heuristics and possibly even +move project generation directly into bxl. + +## Goals + +From the above use cases, BXL should offer a simple Starlark API that allows +easy introspection of the buck2 graph at unconfigured, configured, providers, +and actions stage, maintaining incremental behaviour of the BXL evaluation +itself. + +Some minimal API should be offered to allow BXL to provide additional behaviour +such as output artifacts, and print results. + +Most use cases from LSP desire to also propagate information via the command +line for these operations, so BXL should support command line arguments as +inputs. + +## API + +### Defining a bxl function + +There are multiple models possible. We can have each file be its own bxl, or +have each file declare multiple bxl like rules. + +There are multiple advantages to allowing declaration of multiple bxls, such as +grouping similar bxls in the same file, allowing them to "invoke" each other. It +doesn’t necessarily add much more complexity for the author, as even with one +bxl per file, the author still has to have some declaration for the bxls +arguments. + +```python +# sample.bxl +func1 = bxl_main( + impl = my_func1, + args = { + "arg1": arg.list(arg.str()), + } +) + +func2 = bxl_main( + ... +) + +``` + +To invoke buck2 for that bxl, we can have the command line as follows. + +```shell +buck2 bxl sample.bxl::func1 -- --arg1 foo bar baz +``` + +For bxl functions to read the arguments, a similar api to rule attrs is used + +```python +args = ctx.args.args_for_bxl +``` + +Args defined like attrs when declaring the bxl function above + +### Accessing target nodes + +All standard query functions will be enabled in bxl, allowing users to run query +operations, storing them in variables and interacting with them. These allow +introspection of the unconfigured targets, or the configured targets based on +api + +```python +# some.bxl +targets = ctx.uquery(‘deps("//foo")’) +targets = filter(targets, my_filter) + +# introspect a target +for target in targets: + ctx.print(target.attributes) # prints selects + # also inspect the target like below + ctx.print(target.label) + +target = ctx.cquery("//foo", "//x86").attributes # cquery has selects resolved +``` + +### Inspect providers + +When we have a configured target, bxl can request for the analysis of the rule + +```python +target = + +ctx.analysis(target).providers # access the providers +``` + +### Actions + +For IDEs, to generate compilation databases, or generate project files, writing +them in bxl will entail creating actions, and executing them. As such, bxl will +also be given the rules api to register actions, including dynamic outputs for +the rule in the current bxl invocation to build artifacts as part of a bxl +function. + +BXL has the ability to create actions with some constraints: + +1. Action is tied to a particular target +2. It’s output location is determined in the same pattern as regular actions + defined via rules + +```python +targets = ctx.cquery(‘deps("//foo:rule")’) + +for t in targets: + action_ctx = ctx.analysis(t).actions + # the action context here is tied to the configured target `t` + # actions registered by bxl will be attached with bxl prefix key + action_ctx.registry.write(some_output, "foo") + +``` + +BXL can also interact with the existing actions on an action via the action_ctx, +such as iterating through it, analyzing its outputs, or requesting it to be ran. + +```python +targets = deps("foo:rule") + +for t in targets: + action_ctx = ctx.analysis(t).actions + for action in action_ctx.iter(): + if "foo/path" in action.output: + ctx.build(action) +``` + +### What is cached? + +All computations requested by a bxl function will be treated as inputs. So if a +bxl function calls uquery, then uses the result to do a cquery, and then a +build, if buck2 detects that any of the recorded calls to uquery, cquery, and +build changes, the entire bxl will be reran, with no early cutoff. The +computations itself will still be cached via DICE, so no major performance +issues are expected. However, in the event that a bxl function is +computationally heavy, the recommendation would be to move that to an action, or +split up the bxl and use inter-bxl caching described below. + +### Inter-bxl caching? + +Different bxl can be cacheable between each other if structured as +"outputs"/artifacts. This is essentially the same behaviour as a bxl requesting +`ctx.build`, which is cached. Since we have those as hashes on RE, we can track +properly and not require storing the values in dice. + +i.e. + +```python +# caching_sample.bxl +func1 = bxl_main( + impl = my_func1, + args = { + "arg1": arg.list(arg.str()), + } +) + +my_func1(ctx): + … + # do various stuff that might change a lot, but the final result + # doesn’t change much + ctx.return(some_artifact) + +func2 = bxl_main( + impl = my_func2, + ... +) + +my_func2(ctx): + artifact = ctx.bxl(":func1") + # now read artifact value + # everything below will only be reran if the artifact content changes + … + # do some expensive stuff +``` diff --git a/_src/rfcs/cfg-modifiers/api.md b/_src/rfcs/cfg-modifiers/api.md new file mode 100644 index 000000000000..47f9e24d1cde --- /dev/null +++ b/_src/rfcs/cfg-modifiers/api.md @@ -0,0 +1,461 @@ +# [RFC] Configuration Modifiers + +## Why do we need new configuration setup? + +A target usually needs to be built in multiple build settings. For example, +there may be different OS (ex. linux, mac, windows), architectures (ex. x86, +arm), and sanitizers (ex. asan, tsan, ubsan) to use for a single target. Buck +has 2 main ways of supporting customizations today: + +1. Buckconfigs specified through `--config` or `-c` flags. They are global flags + and are often aggregated in modefiles (`@` on the command line). +2. Target platforms specified through `default_target_platform` attribute or + `--target-platforms` flag), which become a target's "configuration". + `--target-platforms` flags are also commonly specified via modefiles. + +These methods are problematic for the following reasons. + +1. _We have too many modefiles_. A project that needs customizations often ends + up adding its own set of modefiles, causing a continued rise in number of + custom modefiles in the repo. Internally, the number of modefiles in our + monorepo is currently on the order of **10,000s**. + +1. _Changing buckconfigs invalidates Buck's state_. Changing buckconfigs or + modefiles of buckconfigs invalidates global state, which adds non-trivial + Buck overhead on every incremental build that changes state. This does not + affect target platforms. + +1. _Different modefiles of buckconfigs cannot be used in same build_. Users that + need to run multi-configuration builds today often work around this by + writing scripts that wraps multiple buck build invocations of different + modes. This is slow because Buck state keeps getting repeatedly invalidated. + There is also no way to build a target in different modes (ex. dev and opt) + at the same time, so users that need to do this always have to do this + sequentially. This does not affect target platforms. + +1. _Target platform generation is exponential in number of build settings_. + Suppose I want to customize targets based on 3 OSes, 2 architectures, and 3 + compilers. With target platforms, I need to first generate all 18 + permutations of these settings as platform targets before using them. This is + not scalable. + +1. _Target platform does not compose well on command line_. Suppose I want to + use ASAN on top of some existing platform. It's not possible to say specify + ASAN on top of an existing platform on the command line. Instead, I must + create a new platform target with ASAN added to the existing platform before + I can use it. + +1. _Poor user Experience_. When every project needs its own set of modes, it's + onerous for users to track what modes are needed to build what targets. Users + often don't realize when they are using the wrong or unnecessary command line + flags. + +1. _Poor tooling integration_. Similar to user, it's just onerous for tooling to + keep track of what modes are needed to build a target with. Buckconfigs are + also bad for performance for tools like language servers because it's + impossible to request the builds of two modes in parallel when two targets + needs different modes. + +1. _Antithetical to Buck's principles_. Buck's main strength is the ability to + abstract away builds of different languages and libraries under one common + syntax for the user. The need for project-custom flags goes against this + principle. + +The Modifier API introduces a unified way to specify build settings on a +project, target, and command line level. Like target platforms, it constructs +Buck configurations so it supports multi-configuration builds. It avoids +modefile proliferation by allowing users to easily set project-specific build +settings like compiler and toolchain versions in the repo rather than on the +command line. It avoids scalability problems of platform generation by being +composition-first. The goals of this project is to: + +1. _Make `buck build` work on any platform without the use of special flags_. + Today, building a mac target on mac often requires a mac mode, and likewise + for windows. Instead, `buck build` should always work out of the box on any + platform so that there's no need to specify mac mode on macs or windows mode + on windows. +1. _Define a small constrained set of common modifiers that can be used to build + any target in the repo_. This will include common options like mode (ex. dev, + opt, release), OS (ex. linux, mac, iphoneos), and architecture (ex. x86, + arm). +1. _Unblock cross-building for the majority of targets_. `host_info()` is a hack + to obtain information about the host machine that is the main blocker to + Buck2 cross-building (ex. building a mac or windows target from linux) + working everywhere. As an extension of "making `buck build` work on any + platform", modifiers should make it possible to kill off most use cases of + `host_info` in the repo. +1. _Simplify building build tooling_. Because `buck build` works out of the box, + tools like language servers can build targets they need without using + project-specific modefiles or flags. +1. _Delete most modefiles from the repo_. +1. _Deprecate target platforms for modifiers as the sole way of configuring + top-level targets in Buck_. + +## Configuration Background + +_Feel free to skip this if you already understand Buck configurations._ + +A configuration is a collection of `constraint_value` targets (commonly referred +to as constraints). It defines the build settings used by a target. A constraint +value is keyed by a `constraint_setting`, so there can only be one +`constraint_value` of a `constraint_setting` in a configuration. + +For example, suppose `cfg//os:_` is a constraint setting with constraint values +`cfg//os:linux`, `cfg//os:macos`, and `cfg//os:windows`. Then a configuration +may contain either `cfg//os:linux`, `cfg//os:macos`, or `cfg//os:windows` to +indicate which OS a target is built for. + +A constraint or a set of constraints can be selected on via `select()` to +customize a target's behavior. For example, the following adds a linux only dep +to a target. + +```python +deps = select({ + "cfg//os:linux": [":linux_only_dep"], + "DEFAULT": [], +}) +``` + +Before building a target on the command line (known as the top-level target), +Buck needs to know its configuration in order to resolve selects. Modifiers are +a new way to resolve a target's configuration for every top-level target. + +## API + +Every top-level target starts with an empty configuration, and Buck will apply a +list of "modifiers" to obtain a configuration. A modifier is a modification of a +constraint from the existing configuration to obtain a new configuration. There +are two types of modifiers, _conditional_ and _unconditional_ modifiers. + +An unconditional modifier is just a constraint value. Applying an unconditional +modifier will insert the associated constraint value into the configuration for +its respective constraint setting, replacing any existing constraint value for +that setting. For example, specifying `cfg//os:linux` as a modifier will insert +`cfg//os:linux` into the configuration, overriding any existing constraint value +for the `cfg//os:_` constraint setting. + +A conditional modifier is a modifier that only applies when a certain condition +is satisfied. This lets one express powerful composition based on other +criteria. `modifiers.match()` is a conditional modifier that changes the +constraint value inserted based on the existing configuration. For example, a +modifier like + +```python +modifiers.match({ + "cfg//os:windows": "cfg//compiler:msvc", + "DEFAULT": "cfg//compiler:clang", +}) +``` + +will insert msvc constraint into the configuration if OS is windows or clang +constraint otherwise. A `modifiers.match()` behaves similarly to Buck's +`select()` but can only be used in a modifier context. A `modifiers.match()` can +only be used to modify a single constraint setting, so the following example is +not valid. + +```python +# This fails because a modifier cannot modify both compiler and OS. +modifiers.match({ + "cfg//os:windows": "cfg//compiler:msvc", + "DEFAULT": "cfg//os:linux", +}) +``` + +A modifier can be specified in a PACKAGE file, on a target, or on the command +line. This provides the flexibility needed to customize targets on a project, +target, or cli level. + +### PACKAGE Modifier + +In a PACKAGE file, modifiers can be specified using the `cfg_modifiers` function +and would apply to all targets covered under that PACKAGE. For example, +modifiers specified in `repo/PACKAGE` would apply to any target under +`repo//...`. Modifiers specified in `repo/foo/PACKAGE` would apply to any target +under `repo//foo/...` (For resolution order, see "Modifier Resolution" section). + +The `cfg_modifiers` function takes as input a dictionary of constraint setting +to modifier for that setting. For example, the following is an example that sets +modifiers for OS and compiler settings in the repo's top PACKAGE file for all +targets in repo. + +```python +# repo/PACKAGE + +set_cfg_modifiers(cfg_modifiers = [ + "cfg//:linux", + modifiers.match({ + "DEFAULT": "cfg//compiler:clang", + "cfg//os:windows": "cfg//compiler:msvc", + }), +]) +``` + +To make constraints easier to type, you can specify aliases for modifier targets +via Buck's target aliases. + +For example, suppose the following aliases exist in `repo/.buckconfig`. + +```ini +[alias] + os = cfg//os:_ + linux = cfg//os:linux + macos = cfg//os:macos + windows = cfg//os:windows + compiler = cfg//compiler:_ + clang = cfg//compiler:clang + msvc = cfg//compiler:msvc +``` + +Then the same PACKAGE modifiers can be specified as follows. + +```python +# repo/PACKAGE + +set_cfg_modifiers(cfg_modifiers = [ + "linux", + modifiers.match({ + "DEFAULT": "clang", + "windows": "msvc", + }), +}) +``` + +### Target Modifier + +On a target, modifiers can be specified on the `metadata` attribute. For +example, the following specifies modifiers for `repo//foo:bar`. + +```python +# repo/foo/BUCK + +python_binary( + name = "bar", + # ... + metadata = {"buck.cfg_modifiers": [ + "cfg//os:windows", + # Target modifiers can also use aliases + "clang", + ]}, +) +``` + +Note one day all targets will probably have their own `cfg_modifiers` attribute. + +### CLI Modifier + +On the command line, modifiers are specified as +`buck2 build ?`. + +For example, `buck2 build repo//foo:bar?cfg//sanitizer:asan` applies asan +modifier on the command line. +`buck2 build repo//foo:bar?cfg//os:linux,cfg//sanitizer:asan` will apply linux +and asan modifiers. Aliases can also be used on command line, so +`buck2 build repo//foo:bar?asan` is valid. + +Command line modifiers cannot be selects, although this may be revisited if +necessary. + +Modifiers can be specified for any target pattern, so +`buck2 build repo//foo/...?asan` and `buck2 build repo//foo:?asan` are also +valid. When specifying a subtarget and modifier with `?`, subtarget should go +before modifier, ex. `buck2 build repo//foo:bar[comp-db]?asan`. + +To specify modifiers to a list of target patterns on the command line, you can +use the `--modifier` or `-m` flag. For example, +`buck2 build repo//foo:bar repo//foo:baz -m release` is equivalent to +`buck2 build repo//foo:bar?release //foo:baz?release`. + +`--modifier` flag can be specified multiple times to add multiple modifier, so +`buck2 build --modifier=linux --modifier=release repo//foo:bar` is equivalent to +`buck2 build repo//foo:bar?linux,release`. + +It is prohibited to specify both `--modifier` flag and `?` in target pattern. +This restriction can be lifted in the future if there is a need. + +When two modifiers of the same constraint setting are specified, then the later +one overrides the earlier one. For example, +`buck2 build repo//foo:bar?dev,release` is equivalent to +`buck2 build repo//foo:bar?release`. + +On command line, a `config_setting` target can be specified as a collection of +modifiers after `--modifier` or `?`. This will be equivalent to specifying each +constraint inside the `config_setting` as a separate modifier. + +### Modifier Resolution + +Modifiers are resolved in order of constraint setting, and for each constraint +setting, modifiers for that setting are resolved in order of PACKAGE, target, +and command line, with modifier from parent PACKAGE applied before child +PACKAGE. The end of this section will describe how Buck determines the order of +constraint setting to resolve. + +Suppose modifiers for `repo//foo:bar` are specified as follows. + +```python +# repo/PACKAGE + +set_cfg_modifiers(cfg_modifiers = [ + "cfg//:linux", + modifiers.match({ + "DEFAULT": "cfg//compiler:clang", + "cfg//os:windows": "cfg//compiler:msvc", + }), +]) + +# repo/foo/PACKAGE + +set_cfg_modifiers(cfg_modifiers = ["cfg//os:macos"]) + +# repo/foo/BUCK + +python_binary( + name = "bar", + # ... + metadata = {"buck.cfg_modifiers": ["cfg//os:windows"]}, +) +``` + +At the beginning, the configuration will be empty. When resolving modifiers, +Buck will first resolve all modifiers for `cfg//os:_` before resolving all +modifiers for `cfg//compiler:_`. + +For OS, the linux modifier from `repo/PACKAGE` will apply first, followed by +macos modifier from `repo/foo/PACKAGE` and windows modifier from +`repo//foo:bar`'s target modifiers, so `repo//foo:bar` will end up with +`cfg//os:windows` for `cfg//os:_` in its configuration. Next, to resolve +compiler modifier, the `modifiers.match` from `repo/PACKAGE` will resolve to +`cfg//compiler:msvc` since existing configuration is windows and apply that as +the modifier. The target configuration for `repo//foo:bar` ends up with windows +and msvc. + +However, suppose user invokes `repo//foo:bar?linux` on the command line. When +resolving OS modifier, the linux modifier from cli will override any existing OS +constraint and insert linux into the configuraiton. Then, when resolving the +compiler modifier, the `modifiers.match` will resolve to `cfg//compiler:clang`, +giving clang and linux as the final configuration. + +Because command line modifiers will apply at the end, they are also known as +required modifiers. Any modifier specified on the command line will always +override any modifier for the same constraint setting specified in the repo. + +The ordering of constraint setting to resolve modifiers is determined based on +dependency order of constraints specified in the keys of the `modifiers.match` +specified. Because some modifiers match on other constraints, modifiers for +those constraints must be resolved first. In the previous example, because +compiler modifier matches on OS constraints, Buck will resolve all OS modifiers +before resolving compiler modifiers. `modifiers.match` that ends up with a cycle +of matched constraints (ex. compiler modifier matches on sanitizer but sanitizer +modifier also matches on compiler) will be an error. + +### Conditional Modifiers + +Modifiers have 3 types of conditional modifiers that allow for powerful +compositions. Each operator is a function that accepts a dictionary where the +keys are the conditionals and values are modifiers. + +1. `modifiers.match`. Introduced in the previous sections, this is capable of + inserting constraints based on constraints in the existing configuration. + +2. `modifiers.match_rule`. This is capable of selecting based on the rule name + (also known as rule type). The keys are regex patterns to match against the + rule name or "DEFAULT". Partial matches are allowed. + +3. `modifiers.match_host`. This selects based on the host configuration, whereas + `modifiers.match` selects based on the target configuration. This host + configuration is constructed when resolving modifiers. `modifiers.match_host` + is important to making `buck build` work anywhere on any platform. For + example, when the OS to configure is not specified, it's best to assume that + the user wants to target the same OS as the host machine. + +An example using `modifiers.match_rule` and `modifiers.match_host` is as +follows. + +```python +# root/PACKAGE + +# We want OS to target the host machine by default. +# Ex. build linux on linux machine, build windows on windows machine, +# and build mac on mac machine. +# However, if the rule is apple or android specific, then we should +# always be building for apple/android as OS, no matter the host +# configuration. + +set_cfg_modifiers(cfg_modifiers = [ + modifiers.match_rule({ + "apple_.*": "cfg//os:iphone", + "android_.*": "cfg//os:android", + "DEFAULT": host_select({ + "cfg//os:linux": "cfg//os:linux", + "cfg//os:macos": "cfg//os:macos", + "cfg//os:windows": "cfg//os:windows", + }), + }), +]) +``` + +On select resolution, Buck's `select` currently requires unambiguous keys in the +dictionary and resolves to the key with the most refined match. The select +operators used in modifiers will diverge from this and implement a "first-match" +behavior, where select resolves to the first condition that evalutes to true in +the dictionary. + +### Legacy Target platform + +Target platform (`--target-platforms` flag or `default_target_platform` +attribute) will be a deprecated way of specifying configuration and will be +killed once all use cases migrate to modifiers. To maintain backwards +compatibility with target platforms during the migration process, modifier +resolution will take into account the target platform specified. This allows for +an easy migration where modifiers can be introduced one at a time without +reaching feature parity of target platform. + +If a target's modifiers resolve to an empty configuration, then Buck will reuse +the target platform as the configuration. If modifiers resolve to a non-empty +configuration, then Buck look for any constraint in the target platform not +covered by a constraint setting from the modifier configuration and add those to +the configuration. For example, suppose in the previous example, the target +platform for `repo// foo:bar` includes `cfg//sanitizer:asan`, then this +constraint will be inserted into the configuration since no modifier covered the +sanitizer constraint setting. + +## Debugging modifiers + +Because many layers of modifiers can be applied before obtaining a final +configuration, it is important that modifier resolution is easy to debug and +understand. Here are some ways that modifier resolution can be interpreted. + +1. _`buck2 audit modifiers` command_. There will be a `buck2 audit modifiers` + command to show all PACKAGE, target, and required modifiers for a target. It + can also show configuration changes from modifier resolution process if + requested by the user. + +2. _Starlark print statements or debugger_. Modifier resolution process will be + implemented in Starlark in prelude. This means that any user can use any of + the existing way to debug starlark (ex. print statements, Starlark debugger + in VSCode) to debug the resolution process. + +## How configuration modifiers differ from transitions + +Modifiers are largely inspired by configuration transitions. The difference +between modifier and transition is that a transition can change the +configuration of any target in the graph, but a modifier can only change the +configuration of a top-level target. In other words, if you have target A that +depends on target B and you request a build of A, then A's target configuration +would be resolved via modifiers and propagated down to B, but dep B would not do +its own modifier resolution. When a top-level target goes through a per-rule +transition, that transition is applied after modifiers are resolved. + +Below are some examples that show when to use modifier and when to use +transition. + +1. _Python version_ should be modeled as a transition and not modifier. Suppose + we have `python_binary` A nested as a resource of another `python_binary` B. + A should not inherit the python version from B, so a transition is needed to + change A's python version when depended on by B. +2. _Library target_ should use modifiers and not transitions. A C++ library + target should always inherit the configuration of its parent C++ binary when + it is used as a dep, but a top-level C++ library target can still have its + configuration changed via modifiers when requested from command line. + +In the future, we may add support for modifier transition, which can transition +via modifiers, but that is out of the scope of this RFC. diff --git a/_src/rfcs/configured-alias.md b/_src/rfcs/configured-alias.md new file mode 100644 index 000000000000..dd5f35179ba0 --- /dev/null +++ b/_src/rfcs/configured-alias.md @@ -0,0 +1,91 @@ +# Buck support to implement `configured_alias` + +## Intro + +Currently, Buck 2 lacks `configured_alias` rule support. + +`configured_alias` is a builtin rule in Buck v1, and it cannot be currently +implemented as user defined rule in Buck v2. + +This RFC proposes Buck core support for `configured_alias`. + +## What is `configured_alias`? + +Syntax is this: + +```python +configured_alias( + name = "foo-but-linux-release", + actual = ":foo", + platform = "config//platforms:linux-release", +) +``` + +When this rule is built, it ignores "current" target configuration, and builds +the "actual" target with the configuration specified as "platform" argument. + +## How to implement it in buck v2? + +### New rule attribute type: `configured_dep` + +Currently, we have several dependency attributes: + +- `attrs.dep` +- `attrs.exec_dep` +- `attrs.transition_dep` +- `attrs.split_transition_dep` + +This RFC proposes adding another attribute: + +- `attrs.configured_dep` + +`configured_dep` is an attribute which accepts a pair of strings: target and +configuration. During analysis, configured attr deps are resolved to providers +resolved using given configuration. + +### `configured_alias_impl` user defined rule + +The rule implementation is trivial: + +```python + +def _configured_alias_impl(ctx): + return ctx.attrs.actual.providers + +configured_alias_impl = rule( + impl = _configured_alias_impl, + attrs = { + "actual": attrs.configured_dep(), + } +) +``` + +### Finally, `configured_alias` macro + +```python +def configured_alias(name, actual, platform): + configured_alias_impl(name, actual = (actual, platform)) +``` + +## Alternatives + +### No `configured_alias` + +Each specific case where `configured_alias` is used, it can be done with +defining custom transition, and using custom transition rule. + +But having `configured_alias` is a convenient stopgap to unblock people. + +### Use `@configuration` syntax from [another RFC](https://www.internalfb.com/diff/D35136639). + +Instead of passing `confiured_target_label(x, y)` pass `x + "@" + y`. + +### Accept `configured_target_label` in `dep` attribute + +`dep` attribute could support all of: + +- regular target label as string +- configured target label (as either `configured_target_label` or `x@y` + +I don't know practical applications for this magic, and unless there are uses +for it, better keep API simple and explicit. diff --git a/_src/rfcs/drafts/bxl-actions.md b/_src/rfcs/drafts/bxl-actions.md new file mode 100644 index 000000000000..ead5acdadad6 --- /dev/null +++ b/_src/rfcs/drafts/bxl-actions.md @@ -0,0 +1,71 @@ +# Bxl Actions and Build API + +Bxl allows integrators to write Starlark snippets that introspect the buck2 +graph, and perform various operations on them within Starlark to accomplish +complex operations, as previously proposed in [bxl RFC](../bxl.md)) + +This document is intended at discussing the aspects of build and actions +declaration of a bxl function in more details, and proposed changes to deferred +framework to support bxl actions. + +## Actions API + +The actions API should be the same as rules' actions API. That is, it has the +same `ctx.actions` that allows registering of artifacts, creating actions, +dynamic actions via the same api. + +## Creating and Building the Actions + +Bxl allows users to build targets and actions. However, when creating actions, +they are not bound/buildable until the artifact/action factories are finalized. +As such, we will introduce the limitation that bxl cannot build artifacts that +they themselves declared within the bxl. Instead, they will return a set of +artifacts to expose to users, which buck2 will automatically build after +finalizing the action factory. For dynamic-ness, bxl users will use the standard +dynamic output api. There is an issue that during the dynamic output api's +lambda, bxl functions will not be able to access the regular bxl functions for +queries, etc. However, this is likely not important as most use cases should +reasonably query bxl data before the dynamic outputs, and have limited power in +dynamic-ness. We can also always replace the ctx of the dynamic to be the bxl +context in the future, as we see fit. + +Sample: + +```python +def my_bxl(ctx): + actions_factory = ctx.bxl_actions.factory() + + artifact = actions_factory.write("file.txt", "content") + + # note that existing artifacts that were declared by other rules can be built + ctx.actions.build(ctx.analysis(ctx.target("foo")).providers[DefaultInfo].default_output)) + + return [artifact] # exposes the declared artifact to users +``` + +## Internal Representation (Deferred Framework) + +The existing actions framework attaches all actions to a deferred, which is +based off a `ConfiguredLabel`, which also corresponds to the output path prefix. +bxl actions should also have a unique output path prefix, and follow the same +system of having a base deferred key to reuse the action implementation. + +We should extend the `BaseKey` of a `DeferredKey` to support beyond a +`ConfiguredLabel`, so that we can use a `BxlFunctionLabel` in its place. This +would allow `owner` of these actions to point to the correct creator. The output +path would be determined by using the `BxlFunctionLabel` as prefix similar to a +label. While this means that not all outputs are associated with an actual rule, +this is arguably more correct as bxl that creates outputs that doesn't fit the +target graph structure (i.e android project generation follows directory +structure rather than the packages defined by targets) to not have to conform +the attaching their actions to existing rules. bxl functions can examine +multiple rules and create a single action, attached only to their function +label. + +The ActionRegistry will be attached to the evaluation result of `bxl`. Since we +do not allow bxl to explicitly request build of the actions itself declares, we +can wait until the end of the bxl function to finalize the actions. Then, the +action lookup can simply refer to the result of the `bxl`. + +With the above changes, the rest of the actions framework does not need changed +to support the proposed API. DICE caching will work as today. diff --git a/_src/rfcs/drafts/configuration-at-syntax.md b/_src/rfcs/drafts/configuration-at-syntax.md new file mode 100644 index 000000000000..5d44dd79e4dc --- /dev/null +++ b/_src/rfcs/drafts/configuration-at-syntax.md @@ -0,0 +1,50 @@ +# @configuration syntax + +## What + +Command + +```shell +buck2 build //foo:bar@config//platform:linux-x86_64 +``` + +should be equivalent to current syntax: + +```shell +buck2 build //foo:bar --target-platforms=//platform:linux-x86_64 +``` + +## Why + +Might be convenient if we define global (or per-target, as proposed in +[target configuration discovery RFC](https://www.internalfb.com/diff/D35135886)) +alias. For example, if there's an alias + +``` +release=//config:linux-x86_64-release +``` + +The command above can be expressed as: + +```shell +buck2 build //foo:bar@release +``` + +Additionally, if we have +[configuration expression RFC](https://www.internalfb.com/diff/D35135496) +implemented, we can do something like: + +```shell +buck2 build //foo:bar@release+gcc +``` + +## Possible future extensions + +For now, at-syntax only applies to command line arguments + +- of `build`/`targets`/`run`/`test` commands +- probably `cquery` query + +It would be reasonable to expect that this syntax should be allowed anywhere we +need a target (e.g. in `deps` attribute), but this is out of scope of this +proposal. diff --git a/_src/rfcs/drafts/digest-kinds.md b/_src/rfcs/drafts/digest-kinds.md new file mode 100644 index 000000000000..73e8e73cbea0 --- /dev/null +++ b/_src/rfcs/drafts/digest-kinds.md @@ -0,0 +1,58 @@ +# Digest Kinds + +## Use cases: + +- Buck2 needs to support more than just SHA1 for open-sourcing, since publicly + available RE providers use SHA256. +- Internally, we want to migrate to (potentially keyed) Blake3, and there will + be a transition period where we need to support both Blake3 and SHA1. + +## Proposed plan + +Make all the ways in which Buck2 _ingests_ digests either configurable or +explicit about the type of digest they expect. + +Internally, we may keep track of digest types for debugging purposes, but we +will never compute more than one digest. It follows that we won't expose +configuration for the digests we _output_ (namely: to use on RE): if we only +have one digest for each blob, making it configurable has no utility since you +never have a choice about the hash to use. + +## Implementation + +### Hashes received from RE + +For interactions with RE, we'll expose two configurations (this can be on the +CommandExecutorConfig): + +- Preferred hash to use when Buck2 is doing the hashing (e.g. hashing + directories). +- Accepted hashes. + +We'll use the format of the digests we receive from RE (in particular their +size) to infer what algorithm they used (remember: the RE API provides no way of +knowing the format of a digest, it's just a string). + +### Hashes of files + +We'll expose the hash to use via a buckconfig. Our +things-that-produce-hashes-of-files should either use the config to choose how +they hash, or fail if they cannot provide the right hash format (e.g. that'll be +true of Eden I/O). + +### Hashes of directories + +This one gets a little tricky. Our directories currently have an implementation +of fingerprinting that receives only the directory as input, so some refactoring +is in order. + +We have two options: + +- Pick the hashing algorithm based on the contents of the directory (pick one + that's already used). Dealing with empty directories is a bit annoying. +- Refactor the directory implementation and have directories parameterized over + their fingerprints, not their hasher. + +The first one is easier but has the downside of not working with keyed Blake3 +(because you don't have a way to bring in the key), so I'm aiming for the second +implementation for now. diff --git a/_src/rfcs/drafts/plugin-deps.md b/_src/rfcs/drafts/plugin-deps.md new file mode 100644 index 000000000000..3ef52e2c2535 --- /dev/null +++ b/_src/rfcs/drafts/plugin-deps.md @@ -0,0 +1,198 @@ +## Plugin Deps + +### Background on Rust proc macros + +Rust proc macros are compiler plugins. They are a special kind of crate that is +compiled to a dylib, which is then loaded by the compiler when another crate +depends on the proc macro. Notably, like all Rust crates, proc macros may also +be re-exported. This means that if there is a dependency chain like +`bin -> lib -> proc_macro`, the proc macro must be made available when compiling +the binary, even though it does not appear directly in the dependencies. + +Proc macros have posed a challenge to buck2, for two reasons: + +1. Rust users generally expect to not have to distinguish between proc macros + and normal crates when specifying their dependencies. This means it is not + easily possible to make the `lib -> proc_macro` edge an `exec_dep`. +2. `bin` and `lib` might end up with different exec platforms. This means that + even if `proc_macro` were to be correctly configured as an exec dep of + `lib`, that configuration might be wrong for `bin`. + +FIXME: Other use cases for this feature + +### Plugins deps + +This RFC proposes introducing a concept of "plugin deps" to solve this problem. +Plugin deps are deps that can be propagated up the build graph at configuration +time, instead of at analysis time. Here's what this looks like: + +First, plugin deps come in "kinds." Plugin kinds can be created like +`MyKind = plugins.kind()`. These act as identifiers that can be used to divide +all the possible plugin deps up however users need to. + +Each configured target has plugin lists: There is one list for each plugin kind. +The elements of these list are an _unconfigured_ target, together with a +`should_propagate` bool. The same unconfigured target cannot appear more than +once. In other words, this is a `HashMap>`. We +need to describe two things: How to _use_ these list, and how to _create_ them. + +### Using a target's plugin lists + +Using plugin lists is very simple: The rule sets `uses_plugins = [MyKind]` when +declared. Setting this make the elements of the plugin list for the given kind +appear as exec deps on the configured nodes for this rule. This also means that +the plugins participate in exec dep resolution like all other exec deps. + +Analysis will then be able to access a list of the providers for each of the +plugins via `ctx.plugins[MyKind]`. + +The `should_propagate` bool that is associated with each element of the list is +ignored at this stage. + +### Creating a target's plugin lists + +Plugin lists are created by accumulating from two sources: + +The first of these is direct plugin deps. They are defined via a new +`attrs.plugin_dep(kind = "foo")`. This attribute (like other deps), is set to a +label when the target is declared. It then resolves as follows: + +- In the unconfigured graph: To the appropriate unconfigured target +- In the configured graph: To the label of the unconfigured target. In other + words, this will still be displayed in `buck2 cquery -A`, but will not appear + in the deps. +- During analysis: Also to the unconfigured target label. + +The target that appears in the `plugin_dep` is added to the `MyKind` plugin list +with `should_propagate` set. + +The second way to add to the plugin list is by inheriting from regular deps. +This works as follows: Elements of the plugin lists for which the +`should_propagate` value is true are made available to the immediate rdeps of a +configured target. The rdep can use them by setting `pulls_plugins = [MyKind]` +in the appropriate `attrs.dep()` invocation. This will make the targets appear +in the plugin list for the rdep with `should_propagate` unset. Alternatively, +the rdep can set `pulls_and_pushes_plugins = [MyKind]` to add the targets to the +plugin lists with `should_propagate` set to true. This enables transitive +propagation further up the configured graph. + +To decide later: Should we allow plugin rules to appear in regular/exec deps, +with no special behavior? I don't see why not. + +### Example: Proc macros + +```py +RustProcMacro = plugins.kind() + +rust_proc_macro_propagation = rule( + impl = _propagation_impl, + attrs = { + "actual": attrs.plugin_dep(kind = RustProcMacro), + }, +) + +rust_library = rule( + impl = _similar_to_before, # See some notes below + attrs = { + "proc_macro": attrs.bool(default = False), # Same as before + "deps": attrs.list(attrs.dep(pulls_and_pushes_plugins = [RustProcMacro])), + # Here we avoid `pulls_and_pushes` because we do not want to make these deps available to rdeps + "doc_deps": attrs.list(attrs.dep(pulls_plugins = [RustProcMacro])), + }, + uses_plugins = [RustProcMacro] +) + +rust_binary = rule( + impl = _similar_to_before, # See some notes below + attrs = { + "deps": attrs.list(attrs.dep(pulls_plugins = [RustProcMacro])), + "doc_deps": attrs.list(attrs.dep(pulls_plugins = [RustProcMacro])), + }, + uses_plugins = [RustProcMacro] +) + +def _propagation_impl(ctx): + return [ + DefaultInfo(default_outputs = []), + # During analysis for rust libraries, the providers for proc macros will appear in + # `ctx.plugins`. However, this includes the transitive and direct proc macro deps, as + # well as the transitive and direct proc macro doc-deps. Analysis needs to be able to + # distinguish between all of these though. + # + # This dummy provider is passed to allow for precisely that. Generally, it will be passed + # everywhere where the providers of Rust proc macros are currently passed. That ensures that + # analysis on `rust_library` and `rust_binary` have all the information they need about + # where the plugin "entered the dependency graph." + RustProcMacroMarker(ctx.attrs.actual), + ] + +### TARGETS + +# Expanded by macro +rust_library( + name = "p1_REAL", + proc_macro = True, +) + +# Expanded by macro +rust_proc_macro_propagation( + name = "p1", + actual = ":p1_REAL", +) + +# Expanded by macro +rust_library( + name = "p2_REAL", + proc_macro = True, +) + +# Expanded by macro +rust_proc_macro_propagation( + name = "p2", + actual = ":p2_REAL", +) + +rust_library( + name = "l", + deps = [":p1"], + doc_deps = [":p2"], +) + +rust_binary( + name = "b", + deps = [":l"], +) +``` + +Analysis for `:l` will see: + +1. `deps` which contains only the `RustProcMacroMarker("p")` +2. `doc_deps` which contains only the `RustProcMacroMarker("p2")` +3. `ctx.plugins[RustProcMacro]` which contains the providers of `:p1_REAL` and + `:p2_REAL`, correctly configured for the execution platform of `:l`. + +Analysis for `:b` will see: + +1. `deps` which contain the providers of `l` +2. `ctx.plugins[RustProcMacro]` which contain the providers of `:p1_REAL`, also + correctly configured for its own execution platform (which may be different + from `:l`'s). + + Note that because `rust_library` does not re-push doc deps, `:b` will not + see `:p2_REAL`. + +As a result, the implementation of the `rust_library` rule should not propagate +the providers of its proc macro deps (unlike its regular deps). + +There is one downside to this solution: `buck2 build :p` does absolutely none of +the things that the user is probably expecting. They need `buck2 build :p_REAL`. +That's a bit sad. Thankfully directly building proc macros is not that important +a use case? + +#### Alias + +It is already the case today that we can't use the normal `alias` rule on +toolchains. A similar situation crops up here, where aliasing a target that +pushes plugins causes the plugins to "get lost." The right solution to this is +to probably allow `plugins.ALL` as a special value on `pulls_plugins` and +`pulls_and_pushes_plugins`, and then set that for the alias rule. diff --git a/_src/rfcs/drafts/test-info-v2.md b/_src/rfcs/drafts/test-info-v2.md new file mode 100644 index 000000000000..25fc51f74598 --- /dev/null +++ b/_src/rfcs/drafts/test-info-v2.md @@ -0,0 +1,5 @@ +# RFC: TestInfo v2 + +A stub RFC for TestInfo v2 to track lessons learned about TestInfo v1. The stack +starting D36339960 contains the original code for the TestInfo and templated +test API experiment. diff --git a/_src/rfcs/drafts/universal-cfg-naming.md b/_src/rfcs/drafts/universal-cfg-naming.md new file mode 100644 index 000000000000..8295bf2189d5 --- /dev/null +++ b/_src/rfcs/drafts/universal-cfg-naming.md @@ -0,0 +1,61 @@ +# Universal Configuration Naming Function + +_tl;dr:_ This RFC proposes using a single naming function to generate names for +all configurations. + +## Context + +NOTE: The configuration name consists of a readable string followed by the hash +of the configuration. The readable string is technically the `PlatformInfo` +name. For sake of ease of writing, this doc uses configuration name and platform +name interchangeably to describe this concept. + +Currently, there are 3 ways to create and name a configuration. + +1. A `platform` target defines a configuration, and the platform target label + becomes the platform name. +2. A transition function defines the configuration and generates a name for the + configuration. +3. When a modifier is used, the cfg constructor function for modifiers defines + the configuration and its name. There is currently a single naming function + that generates all modifier-based configuration names. + +Modifiers are intended to replace platforms, so in the future all configuration +names will be generated. Unfortuately, most of the generated names today used +today in transitions are not very good. Problems that I've seen in practice +include: + +1. Configuration names barely contain any useful information about the + configuration. This happens a lot in transitions. For example, the android + split CPU architecture transition names the generated configurations "x86_64" + and "arm64", which tells very little about the configuration beyond the CPU + architectures it splits on. +2. Transition function incorrectly retains the old configuration name that is no + longer relevant, misleading the user about what this configuration actually + does. I've seen this happen where a configuration has py3.8 in name but the + python version constraint stored is actually py3.10. + +## Proposal + +Register a single Starlark function to define all configuration names. This +Starlark function would accept a `ConfigurationInfo` and return a string for the +name of the `ConfigurationInfo`. + +```python +# Example +def name(cfg: ConfigurationInfo) -> str: + # ... +``` + +`PlatformInfo` is no longer available in Starlark. Any place that previously +uses a `PlatformInfo` will now use `ConfigurationInfo` instead. Buck2 will +invoke this function each time it encounters a new `ConfigurationInfo` to define +its name. + +This function will attempt to provide a useful name based on the constraints in +the configuration, which mitigates the issue of short or misleading +configuration names. There are some risks that there will be high amount of code +complexity in a function if all configurations are named by one function. + +This function will most likely be registered via a `set_cfg_name` function or +something callable from root PACKAGE file or potentially prelude. diff --git a/_src/rfcs/implemented/provider-collection-at.md b/_src/rfcs/implemented/provider-collection-at.md new file mode 100644 index 000000000000..a2cbc61fde5c --- /dev/null +++ b/_src/rfcs/implemented/provider-collection-at.md @@ -0,0 +1,40 @@ +# Return error in `ProviderCollection[]` on undeclared provider + +Currently, `ctx.attrs.foo[UnknownInfo]` returns `None` if `foo` is a provider +collection. + +This RFC proposes these changes: + +- `ctx.attrs.foo[UnknownInfo]` is an error +- `UnknownInfo in ctx.attrs.foo` is `False` +- `ctx.attrs.foo.get(UnknownInfo)` returns `None` + +## Why + +Better diagnostics when accessing unknown provider. E. g. when writing: + +```python +ctx.attrs.foo[UnknownInfo].bar +``` + +Currently, the error is: + +``` +Object of type `NoneType` has no attribute `bar` +``` + +Instead, the error will be something like: + +``` +provider collection does not contain `UnknownInfo`, + defined providers are `FooInfo`, `BarInfo`. +``` + +## Bazel + +In bazel, `[]` on unknown provider is an error, like this: + +``` +Error: (rule '_sum') + doesn't contain declared provider 'UnknownInfo' +``` diff --git a/_src/rfcs/package-local-values.md b/_src/rfcs/package-local-values.md new file mode 100644 index 000000000000..f5092b4f2290 --- /dev/null +++ b/_src/rfcs/package-local-values.md @@ -0,0 +1,108 @@ +# Package-local values + +This RFC proposes to extend buck2 Starlark with package-local values. + +## Why + +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` mechanism. + +`get_modes` symbol is registered in per-package implicit symbols, +[here](https://fburl.com/code/7ud7e3ci). + +This symbol can be accessed from macros using +[implicit_package_symbol](https://fburl.com/code/u5coj9s7) 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 `get_modes` mechanism. + +## API + +### `PACKAGE` files + +Before evaluating `BUCK` file, buck2 will evaluate all `PACKAGE` files in the +same directory and all parent directories. Absent `PACKAGE` files are treated as +empty files. + +All relevant `PACKAGE` files are executed sequentially from the root directory +to the current directory (but unrelated `PACKAGE` files can be executed in +parallel). Evaluating `PACKAGE` files sequentially provides additional +guarantees, for example, attempt to override a property (unless explicitly +requested) should fail with Starlark call stack. + +Each `PACKAGE` file is evaluated at most once (like `bzl` file). + +`PACKAGE` files may load arbitrary `bzl` files. `BUCK`-specific functions called +in `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` or `BUCK` file. + +### API + +`PACKAGE` files have a global function: + +#### `PACKAGE` file API + +```python +def write_package_value( + name: str, + value: "", + 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. + +When `overwrite` is `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. + +Note `write_package_value` symbol exists in `bzl` globals, and it can be called +from `bzl` file in context of `PACKAGE` evaluation, but calling +`write_package_file` is an error on context of `BUCK` evaluation. + +Modifying `PACKAGE` file logically invalidates the `BUCK` file of this package, +and all `PACKAGE` and `BUCK` files of subpackages. However, `BUCK` file +evaluation may track which package-local values were accessed and only +invalidate `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 +function: + +```python +def read_package_value( + name: str, +): ... +``` + +This function returns the nearest value registered per package, or `None` is +such value does not exist. + +This function is available in `bzl` files, but attempt to call this function in +context of `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. + +### `read_config` + +`PACKAGE` files may call `read_config` function. diff --git a/_src/rule_authors/alias.md b/_src/rule_authors/alias.md new file mode 100644 index 000000000000..4be02fbed3ca --- /dev/null +++ b/_src/rule_authors/alias.md @@ -0,0 +1,102 @@ +--- +id: alias +title: Alias +--- + +The `alias` rule creates another name by which an existing rule can be referred +to. There two variants: [versioned_alias](#versionedalias) and +[configured_alias](#configuredalias), which are detailed below. + +## alias + +The `alias` rule has the following relevant attributes: + +- `name` - (required) what the `actual`'s label should be aliased as. +- `actual` - (required) a target label. +- `default_host_platform` - default host platform to use for the aliased target. + +**Example** + +```python +filegroup( + name = "foo", + srcs = ["foo.txt"], +) + +alias( + name = "other_foo", + actual = ":foo", +) +``` + +## versioned_alias + +The `versioned_alias` rule has the following relevant attributes: + +- `name` - (required) what the `actual`'s label should be aliased as. +- `versions` - (required) a map of versions to their respective versioned target + labels. + +Under the hood, any versioned parameters from the `versioned_alias`'s underlying +`actual` are translated into their `select`-based equivalents, which rely on +constraint settings added to the target platform. + +**Example** + +```Python +versioned_alias( + name = "foo", + versions = { + # Target labels for foo versions + "1.1": "//path/to/lib/1.1:foo", + "1.2": "//path/to/lib/1.2:foo", + }, + visibility = [ + "PUBLIC", + ], +) +``` + +## configured_alias + +The `configured_alias` rule has the following relevant attributes: + +- `name` - (required) what the `actual`'s label should be aliased as. +- `configured_actual` - a configured label (mapped to a configured dep under the + hood so the providers can be simply forwarded). +- `fallback_actual` - if `configured_actual` is not set, then fallback to this + value, which is an unconfigured dep. If `configured_actual` is not set, then + `fallback_actual` must be set. +- `platform` - the platform to build the aliased target with. + + +:::note +The `actual` field is available for `configured_alias` but it is not used under the hood (to keep compatibility of output format with Buck1 queries). + + +::: + +Outside of simply pointing at another target, this target has one other useful +feature - it contains a platform argument. + +This makes the alias rule useful for two distinct scenarios: + +- **Configuration switching during the build**. For example, there is an iOS + target that needs to build a dependency for WatchOS so it can include it in + the bundle. This can be represented by the iOS target having a dependency on + an alias of the Watch app with `platform = "//the/desired/watchos:platform"`. +- **Using a target to refer to another in a non-standard configuration**. For + example, if you want to have an experimental version of an app, you could + represent that as an alias with an 'experimental' configuration pointing to + the original target. + +**Example** + +```Python +configured_alias( + name = "foo-with-platform1", + actual = "//lib:foo", + platform = "//some_config:platform1", + visibility = ["PUBLIC"], +) +``` diff --git a/_src/rule_authors/anon_targets.md b/_src/rule_authors/anon_targets.md new file mode 100644 index 000000000000..1ba5e96b275f --- /dev/null +++ b/_src/rule_authors/anon_targets.md @@ -0,0 +1,418 @@ +--- +id: anon_targets +title: Anonymous Targets +--- + +An anonymous target is defined by the hash of its attributes, rather than its +name. During analysis, rules can define and access the providers of anonymous +targets before producing their own providers. Two distinct rules might ask for +the same anonymous target, sharing the work it performs. + +This solves two distinct problems: + +- **The sharing problem** - if you have two processes that want to share some + work, you can create an anon target that does that work once, which is then + reused by the two processes. Without such a mechanism, all sharing must be + present in the target graph: you can't create any new sharing. +- **The overlay problem** - this is the idea that you want to have a + shadow-graph, similar in structure to the normal graph, but with additional + information attached. Bazel accomplishes this with + [Aspects](https://bazel.build/extending/aspects). With Anonymous (anon) + targets, you can create a shadow-graph by convention, just by using the target + name you wish to shadow as the attribute. + +Dynamic dependencies, in their full generality, enable users to do a thing, look +at the result, then ask for fresh things. However, this full generality is not +provided as it breaks processes, like query, that power the Target Determinator. + +In Buck2, dynamic dependencies are implemented using `dynamic_output`, which +provides users with the ability to create new actions, after running actions, +then look at the result. `dynamic_output` is restricted in its power when +compared to fully generic dynamic dependencies, as detailed in the +[Dynamic Dependencies](dynamic_dependencies.md) page. + +Anon targets enable users to create a new analysis (that is, call an anon target +that may not have existed before) after looking at the result of a previous +analysis (which is passed in, or after looking at an anon target). In many ways, +anon target is the version of `dynamic_output` at analysis time, rather than +action time. + +The execution platform for an anon target is that of the inherited from the +calling target, which is part of the hash. If that is too restrictive, you could +use execution groups, where an anon target gets told which execution group to +use. + +# Creating anon targets + +## Anon rule + +An anonymous rule is defined using `rule` or `anon_rule`. + +Example: + +```python +my_anon_rule = rule( + impl = _anon_impl, + attrs = {}, +) + +# Or: + +my_anon_rule = anon_rule( + impl = _anon_impl, + attrs = {}, + artifact_promise_mappings = {} # only available for anon_rule +) +``` + +For `rule`, these are normal rules, with the difference that they are not in a +configuration, so `ctx.actions.label` won't show configuration information, but +just `unspecified`. + +For `anon_rule`, the configuration restrictions also apply, and there is an +`artifact_promise_mappings` field which you can specify a dict of artifact +promise names to the map function, which would be applied to the anon target's +promise during rule resolution. + +## Anon target + +An anonymous rule is used via `ctx.actions.anon_target` or +`ctx.actions.anon_targets`, passing in the rule and the attributes for the rule. + +The return values of those functions are a `AnonTarget` and `AnonTargets` type, +respectively. + +Example: + +```python +my_anon_rule1 = anon_rule( + impl = _anon_impl, + attrs = {}, + artifact_promise_mappings = {} +) + +my_anon_rule2 = anon_rule( + impl = _anon_impl, + attrs = {}, + artifact_promise_mappings = {} +) + +# +anon_target = ctx.actions.anon_target(my_anon_rule1, {}) + +anon_targets = ctx.actions.anon_targets([(my_anon_rule1, {}), (my_anon_rule2, {})]) +``` + +### `AnonTarget` and `AnonTargets` + +`AnonTarget` has a `promise` attribute, and `artifact()` and `artifacts()` +functions. `AnonTargets` has a `promise` attribute and `anon_targets` attribute. + +The `promise` attribute for both types returns the anon target's promise (type +is `promise`), which when evaluated returns the providers of the anonymous +target. The `promise` type has a few special behaviors. + +- It has a `map` function, which takes a function and applies it to the future, + returning a new future +- All promises will eventually resolve to a list of providers + +For `AnonTarget`, the `artifact()` and `artifacts()` functions only return +something if using `anon_rule`. `artifact()` takes in an artifact name, which +should be found in the `artifact_promise_mappings` dict, and returns the +artifact promise. `artifacts()` returns the dict of all promise artifact names +to the artifact promise itself, as defined in `artifact_promise_mappings`. See +[Convert promise to artifact](#convert-promise-to-artifact) below for more +information about artifact promises. + +Example: + +```python +HelloInfo = provider(fields = ["output"]) + +my_anon_rule = anon_rule( + impl = _anon_impl, + attrs = {}, + artifact_promise_mappings = { + "hello": lambda x: x[HelloInfo].output, + } +) + +# +anon_target = ctx.actions.anon_target(my_anon_rule, {}) +artifact = anon_target.artifact("hello") +artifact_from_dict = anon_target.artifacts()["hello"] +``` + +For `AnonTargets`, the `anon_targets` attribute returns a list of the underlying +`AnonTarget`s. + +Example: + +```python +HelloInfo = provider(fields = ["output"]) +GoodbyeInfo = provider(fields = ["output"]) + +my_anon_rule1 = anon_rule( + impl = _anon_impl, + attrs = {}, + artifact_promise_mappings = { + "hello": lambda x: x[HelloInfo].output, + } +) + +my_anon_rule2 = anon_rule( + impl = _anon_impl, + attrs = {}, + artifact_promise_mappings = { + "goodbye": lambda x: x[GoodbyeInfo].output, + } +) + +# +all_targets = ctx.actions.anon_targets([(my_anon_rule1, {}), (my_anon_rule2, {})]) +hello = all_targets.anon_targets[0].artifact("hello") +goodbye = all_targets.anon_targets[1].artifact("goodbye") +``` + +# Attributes + +Anon targets only support a subset of attributes that normal rules support. + +Supported attributes: + +- `bool` +- `int` +- `str` +- `enum` +- `dep` + - `deps` attributes do not take strings, but dependencies, already in a + configuration + - `exec_deps` are available if the passed in `dep`'s execution platform + matches + - Default `attr.deps` (as used for toolchains) are not permitted, as the + default can't express a dependency. They must be passed forward from the + caller. that of the anon target's caller +- `source` + - Accepts bound artifacts or promise artifacts +- `arg` + - Can only be used if `anon_target_compatible` is `True` when declaring + `attrs.arg` (ex: `attrs.arg(anon_target_compatible = True)`) +- `label` +- `list` +- `tuple` +- `dict` +- `one_of` +- `option` + +You can use these attributes like you would in normal rules: + +```python +my_anon_rule = anon_rule( + impl = _my_anon_impl, + attrs = { + "my_int": attrs.int(), + "my_string_with_default": attrs.string(default = "foo"), + "my_optional_source": attrs.option(attrs.source()), + "my_list_of_labels": attrs.list(attrs.label()), + }, + artifact_promise_mappings = {} +) + +def _my_anon_impl(ctx: AnalysisContext) -> list[Provider]: + my_int = ctx.attrs.my_int + my_string_with_default = ctx.attrs.my_string_with_default + my_optional_source = ctx.attrs.my_optional_source + my_list_of_labels = ctx.attrs.my_list_of_labels + + # do something with the attributes... + + return [DefaultInfo()] +``` + +## Attribute resolution + +Attribute resolution is handled differently from normal code: + +- Transitions and more complex forms of attributes are banned. +- The `name` attribute is a reserved attribute. It is an implicit attribute when + defining a rule for an anon target, but can be optionally set when creating an + anon target. If present, it must be a syntactically valid target, but could + refer to a cell/package that does not exist. If not present, buck2 will + generate a name for the target automatically. + +### `name` attribute example + +```python +# Rule definition for anon target +my_rule = rule( + impl = _my_impl, + attrs = { + # `name` is already implicitly defined as an attribute, and will error + # out if you try to define it again during rule declaration + }, +) + +# Anon target instantiation, elsewhere + ctx.actions.anon_target( + my_rule, + { + # you can optionally pass `name` into the attributes even though it's + # not explicitly defined in the `attrs` field for `my_rule` + "name": "foo//bar:baz" + }, +) +``` + +To access the `name` attribute from an analysis context, you can use +`ctx.label.name`. + +# Examples + +## Simple Example + +```python +# Define an anonymous rule +UpperInfo = provider(fields = ["message"]) + +def _impl_upper(ctx): + return [UpperInfo(message = ctx.attrs.message.upper()] + +upper = rule( + attrs = {"message", attrs.string()}, + impl = _impl_upper +) + +# Use an anonymous target +def impl(ctx): + def k(providers): + print(providers[UpperInfo].message) + # These are the providers this target returns + return [DefaultInfo()] + return ctx.actions.anon_target(upper, { + name: "my//:greeting", + message: "Hello World", + }) + .promise + .map(k) +``` + +## Longer example + +The following code represents a scenario for a compile-and-link language where, +if two targets end up compiling the same file (for example, they are in the same +package and both list it, or it gets export_file'd), then that file is compiled +just once: + +```python +## BUCK ############## +@load(":silly.bzl", "silly_binary") + +silly_binary( + name = "hello", + srcs = ["hello.sil", "world.sil"], +) + +## silly.bzl ############ + +_SillyCompilation = provider(fields = ["compiled"]) + +def _silly_compilation_impl(ctx): + out = ctx.actions.declare_output("output.o") + ctx.actions.run(cmd_args( + ctx.attrs.toolchain.compiler, + ctx.attrs.src, + "-o", + out.as_output(), + )) + return [DefaultInfo(), _SillyCompilation(compiled = out)] + +_silly_compilation = rule( + impl = _silly_compilation_impl, + attrs = { + "src": attrs.src(), + "toolchain": attrs.dep(), + }, +) + +def _silly_binary_impl(ctx): + def k(providers): + # Step 2: now link them all together + out = ctx.actions.declare_output("out.exe") + objs = [p[_SillyCompilation].compiled for p in providers] + ctx.actions.run(cmd_args( + ctx.attrs._silly_toolchain.linker, + objs, + "-o", + out.as_output(), + )) + return [ + DefaultInfo(default_output = out), + RunInfo(args = out), + ] + + # Step 1: compile all my individual files + return ctx.actions.anon_targets( + [(_silly_compilation, { + "src": src, + "toolchain": ctx.attrs._silly_toolchain + }) for src in ctx.attrs.srcs] + ).map(k) + +silly_binary = rule( + impl = _silly_binary_impl, + attrs = { + "srcs": attr.list(attr.src()), + "_silly_toolchain": attr.dep(default = "toolchains//:silly"), + }, +) +``` + +## Convert promise to artifact + +It can be challenging to pass around the promises from anon_target and structure +functions to support that. If you only need an artifact (or multiple artifacts) +from an anon_target, you can use `artifact()` function on the anon target to +convert a promise to an artifact. This artifact can be passed to most things +that expect artifacts, but until it is resolved (at the end of the current +analysis) it can't be inspected with artifact functions like `.extension`, etc. +`.short_path` is supported if `ctx.actions.assert_short_path()` was called, +which produces an artifact type. The promise must resolve to a build (not +source) artifact with no associated artifacts. + +Example: + +```python +HelloInfo = provider(fields = ["hello", "world"]) + +def _anon_impl(ctx: AnalysisContext) -> ["provider"]: + hello = ctx.actions.write("hello.out", "hello") + world = ctx.actions.write("world.out", "world") + return [DefaultInfo(), HelloInfo(hello = hello, world = world)] + +_anon = anon_rule( + impl = _anon_impl, + attrs = {}, + artifact_promise_mappings = { + "hello": lambda x: x[HelloInfo].hello, + "world": lambda x: x[HelloInfo].world, + } +) + +def _use_impl(ctx: AnalysisContext) -> ["provider"]: + anon = ctx.actions.anon_target(_anon, {}) + hello_artifact = anon.artifact("hello") + world_artifact = anon.artifact("world") + + out = ctx.actions.declare_output("output") + ctx.actions.run([ + ctx.attrs.some_tool, + hello_artifact, + world_artifact, + out.as_output() + ], category = "process") + return [DefaultInfo(default_output = out)] + +use_promise_artifact = rule(impl = _use_impl, attrs = { + "some_tool": attr.exec_dep(), +}) +``` diff --git a/_src/rule_authors/configuration_transitions.md b/_src/rule_authors/configuration_transitions.md new file mode 100644 index 000000000000..b0cdbdf886a8 --- /dev/null +++ b/_src/rule_authors/configuration_transitions.md @@ -0,0 +1,216 @@ +--- +id: configuration_transitions +title: Configuration Transitions +--- + +Configuration transition is a mechanism for changing the configuration when +depending on a target. + +Currently, Buck2 has incoming and outgoing transitions: + +- **Incoming** - (or per-rule transitions) declared on the rule. +- **Outgoing** - (or per-attribute transitions) declared on the attribute. + +## Transition rule + +Transition rules are defined in `.bzl` files using the `transition` built-in. + +The `transition` function creates a configuration-related object. The +`transition` object is opaque, it does not have any operations, and can only be +used as an argument to `rule` function or attribute constructor. The +`transition` function call must be assigned to a global variable (this is +similar to user-defined provider declarations). + +The `transition` function takes three arguments: + +- `implementation` - a function. +- `refs` - references to configuration rules to be resolved and passed to the + implementation function. +- `split` - (optional) `bool` flag (default `False`) to indicate whether + transition is a split transition (used in per attribute transitions). + +The `implementation` function takes two arguments: + +- `platform` - a configuration to transition. +- `refs` - resolved references as a struct. + +Example transition from ios to watchos (for example, to build a watchOS bundle +as part of an iOS build): + +```python +def _impl(platform: PlatformInfo.type, refs: struct.type) -> PlatformInfo.type: + # Operating system constraint setting. + os = refs.os[ConstraintSettingInfo] + # Watchos constraint value. + watchos = refs.watchos[ConstraintValueInfo] + # Remove operating system constraint from input platform. + constraints = { + s: v + for (s, v) in platform.configuration.constraints.items() + if s != os.label + } + # Add watchos constraint value. + constraints[watchos.setting.label] = watchos + # Construct configuration structure. + new_cfg = ConfigurationInfo( + # Updated constraints. + constraints = constraints, + # Keep original config values. + values = platform.configuration.values, + ) + # And return new configuration, + # or a dict of marker to configuration in case of split transition. + return PlatformInfo( + # ... supplying configuration label. + label = "", + configuration = new_cfg, + ) + +iphone_to_watch_transition = transition(_impl, refs = { + "os": "//constraints:os", + "watchos": "//constraints:watchos", +}) +``` + +A transition function applied twice must produce the configuration identical to +the configuration produced after applying transition once. + +```python +assert tr(tr(platform=platform, refs=refs), refs=refs) == tr(platform=platform, refs=refs) +``` + +If this invariant is not held, certain operations produce incorrect and possibly +infinite graphs. This is not yet enforced. + +## Per rule transition + +The `rule` function has an optional `cfg` attribute, which takes a reference to +the `transition` object (created with the `transition` function; not a string). + +When such a rule is called, it is instantiated, not with the requested +configuration, but with the requested configuration transformed with a given +rule transition. + +For example, the transition for watchos when the iOS target depends on watchos +resource: + +```python +watchos_resource = rule( + cfg = iphone_to_watch_transition, + ... +) +``` + +## Per attribute transition + +The `attrs` object has two attribute constructors: + +- `attrs.transition_dep(cfg)` +- `attrs.split_transition_dep(cfg)` + +These attributes are similar to the `dep` attribute. When dependencies are +resolved for the rule instance, then they are resolved not with the rule +instance configuration, but with the configuration transformed with the given +transition. + +For split transition, each dependency is resolved into a dict of marker to +providers. + +For example: + +```python +android_binary = rule( + ... + attrs = { + "deps": attrs.list(attrs.split_transition_dep(cfg = cpu_split_transition), default = []), + }, +) +``` + +When the above is invoked as follows: + +```python +android_binary( + deps = ["//foo:bar", "//qux:quux"], +) +``` + +Then the rule implementation gets something like the following in the `deps` +attribute: + +```python +{ + [ + { + # Key in this dict is the marker returned from split transition impl function. + "arm64": "providers for //foo:bar configured for arm64", + "armv7": "providers for //foo:bar configured for armv7", + }, + { + "arm64": "providers for //qux:quux configured for arm64", + "armv7": "providers for //qux:quux configured for armv7", + }, + ] +} +``` + + +:::note +It is an error to pass a split transition object to `attrs.transition_dep` and a non-split transition to `attrs.split_transition_dep`. + + +::: + +## Per target transition + +The Buck2 team is considering the implementation of per target transitions (that +is, transitions referenced at a rule instantiation site as opposed to rule +declaration site). No specific plans or APIs exists at the moment. + +It _could_ be something like the following: + +```python +cxx_binary( + name = "foo", + cfg = "//transitions:opengl-es-1.0", + ... +) +``` + +## Request transition on command line + +For information, see [RFC](../rfcs/drafts/configuration-at-syntax.md). + +## Access rule attributes in transition function implementation + +It might be useful for the transition function to be able to query rule +attributes (for example, to perform transition to different configurations +depending on `java_version` attribute). + +Both incoming (per rule) and outgoing (per dependency) transitions can access +rule attributes. For outgoing transitions, transition rule implementation +accesses the attributes of the target that has dependencies with transitions, +not attributes of dependency targets. + +```python +def _tr(platform, refs, attrs): + # NB: There are some restrictions on what attrs can be made accessible: + # - Only primitive values for now (providers are not resolved) + # - Only unconfigured attributes for now + attrs.my_list_attribute # == [12345, 67890] + +tr = transition( + _tr, + refs = {}, + attrs = { + "my_list_attribute": attr.list(...), + }, +) + +my_rule = rule(..., cfg=tr) + +my_rule( + ..., + my_list_attribute = [12345, 67890], +) +``` diff --git a/_src/rule_authors/configurations.md b/_src/rule_authors/configurations.md new file mode 100644 index 000000000000..52beb6806735 --- /dev/null +++ b/_src/rule_authors/configurations.md @@ -0,0 +1,279 @@ +--- +id: configurations +title: Configurations +--- + +This page mostly focuses on how configurations and related features are +implemented. + +## Context + +Buck configurations provide an API to express the different ways in which +projects and targets can be built. + +A configuration consists of a set of constraints and config settings (values +from buckconfig). These are determined by a base platform that sets the initial +values and then a series of transitions that may change them. + +The common way that users are exposed to configurations is in `select()` +invocations where the resolution is based on the configuration. + +A build may involve many configurations. A particular target label (`//:foo`) +may end up with multiple instances in the configured graph with different +configurations. + +## Selectable attributes + +Almost all rule attributes can be set to a `select()` value; such an attribute +is 'selectable'. These attributes' final resolved values will depend on the +configuration. + +There are some attributes that cannot use a `select()`; such attributes are +termed 'not selectable'. Examples include attributes that buck needs to read +from the unconfigured node (such as `name` and `default_target_platform`) and +attributes that are used by `platform()` rules and their dependencies (see +below). + +## Selectable resolution + +Resolving selectable attributes is pretty straightforward, it happens when +constructing the 'configured target node'. At that point, the full configuration +is available so Buck can lookup whether each constraint in the select is +satisfied or not. + +If multiple conditions of the select() match, then the select will be resolved +to the 'most refined' of the conditions that match. A set of constraints (as in +a `config_setting`) is said to 'refine' another if it is a superset of that +other's constraints. The 'most refined' of a set is then the condition that +refines all the others. If there is no 'most refined' condition of the matching +ones, it is an error. + +## Target Platform Resolution + +In the event that targets are provided on the command line, or when there is no +indication of what configuration the target will be built in, configurations are +determined by performing 'target platform resolution' on the unconfigured target +labels. + +The target platform resolution for a target `//:foo` works as follows: + +1. Look up (unconfigured) target node for `//:foo`. +1. If the command has a `--target-platforms` flag, use that. +1. If there's a `default_target_platform` attribute, use that. +1. Else, use the cell's default platform. + +This is performed independently for any targets that need a platform. Since this +resolution is done without a configuration, it means that the +`default_target_platform` attribute **is not selectable**. + +This target platform will form the initial configuration for the node. + +## Configuration propagation + +Once the top-level nodes have been configured via the target platform +resolution, the configuration is propagated to dependencies (possibly altered by +transitions). + + +:::note +The target platform resolution is not applied to all nodes in the graph. + + +::: + +## Transitions + +A transition transforms a configuration by adding or changing constraint values +and config settings or by setting an entirely new underlying target platform. + +For more details, see [Configuration transitions](configuration_transitions.md). + +## `ConfigurationInfo`, `platform()` analysis, and more + +The definition of a platform (either execution or target) is done with a +`platform` rule instance. The configuration is actually part of the analysis +result of the platform target (the `ConfigurationInfo` provider instance). This +is convenient from an implementation standpoint, but it leads to a situation +where some nodes are analyzed with an 'unbound' Configuration. + +All the rule types involved in defining a platform may be analyzed with an +unbound configuration (`platform()`, `config_setting()`, `constraint_setting()`, +and so on). These are sometimes called 'configuration rules'. This means that +all the attributes of these rules are not selectable. + +Configurations also reference a few other provider instances such as +`ConstraintSettingInfo`. All of these end up being potentially produced in a +context with an unbound configuration. + +Using analysis for this also means that 'configuration' and 'analysis' are not +distinct phases within a build (although they are still distinct for a node and +are still conceptually useful). + +## Configurations and output paths + +Since a target may appear within a build in multiple different configurations, +output paths cannot be derived based on just targets (as multiple actions would +map to the same outputs). For this reason, the target and the configuration are +encoded into output paths. The configuration is currently represented as a hash +of its values (a 'hashed buck-out'). + +## Target platform compatibility + +All (non-configuration) rules support a `target_compatible_with` attribute. In +addition, the rule itself can define `target_compatible_with` constraints that +affect all instances. The `target_compatible_with` attribute is a list of +constraints/config settings and it **is selectable**. + +Target platform compatibility is transitive, all _dependents_ of an incompatible +target are incompatible. In other words, a node is compatible if and only if the +node itself and all of its transitive dependencies are compatible. + +In buck, this is implemented by graph configuration returning either a +configured target node or an indicator that the node is incompatible with the +target platform. + +### Buck v1 compatibility + +Buck2 also supports the Buck v1 legacy `compatible_with` field on nodes but it +has different behavior. + +In summary: + +- `compatible_with`: List of constraints, where _any_ of them must match the + configuration to be compatible. +- `target_compatible_with`: List of constraints, where _all_ of them must match + the configuration to be compatible. + +## Incompatible target skipping + +In a build-like command where a non-literal target pattern is provided (for +example, `buck build //:` or `buck build //foo/...`), the target pattern will be +resolved to a set of unconfigured targets. Those targets will then go through +[target platform resolution](#target-platform-resolution). If any of those +targets resolve to a platform where they are incompatible, building them will be +skipped. Users generally expect and prefer this behavior to needing to +explicitly specify only the targets that can build in their current context. + +If an explicitly specified literal is incompatible, it is an error. + +The implementation checks compatibility when looking up the analysis results for +configured nodes requested (in the non-ignored flow, it uses that analysis +result to lookup the default outputs and build them). + +## Execution platforms + +Execution platforms/configurations are used to represent the platforms where +build execution happens. These are defined in a similar manner to target +platforms. These may or may not be what one would logically consider different +'platforms'. For example, there could be multiple different execution platforms +that all execute things similarly on the local machine. + +A build configures a fixed list of one or more execution platforms. + +## Execution deps + +Some target deps are 'execution deps'. These are the dependencies of the target +that should be built for the execution platform. For example, a compiler or +other build tool would be an execution dep. This includes all exe macro deps +(for example, `$(exe //:tool)`) and includes all `attrs.exec_dep()` deps. + +## Toolchain deps + +In addition to `attrs.exec_dep()`, there are `attrs.toolchain_dep()`, which are +similar but differ in an important way. These nodes don't select their execution +platform, but instead have it forced on them by whatever includes them; hence, +it must be recorded in the configured target label. The execution platform +resolution sees through them. + +In other words, `attrs.toolchain_dep()` is like a mix of `attrs.dep()` and +`attrs.exec_dep()`: it inherits target platform like `attrs.dep()` (so any +`select()`s on the target of the `attrs.toolchain_dep()` will evaluate as if +they were on the target containing the `attrs.toolchain_dep()` - the target +platform gets inherited as normal) and any `attrs.exec_dep()`s of the +`attrs.toolchain_dep()` target become `attrs.exec_deps()` on the dependent of +target the `attrs.toolchain_dep()` (they get passed up the dep tree, so +participate in exec platform resolution). + +This is illustrated in the following example: + +```python +target( + name = "A", + toolchain = attrs.toolchain_dep(default = ":B"), +) +target( + name = "B", + tool = attrs.exec_dep(default = ":C") +) +``` + +The above means that `:C` will be an execution dependency of `:A` and any +`select()`s defined in `:B` would be evaluated against the same target platform +as `:A` (as target platform gets inherited by `attrs.toolchain_dep()`s). + +## Running non-execution deps + +If you have a binary that you want to run, but it isn't a build tool, then you +should use `$(exe_target //:binary)` rather than `$(exe //:binary)`. That will +run the same binary that you'd get from `buck2 build`, rather than one that is +built for the execution platform. + +## Execution platform resolution + +During analysis, unlike target platform resolution, every configured node +undergoes execution platform resolution independently (see exception below). +This means that even for a specific target platform, different nodes in the +graph can be built on different execution platforms. + +This works roughly as follows: + +```python +next: for platform in execution_platforms: + if exec_compatible_with(target, platform): + for dep in target.execution_deps(): + if !target_compatible_with(dep, platform): + continue next + return platform +return err +``` + +One important note here is that until the execution platform has been resolved, +**the configuration for execution deps is not known**. Only after execution +platform has been resolved can the execution deps be configured (also, analysis +for them can only be performed at that point). + +For the normal use case, a particular configured target node performs execution +platform resolution a single time. The execution platform **is not** encoded in +output paths. + +Regarding target compatibility, imagine the following pseudo-code for the +`target_compatible_with()` function above: + +```python +def target_compatible_with(target, cfg): + for constraint in target.target_compatible_with: + if not satisfied(constraint, cfg): + return False + + if len(target.compatible_with) > 0: + found_satisfied_constraint = False + for constraint in target.compatible_with: + if satisfied(constraint, cfg): + found_satisfied_constraint = True + break + if not found_satisfied_constraint: + return False + + for (dep, dep_cfg) in direct_deps(target): + # NB: recursive call + if not target_compatible_with(dep, dep_cfg): + return False + + return True +``` + +## Execution groups + +Execution groups are a future feature that will allow a rule to perform +execution platform resolution multiple times and then specify in which of the +resolved platforms each action runs in. diff --git a/_src/rule_authors/dep_files.md b/_src/rule_authors/dep_files.md new file mode 100644 index 000000000000..089b5e368009 --- /dev/null +++ b/_src/rule_authors/dep_files.md @@ -0,0 +1,135 @@ +--- +id: dep_files +title: Dep Files +--- + +Dep files allow commands to declare which subset of their inputs were used when +the command executed. + +When a command produces a dep file and is later invalidated due to an inputs +change, Buck2 uses the dep file to check whether the inputs that changed were in +the set that the command reported as having used. If none of the inputs that +changed were in that set, Buck2 omits re-running the command and reuses the +previous result. + +## Use Cases + +Dep files are used to make dependencies finer grained than what exists in the +target graph, but they're not a substitute for avoiding unused dependencies. +They're often useful when targets export many outputs (such as C++ headers) that +aren't all used by all their dependents. + +Dep files are currently used to skip recompilation steps in C++ when an unused +header changed. They're also used in Java to skip recompilation when an unused +class changed. + +## Using dep files + +To use dep files, you need to do the following: + +- Declare what output is a dep file and associate it with your command. +- Declare which inputs are covered by the dep file (this can be a subset of your + inputs). +- Have your command produce the dep file in a format Buck2 can use. + +You must also enable +[Deferred Materialization](../users/advanced/deferred_materialization.md) to use +dep files. + +## Declaring the dep files and associating inputs + +To declare a dep file and associate it with your command, you need to tag your +artifacts. + +Specifically, you'll tag the output (the dep file) and the inputs it covers, as +shown in the following code: + +```python +# First, create a tag + +headers_tag = ctx.actions.artifact_tag() + +# Then, tag inputs and the dep file itself in your command line. +# You do this using the `tag_artifacts` method on your tag. +# This method does not mutate the input, it wraps it, so you use the output. +# Any command-line-arg-like can be tagged. + +tagged_headers = headers_tag.tag_artifacts(headers) + +dep_file = ctx.actions.declare_output("deps").as_output() +tagged_dep_file = headers_tag.tag_artifacts(dep_file) + +# Finally, declare your action. +# Use the tagged artifacts as you would regular command-line-arg-likes. +# Pass the tag in `dep_files` and give a name (this is used for logging). + +ctx.actions.run( + ["mycc", "-I", tagged_headers, "-MD", "-MF", tagged_dep_file, "-o", ...], + dep_files = { "headers": headers_tag } +) + +``` + +## Producing the dep file + +Your command must produce dep files in the format Buck2 expects, which is simply +a list of all the inputs that were used, one per line. + +The paths must be the paths Buck2 would use for your inputs, which means paths +relative to the project root. + +If this is not the format your tool produces, use a wrapper to take whatever +output your command produces and rewrite it in the format Buck2 expects. + +## Testing dep files + +When writing a command that produces a dep file, you should test it! At a +minimum, check that the inputs you expect are tagged properly. + +To do so, build your target, then use +`buck2 audit dep-files TARGET CATEGORY IDENTIFIER`, which will show you the set +of inputs your command used and how they're tagged. + +## Extra notes to the implementer + +### Limitations + +Dep files only work if a previous invocation of the command is known to your +Buck2 daemon. Dep files are dropped when the daemon restarts or when you run +`buck2 debug flush-dep-files`. + +This means that, for example, if you change an unused header, then run a build +on a fresh daemon, Buck2 will still need to execute this command in order to +identify that the header was in fact unused. In contrast, if you did the build +(and got a remote cache hit on the command), then applied your change and +re-built, Buck2 would use the dep file on the second execution, and you wouldn't +need to execute anything. + +### Dep files don't need to be covering + +It's OK for the dep file to only cover a subset of the inputs of your action. +However, within that subset, the dep file must declare all the inputs that were +used. + +If you fail to report some inputs you used, then your command will not re-run +when they change, and you'll get stale output. + +### Dep files are lazy + +Dep files aren't parsed by Buck2 unless the command needs to re-run. If the +command ran on RE, they aren't even downloaded until then. This ensures dep +files don't cause a performance hit unless they are used, at which point they +stand a chance of giving a performance boost instead. + +This means that if you produce an invalid dep file, Buck2 will not report this +until your command runs again, at which point Buck2 will report that the dep +file is invalid and refuse to proceed (note: you can unblock yourself using +`buck2 debug flush-dep-files`). + +To flush out issues during development, you can pass `--eager-dep-files` to +Buck2 to force Buck2 to parse your dep files as they are produced. + +## Dep files will traverse symlinks + +If your dep file reports that a symlink was used, Buck2 will track the symlink's +target as covered by this dep file. diff --git a/_src/rule_authors/dynamic_dependencies.md b/_src/rule_authors/dynamic_dependencies.md new file mode 100644 index 000000000000..a6082b2dc9ce --- /dev/null +++ b/_src/rule_authors/dynamic_dependencies.md @@ -0,0 +1,103 @@ +--- +id: dynamic_dependencies +title: Dynamic Dependencies +--- + +Dynamic dependencies allow a rule to use information that was not available when +the rule was first run at analysis time. Dynamic dependencies in Buck2 are +implemented using `dynamic_output` and are restricted in their power compared to +fully generic dynamic dependencies. + +A rule for a target is run with the attributes of the target, plus the providers +of its attribute dependencies, which contain artifacts. Those values (but not +the artifact contents) are all available directly and immediately when running +the rule. The rule generates providers containing artifacts. Using +`dynamic_output`, a rule can read the contents of an artifact to produce new +artifacts and bind existing artifacts, which were already returned in providers. + +Examples of rules requiring dynamic dependencies include: + +- Distributed ThinLTO, where the index file says what the dependencies are. +- OCaml builds, where the dependencies between source files can only be obtained + from running `ocamldeps`. +- Erlang header files, where only a subset of the available headers are + accessed, which can be determined by reading the source file. +- Erlang BEAM files, where some subset of BEAM files must be compiled in a given + order, as they provide features like compiler plugins, but most can be + compiled in parallel. + + + +The original design document with discussion is available +[here](https://docs.google.com/document/d/1K8RgvDMvdDFsLWAu0cehauJstHZaFe-7NeaAqWe4-L4/edit). + + + +## Implementation + +Buck2 provides the following function: + +```python +ctx.actions.dynamic_output(dynamic, inputs, outputs, lambda ctx: …) +``` + +The arguments are: + +- `dynamic` - a list of artifacts whose values will be available in the + function. These will be built before the function is run. +- `inputs` - a container of artifacts (`cmd_args`, list of artifacts, and so + on). + - These inputs must include all the inputs that are referenced by the body of + the function argument, apart from those listed in `dynamic` and `outputs`: + extra inputs may be passed that are not used. + - The inputs are used for `buck2 aquery` functionality, but do not cause + speculative building. In fact, these inputs may form a cycle with other + `dynamic_output` actions if they were all required. + - In the future, it may be possible to not pass all the inputs if the repo is + set to permissive mode, allowing a more powerful form of dynamic + dependencies. +- `outputs` - a list of unbound artifacts (created with `declare_artifact`) + which will be bound by the function. +- The function argument is given 3 arguments: + - `ctx` (context) - which is the same as that passed to the initial rule + analysis. + - `outputs` - using one of the artifacts from the `dynamic_output`'s `outputs` + (example usage: `outputs[artifact_from_dynamic_output_outputs]`) gives an + unbounded artifact. The function argument must use its `outputs` argument to + bind output artifacts, rather than reusing artifacts from the outputs passed + into `dynamic_output` directly. + - `artifacts` - using one of the artifacts from `dynamic` (example usage: + `artifacts[artifact_from_dynamic])` gives an artifact value containing the + methods `read_string`, `read_lines`, and `read_json` to obtain the values + from the disk in various formats. Anything too complex should be piped + through a Python script for transformation to JSON. +- The function must call `ctx.actions` (probably `ctx.actions.run`) to bind all + outputs. It can examine the values of the dynamic variables and depends on the + inputs. + - The function will usually be a `def`, as `lambda` in Starlark does not allow + statements, making it quite underpowered. + +Following is an example of using the function to determine Erlang BEAM +dependencies: + +```python +def erlang(ctx): + beams = {} + for x in ctx.attr.srcs: + dep_file = ctx.actions.declare_output(x + ".out") + ctx.actions.run("erl", "-dump-output", x, dep_file.as_output()) + beam_file = ctx.actions.declare_output(x + ".beam") + beams[x] = beam_file + def f(ctx, artifacts, outputs, x=x, dep_file=dep_file): + deps = artifacts[dep_file].read_lines() + ctx.actions.run( + "erl", "-comp", x, + [beams[d] for d in deps], + outputs[beams[x]].as_output() + ) + ctx.actions.dynamic_output([dep_file], [x] + deps, [beam_file], f) + return [ErlangInfo(objects = beams.values())] +``` + +The above code uses `declare_output` for the `beam_file` then binds it within +the function `f`, after having read the `dep_file` with `read_lines`. diff --git a/_src/rule_authors/incremental_actions.md b/_src/rule_authors/incremental_actions.md new file mode 100644 index 000000000000..f0a251aba642 --- /dev/null +++ b/_src/rule_authors/incremental_actions.md @@ -0,0 +1,115 @@ +--- +id: incremental_actions +title: Incremental Actions +--- + +It's possible to make certain Buck2 actions behave incrementally, that is, to +produce results for a current invocation based on the result from the previous +run. Incrementality could significantly improve performance of some actions such +as packaging (such as Apple App Bundles) or linking (MSVC incremental linking). + +There are two essential requirements to make an action incremental: + +- The result from the previous run should be accessible. +- An understanding of which parts of the result need to be updated; it should be + easy to compare inputs from a previous run with inputs from the current run + and detect those changed. + +The only way to run user-defined commands in Buck2 is with `ctx.actions.run`. +Both of the above requirements are met via its `metadata_env_var`, +`metadata_path` and `no_outputs_cleanup` parameters. + +When the `no_outputs_cleanup` flag is turned on, Buck2 won't perform any +deletion of old outputs for the action. That means the result from the previous +run will be accessible, but the user script has to detect which parts of it +should be deleted and perform a manual cleanup. + +When the `metadata_env_var` and `metadata_path` parameters are present, Buck2 +will create a JSON file on a disk before actually executing the command. The +file will contain a list of paths and hash digests for every command action +input. All paths in the file are relative to the Buck2 project root. Symlinks +are not included in metadata because it is possible for the user script to +resolve symlink and use a resolved path to get the destination hash digest from +action metadata if it's needed, as shown in the following JSON example: + +```json +{ + "version": 1, + "digests": [ + { + "path": "buck-out/v2/gen/cell/configuration_hash/path/to/target/__target_name__/generated_file", + "digest": "da39a3ee5e6b4b0d3255bfef95601890afd80709:10" + }, + ... + ] +} +``` + +A user script that is run as a part of an action execution is responsible for +parsing the JSON file. + +The `version` field is bumped every time there is a non-backwards compatible +change to the format of the file. The user script should verify that the +provided data is of a supported version and should be updated accordingly when +the current version is newer than the supported one. + +The path of the JSON file is provided to the user script via an environment +variable with a key equal to `metadata_env_var`. The user is able to specify the +part of the path relative to the result directory via `metadata_path`. + +For example, if some rule implementation has the following code: + +```python +result = ctx.actions.declare_output("result") +command = cmd_args(["my_script.py", "--output", result.as_output()]) +ctx.actions.run( + command, + category = "my_category", + metadata_env_var = "ACTION_METADATA", + metadata_path = "action_metadata.json", + no_outputs_cleanup = True, +) +``` + +Then `my_script.py` will be executed as: + +```shell +ACTION_METADATA=project/relative/path/to/target/action_metadata.json my_script.py --output resolved/path/to/result +``` + +`my_script.py` is responsible for reading the `ACTION_METADATA` environment +variable and parsing a JSON file with the action metadata. + +Parsed metadata provides information about inputs for the current run, but the +script needs somehow to obtain similar information about inputs from the +previous run. Such information could just be another output of the user script +(as with the previous result, it won't be deleted when +`no_outputs_cleanup = True`). The Format of such a file is an implementation +detail of the user script, but at the very least it should contain a list of +every source that was used to form the result and hash digests for such sources. + +The rule implementation would look something like the following: + +```python +result = ctx.actions.declare_output("result") +state = ctx.actions.declare_output("incremental_state.json") +command = cmd_args(["my_script.py", "--output", result.as_output(), "--incremental-state", state.as_output()]) +ctx.actions.run( + command, + category = "my_category", + metadata_env_var = "ACTION_METADATA", + metadata_path = "action_metadata.json", + no_outputs_cleanup = True, +) +``` + +The user script would then: + +1. Parse `incremental_state.json` and delete it. Deletion prior to amending the + result is important so it doesn't result in a situation where an incremental + state file is out of sync with the result when the user script fails while + changing the result. Such a corrupted state might lead to subsequent + incorrect builds reported as "successful". +2. Parse action metadata file, compute what is needed to update the result, and + amend it accordingly. +3. Calculate the new state and write it into the new `incremental_state.json`. diff --git a/_src/rule_authors/local_resources.md b/_src/rule_authors/local_resources.md new file mode 100644 index 000000000000..7da168d3dc30 --- /dev/null +++ b/_src/rule_authors/local_resources.md @@ -0,0 +1,161 @@ +--- +id: local_resources +title: Local Resources For Tests Execution +--- + +Executing a test might require an external resource which is expensive to +create. For example running an iOS UI test requires an iOS simulator and it +takes relatively long time to setup it prior to test execution. When tests are +executed remotely resources initialization and allocation could be preemptively +managed by remote execution tier which is not the case for local execution. To +effectively manage such resources needed for local execution of tests there is a +separate Buck2 feature backed by `LocalResourceInfo` provider. + +## `LocalResourceInfo` provider + +This provider describes how to initialize and clean up a pool of homogeneous +local resources. Management of initialized resources is done by Buck2 itself +when it executes tests requiring such resources. + +Fields: + +- `setup` — command represented by `cmd_args` object which is executed to + initialize a local resource. Running this command should write a JSON to + stdout. This JSON represents a pool of local resources which are ready to be + used. +- `resource_env_vars` — key-value mapping `{str: str}` from environment variable + (appended to an execution command for test which is dependent on this local + resource) to keys in JSON output of `setup` command. + +Example JSON output of `setup` command: + +``` +{ + "pid": 42, + "resources": [ + {"socket_address": "foo:1"}, + {"socket_address": "bar:2"} + ] +} +``` + +JSON keys: + +- `pid` — an optional attribute which maps to a PID of a process that holds + initialized local resources. If present, on non-Windows platforms the process + will be sent `SIGTERM` when those resources are no longer needed. Signal + should be handled to release any system resources related to local resources. +- `resources` — a list of resource instances, each is a mapping from a string + alias (e.g. `socket_address`) to a value which represents resource. The number + of concurrently running tests that require resources of the same type is + limited by how many instances are in a list. String alias is mapped to an + environment variable key (which will be added to a command requiring such + resource) using a `resource_env_vars` field in `LocalResourceInfo` provider + (see [example](#example-usage) below). + +## Test Execution + +For a general context on how tests are executed, see +[Test Execution](test_execution.md). + +A decision whether certain local resource is required for specific test is made +by a test runner. List of required resources is then passed to Buck2 in +`required_local_resources` field of `ExecuteRequest2` test API protobuf message. + +If resource is required for a certain test execution and test could potentially +be executed locally, `local_resources` field in test's `ExternalRunnerTestInfo` +provider is used to select appropriate `LocalResourceInfo` provider. + +`ExternalRunnerTestInfo.local_resources` is a key-value mapping +`{str: ["label", None]}`. Keys represent resource types that match the values +passed from the test runner, and values are labels that should point to a target +exposing the `LocalResourceInfo` provider to be used for the initialization of +the resource of that type. If the value is `None`, it indicates that a resource +of that type will not be provided, even if the test runner requests it. + +Before running a test, `setup` command from selected provider is executed and +its output is used to create a pool of resource instances. This pool is shared +across all tests pointing to the same configured target label containing +`LocalResourceInfo` provider (normally that means pool is shared for tests +requiring same resource type). A resource is acquired (with potential queuing) +from that pool prior single test is executed and is returned back to the pool +when test finished execution. After `buck2 test` command is finished, cleanup is +performed when SIGTERM is sent to each process holding a pool of resources. + +## Example Usage + +Define a target which has `LocalResourceInfo` provider: + +``` +simulator( + name = "my_resource", + broker = ":broker", +) +``` + +where `broker` points to a runnable handling actual simulators. + +Implementation of `simulator` rule would be: + +``` +def _impl(ctx: AnalysisContext) -> ["provider"]: + return [ + DefaultInfo(), + LocalResourceInfo( + setup = cmd_args([ctx.attrs.broker[RunInfo]]), + resource_env_vars = { "IDB_COMPANION": "socket_address" }, + ) + ] +``` + +Running a `:broker` via `setup` command produces the following JSON: + +``` +{ + "pid": 42, + "resources": [ + {"socket_address": "foo:1"}, + {"socket_address": "bar:2"} + ] +} +``` + +When Buck2 locally executes a test which requires this particular type of local +resource, it reserves one resource from the pool (e.g. +`{"socket_address": "bar:2"}`) and add environment variable representing this +resource to execution command (e.g. `IDB_COMPANION=bar:2`). In our examples +`"socket_address"` alias was substituted by `"IDB_COMPANION"` based on +`LocalResourceInfo.resource_env_vars` field. + +The last part is to map a resource type to desired `LocalResourceInfo` provider. +Let's assume a test runner requires a resource of type "ios_simulator" for every +`apple_test` rule. + +Pass `:my_resource` target as a dependency into `apple_test` rule: + +``` +apple_test = rule( + impl = apple_test_impl, + attrs = { + ... + "_ios_simulator": attrs.default_only(attrs.dep(default = ":my_resource", providers = [LocalResourceInfo])), + ... + }, +) +``` + +Actually map "ios_simulator" resource type to `:broker` target containing +`LocalResourceInfo` provider: + +``` +def apple_test_impl(ctx: AnalysisContext) -> ["provider"]: + ... + return [ + ... + ExternalRunnerTestInfo( + ... + local_resources = { + "ios_simulator": ctx.attrs._ios_simulator, + }, + ... +``` diff --git a/_src/rule_authors/optimization.md b/_src/rule_authors/optimization.md new file mode 100644 index 000000000000..c9040eb8f2ba --- /dev/null +++ b/_src/rule_authors/optimization.md @@ -0,0 +1,162 @@ +--- +id: optimization +title: Observability and Optimization +--- + +Optimization involves the use of techniques for determining and improving the +performance of Buck2 and specific actions performed by Buck2. This page covers +the internals for developers of Buck2 and provides details of Starlark that are +likely to be relevant to end users. + +## Starlark profiling + +`buck2` supports profiling of the evaluation of specific `BUCK` files and +profiling of the analysis of specific targets. + +There are three `buck2` profiling commands: + +- `buck2 profile loading` +- `buck2 profile analysis` +- `buck2 profile bxl` + +For example: + +```shell +buck2 profile loading --mode=heap-summary-allocated -o heap-summary.csv //some/package: +buck2 profile analysis --mode=heap-summary-allocated -o heap-summary.csv //some/package:target +``` + +Possible values for profiling modes are as follows: + +- [heap-summary-allocated](#summary-profiling): The heap profile mode provides + information about the time spent in each function and allocations performed by + each function. Enabling this mode has the side effect of disabling + garbage-collection. This profiling mode is the recommended one. +- heap-summary-retained: Like heap summary, but information about retained + memory after module is frozen. +- time-flame: Provide output compatible with + [flamegraph.pl](https://github.com/brendangregg/FlameGraph/blob/master/flamegraph.pl). +- heap-flame-allocated: Like heap profile, but writes output comparible with + [flamegraph.pl](https://github.com/brendangregg/FlameGraph/blob/master/flamegraph.pl). +- heap-flame-retained: Like heap flame, but information about retained memory + after module is frozen. +- [statement](#statement-profiling): The statement profile mode provides + information about time spent in each statement. +- bytecode: The bytecode profile mode provides information about bytecode + instruction pairs. +- bytecode-pairs: The bytecode profile mode provides information about bytecode + instruction pairs. +- typecheck: Profile runtime typechecking. + +### Summary profiling + +The first profiling mode (`heap-summary-allocated`) provides the time spent +within a function and the allocations that are performed. + +As an example, running over a folly BUCK file, produces a CSV file whose +top-left corner is: + +```text +Function Time(s) TimeRec(s) Calls Allocs +TOTALS 10.455 10.455 9712799 3477203 +fbchain_configs 1.163 2.514 11328 33984 +is_string 0.726 1.028 1514985 0 +apple_library 0.725 0.725 1887 0 +type 0.435 0.435 2053296 0 +... +``` + +This reveals the following: + +- Total execution was 10.455s, which will be a bit slower than normal, because + profiling is on. +- 1.163s was spent in `fbchain_configs` itself and 2.514s in that function and + the things it calls. +- A disturbing 1.5M calls and 1.028s is spent testing if things are strings, + which is almost certainly responsible for half the type calls. +- Happily, `is_string` doesn't allocate, but `fbchain_configs` does. Scrolling + to the right, on the full CSV file (not shown), reveals it allocates 1 tuple + and 2 dict per call. It can also be seen that `fbchain_configs` is mostly + called by `_add_code_coverage_configs`. + +This profiling mode is implemented by turning off garbage collection, so the +heap retains everything, and pushing function entry/exit entries on to the heap +with the time they happen. After execution, the heap can be scanned in order to +reconstruct the call tree and allocation patterns. As a result, this profile +mode may consume significantly more memory. + +### Statement profiling + +The second profiling mode tells us which statements spent most time executing. +Running it over a structured-logger `BUCK` file gives us a CSV file starting +with: + +```text +File Span Duration(s) Count +TOTAL 4.03 7187761 +fbcode_allowed_list.bzl 420:9-423:1 0.27 455884 +cell_defs.bzl 13:5-13:60 0.17 117736 +read_configs.bzl 46:5-46:55 0.08 65042 +prelude.bzl 28:9-29:20 0.07 1004 +... +``` + +This profile shows how much time is spent in each statement. Looking at the +relevant portion of `fbode_allowed_list.bzl`: + +```python +for _package in _recursive_allowlist: + if base_path == _package or base_path.startswith(_package + "/"): + return True +``` + +The `if` statement is at location 420:9-423:1 and takes 0.27s. The `if` +statement runs approximately 456K times. While looking at the outer statement in +the profile (not shown), it can be seen that the `for` loop is only called 3188 +times, implying an average of 143 iterations per call. It's possible that this +loop could be rewritten as some clever dictionary lookup, perhaps iterating over +the path components of `_package`. + +Line profiling builds on top of the `before_stmt` hook that is used for +debugging. It records the time each statement is entered then blames that +statement for all time until the next statement. That means that sometimes, due +to statements making function calls, the `return` of the function call may be +'blamed' until the next statement executes. As a result, treat the results with +slight caution. + +### Flame profiling + +The flame profiling modes produces a `.svg` flamegraph showing either time spent +or allocations. You can open it in Google chrome and inspect the resulting flame +graph. + + + +The flame profile provides a list of how time is used based on call stacks (you +can download an example [here](https://www.internalfb.com/intern/px/p/1Mz2W)). + + + +## Native profiling + +- Profiling on Linux can be done with + `perf record -g --call-graph=dwarf,20000 ...` and `perf report --call-graph` + - Don't profile the `buck2` process directly unless you are interested in + profiling the CLI; you likely want to profile the `buck2` daemon process. + You can find the pid with `buck2 status` and attach `perf` to that PID. +- Profiling on Mac can be done with `Instruments` (for details, + see the Wiki article + [Running and Testing Builds](https://www.internalfb.com/intern/wiki/GraphQL/Build_Infra/Running_and_Testing_Builds/#profiling-the-rust-code)). + +## Benchmarking + +- If you want to do proper statistically relevant A/B testing, use + `absh -a testa -b testb` (see [absh](https://github.com/stepancheg/absh) in + the GitHub repository). +- To measure the number of instructions: + - On Linux, use `perf stat foo` + - On Mac, use `/usr/bin/time -lp foo` +- On Mac, to run something with the time profiler on the command line, use + `xcrun xctrace record --template 'Time Profiler' --launch -- foo`, then + `open Foo.trace` for the name of the trace file it spits out (or pass + `--output` to control the output filename). diff --git a/_src/rule_authors/package.md b/_src/rule_authors/package.md new file mode 100644 index 000000000000..7198d7d6ddf5 --- /dev/null +++ b/_src/rule_authors/package.md @@ -0,0 +1,129 @@ +--- +id: package_files +title: PACKAGE Files +--- + +`PACKAGE` files are per-directory configuration files which are accessible from +Starlark rules/macros. It supports things like per-directory properties, reading +parent `PACKAGE` values (`read_parent_package_value()`), writing `PACKAGE` +values (`write_package_value()`), loading helper `bzl` files, and you can also +inspect `PACKAGE` values via `buck2 audit package-values`. + +Before evaluating `BUCK` file, buck2 will evaluate all `PACKAGE` files in the +same directory and all parent directories. Absent `PACKAGE` files are treated as +empty files. + +All relevant `PACKAGE` files are executed sequentially from the root directory +to the current directory (but unrelated `PACKAGE` files can be executed in +parallel). Evaluating `PACKAGE` files sequentially provides additional +guarantees, for example, attempt to override a property (unless explicitly +requested) should fail with Starlark call stack. + +Each `PACKAGE` file is evaluated at most once (like `bzl` files). + +`PACKAGE` files may load arbitrary `bzl` files. `BUCK`-specific functions called +in `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` or `BUCK` file. + +## APIs + +### `PACKAGE` APIs + +#### [`write_package_value`](../../api/build/globals/#write_package_value) + +```python +def write_package_value( + name: str, + value: "", + overwrite: bool = False, +): ... +``` + +This global API is only available in `PACKAGE` files, or `bzl` files included in +`PACKAGE` files. + +`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. The value must be serializable into JSON. + +When `overwrite` is `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. + +Note `write_package_value` symbol exists in `bzl` globals, and it can be called +from `bzl` file in context of `PACKAGE` evaluation, but calling +`write_package_file` is an error on context of `BUCK` evaluation. + +Modifying `PACKAGE` file logically invalidates the `BUCK` file of this +directory, and all `PACKAGE` and `BUCK` files of sub-`PACKAGE`s. However, `BUCK` +file evaluation may track which `PACKAGE`-local values were accessed and only +invalidate `BUCK` files which were potentially affected (similarly to how we do +it with buckconfigs). + +#### [`read_parent_package_value`](../../api/build/globals/#read_parent_package_value) + +```python +def read_parent_package_value( + key: str, +): ... +``` + +This global API is only available in `PACKAGE` files, or `bzl` files included in +`PACKAGE` files. + +This function returns the `PACKAGE` value defined in a parent `PACKAGE` file, or +`None` is such value does not exist. + +This function is available in `PACKAGE` files, but attempt to call this function +in context of `bzl` file evaluation results in an error. + +#### [`package`](../../api/build/globals/#package) + +```python +def package( + inherit: bool = False, + visibility: list[str] | tuple[str, ...] = [], + within_view: list[str] | tuple[str, ...] = [] +) -> None +``` + +This global API is only available in `PACKAGE` files, or `bzl` files included in +`PACKAGE` files. + +`visibility` is a list of visibility patterns to apply to all targets contained +within the directory, unless the target defines it's own visibility patterns. + +`within_view` is a list of visibility patterns restricting what all target +contained within the `PACKAGE` directory can depend on. Applies to first-order +deps, and not transitive deps. + +If `inherit` is `True`, then the `visibility` and `within_view` will be +inherited from the nearest parent `PACKAGE`. + +#### [`read_config`](../../api/build/globals/#read_config) + +`PACKAGE` files are able to call `read_config` to read buckconfigs. + +### `BUCK`-specific API + +#### [`read_package_value`](../../api/build/globals/#read_package_value) + +```python +def read_package_value( + name: str, +): ... +``` + +This global API is only available in `BUCK` files, or `bzl` files included in +`BUCK` files. + +This function returns the nearest `name` value registered per `PACKAGE`, or +`None` is such value does not exist. + +This function is available in `bzl` files, but attempt to call this function in +context of `PACKAGE` file evaluation results in an error. This restriction can +be lifted in the future. diff --git a/_src/rule_authors/test_execution.md b/_src/rule_authors/test_execution.md new file mode 100644 index 000000000000..64f582c490a5 --- /dev/null +++ b/_src/rule_authors/test_execution.md @@ -0,0 +1,235 @@ +--- +id: test_execution +title: Test Execution +--- + +Test execution in Buck2 is a collaboration with a separate test runner process. + + + +In its open-source build, Buck2 ships with a built-in simplistic test runner. + +This test runner receives the commands defined by `ExternalRunnerTestInfo` and +simply executes them. Exit code zero means the test passed, and one means it +failed. + +Users can of course develop their own test runners. Look at +`fbcode/buck2/app/buck2_test_runner` as a sample. For comparison, here's how +it's used at Meta: + + + +At Meta, this test runner is Tpx +[Tpx](https://www.internalfb.com/intern/wiki/TAE/tpx/). + +Tpx has a large number of responsibilities when used with Buck2, which can be +grouped as follows: + +- **Translation**: + - Understands the output formats of various supported test frameworks. This is + used to identify test cases and collect test results. + - Understands, to an extent, the input formats. For example, given a test + case, Tpx can identify what command needs to run to execute just that test. +- **Orchestration**: + - Interacts with Test Infra to discover what tests should run, under a number + of configurations. + - Separates listing of tests (identifying what tests exists in a test target) + and execution (running specific tests within that target). + - Coordinates the execution of tests. For example, it may request retries, or + choose to bundle multiple tests in a single execution (or not). + - Reports test results to Test Infra as well. + +In Buck2, rules interact with the test runner via a provider called +`ExternalRunnerTestInfo`. + +## Anatomy of a test run + +When a user runs `buck2 test $targets`: + +- Buck2 identifies all matching targets that have an `ExternalRunnerTestInfo`. +- Buck2 builds all the artifacts referenced by those targets (this will likely + change eventually to build them only if they are used). +- Buck2 then notifies the test runner that those tests exist. Currently, the + test runner receives a subset of `ExternalRunnerTestInfo`. +- The test runner can request command execution from Buck2 to list and execute + tests. +- When it receives command results from Buck2, the test runner may fire off + events that the end-user will see (such as test results), upload logs + externally, request further executions, and so on. + + +:::note +If more than one target is being built, test building and execution will proceed concurrently. + + +::: + +## Information available on `ExternalRunnerTestInfo` + +As noted, rules communicate their testing capabilities via +`ExternalRunnerTestInfo`. There are a number of fields available on +`ExternalRunnerTestInfo` to control how a given target is tested, as detailed in +the following sub-sections. + +### Fields exposed to the test runner + +The following list shows what is available in `ExternalRunnerTestInfo`, with +which the test runner can interact: + +- `type` - a string key that defines the type of test this is. + Tpx uses this internally to choose a translator. Examples include `gtest`, + `apple_test`, `custom`. Note that Tpx also allows labels to influence the + orchestrator selection. +- `command` and `env` - respectively, a list and a key-value mapping of + arguments. These are the inputs to translation in + Tpx. They are not always visible to the test runner (for more + details, see + [Verbatim arguments and handles](#verbatim-arguments-and-handles), below). +- `labels` - a set of string labels to pass to the test runner. + They have no meaning to Buck2, but some labels have impact on translation in + Tpx. +- `contacts` - a list of contacts for the tests; usually oncalls. +- `executor_overrides` - a key-value mapping of executor configurations that the + test runner can use when requesting execution from Buck2. +- `local_resources` - a key-value mapping from resource type to optional + `LocalResourceInfo` provider. Provider is used for initialization of that + resource type. If the value is `None` resource type is ignored even though + test runner required it. For context see + [Local Resources For Tests Execution](local_resources.md). + +### Fields pertinent for Remote Execution + +For compatibility with Remote Execution (RE), there are two fields that rules +should set in their `ExternalRunnerTestInfo` if they should be run on RE: + +- `use_project_relative_paths` - if `true` (the default is + `false` `true`), Buck2 + will produce relative paths. If not, it'll produce absolute paths. +- `run_from_project_root` - if `true` (the default is + `false` `true`), tests + will run from the project root (their `cwd` will be the project root, which is + the same as all build commands). If `false`, it'll be the cell root. + +Note that passing `--unstable-allow-all-tests-on-re` to `buck2 test` will +override those fields and set them to `true`, since they are a pre-requisite to +run on RE. In contrast, passing `--unstable-allow-compatible-tests-on-re` will +only allow tests that already set both those fields to `true` to execute on RE. + +Also note that when `executor_overrides` are set, if an executor override is +used and results in execution on RE, it'll happen on RE unconditionally. +Therefore, it's a good idea to set those fields if RE-only executor overrides +are provided. + +## Verbatim arguments and handles + +As noted above, the test runner only interacts with a subset of arguments +provided by rules in `ExternalRunnerTestInfo`. The reason for this is that the +test runner doesn't get to access, for example, artifacts, that Buck2 knows +about. + +Consider the following example: + +```python +binary = ctx.attrs.dep[RunInfo] +test_info = ExternalRunnerTestInfo(command = [binary, "run-tests"], ...) +``` + +When Buck2 actually runs this command, `binary` is expanded to a path (and +possibly to more args). Buck2 would also account for any hidden arguments and +make those available where the command is executed. It is important for Buck2 to +retain this capability when running with the test runner. + +To that end, all non-trivial arguments present in `command` (and in the values +of `env`), such as `cmd_args` or `RunInfo`, are exposed to the test runner as +opaque handles, and simple string arguments are passed as-is to the test runner. + +This means that the test runner would see the command described above as: + +```python +[ArgHandle(index = 0), Verbatim("foobar")] +``` + +When requesting execution from Buck2, the test runner can use the `ArgHandle` +and Buck2 will swap it back for the underlying value that was set on the +provider. + +This allows the test runner to introspect and modify parts of the command lines +it receives, as long as it doesn't need to access the actual text value of +non-verbatim arguments. Usually, this works out to be sufficient (or can be made +sufficient with a bit of refactoring in the test runner). + +## Execution Configurations + +By default, tests execute using the execution configuration of the associated +target. This is the execution configuration that would be used for run actions +(`ctx.actions.run`) declared in the same target. This is a default that actually +makes little sense but works out as long as cross-compiling is not the norm. + + + +That said, it's easy to see where this breaks down. + +For example: + +- For iOS tests, the execution platform for builds needs to be XCode (local or + RE Mac). +- For test listing, XCode is not needed (it's preferable to do it on RE Linux + where capacity is cheaper). +- To run the tests, a simulator is required. + + + +To support this, `ExternalRunnerTestInfo` allows specifying override platforms, +which are given a name. The test runner can request execution on them by passing +their name when it sends execution requests to Buck2, as shown in the following +code: + +```python +ExternalRunnerTestInfo( + executor_overrides = { + "ios-simulator": CommandExecutorConfig( + local_enabled = False, + remote_enabled = True, + remote_execution_properties = { + "platform": "ios-simulator-pure-re", + "subplatform": "iPhone 8.iOS 15.0", + "xcode-version": "xcodestable", + }, + remote_execution_use_case = "tpx-default", + ), + "static-listing": CommandExecutorConfig(local_enabled = True, remote_enabled = False), + }, + ... +) +``` + +The default execution platform can also be overridden: + +```python +ExternalRunnerTestInfo( + default_executor = CommandExecutorConfig( + local_enabled = False, + remote_enabled = True, + remote_execution_properties = { + "platform": "ios-simulator-pure-re", + "subplatform": "iPhone 8.iOS 15.0", + "xcode-version": "xcodestable", + }, + remote_execution_use_case = "tpx-default", + ), + ... +) +``` + +## Working Directory + + +Tests can be run from the cell root by setting `run_from_project_root = False`. + + + +As noted above, tests run from the cell root unless `run_from_project_root` is set. + + +To produce paths relative to the cell root for use by tests, use +`relative_to(ctx.label.cell_root)` on `cmd_args`. diff --git a/_src/rule_authors/transitive_sets.md b/_src/rule_authors/transitive_sets.md new file mode 100644 index 000000000000..804667e1377d --- /dev/null +++ b/_src/rule_authors/transitive_sets.md @@ -0,0 +1,269 @@ +--- +id: transitive_sets +title: Transitive Sets +--- + +Transitive sets enable the propagation of data up dependency trees in a manner +that is both efficient in Starlark code (low cost of creation, low memory usage) +and efficient for execution by Buck (edges can be shared instead of having each +action depend directly on all its inputs). + +Examples of where transitive sets are useful include: + +- Propagating transitive link-time dependencies of a library all the way to a + binary to build. +- Propagating transitive compile-time headers. + +## Rule API + +First, you need to declare your transitive set type, then you can use it, as +follows: + +```starlark +# This is the type +MySet = transitive_set() + +# Those are transitive sets: +set1 = ctx.actions.tset(MySet, value = "foo") +set2 = ctx.actions.tset(MySet, value = "bar", children = [set1]) +``` + +Values are optional, and so are children. This means you can have a set with no +value and sets with no children. + +## Projections: using transitive sets in command lines + +Sets aren't useful unless you can use their contents! + +To use a set in a command line, you use a concept called a 'projection', which +defines how to turn individual values found in the set into command line +arguments. + +To define a projection, you write a function that takes a value of your set and +returns a command-line like object (`cmd_args`, `string`, `attr.arg()` +attributes, `artifact`, and so on) or a list of them in whichever way makes +sense for your use case. + +Then, you call `project_as_args` to turn a set into a value suitable for +inclusion in a command line. When expanded, this projection will expand like a +list of all the node's individual projected values. + +Following is an example: + +```starlark +# Declare the projection +def project_as_define(value: str): + return cmd_args(value, format = "-D{}") + +# Add it to the set definition +MySet = transitive_set(args_projections = { "define": project_as_define }) + +# Create a set +set1 = ctx.actions.tset(MySet, value = "foo") +set2 = ctx.actions.tset(MySet, value = "bar", children = [set1]) + +# Call the projection. +# Note "define" is the key used above in `args_projections`. +args = set2.project_as_args("define") +``` + +When you use `args` in a command line, it will expand to `-Dbar -Dfoo`. + +Note that creating projections is very cheap. Notably, it is independent of the +size of the set. + +## Projections: using transitive sets in write_json() + +As with command lines, sets can form json projections to be used in write_json. + +A json projection is defined in the same way as an arg projection. The function +should return a value that `write_json` otherwise supports. Then, you call +`project_as_json` to turn a set into a value that can be passed to `write_json` +(or can appear within the value passed to it, it doesn't need to be the +top-level value). When expanded, the projection will expand like a list of all +the node's individual projected values. + +Following is an example: + +```starlark +# Declare the projection +def project_as_json(value: str): + return struct(key = "foo", value = value) + +# Add it to the set definition +MySet = transitive_set(json_projections = { "define": project_as_json }) + +# Create a set +set1 = ctx.actions.tset(MySet, value = "foo") +set2 = ctx.actions.tset(MySet, value = "bar", children = [set1]) + +# Call the projection. +# Note "define" is the key we used above in `json_projections`. +args = set2.project_as_json("define") +``` + +Note that if your projected values include (or may include) artifacts, you will +likely want to use `write_json(with_inputs=True)` to get back a cmd_args that +has all the artifacts in the json structure already in its `.hidden`. + +### Traversals in depth + +Transitive sets form DAGs. Notably, this means individual nodes can exist more +than once in a given transitive set. + +When a transitive set is traversed, nodes that have already been visited are +skipped. This means their arguments will only be emitted once. + +For example: + +```mermaid +flowchart TD + foo((foo)) + bar((bar)) + qux((qux)) + qux --> foo + bar --> foo + qux --> bar +``` + +```starlark +set1 = ctx.actions.tset(MySet, value = "foo") +set2 = ctx.actions.tset(MySet, value = "bar", children = [set1]) +set3 = ctx.actions.tset(MySet, value = "qux", children = [set1, set2]) + +args = set3.project_as_args("define") +``` + +This will expand to `-Dqux -Dfoo -Dbar`, even though `set1` (`"foo"`) shows up +twice in the DAG. + +## Other APIs + +### Transitive set reductions + +You can aggregate values of a transitive set via a reduction. This can be +helpful for tasks such as propagating Boolean flags up the tree. + +Following is a real-world example. + +When defining a reduction, you receive the reduced values of all your children, +and an optional value for the current node (the value will be `None` when you +create a set and you don't pass a `value`), and you need to merge them together +to produce this node's value: + +```starlark +def link_info_has_default_filelist(children: list[bool], infos: LinkInfos | None): + if infos: + info = infos.default + if info.filelist: + return True + return any(children) + +# Set of LinkInfos +LinkInfosTSet = transitive_set( + reductions = { + "has_default_filelist": link_info_has_default_filelist, + }, +) +``` + +### Transitive set iteration + +You _can_ iterate over a transitive set. This will yield each value once. You +can also iterate over projections. + +However, note that this is generally not recommended, since unlike creating and +using a projection, this operation is `O(set)`. + +You should use this as an escape hatch if and only if you need to implement +something transitive sets don't support via projections or reductions, because +in doing so you'll lose a lot of the performance benefits. + +For example: + +```starlark +set1 = ctx.actions.tset(MySet, value = "foo") +set2 = ctx.actions.tset(MySet, value = "bar", children = [set1]) +set3 = ctx.actions.tset(MySet, value = "qux", children = [set1, set2]) + +values = list(set3.traverse()) +``` + +This will yield `["qux", "foo", "bar"]`. + +### Ordering + +Transitive set iteration uses a left-to-right, pre-order traversal by default, +and ignores nodes that have already been visited. This order is reflected in +projections as well. + +A few different traversal orders are supported with the `ordering` attribute: + +| Ordering | Description | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `preorder` (default) | Traverses using a depth-first-search, visiting nodes left-to-right. | +| `postorder` | Traverses children left-to-right, and then visits the current node. | +| `topological` | A Topological sort, such that nodes are listed after all nodes that have them as descendants. This is similar to a pre-order traversal, except that when nodes are shared with more than one parent it is returned in the order of its last occurrence. | +| `bfs` | Breadth-first-search (BFS) traversal, traverses nodes left-to-right before traversing children. | + +For example: + +```starlark src=fbcode/buck2/app/buck2_build_api_tests/src/interpreter/transitive_set/tests.rs +set1 = ctx.actions.tset(MySet, value = "foo") +set2 = ctx.actions.tset(MySet, value = "bar", children = [set1]) +set3 = ctx.actions.tset(MySet, value = "qux", children = [set1, set2]) + +values = list(set3.traverse(ordering = "topological")) + +# This also works for projections +args = set3.project_as_args("project", ordering = "topological")) +``` + +Following is an example of how different orderings evaluate: + +```mermaid +flowchart TD + foo((foo)) + bar((bar)) + qux((qux)) + qux --> foo + bar --> foo + qux --> bar +``` + +| Ordering | Result | +| ------------- | ----------------------- | +| `preorder` | `["qux", "foo", "bar"]` | +| `postorder` | `["foo", "bar", "qux"]` | +| `topological` | `["qux", "bar", "foo"]` | +| `bfs` | `["qux", "foo", "bar"]` | + + + +This is verified by the test: + +```starlark src=fbcode/buck2/app/buck2_build_api_tests/src/interpreter/transitive_set/tests.rs title=fbcode/buck2/app/buck2_build_api_tests/src/interpreter/transitive_set/tests.rs +# Test all orderings which show up in the table. +assert_eq(list(set3.traverse()), ["qux", "foo", "bar"]) +assert_eq(list(set3.traverse(ordering = "preorder")), ["qux", "foo", "bar"]) +assert_eq(list(set3.traverse(ordering = "postorder")), ["foo", "bar", "qux"]) +assert_eq(list(set3.traverse(ordering = "topological")), ["qux", "bar", "foo"]) +assert_eq(list(set3.traverse(ordering = "bfs")), ["qux", "foo", "bar"]) +``` + + + +## Implementation details + +### Performance + +The performance benefits of tsets arise due to: + +- **Caching**: projections and reductions are cached. +- **Lazy Evaluation**: projection traversals are evaluated lazily. + +### Evaluation + +Projections and reductions are evaluated eagerly for each node of your +transitive set. This means that if your projection throws an error, you'll find +out when creating a set via `ctx.actions.tset`. diff --git a/_src/rule_authors/writing_rules.md b/_src/rule_authors/writing_rules.md new file mode 100644 index 000000000000..f2fee05771cb --- /dev/null +++ b/_src/rule_authors/writing_rules.md @@ -0,0 +1,285 @@ +--- +id: writing_rules +title: Writing Rules +--- + +This page describes how to write rules for Buck2 and explains the flow for +implementing rules that are already defined in Buck1. + +For a list of the API functions available, see the +[Build APIs](../../api/build/globals). + + +:::note +Rules such as `@fbcode_macros//build_defs:native_rules.bzl buck_genrule` are not actually rules, they are _macros_ (Starlark functions that eventually call out the underlying `genrule` _rule_). Macros in Buck2 are mostly compatible with Buck1 and should be written in the same way. + + +::: + +## Workflow by example + +The built-in Buck2 rules are stored in `fbsource` in `fbcode/buck2/prelude`. To +add a rule for a language, say `pascal`: + +1. Look at + [prelude/decls](https://github.com/facebook/buck2/blob/main/prelude/decls/) + to see the attributes that are supported in Buck1 and are mirrored into + Buck2. If `pascal` was an existing rule, you would see what attributes it + takes (often it will be `pascal_library` and `pascal_binary`). + +2. Create a file `pascal.bzl` that will contain your rule implementations. The + details are explained later, but a dummy rule looks like the following: + + ```python + def pascal_binary_impl(_ctx: AnalysisContext) -> list[Provider]: + return [DefaultInfo()] + ``` + +3. Create a directory in `fbcode/buck2/tests/targets/rules/pascal` with + `TARGETS` and whatever source files and test targets you need to test your + project. Note, Apple tests are currently located at + `xplat/buck2/tests/apple/...`. + +4. Test your code with `buck2 build fbcode//buck2/tests/targets/rules/pascal:`. + They should succeed with no actual output produced. + +5. Now implement the rules (see the rest of this page). + + +:::note +Before merging a diff, it's important that all your Starlark is warning free (if you don't want to set up Buck2 for local development, test it in CI). If you do set it up locally, see the `README.md` in the root of `fbcode/buck2`. Running `./test.py --lint-only` will confirm your Starlark code is warning free. + + +::: + +## Concepts and design + +A _rule_ for a _target_ uses _attributes_ to declare _actions_, which produce +_artifacts_ that get included in _providers_. + +For example, given: + +```python +def pascal_binary_impl(ctx: AnalysisContext) -> list[Provider]: + ... + binary = ctx.actions.declare_output(ctx.attrs.out) + ctx.actions.run(["pascalc", ctx.attrs.srcs, "-o", binary.as_output()]) + return [ + DefaultInfo(default_output = binary), + ] + +pascal_binary = rule(impl = pascal_binary_impl, attrs = { + "out": attrs.string(), + ... +}) +``` + +In the above snippet: + +- **Rule** is `pascal_binary`, which is implemented by `pascal_binary_impl`. The + rule says how to build things. +- **Target** will be something like + `fbcode//buck2/tests/targets/rules/pascal:my_binary`. The rule implementation + `pascal_binary_impl` will be called once per target. +- **Attributes** are the fields on the target (for example, you might have + `out`, which can be accessed via `ctx.attrs.out`). +- **Actions** are declared by the rule with things like `ctx.actions.run`, which + takes a command line. Note that the actions are not run by the rule, but + declared, so that Buck2 can run them later. +- **Artifacts** represent files on disk, which could be source or build outputs + (`binary` in the above example). + - For build outputs, the artifact is produced by an action, and the existence + of the artifact does not imply the build has been run: the artifact + 'remembers' what should be run if it is required. +- **Providers** are returned, which is information that other rules get to use. + These will often contain artifacts. + +The rule implementation takes in a `ctx`, which is the rule context. The two +most important fields are `ctx.attrs`, which picks up the attributes declared by +the rule, and `ctx.actions`, which lets you create new actions to actually do +something. + +The output of any actions performed will be materialized in `buck-out`. However, +only the defined outputs of providers are available for dependent rules to +consume and only the actions necessary to produce those outputs being consumed +will be run. By default, the `default_output` of the `DefaultInfo` provider is +built and output during a `buck build`. + +### Providers + +Providers are the data returned from a rule and are the only way that +information from this rule is available to rules that depend on it. Every rule +must return at least the `DefaultInfo` provider, but most will also return +either `RunInfo` (because they are executable) or some custom provider (because +they are incorporated into something that is ultimately executable). + +The `DefaultInfo` provider has a field `default_output`, which is the file that +will be built when someone executes a `buck2 build` on this particular target, +and the file that will be used when someone runs `$(location target)` or uses it +as a source file (such as `srcs = [":my_target"]`.) + +The current rule of thumb is that if you can build the `default_output`, the +rule must 'work', and, if usable, should be 'ready'. For example, for a binary, +the executable and runtime libraries it depends on might be returned. For a +library, because neither the static or dynamic library is the 'default', you +merely have to do enough work to ensure that the static and dynamic library +probably work. + +Similar to how `DefaultInfo` wraps a list of artifacts and `$(location)` selects +from `DefaultInfo`, `RunInfo` wraps a command line and `$(exe)` selects from +`RunInfo`. + +For more information about command lines, see [Run action](#run-action), below. + +For libraries, usually you need to pass some information about the library up to +the binary. The _only_ information that dependents on the library get are the +providers, so designing the information that flows around the provider is +critical to designing good rules. + +For a hypothetical rule, you may decide you want the name of the library and the +artifact that represents the `.so` file, for which you could define the +following provider: + +```python +PascalLibraryInfo = provider(fields=[ + "name", # The name of the library + "object" # An artifact, the .so file that needs linking in + ] +) +``` + +Often, you'll grab your dependencies from all your providers: + +```python +my_deps = [x[PascalLibraryInfo] for x in ctx.attrs.deps] +``` + +In many cases, it becomes apparent you need the transitive closure of all +libraries (for example, the libraries and everything they depend upon), in which +case, the standard pattern is to move to a provider of a list of `record` (see +the +[types.md](https://github.com/facebook/starlark-rust/blob/main/docs/types.md) +document in GitHub) and the `flatten/dedupe` functions, defining it as: + +```python +PascalLibraryInfo = provider(fields=["links"]) # a list of LinkData + +LinkData = record(name = str, object = "artifact") +``` + +And then consuming it: + +```python +my_links = dedupe(flatten([x[PascalLibraryInfo].links for x in ctx.attrs.deps])) +my_info = PascalLibraryInfo(links = my_links) +``` + +However, this `flatten`/`dupe` pattern can get expensive, especially when you +have a deep dependency graph. To fix that it's recommended to use +[transitive sets](transitive_sets.md). + +### Actions + +There are several actions you can use to create symlink trees, and so on. + +#### Run action + +Of the various actions, the `run` action is by far the most important: it's the +one that invokes a command line. + +A command line is both a list of string arguments and a list of artifacts they +depend on; with syntactic niceties for adding artifacts to command lines in a +way that ensures the dependencies are usually correct. + +Following are examples of command line manipulations: + +```python +cmd = cmd_args(["some", "arguments"]) +cmd.add("another-arg") +cmd.add(ctx.attrs.src) # An input artifact +out = ctx.actions.declare_output("an output") +cmd.add(out.as_output()) +ctx.actions.run(cmd) +``` + +The action `declare_output` creates a new artifact which is not bound to +anything. You can call `.as_output()` on it when adding it to a command line to +say that this command line doesn't take the artifact as an input but produces it +as an output. + +From now on, if `out` is used as a dependency (either to another command line, +or in `DefaultInfo`) then the action will be run to produce that artifact. +Typically, these outputs are declared (`declare_output`), bound in a +`ctx.actions.run` call with `.as_output()`, then either used locally as the +input to another action or returned in a provider. + +As another example: + +```python +cmd = cmd_args(["cp", input, output.as_output()]) +ctx.actions.run(cmd) +``` + +A command provides both a string (what to write when used) and a list of +artifacts (what must be available when used). Normally, as in the case above, +the artifacts that are used correspond to those on the command line. But imagine +the rule is changed to write the command to a shell script first: + +```python +sh = ctx.actions.write("test.sh", ["cp", input, output]) +cmd = cmd_args(["sh",sh]) +cmd.hidden([input, output.as_output()]) +ctx.actions.run(cmd) +``` + +The command has been written to a shell script, which is now run. Beforehand, +all the artifacts used by the command appeared on the command line. Now they +don't. However, the shell script still accesses input and output. To inform the +run command, use the hidden field of the command line to declare the dependency. + +For more complicated actions, which perform meaningful logic beyond invoking a +simple command, the tendency is to write custom Python scripts. Python scripts +are used instead of shell scripts as they have better cross-platform +compatibility and fewer hidden corners (especially in error paths). + +As an example of a Python helper, see +[make_comp_db.py](https://github.com/facebook/buck2/blob/main/prelude/cxx/tools/make_comp_db.py). + +A further advantage of using Python is that these commands can be tested in +isolation, outside of Buck2. + +## Debugging + +The functions `fail`, `print` and `pprint` are your friends. To get started, a +`buck2 build fbcode//buck2/tests/targets/rules/pascal:` builds everything or +`buck2 run fbcode//buck2/tests/targets/rules/pascal:my_binary` runs a specific +binary that returns a `RunInfo`. + +## Testing Rules + +A common way to test is to use `genrule` to cause the produced binary to run and +assert some properties from it. If your rule is in Buck1 and Buck2, use a +`TARGETS` file so you can test with both. If your tests are incompatible with +Buck1 (such as if it is a new rule), use `TARGETS.v2`, which will only be seen +by Buck2 and won't cause errors with Buck1. + +## New rules + +If your rule is **not** already in Buck1, then you can define it wherever you +like, with a preference for it not being in `fbcode/buck2/prelude`. + +The only advantage of the `prelude` is that rules can be used without a +corresponding `load`, which is generally considered a misfeature. The attributes +should usually be placed adjacent to the rule itself. + +As an example, just below the `pascal_binary_impl` function, you could write: + +```python +pascal_binary = rule( + impl = pascal_binary_impl, + attrs = { + "deps": attrs.list(attrs.dep()), + "src": attrs.source(), + } +) +``` diff --git a/_src/users/advanced/deferred_materialization.md b/_src/users/advanced/deferred_materialization.md new file mode 100644 index 000000000000..a178347bcb2e --- /dev/null +++ b/_src/users/advanced/deferred_materialization.md @@ -0,0 +1,116 @@ +--- +id: deferred_materialization +title: Deferred Materialization +--- + +When using [Remote Execution](../remote_execution.md), Buck2 can optionally +operate with Deferred Materialization, which means that Buck2 will avoid +downloading outputs until they are required by a local action. + +This can provide very substantial performance savings on builds that execute +primarily on Remote Execution, since those builds become able to proceed without +ever downloading any intermediary outputs. + +At Meta, despite very fast networks being used internally, this was was observed +to make real-world builds finish approximately 2.5 times faster. + +## Pitfalls + +Buck2's deferred materialization makes assumptions about your Remote Execution +backend. In particular, it expects that the TTL returned from action cache +entries by your Remote Execution backend always exceeds the TTL of all output +artifacts it references. + +Nonetheless, artifacts may also eventually expire from your Remote Execution +backend. When that happens, builds using Deferred Materialization may fail if +those artifacts are needed locally. + +A kill is necessary to recover from those builds. However, the +[Restarter](restarter.md) can be used to mitigate this issue by restarting Buck +when it encounters an expired artifact. + + +At Meta, artifacts get periodically refreshed, but open source RE backends do not expose the TTL of artifacts, so this feature does not work outside of Meta. + + +## Enabling Deferred Materialization + +To enable deferred materialization, add this to your +[Buckconfig](../../concepts/buckconfig.md): + +``` +[buck2] +materializations = deferred +``` + +## On-disk state + +Buck2 can also optionally track its state on disk in a SQLite database. This +allows Buck2 to remember what files are on disk across restarts. + +This can allow Buck2 to avoid re-downloading outputs from your Remote Execution +backend if they are already on disk. + +To enable, add this to your Buckconfig: + +``` +[buck2] +sqlite_materializer_state = true +``` + +## Deferring Write Actions + +To further speedup builds, Buck2 can also be instructed to not execute any +writes on the critical path for a build. + +To enable, add this to your Buckconfig: + +``` +[buck2] +defer_write_actions = true +``` + +This mechanism is recommended if you're using the On-disk State, since it means +Buck can omit writes entirely if the same content is already on disk. + +## `buck2 clean --stale` + +The deferred materializer can be configured to continuously delete stale +artifacts, that haven't been recently accessed, or untracked artifacts, that +exist in buck-out but not in the materalizer state. + +Unlike `buck2 clean` this does not fully wipe buck-out but it should not +negatively impact build performance if you are building and rebasing regularly. + +Enabling this requires enabling [on-disk state](#on-disk-state) and +[deferred write actions](#deferring-write-actions), and adding this to your +Buckconfig: + +``` +[buck2] +clean_stale_enabled = true +``` + +It can be further configured by changing these default values: + +``` +[buck2] +# one week +clean_stale_artifact_ttl_hours = 24 * 7 +clean_stale_period_hours = 24 +clean_stale_start_offset_hours = 12 +``` + +- `clean_stale_start_offset_hours` determines the time following daemon start up + before the first clean will be scheduled. +- `clean_stale_period_hours` determines how frequently to schedule recurring + clean events. +- `clean_stale_artifact_ttl_hours` determines how long artifacts should be kept + in buck-out before cleaning them. + +If clean stale is running in the background at the same time that a build begins +to materialize artifacts, the clean will be interrupted and not run again until +after the next scheduled period, but it should be able to make gradual progress +and prevent long term accumulation of artifacts. + +If needed, a clean can be manually triggered by calling `buck2 clean --stale`. diff --git a/_src/users/advanced/external_cells.md b/_src/users/advanced/external_cells.md new file mode 100644 index 000000000000..b6d863c9ae18 --- /dev/null +++ b/_src/users/advanced/external_cells.md @@ -0,0 +1,100 @@ +--- +id: external_cells +title: External Cells +--- + +Normally, buck2 requires source files to be checked into the repo. However, this +is sometimes inconvenient. It makes distribution of the prelude hard, and users +may want to pull in third party dependencies without vendoring them or using +source control tricks. + +To help support these use cases, buck2 has a concept of "external cells." +External cells act much like [normal cells], except that instead of having their +source files checked into the repo, the source files have some alternative +origin. + +[normal cells]: ../../concepts/buckconfig.md/#cells + +## Setting up an external cell + +Configuring an external cell looks much like configuring a regular cell. First, +add the cell to the `cells` section of your `.buckconfig` like normal: + +``` +[cells] + prelude = some/path +``` + +The external cell's files won't actually be generated in the repo. However, you +still need to provide a path for it - this path influences the handling of tree +files, since those cross cell boundaries. It's also used for +`expand-external-cells`, more on that below. + +Next, add an entry to the `external_cells` buckconfig section that specifies the +"origin" of the external cell given an alias. This tells buck2 where you want to +get the cell from, if not files in the source repo. + +``` +[external_cells] + prelude = bundled +``` + +For the `bundled` origin, that's it. Other origins may require additional +configuration. + +## Origins + +Buck2 currently supports two external cell origins, `bundled` and `git`. + +### The `bundled` origin + +The bundled origin can only be used with the `prelude` cell, and provides access +to a copy of the prelude that is bundled as part of the buck2 binary. This is +useful as an easier-to-install alternative to vendoring or submoduling the +prelude. + +### The `git` origin + +The `git` origin indicates that an external cell's content should be loaded from +some git repo. It accepts two additional configuration parameters, `git_origin` +and `commit`, like this: + +``` +[cells] + root = . + libfoo = libfoo + +[external_cells] + libfoo = git + +[external_cell_libfoo] + git_origin = https://github.com/facebook/foo + commit_hash = +``` + +The `commit_hash` value must be a sha1, it cannot be eg a branch name. + +## Expanding external cells + +Because external cells only represent a different way to access source files, +buck2 provides an `expand-external-cell` command. This command will make a copy +of the external cell into the path in the repo you specified for your cell. By +commenting out the `external_cells` buckconfig entry, this allows you to make +direct edits to the cell's files in your repo. + +## Details & Limitations + +- External cells can only be configured in the project root's `.buckconfig`. + This also means that there is no support for "transitive" external cells, ie + an external cell cannot specify additional external cells to pull in. +- External cells cannot have nested cells inside them. +- The `cells` buckconfig section of external cells is ignored. This is done to + ensure that when using an external cell to access some dependency in a git + repo, that git repo can still be an independently building project that + specifies its own toolchain and prelude configuration. + + Because of this difference between external and non-external cells, it's + possible that running `buck2 expand-external-cell` may not produce a working + cell immediately, but instead require you to delete the `cells` section first. + + `cell_aliases` still work just like with regular cells. diff --git a/_src/users/advanced/in_memory_cache.md b/_src/users/advanced/in_memory_cache.md new file mode 100644 index 000000000000..123073e6bd5e --- /dev/null +++ b/_src/users/advanced/in_memory_cache.md @@ -0,0 +1,22 @@ +--- +id: in_memory_cache +title: In Memory Cache +--- + +Buck2 can maintain an in-memory cache of actions it executed. This allows +actions to skip re-running even when they are (transitively) affected by file +changes. + +## Enabling the in-memory cache + +This feature requires enabling +[Deferred Materialization](deferred_materialization.md) first. This is necessary +so that Buck2 knows what's on disk. This requirement might go away once we +decouple keeping track of what's on disk and deferred materialization. + +Once done, to enable, add this to your Buckconfig: + +``` +[buck2] +hash_all_commands = true +``` diff --git a/_src/users/advanced/restarter.md b/_src/users/advanced/restarter.md new file mode 100644 index 000000000000..e0b9c57e746b --- /dev/null +++ b/_src/users/advanced/restarter.md @@ -0,0 +1,21 @@ +--- +id: restarter +title: Restarter +--- + +The Restarter can automatically restart Buck2 when Buck2 detects that it hit a +condition that may be recovered by restarting the Buck2 daemon. + +This is particularly useful with +[Deferred Materialization](deferred_materialization.md), which may require a +daemon restart if your daemon holds references to artifacts that have expired in +your Remote Execution backend. + +## Enabling the Restarter + +To enable, add this to your Buckconfig: + +``` +[buck2] +restarter = true +``` diff --git a/_src/users/build_observability/build_report.md b/_src/users/build_observability/build_report.md new file mode 100644 index 000000000000..b8b34a3c59b0 --- /dev/null +++ b/_src/users/build_observability/build_report.md @@ -0,0 +1,218 @@ +--- +id: build_report +title: Build Report +--- + +The build report is a JSON file that you can ask buck to output which contains +structured information about the result of your build. It is particularly +valuable for its reporting of _unsuccessful_ outcomes in addition to +_successful_ ones; usually, most use cases that only need to care about +successful outcomes are well served by direct usage of the CLI. + +To request a build report, pass `--build-report ` to `buck build` on the +CLI. + +At a high level, the build report outputs information for each of the targets +that you requested to have built on the CLI. As a result, it may report +information for more than one configuration or subtarget of a target. For +example, this can happen if you passed `--target-platforms` or built `:target` +and `:target[sub]`. + +## Schema + +``` +BuildReport { + # A unique ID identifying this buck invocation. Currently a UUID, however + # that may change in the future. + trace_id: str, + + # True if all requested targets built successfully + success: bool, + + # The absolute path to the project root + project_root: Path, + + # The results of the build, categorized by unconfigured target + results: dict[TargetLabel, BuildReportEntry], + + # A cache for error message lookup. This is meant for deduplicating strings + # that might otherwise appear many times in the build report and cause an + # unnecessary size increase. They keys are used in other fields in the build + # report in reference to these strings. + strings: dict[str, str], + + # BUCK1 BACKCOMPAT ONLY! + # + # Currently always empty. Will be filled in if a flag is passed in the future. + # + # A map from targets that failed to build to error messages describing the + # failure. + failures: dict[TargetLabel, str], +} + +BuildReportEntry { + # The results of building the target in the given configurations + configured: dict[Configuration, ConfiguredBuildReportEntry], + + # Errors encountered while building this target. + # + # Note that this does not include the errors that are found within the + # `ConfiguredBuildReportEntry`s. Instead, it includes additional errors + # which could not be associated with a specific configuration of the + # target, typically because they occurred before the target could be + # configured. + errors: list[Error], + + # BUCK1 BACKCOMPAT ONLY! + # + # The two fields below are included for buck1 backwards compatibility only. + # They are both computed by aggregating across all the configured targets in + # the way you might expect. + success: "FAIL" | "SUCCESS, + outputs: dict[str, list[Path]], + + # The path to the package containing this target, relative to the project + # root. This is the source code location for this target. + package_project_relative_path: Optional[str] +} + +ConfiguredBuildReportEntry { + # Did this target build successfully or not? + success: "FAIL" | "SUCCESS, + + # A map of subtargets that were built to a list of the successfully built + # outputs for that subtarget. + # + # The keys are generated by joining the subtargets with a `|`. For example, + # if you request to have `:target` and `:target[foo][bar]` built on the CLI, + # this list will contain one entry for `""` and one for `"foo|bar"`. + outputs: dict[str, list[Path]], + + # The number of targets in the configured dependency graph of this target. + # + # This is only included if `-c buck2.log_configured_graph_size=true` is set. + # Otherwise, it is left as None. + configured_graph_size: Optional[uint], +} + +Error { + # The stringified hash of the same stringified error message that is shown to the user on the + # console. The hash is stored as the key in the `strings` cache of the `BuildReport` + message_content: str, + + # Structured action error. Present only if the error was actually an action error + action_error: Optional[ActionError], + + # An index that can be used to detect duplicate errors. Two errors with the + # same cause index have the same cause. Note that that does not mean that + # they have the same error message. + cause_index: uint, +} + +ActionError { + # The action key + key: ActionKey, + + # The action name + name: ActionName, + + # Digest of the action + digest: str, + + # Stringified hash of the stderr of the action + stderr: str, + + # Stringified hash of the stdout of the action + stdout: str, + + # Stringified hash of the same stringified error message that is provided by the action + error: str, + + # Optional list of error categorizations provided by an error handler which is invoked + # in the event of a failed action, or an error message if the error handler failed. + error_diagnostics: Optional[ActionErrorDiagnostics], +} + +ActionKey { + # The configured target, anon target, or bxl function which owns this action + owner: str, +} + +ActionName { + # The category of the action + category: str, + + # The optional identifier of the action + identifier: Optional[str], +} + +enum ActionErrorDiagnostics { + # The list of sub errors if the error handler succeeded + sub_errors: list[ActionSubError], + + # The stringified hash of the error message if the error handler failed + handler_invocation_error: String, +} + +ActionSubError { + # Name of the error category. The category should be finer grain error categorizations + # provided by the rule authors, and tend to be language specific. These should not be + # any kind of shared concepts among all errors for all languages/rules. For example, + # timeouts and infra errors should not go here - buck2 tries to categorize these types + # of errors automatically. An example of a finer grain error category may be the error + # code for rustc outputs. + category: str, + + # The stringified hash of the extra message provided for the specific sub-error category. + message_content: str, + + # List of error locations, if any + locations: Optional[list[ActionErrorLocation]], +} + +ActionErrorLocation { + # File path where the error appeared, preferrably either project-relative or absolute. + file: str, + + # Optional line number + line: Optional[u64] +} +``` + +### On Compatibility + +The format of the build report is generally stable. However, note that new +fields may be added at any time, and you should ensure this does not cause your +parsing to fail. + +A number of fields above are marked as being for buck1 backwards compatibility +only. These fields all have superior alternatives available in the build report +already. We would strongly prefer that new code neither use nor parse them, as +this increases the likelyhood that they can be removed one day. + +The build report additionally outputs a few fields that are intentionally not +documented here. Those fields are even less useful than ones documented as being +for backwards compatibility only, and even closer to removal. **Please** avoid +using or parsing these if at all possible. + +### Limitations + +The build report currently has at least the following limitations: + +1. It includes only one action error per failed target. This is the expected + behavior when `--keep-going` is not passed, but when `--keep-going` is + passed, this is a bug. +1. It is currently not generated when a non-existant package is specified on + the command line. This is also a bug. +1. It cannot be requested for any buck2 command other than `build` +1. Errors do not contain any additional metadata outside of the error message. + This will be made available as such metadata is available in buck2. +1. The "failures" field is always empty. This will be changed under a + backcompat opt-in flag in the future. + +Finally, it's worth raising that the concept of error deduplication has some +fundamental limitations; if two targets both refer to the same non-existant +dependency, do those errors have the same cause (the dependency doesn't exist) +or different causes (each target is individually broken)? As a result, the exact +details of when two errors are considered to have the same cause are not +generally stable, and may not always be what you expect. diff --git a/_src/users/build_observability/interactive_console.md b/_src/users/build_observability/interactive_console.md new file mode 100644 index 000000000000..79d9c2127c32 --- /dev/null +++ b/_src/users/build_observability/interactive_console.md @@ -0,0 +1,86 @@ +--- +id: interactive_console +title: Buck2 Consoles +--- + +Buck2 offers several console types for build-like commands (e.g. `build`, +`install`, `test`, etc.). The console is always written to stderr. + +The console can be specified via the `--console` flag, or the `BUCK_CONSOLE` env +variable. The default console type is `auto`. Supported `--console` types: + +- `auto` - Default console type. Auto defaults to the superconsole if the stderr + is a TTY. Otherwise will uses simple console +- `simple` - Build a simpleconsole with TTY, if TTY is supported by the OS. See + [Simpleconsole](#simpleconsole) +- `simplenotty` - Build a simpleconsole without TTY. See + [Simpleconsole](#simpleconsole) +- `simpletty` - Build a simpleconsole with TTY. See + [Simpleconsole](#simpleconsole) +- `super` - Build a superconsole regardless of whether stderr is a TTY. See + [Superconsole](#superconsole) +- `none` - See [No console](#no-console) + +If `simplenotty` or `none` are specified, or if TTY is not supported by the OS, +then we strip out any color within the error messages. + +All console options will output the build result, whether succeeded or not, to +stdout. Note that action execution stderr is hidden if the build succeeded. + +The simple and superconsole will also print metadata about the build itself, +such as the Buck2 UUID, the percentage of cache hits, and the number of action +commands ran. In addition, they will print the event spans detected within the +build. + +## Simpleconsole + +The simpleconsole prints the stdout/stderr messages and event spans, line by +line. There is no resource usage telemetry emitted. + +### Demo + +![Simpleconsole running a build](simpleconsole.gif) + +## Superconsole + +The superconsole uses the +[superconsole](https://github.com/facebookincubator/superconsole) library to +provide an interactive console which shows the event spans going on within +Buck2. + +### Demo + +![Superconsole running a build](superconsole.gif) + +### Toggles + +The superconsole also provides several toggles to inspect ongoing Buck2 +telemetry. + +To see what's available you can press `?` or `h`. This will work as long as +stdin is a TTY, which will be true most of the time if you're not piping +anything into Buck2. To disable to allow alternate use of stdin, or for follow +up pasted commands to not get swallowed, you can set the +`BUCK_NO_INTERACTIVE_CONSOLE` environment variable, or use the flag +`--no-interactive-console`. + +We support the following toggles: + +- `c` - toggle commands (shown in superconsole by default) +- `d` - toggle DICE key states +- `e` - toggle debugging events, such as spans and instant event counts +- `2` - toggle two lines mode when showing events +- `r` - toggle detailed remote execution info, such as uploads, downloads, and + action cache calls +- `i` - toggle I/O counters +- `p` - display target configurations +- `+` - show more lines +- `-` - show fewer lines +- `h` - show help + +Note: Not available yet for Windows + +## No console + +When specifying the `none` console type, Buck2 will only print if the build +succeeded, or the error if the build failed. diff --git a/_src/users/build_observability/logging.md b/_src/users/build_observability/logging.md new file mode 100644 index 000000000000..88ea1688f200 --- /dev/null +++ b/_src/users/build_observability/logging.md @@ -0,0 +1,158 @@ +--- +id: logging +title: Logging +--- + +Buck2 produces detailed event logs for each invocation, which follow a schema +outlined in `app/buck2_data/data.proto` in the buck2 parent directory. The event +logs that Buck2 produces automatically are always in protobuf zstd-compressed +format (see [Viewing the event log](#viewing-the-event-log) for more details). + +## Event log format + +Warning: the schemas are all subject to change, so we do not recommend relying +on the format. For the source of truth, take a look at `data.proto`. + +### Invocation header + +The first line of the event log is always the `Invocation` header: + +```python +Invocation { + # CLI args split into a list of strings + command_line_args: List[str], + # Expanded CLI args, which expand any argsfiles + expanded_command_line_args: List[str], + # Absolute path of the current working directory of the Buck2 command + working_dir: str, + # UUID of the Buck2 command + trace_id: str, +} +``` + +### Command result footer + +The last line is always the `CommandResult`: + +```python +Result { + # One of the result types of CommandResult protobuf type in data.proto + result: BuildResponse | CqueryResponse | BxlResponse | ..., +} +``` + +### Buck events + +The rest of the event log contain `BuckEvent`s, which are either +`SpanStartEvent`s, `SpanEndEvent`s, or `InstantEvent`s. + +The `BuckEvent` format is roughly as follows: + +```python +Event { + # When the event was fired. This is always a 2-item list, where the first + # value is millis, second value is micros + timestamp: List[u64], + # UUID of the Buck2 command, same one as the invocation header + trace_id: str, + # A trace-unique 64-bit integer identifying this event's span ID, + # if this event begins a new span or belongs to one. + span_id: u64, + # A trace-unique 64-bit identifying the span that this event is logically + # parented to. + parent_id: u64, + # See sections below for more details + data: SpanStart | SpanEnd | Instant, +} +``` + +#### Span starts + +The `SpanStartEvent` indicates that a span of work starting: + +```python +SpanStart { + # One of the data types of SpanStartEvent protobuf type in data.proto + data: AnalysisStart | ActionExecutionStart | ..., +} +``` + +#### Span ends + +The `SpanEndEvent` indicates that a span of work has finished: + +```python +SpanEnd { + # Duration of the span + duration_us: u64, + # CPU poll times for this span + stats: SpanStats, + # One of the data types of SpanEndEvent protobuf type in data.proto + data: AnalysisEnd | ActionExecutionEnd | ..., +} + +# CPU poll times for this span +SpanStats { + max_poll_time_us: u64, + total_poll_time_us: u64, +} +``` + +#### Instant events + +The `InstantEvent` represents a single point in time: + +```python +InstantEvent { + # One of the data types of InstantEvent protobuf type in data.proto + data: ConsoleMessage | ActionError | ..., +} +``` + +One specific instant event type that may be of interest is the `SnapShot` event, +which includes some interesting details like RSS, CPU, I/O, remote execution, +and DICE metrics. + +## Viewing the event log + +Event logs can be accessed using commands under `buck2 log show`, which outputs +the event logs in JSONL format. You can run `buck2 log show --help` to see all +available options. Some useful commands: + +- Show the logs for the most recent Buck2 command: + +```sh +buck2 log show +``` + +- Show the logs for a specific Buck2 command, given the command's UUID: + +```sh +buck2 log show --trace-id +``` + +- Show the logs for a recent Buck2 command: + +```sh +buck2 log show --recent +``` + + + +You can also download the logs locally from Buck2 UI. The logs will be +downloaded from Manifold in protobuf zstd-compressed format, and you can view +them in JSONL format by passing the path into `buck2 log show`. + + +The JSON schema is derived from the protobuf types, and the log itself could be +quite large. [jq](https://jqlang.github.io/jq/) can be useful to find specific +things. For example, this jq script shows the max event delay between a snapshot +event creation on the daemon side, and when the client receives it. + +```sh +buck2 log show | jq -s ' + map( + .Event.data.Instant.data.Snapshot.this_event_client_delay_ms + | select(. != null) + ) | max' +``` diff --git a/_src/users/build_observability/simpleconsole.gif b/_src/users/build_observability/simpleconsole.gif new file mode 100644 index 000000000000..079ae7038d5a Binary files /dev/null and b/_src/users/build_observability/simpleconsole.gif differ diff --git a/_src/users/build_observability/superconsole.gif b/_src/users/build_observability/superconsole.gif new file mode 100644 index 000000000000..f04a970e67d0 Binary files /dev/null and b/_src/users/build_observability/superconsole.gif differ diff --git a/_src/users/cheatsheet.md b/_src/users/cheatsheet.md new file mode 100644 index 000000000000..8ddf61889f2a --- /dev/null +++ b/_src/users/cheatsheet.md @@ -0,0 +1,130 @@ +--- +id: cheat_sheet +title: Cheat Sheet +--- + +# Buck2 Cheat Sheet + +This section provides example command lines that you can use to obtain +information about Buck2 and about your build. These techniques can help you to +understand how your build works and to troubleshoot issues with your build. +These examples use the [`buck2 cquery`](../query/cquery) command. We recommend +cquery over uquery in most cases because cquery operates on the configured +graph, which means that targets have had the expected configurations applied on +them. + +--- + +- How do I see the arguments for a given rule from the command line? +- How do I find all the targets for a package? +- How do I specify more than one target to `buck2 cquery`? +- How do I get the attribute names and values for the targets that result from a + query? +- How do I perform a query inside of a rule? +- How do I find the dependencies for a target, that is, the targets on which a + specified target depends? +- How do I find the reverse-dependencies for a target, that is, the targets that + depend on a specified target? +- How do I find the build file that contains the target that owns a source file? + +--- + +### How do I find all the targets for a package? + +Specify a _build target pattern_ that represents the targets in the package. + +``` +buck2 cquery //path/to/dir/... +``` + +The `buck2 cquery` command can accept a +[build target pattern](../../concepts/target_pattern) as a parameter. If you +specify a build target pattern, Buck2 evaluates this pattern and shows all the +build targets that match it. + +### How do I specify more than one target to `buck2 cquery`? + +Use the `buck2 cquery set()` operator. The following command line returns the +target `main` in the build file in the root of the Buck2 project and all the +targets from the build file in the `myclass` subdirectory of the root. + +``` +buck2 cquery "set( '//:main' '//myclass:' )" +``` + +### How do I get the attribute names and values for the targets returned by a query? + +Add the `--output-attribute ` or `--output-all-attributes` option to +the command line, followed by regular expressions that represent the attributes +of interest. + +``` +buck2 cquery "deps(//foo:bar)" --output-attribute 'name' 'exported_headers' +``` + +The `--output-attribute` option enables you to specify which attributes Buck2 +should return. Instead of returning the names of the targets that match the +query expression, Buck2 returns the names and values of the specified attributes +for those targets in JSON format. Attributes are specified as regular +expressions. For example, `'.*'` matches all attributes. See the +[`buck2 cquery` docs](../query/cquery) for more details. The output for the +example query above might look something like the following. + +``` +{"//foo/bar/lib:lib" : {"exported_headers" : [ "App/util.h" ],"name" : "lib"},"//foo/bar:app" : {"exported_headers" : [ "App/lib.h" ],"name" : "app"}} +``` + +### How do I perform a query** \***inside**\* **of a rule? + +Buck2 supports certain string parameter macros to be used when defining a +target. You can use the query macros as such: + +``` +$(query_targets "queryfunction(//:foo)") +$(query_outputs "queryfunction(//:foo)") +$(query_targets_and_outputs [SEPARATOR] "queryfunction(//:foo)") +``` + +Note, however, that the query macros are supported only for +[`genrule`](../../api/rules/#genrule) and +[`apk_genrule`](../../api/rules/#apk_genrule). + +### How do I find the dependencies for a target? + +Use the `deps()` operator. + +``` +buck2 cquery "deps('//foo:bar')" +buck2 cquery "deps('//foo:bar', 1, first_order_deps())" +buck2 cquery "deps(set('//foo:bar' '//foo:lib' '//foo/baz:util'))" +``` + +The `deps` operator finds the dependencies of the specified targets. The first +argument represents the targets of interest. This can be a single +[build target](../../concepts/build_target) or +[build target pattern](../../concepts/target_pattern), or a set of these. The +optional second argument is the _depth_ of the search for dependencies from the +specified targets. For example, `1`, as shown in the example above, returns only +the direct dependencies. If you do not provide this argument, the output is the +complete set of transitive dependencies. How do I find the reverse-dependencies +for a target, that is, the targets that** \***depend on**\* **a specified +target? Use the `buck2 cquery rdeps()` (reverse dependencies) operator. The +following example, returns the targets in the +[transitive closure](https://en.wikipedia.org/wiki/Transitive_closure) of +`//foo:bar` that depend directly on `//example:baz`. + +``` +buck2 cquery "rdeps('//foo:bar', '//example:baz', 1)" +``` + +### How do I find the buildfile that contains the target that owns a source file? + +In order to find the build file associated with a source file, combine the +`owner` operator with `buildfile`. For example, + +``` +buck2 cquery "buildfile(owner('foo/bar/main.cpp'))" +``` + +first finds the targets that _own_ `foo/bar/main.cpp` and then returns the build +files, such as `foo/bar/BUCK`, that define those targets. diff --git a/_src/users/faq/buck_hanging.md b/_src/users/faq/buck_hanging.md new file mode 100644 index 000000000000..660558c6bca4 --- /dev/null +++ b/_src/users/faq/buck_hanging.md @@ -0,0 +1,83 @@ +--- +id: buck_hanging +title: Why is Buck2 hanging? +--- + +Let's look at how to troubleshoot when buck2 hangs, i.e. it just sits there +saying "Jobs: In progress: 0, ..." but it’s not finishing... + +When buck2 hangs, there are two possibilities: It’s either hanging doing +_something_, or it’s hanging doing _nothing_. The first thing you should do is +figure out which of those is happening. That’s because the tools to debug either +of those are _very_ different! We will mainly focus on the first in this case. + +To figure out which hang you have on your hands, just look at how much CPU buck2 +is using when the hang occurs using your favorite activity monitor (e.g. `top`, +`htop`). Remember that you can find the buck2 daemon’s PID using `buck2 status`. +Ideally, break the utilization down by threads (in top, that’s `top -Hp $PID`). + +If any thread is using 100% CPU for some period of time, then you probably have +a busy hang (buck2 is doing “something”) which are usually easier to debug. + +## How to debug a “busy” hang + +### Getting a stack trace + +When debugging a busy hang, the first thing to do is to work out what the +process is doing. There are many tools you can use for this (like a profiler), +but the absolute simplest one is quickstack: just run `quickstack -p $PID`, and +it’ll show you a stack dump for all the threads in your process. If you prefer +`gdb`, you can use `gdb -p $PID`, then `thread apply all bt`, and that’s the +same thing. + +Note that a stack trace tells you what the process is doing at a point in time, +so don’t just look at the very last frame and call it the culprit. Instead, look +at the stack as a whole. If you need more perspective, use a sampling profiler +(strobeclient run --pid $PID). You can also +just grab stack traces at a few points in time and see if they look similar: +this is exactly what a sampling profiler does, albeit at a higher frequency. + +### Interpreting the stack trace + +Let's consider an example user report ( see +[here](https://fb.workplace.com/groups/buck2users/permalink/3232782826978076/)) +with the following stack trace: + +``` +#01 0x0000000005b1ec26 in as core::iter::traits::iterator::Iterator>::next () from ... +#02 0x0000000005b23998 in as itertools::Itertools>::exactly_one () from ... +#03 0x00000000059dbb2c in buck2_server_commands::commands::build::create_unhashed_outputs () from ... +#04 0x0000000005c3c677 in ::command::{closure#0}> as core::future::future::Future>::poll () from ... +#05 0x00000000054c58a3 in as buck2_server_ctx::ctx::ServerCommandDiceContext>::with_dice_ctx::{closure#0}::{closure#0}::{closure#0}, core::pin::Pin> + core::marker::Send>>, cli_proto::BuildResponse>::{closure#0}> as core::future::future::Future>::poll () from ... +#06 0x00000000054c7ae3 in ::{closure#0}::{closure#0}> as core::future::future::Future>::poll () from ... +#07 0x0000000005370df8 in ::call_in_span::, buck2_data::CommandEnd)>, ::span_async::{closure#0}::{closure#0}>, core::result::Result>::{closure#0}::{closure#0}::{closure#0}> () from ... +#08 0x00000000054f7288 in ::build::{closure#0}> as core::future::future::Future>::poll () from... + ... +``` + +At this point, you can look at the code, and note that there is no span around +the output symlink creation function (`create_unhashed_outputs`). This suggests +you’ve found your culprit: there is indeed a buck2 bug and we’re spending ages +creating unhashed output symlinks, and since you need a span to get any console +feedback, the console says nothing is happening. + +**An easy fix**: In this particular instance, Thomas spotted +[an easy optimization](https://github.com/facebook/buck2/commit/d677e41253b73a31aafa1255a532c38992482efd) +which resolved the issue. But, of course, that’s not always possible. If the +easy fix hadn't been available, we’d be at a dead end, so what do we do next? + +**A harder fix**: If it is not clear what the root-cause is, you can +bisect[you can bisect](users/faq/how_to_bisect.fb.md): +i.e. do a binary search across commits for the commit that introduced a given +breakage/perf degradation. Thanks to the fact that we enforce a +linear history, bisecting is pretty straightforward in +`fbsource`. Then, once you identify their commit that caused +breakage, investigate what caused the issue. + +## How to debug a “doing nothing” hang + +**Cycle in dependencies**: If buck2 seems to be doing nothing (e.g. CPU usage is +0%), one of the reasons could be a cycle in your dependencies, which may cause +buck2 to hang (buck2 does implement a form of cycle detection, but it +unfortunately has false negatives). You can confirm this by running buck1, which +will report cycles properly. diff --git a/_src/users/faq/common_issues.md b/_src/users/faq/common_issues.md new file mode 100644 index 000000000000..d66f97fd0fa1 --- /dev/null +++ b/_src/users/faq/common_issues.md @@ -0,0 +1,97 @@ +--- +id: common_issues +title: Common Issues +--- + +## Why is stdin being swallowed? + +Buck2 offers an interactive console by default. + +To disable either use an env var: `BUCK_NO_INTERACTIVE_CONSOLE` or a flag: +`--no-interactive-console` + +## Where is my output file? + +To find the location of output for a target, use +`buck2 build //foo:bar --show-output`. This will print the output corresponding +to each built target, in this case `//foo:bar output_path`. + +To only get the output path (without the target behorehand) you want to use +`buck2 build //foo:bar --show-simple-output`. + +The resultant path is relative to the root of the repo (such as +`~/repo_root/...`). For the full path use `--show-full-output` or +`--show-full-simple-output`. + +Note: in Buck1, the path is relative to the enclosing cell (such as +`~/repo_root/cell/...`). + + +For Meta, repo_root = fbsource, cell = fbcode/fbobjc/... + + +## Why is Buck2 hanging? + +If Buck2 seems to be doing nothing, it could be caused be a cycle in your +dependencies, which may cause Buck2 to hang (Buck2 does implement a form of +cycle detection, but it unfortunately has false negatives). You can confirm this +by running Buck1, which will report cycles properly. + +## How do I get the commands Buck2 executed so I can reproduce them in isolation? + +For information, see +[Finding Commands that Buck2 Ran](../../developers/what-ran.md). + +## Are multiple concurrent commands supported? + +Yes, they are supported. There are 2 types of concurrent commands: 1) parallel +invocations, and 2) recursive invocations. + +**Parallel invocations:** + +If the state of all the commands are the same, then they will run at the same +time. "State" is referring to the same configs and source files. If the state is +different amongst the commands, then buck2 will block the commands properly such +that the states do not interfere with each other. Different states are caused by +source file changes or config changes (ex: using a different mode). + +**Recursive invocations:** + +A recursive invocation is when an outer buck2 command ends up calling another +buck2 command as it's running. Recursive invocations are most commonly seen with +genrules and tests. For example: + +- If you have a `genrule` where the command contains a `buck2 cquery`, and you + build the genrule with `buck2 build`, you have a recursive invocation where + the outer command is `buck2 build` and the inner command is `buck2 cquery` +- If you have a test which contains `buck2 build`, and you run your test with + `buck2 test`, you have a recursive invocation where the outer command is + `buck2 test` and the inner command is `buck2 build` + +Recursive invocations should specify an `--isolation-dir`, or else buck2 will +return an error. + +## Why did my build OOM? + +If your build OOMs, you can check the last actions running by using +`buck2 log whatup`. This will print the superconsole state at the moment the +event log ended, which will indicate what actions were being run (and consuming +memory) when your machine ran out of memory. + +You can also use the `--after ` option to see all open spans at a +certain point in time of the build. + +## Why does my target not have any outputs? + +If you see that your build succeeded, but the console message stated that your +target did not have any outputs, this means that the underlying rule did not +declare any outputs artifacts, defined as outputs declared in: + +- `default_outputs` and/or `other_outputs` in `DefaultInfo` +- `cmd_args` in `RunInfo` +- `cmd_args` inside the `command` in `ExternalRunnerTestInfo` + +For example, building a target which uses a `python_library` rule merely groups +source files together and does not generate any output artifacts such as a +python executable. You would need to build a `python_binary` which uses that +library in order to get an output. diff --git a/_src/users/faq/starlark_peak_mem.md b/_src/users/faq/starlark_peak_mem.md new file mode 100644 index 000000000000..a90fa2677556 --- /dev/null +++ b/_src/users/faq/starlark_peak_mem.md @@ -0,0 +1,168 @@ +--- +id: starlark_peak_mem +title: Debugging Excess Starlark Peak Memory +--- + +## Wut memory? + +Peak memory is the maximum amount of memory used during evaluation of that +particular Starlark file. The memory is usually released after we finish the +evaluation of the file. Because Starlark is only garbage collected in between +top-level statements in the BUCK file, but not garbage collected inside function +calls/macros, on large servers with 64 hardware threads (or more), memory usage +might accumulate, causing slowdowns or OOMs or even SEVs (e.g. +S372092). See +[this post](https://fb.workplace.com/groups/1267349253953900/permalink/1312921066063385/) +for more details on how Starlark's current GC works . + +To prevent such issues until proper GC is implemented, we have set a hard `2GB` +memory limit for Starlark's evaluation of build files. This is a per-file limit. + +Note that this is different than the actual process memory which might include +other things apart from Starlark’s evaluation. + +## How do I see my build file's peak memory usage? + +To see the Starlark peak memory usage of a build file, you can inspect the event +log for your build file. Here is an example entry from the event log for buck2 +uquery `target` showing that it uses 1.5GB: + +``` +{"Event":{..."data":{"Load":{"module_id":"target:BUCK","cell":"...","error":null,"starlark_peak_allocated_bytes":1610608640}}}}}} +``` + +## Profiler to the rescue! + +If you want to see more detailed breakdown where the memory is used, you should +profile Starlark's evaluation of build files. See +[this page](../../rule_authors/optimization.md/#starlark-profiling) for details +of profiling in the loading stage. This is a great starting point for +troubleshooting. + +## How do I reduce memory footprint? + +There are many reasons why Starlark's evaluation of your build file might use a +lot of memory. We list a few common cases below but there might be more +cases. See +[this post](https://fb.workplace.com/groups/buck2eng/permalink/3309329642697846/) +for a few real world examples of debugging Starlark peak memory usage of core +Android macros that have saved over 5.7GB peak memory! + +High level guidance is to pay attention to loops as a starting point. Are there +any unnecessary computations? Can you shave them off? + +### Repeatedly allocating memory unnecessarily in a loop + +A common case where memory usage might accumulate is repeatedly allocating +memory in a loop. For instance, below we call a memory intensive function in a +loop unnecessarily: + +``` +for target in huge_target_list: + memory_intensive_fun(x,y) + ... +``` + +Instead, if we know that arguments `x` and `y` don't change, we could hoist the +call to `memory_intensive_fun` outside of the loop as follows: + +``` +memory_intensive_fun(x,y) +for target in huge_target_list: + ... +``` + +### Simply allocating very big data-structures! + +Another reason why Starlark uses a lot of memory could simply be because the +build file allocates a very big-data structure. For instance, below we allocate +a list with 1 billion integers! + +``` +million_list = [1 for i in range(1 << 20)] +billion_list = million_list * (1 << 10) + +``` + +As a workaround, could you think of splitting the list? + +### Algorithmically inefficient code + +Another reason could be because memory efficiency of your code is bad, i.e. you +are unnecessarily allocating a lot of memory. Let's look at an example where we +try to process a bunch of targets inefficiently: + +``` +targets = generate_targets(n) +for target in targets: + process(target) + +``` + +If `targets` list is big **and** each target takes a lot of space in memory, +memory usage might exceed the limit. Instead, a more efficient version might be +to process each target as you generate it: + +``` +for i in range(n): + target = generate_target(i) + process(target) +``` + +In this version, each target is processed as it is generated so we never need to +store more than one target in memory. + +### Usage of inefficient library calls + +A more subtle reason could be unknowingly invoking library calls that allocate +each time they are called. A well-known case of this is the `dict.items()` call. + +``` +for project, version in constraints.items(): + # process each project .... +``` + +We do an allocation on every call to `constraints.items()`. Especially if this +is a hot code in Starlark, this could cause an OOM. Instead, a potential fix is +to hoist the call out: + +``` +constraints = constraints.items() +for project, version in constraints: + # process each project .... +``` + +However, you need to ensure that the dictionary is not mutated inside, otherwise +you would get functionally different code. A similar case occurs for +`dict.keys()` where it returns a new list for containing the keys. + +### Allocating for rare cases + +Finally, another pattern is allocating memory for the rare cases. For instance, +consdier the following example + +``` +for target in huge_target_list: + if memory_intensive_condition([target]) + fail(...) +``` + +Above program could be optimized as follows: + +``` +if memory_intensive_condition(huge_target_list) + for target in huge_target_list: + if memory_intensive_condition([target]) + fail(...) +``` + +so that in the common non-failure case, we don't end up allocating excessive +memory. + +## I still need more help! + +If you still can not figure out how to reduce Starlark memory footprint of your +build files, please post in +[Buck2 Users](https://fb.workplace.com/groups/buck2users)raise +[an issue](https://github.com/facebook/buck2/issues) in our Github +project. diff --git a/_src/users/remote_execution.md b/_src/users/remote_execution.md new file mode 100644 index 000000000000..1d72fa14d91a --- /dev/null +++ b/_src/users/remote_execution.md @@ -0,0 +1,72 @@ +--- +id: remote_execution +title: Remote Execution +--- + +Buck2 can use services that expose +[Bazel's remote execution API](https://github.com/bazelbuild/remote-apis) in +order to run actions remotely. + +Buck2 projects have been successfully tested for remote execution against +[EngFlow](https://www.engflow.com/), +[BuildBarn](https://github.com/buildbarn/bb-remote-execution) and +[BuildBuddy](https://www.buildbuddy.io). Sample project configurations for those +providers are available under +[examples/remote_execution](https://github.com/facebook/buck2/tree/main/examples/remote_execution). + +## RE configuration in `.buckconfig` + +Configuration for remote execution can be found under `[buck2_re_client]` in +`.buckconfig`. + +Keys supported include: + +- `engine_address` - address to your RE's engine. +- `action_cache_address` - address to your action cache endpoint. +- `cas_address` - address to your content-addressable storage (CAS) endpoint. +- `tls_ca_certs` - path to a CA certificates bundle. This must be PEM-encoded. + If none is set, a default bundle will be used. This path contains environment + variables using shell interpolation syntax (i.e. $VAR). They will be + substituted before reading the file. +- `tls_client_cert` - path to a client certificate (and intermediate chain), as + well as its associated private key. This must be PEM-encoded. This path can + contain environment variables using shell interpolation syntax (i.e. $VAR). + They will be substituted before reading the file. +- `http_headers` - HTTP headers to inject in all requests to RE. This is a + comma-separated list of `Header: Value` pairs. Minimal validation of those + headers is done here. This can contain environment variables using shell + interpolation syntax ($VAR). They will be substituted before reading the file. +- `instance_name` - an instance name to pass on execution, action cache, and CAS + requests. + +Buck2 uses `SHA256` for all its hashing by default. If your RE engine requires +something else, this can be configured in `.buckconfig` as follows: + +```ini +[buck2] +# Accepts BLAKE3, SHA1, or SHA256 +digest_algorithms = BLAKE3 +``` + +## RE platform configuration + +Next, your build will need an +[execution platform](https://buck2.build/docs/concepts/glossary/#execution-platform) +that specifies how and where actions should be executed. For a sample platform +definition that sets up an execution platform to utilize RE, take a look at the +[EngFlow example](https://github.com/facebook/buck2/blob/main/examples/remote_execution/engflow/platforms/defs.bzl), +[BuildBarn example](https://github.com/facebook/buck2/blob/main/examples/remote_execution/buildbarn/platforms/defs.bzl), +or the +[BuildBuddy example](https://github.com/facebook/buck2/blob/main/examples/remote_execution/buildbuddy/platforms/defs.bzl). + +To enable remote execution, configure the following fields in +[CommandExecutorConfig](https://buck2.build/docs/api/build/globals/#commandexecutorconfig) +as follows: + +- `remote_enabled` - set to `True`. +- `local_enabled` - set to `True` if you also want to run actions locally. +- `use_limited_hybrid` - set to `False` unless you want to exclusively run + remotely when possible. +- `remote_execution_properties` - other additional properties. + - If the RE engine requires a container image, this can be done by setting + `container-image` to an image URL, as is done in the example above. diff --git a/_src/why.md b/_src/why.md new file mode 100644 index 000000000000..e3c2aa353cd4 --- /dev/null +++ b/_src/why.md @@ -0,0 +1,148 @@ +--- +id: why +title: Why Buck2 +--- + +Buck2 is a build system from Meta. This page answers the questions: +[why does Buck2 exist](#why-does-buck2-exist), +[what's different about Buck2](#whats-different-about-buck2), and +[why use Buck2](#why-use-buck2). + +## Why does Buck2 exist? + +Meta employs a very large monorepo, consisting of a variety of programming +languages, including C++, Python, Rust, Kotlin, Swift, Objective-C, Haskell, +OCaml, and more. Google employs a different but functionally similar monorepo. + +These large scale and multi-language repositories are generally beyond the +capabilities of traditional build systems like `make`. To optimize the build and +performance of these large systems, Facebook and Google developed their own +build systems, respectively Buck and Bazel. While the internal version of Bazel +was started first (also known as Blaze), Buck was open sourced first (back in +March 2013), followed by Bazel a few years later (March 2015). + +The retroactively named Buck1 was a capable build system and is still in use +today at Meta (although many users have migrated). Buck2 is a rewrite that aims +to keep the best bits of Buck1 (with a high degree of target compatibility) but +also borrows ideas from [academic](https://ndmitchell.com/#shake_10_sep_2012) +[research](https://ndmitchell.com/#shake_21_apr_2020) and build systems, +including [Bazel](https://bazel.build/), [Pants](https://www.pantsbuild.org/), +[Shake](https://shakebuild.com/), [Tup](https://gittup.org/tup/), and more. + +Following are aspects common to Buck1 and Buck2 (and in most cases, Bazel): + +- **Targets that can be queried** - the build is defined as a series of targets, + specified in `BUCK` files, that depend on other targets. This graph of targets + can be queried to understand how they relate to each other and what the + potential impact of a change might be. +- **Remote execution** - the build can send actions to a set of remote servers + to be executed, increasing the parallelism significantly. +- **Multi-language composability** - there can be lots of different languages in + a single build, and they can be put together. For example, you could have a + Python library that depends on a Rust library, which, in turn depends on a C + library. +- **File watching** - at large enough scale, simply looking for changed files is + prohibitively expensive. Buck can integrate with + [Watchman](https://facebook.github.io/watchman/) to discover which files have + changed efficiently. However, for simplicity of setup, the open-source version + defaults to using `inotify` or similar functionality. +- **Uses Starlark** - Starlark is a deterministic Python-like language used to + specify the targets, enabling the definition of targets as literals and more + advanced manipulation/sharing. + +## What's different about Buck2? + +Buck2 has many minor differences from Buck1, but there are a number that give +new efficiency or expressiveness that are of note (most of these are also +differences from Bazel). + +- **Buck2 is written in Rust** - Buck1 was written in Java. One of the + advantages of using Rust is the absence of GC pauses, However, Java also has + advantages, such as better memory profiling tools. +- **Buck2 is remote execution first** - local execution is considered a special + case of remote execution, in contrast to Buck1 where it was added after. That + means that things such as directory hashes can be pre-computed ready to send + to remote execution, giving efficiency benefits. +- **All Buck2 rules are written in Starlark** - whereas, in Buck1, they were + written in Java as part of the binary, which makes iteration on rules much + faster. +- **The Buck2 binary is entirely language agnostic** - as a consequence of + having all the rules external to the binary, the most important and complex + rule (such as in C++), don't have access to magic internal features. As a + result, features have been made available to all rules, including: + - [Dep files](rule_authors/dep_files.md) - the ability to declare that a + subset of the files weren't actually used, and thus not be sensitive to + changes within them. + - [Incremental actions](rule_authors/incremental_actions.md) - the ability to + have the action short-circuit some subset of the work if run again. +- **Buck2 uses a dynamic (aka monadic) graph as its underlying computation + engine** - while most dependencies are specified statically, there are two + particular features that expose dynamic power to rule authors: + - [Dynamic dependencies](rule_authors/dynamic_dependencies.md) - enable rules + to build a file then look at its contents before specifying the dependencies + and steps in future actions. Common uses are languages where the dependency + structure within a project must follow imports (e.g. Haskell, OCaml) and + distributed ThinLTO (where the best optimization plan is generated from + summaries). + - [Anonymous targets](rule_authors/anon_targets.md) - enable rules to create a + graph that has more sharing than the original user graph. As a result, two + unrelated binaries can compile shared code only once, despite the shared + code not knowing about this commonality. This feature is useful for rules + like Swift feature resolution. +- **[Transitive-sets](rule_authors/transitive_sets.md)** - similar in purpose to + Bazel's [depset](https://bazel.build/rules/lib/depset). But, instead of being + just a memory optimization, are also wired into the dependency graph, + providing a reduction in the size of the dependency graph. +- **Buck2 is not phased** - there are no target graph/action graph phases, just + a series of dependencies in a + [single graph on DICE](https://github.com/facebook/buck2/blob/main/dice/dice/docs/index.md) + that result in whatever the user requested. That means that Buck2 can + sometimes parallelise different phases and track changes very precisely. +- **Buck2 can integrate with the virtual filesystem + [Eden](https://github.com/facebook/sapling)** - this provides good + performance, even when the file system is backed by source control fetches. + However, Eden is not required, and a normal file system will also work well. +- **The Buck2 Starlark implementation is available + [as a standalone library](https://developers.facebook.com/blog/post/2021/04/08/rust-starlark-library/)** - + this provides features such as IDE integration (both LSP and DAP bindings), + linters, typecheckers, and more. These features are integrated into Buck2 to + give a better developer experience (which is still evolving). +- **Buck2 supports configurations** - (such as `select`) to provide + multi-platform/architecture builds, which are heavily inspired by Bazel. + Within that space, there is a number of small differences, such as + `toolchain_deps`. +- **Buck2 is fast** - in our internal tests, we observed that Buck2 completed + builds 2x as fast as Buck1. + +For a comprehensive list of benefits, see +[Benefits Compared to Buck1](benefits.md). + +## Why use Buck2? + +It would be delightful if you tried out Buck2! But it is early-stage software, +so users may run into unexpected issues. If you encounter an issue, please +report it via [Github issues](https://github.com/facebook/buck2/issues). + +Buck2 is being used internally within Meta and is available as open-source +from 2023. + +There are several differences between the internal and open-source versions: + +- Meta uses an internal version of remote execution with builds always hooked up + to remote execution. The open-source binding, which uses Buck2 without remote + execution, may be less polished. +- There are some configuration differences between the open source and internal + versions. For example, file changes default to `inotify` in open-source, and + to Watchman internally. +- The prelude (containing all the rules) is the same for open-source as + internal, but toolchains are not open-sourced. The required custom toolchains + may not work as well. + +There are also some things that aren't quite yet finished: + +- There are not yet mechanisms to build in release mode (that should be achieved + by modifying the toolchain). +- Windows/Mac builds are still in progress; open-source code is mostly tested on + Linux. + +If none of that puts you off, [give Buck2 a go](getting_started.md)! diff --git a/assets/css/styles.96950b1b.css b/assets/css/styles.96950b1b.css new file mode 100644 index 000000000000..7a0fbdfa7336 --- /dev/null +++ b/assets/css/styles.96950b1b.css @@ -0,0 +1 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}body,ol ol,ol ul,ul ol,ul ul{margin:0}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}*,.FeedbackButton_oOHZ,.algolia-autocomplete .ds-dropdown-menu *{box-sizing:border-box}.searchbox__reset:focus,.searchbox__submit:focus,body:not(.navigation-with-keyboard) :not(input):focus{outline:0}pre,table{overflow:auto}.markdown li,body{word-wrap:break-word}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#4566a4;--ifm-color-primary-dark:#21af90;--ifm-color-primary-darker:#1fa588;--ifm-color-primary-darkest:#1a8870;--ifm-color-primary-light:#46cbae;--ifm-color-primary-lighter:#66d4bd;--ifm-color-primary-lightest:#92e0d0;--ifm-code-font-size:95%;--docusaurus-announcement-bar-height:auto;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul,.tabList__CuJ{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_tbUL,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area.breadcrumbs__link[href]:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_S0QG>:last-child,.collapsibleContent_i85q>:last-child,.footer__items,.tabItem_Ymn6>:last-child{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter);content:""}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.cta_wrapper_gL2E,.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-duration:.25s;transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-duration:.1s;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec;--ifm-color-primary:#88aaeb}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}.docusaurus-highlight-code-line{background-color:#0000001a;display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}html[data-theme=dark] .docusaurus-highlight-code-line{background-color:#0000004d}.button{margin:0 10px}table.starlark_members_table td:first-child{max-width:0;width:20%}table.starlark_members_table td:nth-child(2){width:45%}table.starlark_members_table td:nth-child(3){max-width:0;width:30%}#docusaurus-base-url-issue-banner-container,.themedImage_ToTc,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}[data-theme=dark] .themedImage--dark_i4oU,[data-theme=light] .themedImage--light_HNdA{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity .2s ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:.15s;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.CodeBlockFilenameTab_T2zd{border:1px solid var(--ifm-color-primary-contrast-foreground);border-radius:8px 8px 0 0;color:var(--ifm-color-primary-contrast-foreground);font-weight:300;padding:6px 10px}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.img_ev3q{height:auto}.admonition_LlT9{margin-bottom:1em}.admonitionHeading_tbUL{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.3rem}.admonitionHeading_tbUL code{text-transform:none}.admonitionIcon_kALy{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_kALy svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.button_ipBY{background-color:var(--ifm-color-primary-dark);border:2px solid #0000;border-radius:6px;color:#fff;cursor:pointer;display:inline-block;font-size:14px;padding:12px 27px;text-align:center;text-decoration:none}.button_ipBY:hover{background-color:#fff;border:2px solid var(--ifm-color-primary-dark);color:var(--ifm-color-primary-dark)}.button_ipBY:disabled{cursor:not-allowed;opacity:.6}.editor_ksb3{grid-gap:12px;display:grid;grid-template-areas:"c c" "d e";grid-template-columns:50% 50%}.editor_header_k1u9{align-content:center;align-items:baseline;display:flex;grid-area:c;justify-content:space-between}.cta_wrapper_gL2E>*+*{margin-left:8px}.editor_input_J9Qe{background:#3a3b3c;grid-area:d}.editor_preview_IykG{grid-area:e}.preview_fail_note_lUiM{border:1px solid #f6f6f6;color:var(--ifm-color-primary-dark);width:50%}.live_editor_gff9{background-color:#3a3b3c;caret-color:#fff;font-family:Roboto Mono,Menlo,monospace;font-size:14px;min-height:400px}.live_error_EIYU{background:none;color:red;font-family:monospace;font-size:1em;padding:10px;white-space:break-spaces}.live_preview_LmGk{border:1px solid #fff;padding:10px}.unknown_component_htsO{background-color:#ffe9e9;border:2px solid #ff7e7e;border-radius:var(--ifm-global-radius);margin-bottom:8px;padding:2px 8px}.unknown_component_children_WmeU{border:2px solid var(--collapse-button-bg-color-dark);border-radius:var(--ifm-global-radius);padding:4px 8px;position:relative}.unknown_component_children_WmeU:before{background:var(--collapse-button-bg-color-dark);border-bottom-left-radius:var(--ifm-global-radius);color:var(--ifm-color-primary-contrast-background);content:"children";display:block;padding:0 4px;position:absolute;right:0;top:-1px}.filepath_validation_list_jJSD{color:#ea0000}.FeedbackButton_oOHZ{background-color:#e4e6eb;border:0 solid #e2e8f0;border-radius:1.5rem;color:#000;cursor:pointer;display:inline-block;font-size:16px;font-weight:600;line-height:1;padding:1rem 1.6rem;text-align:center;touch-action:manipulation;user-select:none;-webkit-user-select:none}.FeedbackButton_oOHZ:hover{background-color:#828282}.FeedbackIcon_kE_h{height:13px;padding-right:5px}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docSidebarContainer_b6E3,.sidebarLogo_isFc{display:none}.docMainContainer_gTbr,.docPage__5DB{display:flex;width:100%}.docsWrapper_BCFX{display:flex;flex:1 0 auto}.heroBanner_qdFl{overflow:hidden;padding:4rem 0;position:relative;text-align:center}.buttons_AeoN{justify-content:center}.buttons_AeoN,.features_xdhU{align-items:center;display:flex}.searchbox,.searchbox__input{box-sizing:border-box;display:inline-block}.features_xdhU{padding:2rem 0;width:100%}.featureSvg__8YW{height:200px;width:200px}.algolia-docsearch-suggestion{border-bottom-color:#3a3dd1}.algolia-docsearch-suggestion--category-header{background-color:#4b54de}.algolia-docsearch-suggestion--highlight{color:#3a33d1}.algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight{background-color:#4d47d5}.aa-cursor .algolia-docsearch-suggestion--content{color:#272296}.aa-cursor .algolia-docsearch-suggestion{background:#ebebfb}.searchbox{height:32px!important;position:relative;visibility:visible!important;white-space:nowrap;width:200px}.searchbox .algolia-autocomplete{display:block;height:100%;width:100%}.searchbox__wrapper{height:100%;position:relative;width:100%;z-index:999}.searchbox__input{-webkit-appearance:none;appearance:none;background:#fff!important;border:0;border-radius:16px;box-shadow:inset 0 0 0 1px #ccc;font-size:12px;height:100%;padding:0 26px 0 32px;transition:box-shadow .4s,background .4s;vertical-align:middle;white-space:normal;width:100%}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{background:#fff;box-shadow:inset 0 0 0 1px #aaa;outline:0}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{background-color:#458ee100;border:0;border-radius:16px 0 0 16px;font-size:inherit;height:100%;left:0;margin:0;padding:0;position:absolute;right:inherit;text-align:center;top:0;-webkit-user-select:none;user-select:none;vertical-align:middle;width:32px}.searchbox__submit:before{content:"";display:inline-block;height:100%;margin-right:-4px;vertical-align:middle}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion,.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit svg{fill:#6d7e96;height:14px;vertical-align:middle;width:14px}.searchbox__reset{fill:#00000080;background:none;border:0;cursor:pointer;display:block;font-size:inherit;margin:0;padding:0;position:absolute;right:8px;top:8px;-webkit-user-select:none;user-select:none}.searchbox__reset.hide{display:none}.searchbox__reset svg{display:block;height:8px;margin:4px;width:8px}.searchbox__input:valid~.searchbox__reset{animation-duration:.15s;animation-name:a;display:block}@keyframes a{0%{opacity:0;transform:translate3d(-20%,0,0)}to{opacity:1;transform:none}}.algolia-autocomplete .ds-dropdown-menu:before{background:#373940;border-radius:2px;border-right:1px solid #373940;border-top:1px solid #373940;content:"";display:block;height:14px;position:absolute;top:-7px;transform:rotate(-45deg);width:14px;z-index:1000}.algolia-autocomplete .ds-dropdown-menu{box-shadow:0 1px 0 0 #0003,0 2px 3px 0 #0000001a}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{background:#fff;border-radius:4px;overflow:auto;padding:0;position:relative}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;overflow:hidden;padding:0;position:relative;text-decoration:none}.algolia-autocomplete .ds-cursor .algolia-docsearch-suggestion--wrapper{background:#f1f1f1;box-shadow:inset -2px 0 0 #61dafb}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{background:#ffe564;padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight{background:inherit;color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{background:inherit;box-shadow:inset 0 -2px 0 0 #458ee1cc;color:inherit;padding:0 0 1px}.algolia-autocomplete .algolia-docsearch-suggestion--content{cursor:pointer;display:block;float:right;padding:5.33333px 0 5.33333px 10.66667px;position:relative;width:70%}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{background:#ececec;content:"";display:block;height:100%;left:-1px;position:absolute;top:0;width:1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{background-color:#373940;color:#fff;display:none;font-size:14px;font-weight:700;letter-spacing:.08em;margin:0;padding:5px 8px;position:relative;text-transform:uppercase}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{background-color:#fff;float:left;padding:8px 0 0;width:100%}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{word-wrap:break-word;color:#777;display:none;float:left;font-size:.9em;padding:5.33333px 10.66667px;position:relative;text-align:right;width:30%}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{background:#ececec;content:"";display:block;height:100%;position:absolute;right:0;top:0;width:1px}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before,.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column .algolia-docsearch-suggestion--highlight{background-color:inherit;color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--title{color:#02060c;font-size:.9em;font-weight:700;margin-bottom:4px}.algolia-autocomplete .algolia-docsearch-suggestion--text{color:#63676d;display:block;font-size:.85em;line-height:1.2em;padding-right:2px}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{background-color:#373940;font-size:1.2em;margin-top:-8px;padding:8px 0;text-align:center;width:100%}.algolia-autocomplete .algolia-docsearch-suggestion--no-results .algolia-docsearch-suggestion--text{color:#fff;margin-top:4px}.algolia-autocomplete .algolia-docsearch-suggestion code{background-color:#ebebeb;border:none;border-radius:3px;color:#222;font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace;font-size:90%;padding:1px 5px}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header{color:#fff;display:block}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary .algolia-docsearch-suggestion--subcategory-column{display:block}.algolia-autocomplete .algolia-docsearch-footer{background-color:#fff;float:right;font-size:0;height:30px;line-height:0;width:100%;z-index:2000}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 130 18'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='url(%2523a)' d='M59.4.02h13.3a2.37 2.37 0 0 1 2.38 2.37V15.6a2.37 2.37 0 0 1-2.38 2.36H59.4a2.37 2.37 0 0 1-2.38-2.36V2.38A2.37 2.37 0 0 1 59.4.02z'/%3E%3Cpath fill='%2523FFF' d='M66.26 4.56c-2.82 0-5.1 2.27-5.1 5.08 0 2.8 2.28 5.07 5.1 5.07 2.8 0 5.1-2.26 5.1-5.07 0-2.8-2.28-5.07-5.1-5.07zm0 8.65c-2 0-3.6-1.6-3.6-3.56 0-1.97 1.6-3.58 3.6-3.58 1.98 0 3.6 1.6 3.6 3.58a3.58 3.58 0 0 1-3.6 3.57zm0-6.4v2.66c0 .07.08.13.15.1l2.4-1.24c.04-.02.06-.1.03-.14a2.96 2.96 0 0 0-2.46-1.5.1.1 0 0 0-.1.1zm-3.33-1.96-.3-.3a.78.78 0 0 0-1.12 0l-.36.36a.77.77 0 0 0 0 1.1l.3.3c.05.05.13.04.17 0 .2-.25.4-.5.6-.7.23-.23.46-.43.7-.6.07-.04.07-.1.03-.16zm5-.8V3.4a.78.78 0 0 0-.78-.78h-1.83a.78.78 0 0 0-.78.78v.63c0 .07.06.12.14.1a5.74 5.74 0 0 1 1.58-.22c.52 0 1.04.07 1.54.2a.1.1 0 0 0 .13-.1z'/%3E%3Cpath fill='%2523182359' d='M102.16 13.76c0 1.46-.37 2.52-1.12 3.2-.75.67-1.9 1-3.44 1-.56 0-1.74-.1-2.67-.3l.34-1.7c.78.17 1.82.2 2.36.2.86 0 1.48-.16 1.84-.5.37-.36.55-.88.55-1.57v-.35a6.37 6.37 0 0 1-.84.3 4.15 4.15 0 0 1-1.2.17 4.5 4.5 0 0 1-1.6-.28 3.38 3.38 0 0 1-1.26-.82 3.74 3.74 0 0 1-.8-1.35c-.2-.54-.3-1.5-.3-2.2 0-.67.1-1.5.3-2.06a3.92 3.92 0 0 1 .9-1.43 4.12 4.12 0 0 1 1.45-.92 5.3 5.3 0 0 1 1.94-.37c.7 0 1.35.1 1.97.2a15.86 15.86 0 0 1 1.6.33v8.46zm-5.95-4.2c0 .9.2 1.88.6 2.3.4.4.9.62 1.53.62.34 0 .66-.05.96-.15a2.75 2.75 0 0 0 .73-.33V6.7a8.53 8.53 0 0 0-1.42-.17c-.76-.02-1.36.3-1.77.8-.4.5-.62 1.4-.62 2.23zm16.13 0c0 .72-.1 1.26-.32 1.85a4.4 4.4 0 0 1-.9 1.53c-.38.42-.85.75-1.4.98-.54.24-1.4.37-1.8.37-.43 0-1.27-.13-1.8-.36a4.1 4.1 0 0 1-1.4-.97 4.5 4.5 0 0 1-.92-1.52 5.04 5.04 0 0 1-.33-1.84c0-.72.1-1.4.32-2 .22-.6.53-1.1.92-1.5.4-.43.86-.75 1.4-.98a4.55 4.55 0 0 1 1.78-.34 4.7 4.7 0 0 1 1.8.34c.54.23 1 .55 1.4.97.38.42.68.92.9 1.5.23.6.35 1.3.35 2zm-2.2 0c0-.92-.2-1.7-.6-2.22-.38-.54-.94-.8-1.64-.8-.72 0-1.27.26-1.67.8-.4.54-.58 1.3-.58 2.22 0 .93.2 1.56.6 2.1.38.54.94.8 1.64.8s1.25-.26 1.65-.8c.4-.55.6-1.17.6-2.1zm6.97 4.7c-3.5.02-3.5-2.8-3.5-3.27L113.57.92l2.15-.34v10c0 .25 0 1.87 1.37 1.88v1.8zm3.77 0h-2.15v-9.2l2.15-.33v9.54zM119.8 3.74c.7 0 1.3-.58 1.3-1.3 0-.7-.58-1.3-1.3-1.3-.73 0-1.3.6-1.3 1.3 0 .72.58 1.3 1.3 1.3zm6.43 1c.7 0 1.3.1 1.78.27.5.18.88.42 1.17.73.28.3.5.74.6 1.18.13.46.2.95.2 1.5v5.47a25.24 25.24 0 0 1-1.5.25c-.67.1-1.42.15-2.25.15a6.83 6.83 0 0 1-1.52-.16 3.2 3.2 0 0 1-1.18-.5 2.46 2.46 0 0 1-.76-.9c-.18-.37-.27-.9-.27-1.44 0-.52.1-.85.3-1.2.2-.37.48-.67.83-.9a3.6 3.6 0 0 1 1.23-.5 7.07 7.07 0 0 1 2.2-.1l.83.16V8.4c0-.25-.03-.48-.1-.7a1.5 1.5 0 0 0-.3-.58c-.15-.18-.34-.3-.58-.4a2.54 2.54 0 0 0-.92-.17c-.5 0-.94.06-1.35.13-.4.08-.75.16-1 .25l-.27-1.74c.27-.1.67-.18 1.2-.28a9.34 9.34 0 0 1 1.65-.14zm.18 7.74c.66 0 1.15-.04 1.5-.1V10.2a5.1 5.1 0 0 0-2-.1c-.23.03-.45.1-.64.2a1.17 1.17 0 0 0-.47.38c-.13.17-.18.26-.18.52 0 .5.17.8.5.98.32.2.74.3 1.3.3zM84.1 4.8c.72 0 1.3.08 1.8.26.48.17.87.42 1.15.73.3.3.5.72.6 1.17.14.45.2.94.2 1.47v5.48a25.24 25.24 0 0 1-1.5.26c-.67.1-1.42.14-2.25.14a6.83 6.83 0 0 1-1.52-.16 3.2 3.2 0 0 1-1.18-.5 2.46 2.46 0 0 1-.76-.9c-.18-.38-.27-.9-.27-1.44 0-.53.1-.86.3-1.22.2-.36.5-.65.84-.88a3.6 3.6 0 0 1 1.24-.5 7.07 7.07 0 0 1 2.2-.1c.26.03.54.08.84.15v-.35c0-.24-.03-.48-.1-.7a1.5 1.5 0 0 0-.3-.58c-.15-.17-.34-.3-.58-.4a2.54 2.54 0 0 0-.9-.15c-.5 0-.96.05-1.37.12-.4.07-.75.15-1 .24l-.26-1.75c.27-.08.67-.17 1.18-.26a8.9 8.9 0 0 1 1.66-.15zm.2 7.73c.65 0 1.14-.04 1.48-.1v-2.17a5.1 5.1 0 0 0-1.98-.1c-.24.03-.46.1-.65.18a1.17 1.17 0 0 0-.47.4c-.12.17-.17.26-.17.52 0 .5.18.8.5.98.32.2.75.3 1.3.3zm8.68 1.74c-3.5 0-3.5-2.82-3.5-3.28L89.45.92 91.6.6v10c0 .25 0 1.87 1.38 1.88v1.8z'/%3E%3Cpath fill='%25231D3657' d='M5.03 11.03c0 .7-.26 1.24-.76 1.64-.5.4-1.2.6-2.1.6-.88 0-1.6-.14-2.17-.42v-1.2c.36.16.74.3 1.14.38.4.1.78.15 1.13.15.5 0 .88-.1 1.12-.3a.94.94 0 0 0 .35-.77.98.98 0 0 0-.33-.74c-.22-.2-.68-.44-1.37-.72-.72-.3-1.22-.62-1.52-1C.23 8.27.1 7.82.1 7.3c0-.65.22-1.17.7-1.55.46-.37 1.08-.56 1.86-.56.76 0 1.5.16 2.25.48l-.4 1.05c-.7-.3-1.32-.44-1.87-.44-.4 0-.73.08-.94.26a.9.9 0 0 0-.33.72c0 .2.04.38.12.52.08.15.22.3.42.4.2.14.55.3 1.06.52.58.24 1 .47 1.27.67.27.2.47.44.6.7.12.26.18.57.18.92zM9 13.27c-.92 0-1.64-.27-2.16-.8-.52-.55-.78-1.3-.78-2.24 0-.97.24-1.73.72-2.3.5-.54 1.15-.82 2-.82.78 0 1.4.25 1.85.72.46.48.7 1.14.7 1.97v.67H7.35c0 .58.17 1.02.46 1.33.3.3.7.47 1.24.47.36 0 .68-.04.98-.1a5.1 5.1 0 0 0 .98-.33v1.02a3.87 3.87 0 0 1-.94.32 5.72 5.72 0 0 1-1.08.1zm-.22-5.2c-.4 0-.73.12-.97.38s-.37.62-.42 1.1h2.7c0-.48-.13-.85-.36-1.1-.23-.26-.54-.38-.94-.38zm7.7 5.1-.26-.84h-.05c-.28.36-.57.6-.86.74-.28.13-.65.2-1.1.2-.6 0-1.05-.16-1.38-.48-.32-.32-.5-.77-.5-1.34 0-.62.24-1.08.7-1.4.45-.3 1.14-.47 2.07-.5l1.02-.03V9.2c0-.37-.1-.65-.27-.84-.17-.2-.45-.28-.82-.28-.3 0-.6.04-.88.13a6.68 6.68 0 0 0-.8.33l-.4-.9a4.4 4.4 0 0 1 1.05-.4 4.86 4.86 0 0 1 1.08-.12c.76 0 1.33.18 1.7.5.4.33.6.85.6 1.56v4h-.9zm-1.9-.87c.47 0 .83-.13 1.1-.38.3-.26.43-.62.43-1.08v-.52l-.76.03c-.6.03-1.02.13-1.3.3s-.4.45-.4.82c0 .26.08.47.24.6.16.16.4.23.7.23zm7.57-5.2c.25 0 .46.03.62.06l-.12 1.18a2.38 2.38 0 0 0-.56-.06c-.5 0-.92.16-1.24.5-.3.32-.47.75-.47 1.27v3.1h-1.27V7.23h1l.16 1.05h.05c.2-.36.45-.64.77-.85a1.83 1.83 0 0 1 1.02-.3zm4.12 6.17c-.9 0-1.58-.27-2.05-.8-.47-.52-.7-1.27-.7-2.25 0-1 .24-1.77.73-2.3.5-.54 1.2-.8 2.12-.8.63 0 1.2.1 1.7.34l-.4 1c-.52-.2-.96-.3-1.3-.3-1.04 0-1.55.68-1.55 2.05 0 .67.13 1.17.38 1.5.26.34.64.5 1.13.5a3.23 3.23 0 0 0 1.6-.4v1.1a2.53 2.53 0 0 1-.73.28 4.36 4.36 0 0 1-.93.08zm8.28-.1h-1.27V9.5c0-.45-.1-.8-.28-1.02-.18-.23-.47-.34-.88-.34-.53 0-.9.16-1.16.48-.25.3-.38.85-.38 1.6v2.94h-1.26V4.8h1.26v2.12c0 .34-.02.7-.06 1.1h.08a1.76 1.76 0 0 1 .72-.67c.3-.16.66-.24 1.07-.24 1.43 0 2.15.74 2.15 2.2v3.86zM42.2 7.1c.74 0 1.32.28 1.73.82.4.53.62 1.3.62 2.26 0 .97-.2 1.73-.63 2.27-.42.54-1 .82-1.75.82s-1.33-.27-1.75-.8h-.08l-.23.7h-.94V4.8h1.26v2l-.02.64-.03.56h.05c.4-.6 1-.9 1.78-.9zm-.33 1.04c-.5 0-.88.15-1.1.45-.22.3-.34.8-.35 1.5v.08c0 .72.12 1.24.35 1.57.23.32.6.48 1.12.48.44 0 .78-.17 1-.53.24-.35.36-.87.36-1.53 0-1.35-.47-2.03-1.4-2.03zm3.24-.92h1.4l1.2 3.37c.18.47.3.92.36 1.34h.04l.18-.72 1.37-4H51l-2.53 6.73c-.46 1.23-1.23 1.85-2.3 1.85-.3 0-.56-.03-.83-.1v-1c.2.05.4.08.65.08.6 0 1.03-.36 1.28-1.06l.22-.56-2.4-5.94z'/%3E%3C/g%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100%;display:block;height:100%;margin-left:auto;margin-right:5px;overflow:hidden;text-indent:-9000px;width:110px}@media (min-width:601px){.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{left:inherit!important;right:0!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete .ds-dropdown-menu{background:#0000;border:none;border-radius:4px;height:auto;margin:6px 0 0;max-width:600px;min-width:500px;padding:0;position:relative;text-align:left;top:-6px;z-index:999}}@media (min-width:768px){.algolia-docsearch-suggestion{border-bottom-color:#7671df}.algolia-docsearch-suggestion--subcategory-column{border-right-color:#7671df;color:#4e4726}}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.searchBox_ZlJk{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn{max-width:75%!important}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_BlDH,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_m80_:focus,.expandButton_m80_:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_m80_{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_BlDH{transform:rotate(180deg)}.docSidebarContainer_b6E3{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_b3ry{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_Xe31{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_gTbr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_Uz_u{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_czyv{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media screen and (max-width:966px){.heroBanner_qdFl{padding:2rem}}@media (max-width:600px){.algolia-autocomplete .ds-dropdown-menu{display:block;left:auto!important;max-height:calc(100% - 5rem);max-width:calc(100% - 2rem);position:fixed!important;right:1rem!important;top:50px!important;width:600px;z-index:100}.algolia-autocomplete .ds-dropdown-menu:before{right:6rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/assets/images/simpleconsole-5bfa37b932256fce081a21ce4f4c4b92.gif b/assets/images/simpleconsole-5bfa37b932256fce081a21ce4f4c4b92.gif new file mode 100644 index 000000000000..079ae7038d5a Binary files /dev/null and b/assets/images/simpleconsole-5bfa37b932256fce081a21ce4f4c4b92.gif differ diff --git a/assets/images/superconsole-71265cd99fd66f981336092604efff94.gif b/assets/images/superconsole-71265cd99fd66f981336092604efff94.gif new file mode 100644 index 000000000000..f04a970e67d0 Binary files /dev/null and b/assets/images/superconsole-71265cd99fd66f981336092604efff94.gif differ diff --git a/assets/js/00acdd45.bcadd3ae.js b/assets/js/00acdd45.bcadd3ae.js new file mode 100644 index 000000000000..7417ebee5269 --- /dev/null +++ b/assets/js/00acdd45.bcadd3ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1796],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>c,MDXProvider:()=>g,mdx:()=>b,useMDXComponents:()=>p,withMDXComponents:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),d=function(e){return function(t){var n=p(t.components);return r.createElement(e,i({},t,{components:n}))}},p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},g=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),g=o,f=d["".concat(a,".").concat(g)]||d[g]||u[g]||i;return n?r.createElement(f,l(l({ref:t},c),{},{components:n})):r.createElement(f,l({ref:t},c))}));function b(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[f]="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const i={id:"digest_config"},a="digest_config type",l={unversionedId:"api/build/digest_config",id:"api/build/digest_config",title:"digest_config type",description:"digest\\config.allows\\blake3",source:"@site/../docs/api/build/digest_config.generated.md",sourceDirName:"api/build",slug:"/api/build/digest_config",permalink:"/docs/api/build/digest_config",draft:!1,tags:[],version:"current",frontMatter:{id:"digest_config"},sidebar:"manualSidebar",previous:{title:"dependency type",permalink:"/docs/api/build/dependency"},next:{title:"label type",permalink:"/docs/api/build/label"}},s={},c=[{value:"digest_config.allows_blake3",id:"digest_configallows_blake3",level:2},{value:"digest_config.allows_blake3_keyed",id:"digest_configallows_blake3_keyed",level:2},{value:"digest_config.allows_sha1",id:"digest_configallows_sha1",level:2},{value:"digest_config.allows_sha256",id:"digest_configallows_sha256",level:2}],d={toc:c};function p(e){let{components:t,...n}=e;return(0,o.mdx)("wrapper",(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.mdx)("h1",{id:"digest_config-type"},(0,o.mdx)("inlineCode",{parentName:"h1"},"digest_config")," type"),(0,o.mdx)("h2",{id:"digest_configallows_blake3"},"digest","_","config.allows","_","blake3"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-python"},"def digest_config.allows_blake3() -> bool\n")),(0,o.mdx)("hr",null),(0,o.mdx)("h2",{id:"digest_configallows_blake3_keyed"},"digest","_","config.allows","_","blake3","_","keyed"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-python"},"def digest_config.allows_blake3_keyed() -> bool\n")),(0,o.mdx)("hr",null),(0,o.mdx)("h2",{id:"digest_configallows_sha1"},"digest","_","config.allows","_","sha1"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-python"},"def digest_config.allows_sha1() -> bool\n")),(0,o.mdx)("hr",null),(0,o.mdx)("h2",{id:"digest_configallows_sha256"},"digest","_","config.allows","_","sha256"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-python"},"def digest_config.allows_sha256() -> bool\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0104ca5c.11d07519.js b/assets/js/0104ca5c.11d07519.js new file mode 100644 index 000000000000..1d5f2b72136c --- /dev/null +++ b/assets/js/0104ca5c.11d07519.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9557],{3905:(t,e,r)=>{r.r(e),r.d(e,{MDXContext:()=>u,MDXProvider:()=>d,mdx:()=>b,useMDXComponents:()=>c,withMDXComponents:()=>s});var n=r(67294);function a(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function i(){return i=Object.assign||function(t){for(var e=1;e=0||(a[r]=t[r]);return a}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(a[r]=t[r])}return a}var u=n.createContext({}),s=function(t){return function(e){var r=c(e.components);return n.createElement(t,i({},e,{components:r}))}},c=function(t){var e=n.useContext(u),r=e;return t&&(r="function"==typeof t?t(e):p(p({},e),t)),r},d=function(t){var e=c(t.components);return n.createElement(u.Provider,{value:e},t.children)},f="mdxType",h={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var r=t.components,a=t.mdxType,i=t.originalType,o=t.parentName,u=l(t,["components","mdxType","originalType","parentName"]),s=c(r),d=a,f=s["".concat(o,".").concat(d)]||s[d]||h[d]||i;return r?n.createElement(f,p(p({ref:e},u),{},{components:r})):n.createElement(f,p({ref:e},u))}));function b(t,e){var r=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var i=r.length,o=new Array(i);o[0]=m;var p={};for(var l in e)hasOwnProperty.call(e,l)&&(p[l]=e[l]);p.originalType=t,p[f]="string"==typeof t?t:a,o[1]=p;for(var u=2;u{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>p,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const i={id:"ensured_artifact"},o="ensured_artifact type",p={unversionedId:"api/bxl/ensured_artifact",id:"api/bxl/ensured_artifact",title:"ensured_artifact type",description:"An artifact that will be materialized to buck-out at the end of the bxl invocation. These artifacts can be printed to bxl's results. Doing so will print the path of the artifact rather than the standard representation.",source:"@site/../docs/api/bxl/ensured_artifact.generated.md",sourceDirName:"api/bxl",slug:"/api/bxl/ensured_artifact",permalink:"/docs/api/bxl/ensured_artifact",draft:!1,tags:[],version:"current",frontMatter:{id:"ensured_artifact"},sidebar:"manualSidebar",previous:{title:"digest_config type",permalink:"/docs/api/bxl/digest_config"},next:{title:"ensured_artifact_group type",permalink:"/docs/api/bxl/ensured_artifact_group"}},l={},u=[{value:"ensured_artifact.abs_path",id:"ensured_artifactabs_path",level:2},{value:"ensured_artifact.rel_path",id:"ensured_artifactrel_path",level:2}],s={toc:u};function c(t){let{components:e,...r}=t;return(0,a.mdx)("wrapper",(0,n.Z)({},s,r,{components:e,mdxType:"MDXLayout"}),(0,a.mdx)("h1",{id:"ensured_artifact-type"},(0,a.mdx)("inlineCode",{parentName:"h1"},"ensured_artifact")," type"),(0,a.mdx)("p",null,"An artifact that will be materialized to buck-out at the end of the bxl invocation. These artifacts can be printed to bxl's results. Doing so will print the path of the artifact rather than the standard representation."),(0,a.mdx)("p",null,"Ensured artifacts are serializable and hashable."),(0,a.mdx)("h2",{id:"ensured_artifactabs_path"},"ensured","_","artifact.abs","_","path"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-python"},"def ensured_artifact.abs_path()\n")),(0,a.mdx)("p",null,"Converts this artifact to be printed by its absolute path. Note that this will only print out the absolute path via ",(0,a.mdx)("inlineCode",{parentName:"p"},"ctx.output.print()"),". Starlark's ",(0,a.mdx)("inlineCode",{parentName:"p"},"print()")," will print out the display info for an ensured artifact."),(0,a.mdx)("p",null,"Sample usage:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-text"},'def _impl_abs_path(ctx):\n actions = ctx.bxl_actions().actions\n output = actions.write("my_output", "my_content")\n ensured = ctx.output.ensure(output) # currently defaults to creating an EnsuredArtifact with a relative path\n\n ensured_with_abs_path = ensured.abs_path() # create a new EnsuredArtifact with absolute path to reuse\n print(ensured_with_abs_path) # should return something like \n ctx.output.print(ensured_with_abs_path) # should return the absolute path of the artifact\n')),(0,a.mdx)("hr",null),(0,a.mdx)("h2",{id:"ensured_artifactrel_path"},"ensured","_","artifact.rel","_","path"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-python"},"def ensured_artifact.rel_path()\n")),(0,a.mdx)("p",null,"Converts this artifact to be printed by its path relative to the project root. Note that this will only print out the relative path via ",(0,a.mdx)("inlineCode",{parentName:"p"},"ctx.output.print()"),". Starlark's ",(0,a.mdx)("inlineCode",{parentName:"p"},"print()")," will print out the display info for an ensured artifact."),(0,a.mdx)("p",null,"Sample usage:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-text"},'def _impl_rel_path(ctx):\n actions = ctx.bxl_actions().actions\n output = actions.write("my_output", "my_content")\n ensured = ctx.output.ensure(output) # currently defaults to creating an EnsuredArtifact with a relative path\n\n ensured_with_rel_path = ensured.rel_path() # create a new EnsuredArtifact with relative path to reuse\n print(ensured_with_rel_path) # should return something like \n ctx.output.print(ensured_with_rel_path) # should return the relative path of the artifact\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/014949af.31eceace.js b/assets/js/014949af.31eceace.js new file mode 100644 index 000000000000..cfdb9ace6738 --- /dev/null +++ b/assets/js/014949af.31eceace.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6986],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>d,MDXProvider:()=>c,mdx:()=>g,useMDXComponents:()=>p,withMDXComponents:()=>u});var a=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(){return r=Object.assign||function(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var d=a.createContext({}),u=function(e){return function(t){var n=p(t.components);return a.createElement(e,r({},t,{components:n}))}},p=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(d.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,o=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=p(n),c=i,h=u["".concat(o,".").concat(c)]||u[c]||m[c]||r;return n?a.createElement(h,s(s({ref:t},d),{},{components:n})):a.createElement(h,s({ref:t},d))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[h]="string"==typeof e?e:i,o[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=n(87462),i=(n(67294),n(3905));const r={id:"dep_files",title:"Dep Files"},o=void 0,s={unversionedId:"rule_authors/dep_files",id:"rule_authors/dep_files",title:"Dep Files",description:"Dep files allow commands to declare which subset of their inputs were used when",source:"@site/../docs/rule_authors/dep_files.md",sourceDirName:"rule_authors",slug:"/rule_authors/dep_files",permalink:"/docs/rule_authors/dep_files",draft:!1,tags:[],version:"current",frontMatter:{id:"dep_files",title:"Dep Files"},sidebar:"manualSidebar",previous:{title:"PACKAGE Files",permalink:"/docs/rule_authors/package_files"},next:{title:"Why BXL",permalink:"/docs/developers/bxl"}},l={},d=[{value:"Use Cases",id:"use-cases",level:2},{value:"Using dep files",id:"using-dep-files",level:2},{value:"Declaring the dep files and associating inputs",id:"declaring-the-dep-files-and-associating-inputs",level:2},{value:"Producing the dep file",id:"producing-the-dep-file",level:2},{value:"Testing dep files",id:"testing-dep-files",level:2},{value:"Extra notes to the implementer",id:"extra-notes-to-the-implementer",level:2},{value:"Limitations",id:"limitations",level:3},{value:"Dep files don't need to be covering",id:"dep-files-dont-need-to-be-covering",level:3},{value:"Dep files are lazy",id:"dep-files-are-lazy",level:3},{value:"Dep files will traverse symlinks",id:"dep-files-will-traverse-symlinks",level:2}],u={toc:d};function p(e){let{components:t,...n}=e;return(0,i.mdx)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.mdx)("p",null,"Dep files allow commands to declare which subset of their inputs were used when\nthe command executed."),(0,i.mdx)("p",null,"When a command produces a dep file and is later invalidated due to an inputs\nchange, Buck2 uses the dep file to check whether the inputs that changed were in\nthe set that the command reported as having used. If none of the inputs that\nchanged were in that set, Buck2 omits re-running the command and reuses the\nprevious result."),(0,i.mdx)("h2",{id:"use-cases"},"Use Cases"),(0,i.mdx)("p",null,"Dep files are used to make dependencies finer grained than what exists in the\ntarget graph, but they're not a substitute for avoiding unused dependencies.\nThey're often useful when targets export many outputs (such as C++ headers) that\naren't all used by all their dependents."),(0,i.mdx)("p",null,"Dep files are currently used to skip recompilation steps in C++ when an unused\nheader changed. They're also used in Java to skip recompilation when an unused\nclass changed."),(0,i.mdx)("h2",{id:"using-dep-files"},"Using dep files"),(0,i.mdx)("p",null,"To use dep files, you need to do the following:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Declare what output is a dep file and associate it with your command."),(0,i.mdx)("li",{parentName:"ul"},"Declare which inputs are covered by the dep file (this can be a subset of your\ninputs)."),(0,i.mdx)("li",{parentName:"ul"},"Have your command produce the dep file in a format Buck2 can use.")),(0,i.mdx)("p",null,"You must also enable\n",(0,i.mdx)("a",{parentName:"p",href:"/docs/users/advanced/deferred_materialization"},"Deferred Materialization")," to use\ndep files."),(0,i.mdx)("h2",{id:"declaring-the-dep-files-and-associating-inputs"},"Declaring the dep files and associating inputs"),(0,i.mdx)("p",null,"To declare a dep file and associate it with your command, you need to tag your\nartifacts."),(0,i.mdx)("p",null,"Specifically, you'll tag the output (the dep file) and the inputs it covers, as\nshown in the following code:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-python"},'# First, create a tag\n\nheaders_tag = ctx.actions.artifact_tag()\n\n# Then, tag inputs and the dep file itself in your command line.\n# You do this using the `tag_artifacts` method on your tag.\n# This method does not mutate the input, it wraps it, so you use the output.\n# Any command-line-arg-like can be tagged.\n\ntagged_headers = headers_tag.tag_artifacts(headers)\n\ndep_file = ctx.actions.declare_output("deps").as_output()\ntagged_dep_file = headers_tag.tag_artifacts(dep_file)\n\n# Finally, declare your action.\n# Use the tagged artifacts as you would regular command-line-arg-likes.\n# Pass the tag in `dep_files` and give a name (this is used for logging).\n\nctx.actions.run(\n ["mycc", "-I", tagged_headers, "-MD", "-MF", tagged_dep_file, "-o", ...],\n dep_files = { "headers": headers_tag }\n)\n\n')),(0,i.mdx)("h2",{id:"producing-the-dep-file"},"Producing the dep file"),(0,i.mdx)("p",null,"Your command must produce dep files in the format Buck2 expects, which is simply\na list of all the inputs that were used, one per line."),(0,i.mdx)("p",null,"The paths must be the paths Buck2 would use for your inputs, which means paths\nrelative to the project root."),(0,i.mdx)("p",null,"If this is not the format your tool produces, use a wrapper to take whatever\noutput your command produces and rewrite it in the format Buck2 expects."),(0,i.mdx)("h2",{id:"testing-dep-files"},"Testing dep files"),(0,i.mdx)("p",null,"When writing a command that produces a dep file, you should test it! At a\nminimum, check that the inputs you expect are tagged properly."),(0,i.mdx)("p",null,"To do so, build your target, then use\n",(0,i.mdx)("inlineCode",{parentName:"p"},"buck2 audit dep-files TARGET CATEGORY IDENTIFIER"),", which will show you the set\nof inputs your command used and how they're tagged."),(0,i.mdx)("h2",{id:"extra-notes-to-the-implementer"},"Extra notes to the implementer"),(0,i.mdx)("h3",{id:"limitations"},"Limitations"),(0,i.mdx)("p",null,"Dep files only work if a previous invocation of the command is known to your\nBuck2 daemon. Dep files are dropped when the daemon restarts or when you run\n",(0,i.mdx)("inlineCode",{parentName:"p"},"buck2 debug flush-dep-files"),"."),(0,i.mdx)("p",null,"This means that, for example, if you change an unused header, then run a build\non a fresh daemon, Buck2 will still need to execute this command in order to\nidentify that the header was in fact unused. In contrast, if you did the build\n(and got a remote cache hit on the command), then applied your change and\nre-built, Buck2 would use the dep file on the second execution, and you wouldn't\nneed to execute anything."),(0,i.mdx)("h3",{id:"dep-files-dont-need-to-be-covering"},"Dep files don't need to be covering"),(0,i.mdx)("p",null,"It's OK for the dep file to only cover a subset of the inputs of your action.\nHowever, within that subset, the dep file must declare all the inputs that were\nused."),(0,i.mdx)("p",null,"If you fail to report some inputs you used, then your command will not re-run\nwhen they change, and you'll get stale output."),(0,i.mdx)("h3",{id:"dep-files-are-lazy"},"Dep files are lazy"),(0,i.mdx)("p",null,"Dep files aren't parsed by Buck2 unless the command needs to re-run. If the\ncommand ran on RE, they aren't even downloaded until then. This ensures dep\nfiles don't cause a performance hit unless they are used, at which point they\nstand a chance of giving a performance boost instead."),(0,i.mdx)("p",null,"This means that if you produce an invalid dep file, Buck2 will not report this\nuntil your command runs again, at which point Buck2 will report that the dep\nfile is invalid and refuse to proceed (note: you can unblock yourself using\n",(0,i.mdx)("inlineCode",{parentName:"p"},"buck2 debug flush-dep-files"),")."),(0,i.mdx)("p",null,"To flush out issues during development, you can pass ",(0,i.mdx)("inlineCode",{parentName:"p"},"--eager-dep-files")," to\nBuck2 to force Buck2 to parse your dep files as they are produced."),(0,i.mdx)("h2",{id:"dep-files-will-traverse-symlinks"},"Dep files will traverse symlinks"),(0,i.mdx)("p",null,"If your dep file reports that a symlink was used, Buck2 will track the symlink's\ntarget as covered by this dep file."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/01e98fbb.7e25563c.js b/assets/js/01e98fbb.7e25563c.js new file mode 100644 index 000000000000..aa6ba239d474 --- /dev/null +++ b/assets/js/01e98fbb.7e25563c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3907],{3905:(t,e,a)=>{a.r(e),a.d(e,{MDXContext:()=>s,MDXProvider:()=>f,mdx:()=>x,useMDXComponents:()=>d,withMDXComponents:()=>p});var r=a(67294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function i(){return i=Object.assign||function(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var s=r.createContext({}),p=function(t){return function(e){var a=d(e.components);return r.createElement(t,i({},e,{components:a}))}},d=function(t){var e=r.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):c(c({},e),t)),a},f=function(t){var e=d(t.components);return r.createElement(s.Provider,{value:e},t.children)},m="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},h=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,i=t.originalType,o=t.parentName,s=l(t,["components","mdxType","originalType","parentName"]),p=d(a),f=n,m=p["".concat(o,".").concat(f)]||p[f]||u[f]||i;return a?r.createElement(m,c(c({ref:e},s),{},{components:a})):r.createElement(m,c({ref:e},s))}));function x(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var i=a.length,o=new Array(i);o[0]=h;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[m]="string"==typeof t?t:n,o[1]=c;for(var s=2;s{a.r(e),a.d(e,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var r=a(87462),n=(a(67294),a(3905));const i={id:"artifact"},o="artifact type",c={unversionedId:"api/bxl/artifact",id:"api/bxl/artifact",title:"artifact type",description:"A single input or output file for an action.",source:"@site/../docs/api/bxl/artifact.generated.md",sourceDirName:"api/bxl",slug:"/api/bxl/artifact",permalink:"/docs/api/bxl/artifact",draft:!1,tags:[],version:"current",frontMatter:{id:"artifact"},sidebar:"manualSidebar",previous:{title:"aqueryctx type",permalink:"/docs/api/bxl/aqueryctx"},next:{title:"attrs type",permalink:"/docs/api/bxl/attrs"}},l={},s=[{value:"artifact.as_output",id:"artifactas_output",level:2},{value:"artifact.basename",id:"artifactbasename",level:2},{value:"artifact.extension",id:"artifactextension",level:2},{value:"artifact.is_source",id:"artifactis_source",level:2},{value:"artifact.owner",id:"artifactowner",level:2},{value:"artifact.project",id:"artifactproject",level:2},{value:"artifact.short_path",id:"artifactshort_path",level:2},{value:"artifact.with_associated_artifacts",id:"artifactwith_associated_artifacts",level:2},{value:"artifact.without_associated_artifacts",id:"artifactwithout_associated_artifacts",level:2}],p={toc:s};function d(t){let{components:e,...a}=t;return(0,n.mdx)("wrapper",(0,r.Z)({},p,a,{components:e,mdxType:"MDXLayout"}),(0,n.mdx)("h1",{id:"artifact-type"},(0,n.mdx)("inlineCode",{parentName:"h1"},"artifact")," type"),(0,n.mdx)("p",null,"A single input or output file for an action."),(0,n.mdx)("p",null,"There is no ",(0,n.mdx)("inlineCode",{parentName:"p"},".parent")," method on ",(0,n.mdx)("inlineCode",{parentName:"p"},"artifact"),", but in most cases\n",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_args(my_artifact).parent()")," can be used to similar effect."),(0,n.mdx)("h2",{id:"artifactas_output"},"artifact.as","_","output"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.as_output() -> output_artifact\n")),(0,n.mdx)("p",null,"Returns a ",(0,n.mdx)("inlineCode",{parentName:"p"},"StarlarkOutputArtifact")," instance, or fails if the artifact is either an ",(0,n.mdx)("inlineCode",{parentName:"p"},"Artifact"),", or is a bound ",(0,n.mdx)("inlineCode",{parentName:"p"},"Artifact")," (You cannot bind twice)"),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactbasename"},"artifact.basename"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.basename: str\n")),(0,n.mdx)("p",null,"The base name of this artifact. e.g. for an artifact at ",(0,n.mdx)("inlineCode",{parentName:"p"},"foo/bar"),", this is ",(0,n.mdx)("inlineCode",{parentName:"p"},"bar")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactextension"},"artifact.extension"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.extension: str\n")),(0,n.mdx)("p",null,"The file extension of this artifact. e.g. for an artifact at foo/bar.sh, this is ",(0,n.mdx)("inlineCode",{parentName:"p"},".sh"),". If no extension is present, ",(0,n.mdx)("inlineCode",{parentName:"p"},'""')," is returned."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactis_source"},"artifact.is","_","source"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.is_source: bool\n")),(0,n.mdx)("p",null,"Whether the artifact represents a source file"),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactowner"},"artifact.owner"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.owner: None | label\n")),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"Label")," of the rule that originally created this artifact. May also be None in the case of source files, or if the artifact has not be used in an action, or if the action was not created by a rule."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactproject"},"artifact.project"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.project(\n path: str,\n /,\n *,\n hide_prefix: bool = False\n) -> artifact\n")),(0,n.mdx)("p",null,"Create an artifact that lives at path relative from this artifact."),(0,n.mdx)("p",null,"For example, if artifact foo is a directory containing a file bar, then ",(0,n.mdx)("inlineCode",{parentName:"p"},'foo.project("bar")'),"\nyields the file bar. It is possible for projected artifacts to hide the prefix in order to\nhave the short name of the resulting artifact only contain the projected path, by passing\n",(0,n.mdx)("inlineCode",{parentName:"p"},"hide_prefix = True")," to ",(0,n.mdx)("inlineCode",{parentName:"p"},"project()"),"."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactshort_path"},"artifact.short","_","path"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.short_path: str\n")),(0,n.mdx)("p",null,"The interesting part of the path, relative to somewhere in the output directory. For an artifact declared as ",(0,n.mdx)("inlineCode",{parentName:"p"},"foo/bar"),", this is ",(0,n.mdx)("inlineCode",{parentName:"p"},"foo/bar"),"."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactwith_associated_artifacts"},"artifact.with","_","associated","_","artifacts"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.with_associated_artifacts(artifacts: list[artifact]) -> artifact\n")),(0,n.mdx)("p",null,"Returns a ",(0,n.mdx)("inlineCode",{parentName:"p"},"StarlarkArtifact")," instance which is identical to the original artifact, but with potentially additional artifacts. The artifacts must be bound."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactwithout_associated_artifacts"},"artifact.without","_","associated","_","artifacts"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.without_associated_artifacts() -> artifact\n")),(0,n.mdx)("p",null,"Returns a ",(0,n.mdx)("inlineCode",{parentName:"p"},"StarlarkArtifact")," instance which is identical to the original artifact, except with no associated artifacts"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/01f44ee0.45745c0e.js b/assets/js/01f44ee0.45745c0e.js new file mode 100644 index 000000000000..a06b67d81e6e --- /dev/null +++ b/assets/js/01f44ee0.45745c0e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6708],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>l,MDXProvider:()=>d,mdx:()=>b,useMDXComponents:()=>p,withMDXComponents:()=>c});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(){return o=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){return function(t){var n=p(t.components);return r.createElement(e,o({},t,{components:n}))}},p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=u(e,["components","mdxType","originalType","parentName"]),c=p(n),d=a,m=c["".concat(s,".").concat(d)]||c[d]||f[d]||o;return n?r.createElement(m,i(i({ref:t},l),{},{components:n})):r.createElement(m,i({ref:t},l))}));function b(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=h;var i={};for(var u in t)hasOwnProperty.call(t,u)&&(i[u]=t[u]);i.originalType=e,i[m]="string"==typeof e?e:a,s[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=n(87462),a=(n(67294),n(3905));const o={id:"query",title:"query"},s=void 0,i={unversionedId:"users/commands/query",id:"users/commands/query",title:"query",description:"These are the flags/commands under buck2 query and their --help output:",source:"@site/../docs/users/commands/query.generated.md",sourceDirName:"users/commands",slug:"/users/commands/query",permalink:"/docs/users/commands/query",draft:!1,tags:[],version:"current",frontMatter:{id:"query",title:"query"},sidebar:"manualSidebar",previous:{title:"profile",permalink:"/docs/users/commands/profile"},next:{title:"root",permalink:"/docs/users/commands/root"}},u={},l=[{value:"buck query",id:"buck-query",level:2}],c={toc:l};function p(e){let{components:t,...n}=e;return(0,a.mdx)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"These are the flags/commands under ",(0,a.mdx)("inlineCode",{parentName:"p"},"buck2 query")," and their ",(0,a.mdx)("inlineCode",{parentName:"p"},"--help")," output:"),(0,a.mdx)("h2",{id:"buck-query"},"buck query"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-text"},"Alias for `uquery`\n\nUsage: buck2-release query [OPTIONS] [QUERY_ARGS]...\n\nArguments:\n \n the query to evaluate\n\n [QUERY_ARGS]...\n list of literals for a multi-query (one containing `%s` or `%Ss`)\n\nOptions:\n -A, --output-all-attributes\n Output all attributes, equivalent of --output-attribute ''.\n \n Avoid using this flag in automation because it may be expensive to produce certain\n attributes, and because it makes harder to track which special attributes are used.\n\n -B, --output-basic-attributes\n Output basic attributes, namely those the user can supply, plus rule type and package name\n\n -a, --output-attribute \n Regular expressions to match attributes. Regular expressions are used in \"search\" mode, so\n for example empty string matches all attributes including special attributes.\n \n When using in automation, please specify the regular expression to match the attribute\n precisely, for example `--output-attribute '^headers$'` to make it easier to track which\n special attributes are used.\n\n --output-attributes ...\n Deprecated: Use `--output-attribute` instead.\n \n List of space-separated attributes to output, --output-attributes attr1 attr2.\n\n --json\n Output in JSON format\n\n --dot\n Output in Graphviz Dot format\n\n --dot-compact\n Output in a more compact format than Graphviz Dot\n\n --output-format \n Output format (default: list). \n \n dot - dot graph format. \n \n dot_compact - compact alternative to dot format. \n \n json - JSON format. \n \n starlark - targets are printed like starlark code that would produce them.\n \n \n [possible values: dot, json, dot_compact, starlark]\n\n --modifier \n This option is not used\n\n -h, --help\n Print help (see a summary with '-h')\n\nBuckconfig Options:\n -c, --config \n List of config options\n\n --config-file \n List of config file paths\n\n --fake-host \n [possible values: default, linux, macos, windows]\n\n --fake-arch \n [possible values: default, aarch64, x8664]\n\n --fake-xcode-version \n Value must be formatted as: version-build (e.g., 14.3.0-14C18 or 14.1-14B47b)\n\n --reuse-current-config\n Re-uses any `--config` values (inline or via modefiles) if there's a previous command,\n otherwise the flag is ignored.\n \n If there is a previous command and `--reuse-current-config` is set, then the old config is\n used, ignoring any overrides.\n \n If there is no previous command but the flag was set, then the flag is ignored, the\n command behaves as if the flag was not set at all.\n\n --exit-when-different-state\n Used for exiting a concurrent command when a different state is detected\n\n --preemptible \n Used to configure when this command could be preempted by another command\n \n [possible values: never, always, ondifferentstate]\n\nStarlark Options:\n --disable-starlark-types\n Disable runtime type checking in Starlark interpreter.\n \n This option is not stable, and can be used only locally to diagnose evaluation performance\n problems.\n\n --stack\n Record or show target call stacks.\n \n Starlark call stacks will be included in duplicate targets error.\n \n If a command outputs targets (like `targets` command), starlark call stacks will be\n printed after the targets.\n\nConsole Options:\n --console \n Which console to use for this command\n \n [env: BUCK_CONSOLE=]\n [default: auto]\n [possible values: simple, simplenotty, simpletty, super, auto, none]\n\n --ui ...\n Configure additional superconsole ui components.\n \n Accepts a comma-separated list of superconsole components to add. Possible values are:\n \n dice - shows information about evaluated dice nodes debugevents - shows information about\n the flow of events from buckd\n \n These components can be turned on/off interactively. Press 'h' for help when superconsole\n is active.\n\n Possible values:\n - dice\n - debugevents\n - io: I/O panel\n - re: RE panel\n\n --no-interactive-console\n Disable console interactions\n \n [env: BUCK_NO_INTERACTIVE_CONSOLE=]\n\nEvent Log Options:\n --event-log \n Write events to this log file\n\n --write-build-id \n Write command invocation id into this file\n\n --unstable-write-invocation-record \n Write the invocation record (as JSON) to this path. No guarantees whatsoever are made\n regarding the stability of the format\n\nUniversal Options:\n -v, --verbose \n How verbose buck should be while logging.\n \n Values: 0 = Quiet, errors only; 1 = Show status. Default; 2 = more info about errors; 3 =\n more info about everything; 4 = more info about everything + stderr;\n \n It can be combined with specific log items (stderr, full_failed_command, commands,\n actions, status, stats, success) to fine-tune the verbosity of the log. Example usage\n \"-v=1,stderr\"\n \n [default: 1]\n\n --oncall \n The oncall executing this command\n\n --client-metadata \n Metadata key-value pairs to inject into Buck2's logging. Client metadata must be of the\n form `key=value`, where `key` is a snake_case identifier, and will be sent to backend\n datasets\n\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/03a88bad.6a4c54f1.js b/assets/js/03a88bad.6a4c54f1.js new file mode 100644 index 000000000000..a66dc486773f --- /dev/null +++ b/assets/js/03a88bad.6a4c54f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6568],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>s,MDXProvider:()=>d,mdx:()=>f,useMDXComponents:()=>c,withMDXComponents:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),m=function(e){return function(t){var n=c(t.components);return a.createElement(e,i({},t,{components:n}))}},c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},b=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,o=e.parentName,s=u(e,["components","mdxType","originalType","parentName"]),m=c(n),d=r,p=m["".concat(o,".").concat(d)]||m[d]||h[d]||i;return n?a.createElement(p,l(l({ref:t},s),{},{components:n})):a.createElement(p,l({ref:t},s))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=b;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l[p]="string"==typeof e?e:r,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var a=n(87462),r=(n(67294),n(3905));const i={id:"index",title:"Introduction"},o=void 0,l={unversionedId:"index",id:"index",title:"Introduction",description:"Welcome to Buck2, a large scale, fast, reliable, and extensible build tool",source:"@site/../docs/index.md",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,tags:[],version:"current",frontMatter:{id:"index",title:"Introduction"},sidebar:"manualSidebar",next:{title:"Why Buck2",permalink:"/docs/why"}},u={},s=[{value:"Buck2 Documentation Website Links",id:"buck2-documentation-website-links",level:2},{value:"For end users",id:"for-end-users",level:3},{value:"For people writing rules",id:"for-people-writing-rules",level:3},{value:"For people integrating with Buck2",id:"for-people-integrating-with-buck2",level:3},{value:"External articles about Buck2",id:"external-articles-about-buck2",level:3},{value:"External videos about Buck2",id:"external-videos-about-buck2",level:3},{value:"External projects using Buck2",id:"external-projects-using-buck2",level:3},{value:"For people developing Buck2",id:"for-people-developing-buck2",level:3}],m=(c="FbInternalOnly",function(e){return console.warn("Component "+c+" was not imported, exported, or provided by MDXProvider as global scope"),(0,r.mdx)("div",e)});var c;const d={toc:s};function p(e){let{components:t,...n}=e;return(0,r.mdx)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.mdx)("p",null,"Welcome to Buck2, a large scale, fast, reliable, and extensible build tool\ndeveloped and used by Meta. Buck2 supports a variety of languages on many\nplatforms."),(0,r.mdx)("p",null,"Buck2's core is written in ",(0,r.mdx)("a",{parentName:"p",href:"https://www.rust-lang.org/"},"Rust"),".\n",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/bazelbuild/starlark"},"Starlark"),", which is a deterministic,\nimmutable dialect of Python, is used to extend the Buck2 build system, enabling\nBuck2 to be language-agnostic. With Starlark, users can define their own custom\nrules."),(0,r.mdx)("p",null,"Buck2 leverages the Bazel spec of\n",(0,r.mdx)("a",{parentName:"p",href:"https://bazel.build/remote/rbe"},"Remote Build Execution")," as the primary means of\nparallelization and caching, which increases the importance of idempotency (no\nmatter how many times an operation is performed, it yields the same result) and\nhermeticity (code is sealed off from the world), giving the right results,\nreliably."),(0,r.mdx)("p",null,"Buck2 multi-language support includes C++, Python, Java, Go, Rust, Erlang,\nOCaml, and more."),(0,r.mdx)("p",null,"The following sub-sections contain a list of links to key points in the Buck2\nDocumentation website that explain the advantages of using Buck2 for you and\nyour team."),(0,r.mdx)("h2",{id:"buck2-documentation-website-links"},"Buck2 Documentation Website Links"),(0,r.mdx)("h3",{id:"for-end-users"},"For end users"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"/docs/getting_started"},"Getting Started")," - how to get started with using Buck2."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"/docs/benefits"},"Benefits")," - the benefits of using Buck2.")),(0,r.mdx)(m,{mdxType:"FbInternalOnly"},(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"users/migration_guide.fb.md"},"Migration Guide")," - how to port projects from\nBuck to Buck2, including the issues you might face and notable differences."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"users/build_observability/observability.fb.md"},"Buck2 and Build Observability")," -\nhow to use Buck2's datasets to analyze specific invocations or classes of\ninvocations."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"users/advanced/vpnless.fb.md"},"Migrating builds to work VPNless")," - how to\nmigrate builds to work without VPN or lighthouse access."))),(0,r.mdx)("h3",{id:"for-people-writing-rules"},"For people writing rules"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"/docs/rule_authors/writing_rules"},"Writing Rules")," - how to write rules to support\nnew languages."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"api/build/globals"},"Build APIs")," - documentation for the APIs available when\nwriting rules."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebook/starlark-rust/blob/main/docs/types.md"},"Starlark Types")," -\nrules are written in Starlark (which is approximately Python), but our version\nadds types.")),(0,r.mdx)(m,{mdxType:"FbInternalOnly"},(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"rule_authors/rule_writing_tips.fb.md"},"Rule Writing Tips")," - tips for migrating\nrules from Buck1 to Buck2."))),(0,r.mdx)("h3",{id:"for-people-integrating-with-buck2"},"For people integrating with Buck2"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"/docs/developers/bxl"},"Extending Buck via BXL")," - powerful Starlark scripts for\nintrospection of Buck2's graphs."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebookincubator/buck2-change-detector"},"Buck2 change detector")," -\ntools for building a CI that only builds/tests what has changed in diff/PR."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/dtolnay/install-buck2"},"Buck2 GitHub actions installer")," -\nscript to make GitHub CI with Buck2 easier."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebookincubator/reindeer"},"Reindeer")," - a set of tools for\nimporting Rust crates from crates.io, git repos etc and generating a BUCK file\nfor using them."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebook/ocaml-scripts"},"ocaml-scripts")," - scripts to\ngenerate a BUCK file enabling the use of OCaml packages from an OPAM switch."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/benbrittain/buckle"},"Buckle")," - a launcher for Buck2 on a\nper-project basis. Enables a project or team to do seamless upgrades of their\nbuild system tooling.")),(0,r.mdx)("h3",{id:"external-articles-about-buck2"},"External articles about Buck2"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://engineering.fb.com/2023/04/06/open-source/buck2-open-source-large-scale-build-system/"},"Introducing Buck2")," -\nour initial introduction when we open sourced Buck2."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://old.reddit.com/r/rust/comments/136qs44/hello_rrust_we_are_meta_engineers_who_created_the/"},"Reddit AMA"),"\nwhere the Buck2 team answered a number of questions."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://steveklabnik.com/writing/using-buck-to-build-rust-projects"},"Using buck to build Rust projects")," -\nworking through an initial small Rust project, by\n",(0,r.mdx)("a",{parentName:"li",href:"https://steveklabnik.com/"},"Steve Klabnik"),". Followed up by\n",(0,r.mdx)("a",{parentName:"li",href:"https://steveklabnik.com/writing/using-cratesio-with-buck"},"building from crates.io"),"\nand ",(0,r.mdx)("a",{parentName:"li",href:"https://steveklabnik.com/writing/updating-buck"},"updating Buck2"),"."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/sluongng/awesome-buck2"},"Awesome Buck2")," is a collection of\nresources about Buck2."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.buildbuddy.io/blog/buck2-review/"},"Buck2 Unboxing")," is a general\nreview of Buck2 by ",(0,r.mdx)("a",{parentName:"li",href:"https://github.com/sluongng/"},"Son Luong Ngoc"),"."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.tweag.io/blog/2023-07-06-buck2/"},"A tour around Buck2")," gives an\noverview of Buck2 and how it differs from Bazel.")),(0,r.mdx)("h3",{id:"external-videos-about-buck2"},"External videos about Buck2"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=oMIzKVxUNAE"},"Accelerating builds with Buck2"),"\nNeil talks about why Buck2 is fast."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=EQfVu42KwDs"},"Buck2: optimizations & dynamic dependencies"),"\nNeil and Chris talk about why Buck2 is fast and some of the advanced\ndependency features."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=4ALgsBqNBhQ"},"Building Erlang with Buck2"),"\nAndreas talks about building WhatsApp with Buck2."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=Wv-ilbckSx4"},"antlir2: Deterministic image bulids with Buck2"),"\ntalks about layering a packaging system over Buck2.")),(0,r.mdx)("h3",{id:"external-projects-using-buck2"},"External projects using Buck2"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.systeminit.com/"},"System Initiative")," build their DevOps product\n",(0,r.mdx)("a",{parentName:"li",href:"https://nickgerace.dev/post/system-initiative-the-second-wave-of-devops/#under-the-hood"},"using Buck2"),",\nwith their own custom prelude."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/dtolnay/cxx"},"Rust ",(0,r.mdx)("inlineCode",{parentName:"a"},"cxx")," library")," has examples and tests\nwith a wide variety of build systems, including Buck2."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebook/ocamlrep"},(0,r.mdx)("inlineCode",{parentName:"a"},"ocamlrep")," library")," allows for interop\nbetween OCaml and Rust code, and can be\n",(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebook/ocamlrep/blob/main/README-BUCK.md"},"built with Buck2"),"."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://github.com/thoughtpolice/buck2-nix"},(0,r.mdx)("inlineCode",{parentName:"a"},"buck2-nix"))," is an experiment to\nintegrate Buck2, ",(0,r.mdx)("a",{parentName:"li",href:"https://sapling-scm.com"},"Sapling")," and\n",(0,r.mdx)("a",{parentName:"li",href:"https://nixos.org"},"Nix")," together in a harmonious way.")),(0,r.mdx)("p",null,"Feel free to\n",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck2/edit/main/docs/index.md"},"send a PR")," adding\nyour project."),(0,r.mdx)(m,{mdxType:"FbInternalOnly"},(0,r.mdx)("h3",{id:"for-people-developing-buck2"},"For people developing Buck2"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"https://www.internalfb.com/code/fbsource/fbcode/buck2/README.md"},"Basic README")," -\nhow to get started, compile Buck2 and the basic workflows."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("a",{parentName:"li",href:"developers/developers.fb.md"},"Notes for Developers")," - more advanced workflows\nand notes around debugging, profiling etc."))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/040433d8.c465ec7a.js b/assets/js/040433d8.c465ec7a.js new file mode 100644 index 000000000000..cf89354f4eda --- /dev/null +++ b/assets/js/040433d8.c465ec7a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6598],{3905:(t,e,a)=>{a.r(e),a.d(e,{MDXContext:()=>s,MDXProvider:()=>f,mdx:()=>x,useMDXComponents:()=>d,withMDXComponents:()=>p});var r=a(67294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function i(){return i=Object.assign||function(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var s=r.createContext({}),p=function(t){return function(e){var a=d(e.components);return r.createElement(t,i({},e,{components:a}))}},d=function(t){var e=r.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):c(c({},e),t)),a},f=function(t){var e=d(t.components);return r.createElement(s.Provider,{value:e},t.children)},u="mdxType",m={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},h=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,i=t.originalType,o=t.parentName,s=l(t,["components","mdxType","originalType","parentName"]),p=d(a),f=n,u=p["".concat(o,".").concat(f)]||p[f]||m[f]||i;return a?r.createElement(u,c(c({ref:e},s),{},{components:a})):r.createElement(u,c({ref:e},s))}));function x(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var i=a.length,o=new Array(i);o[0]=h;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[u]="string"==typeof t?t:n,o[1]=c;for(var s=2;s{a.r(e),a.d(e,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var r=a(87462),n=(a(67294),a(3905));const i={id:"artifact"},o="artifact type",c={unversionedId:"api/build/artifact",id:"api/build/artifact",title:"artifact type",description:"A single input or output file for an action.",source:"@site/../docs/api/build/artifact.generated.md",sourceDirName:"api/build",slug:"/api/build/artifact",permalink:"/docs/api/build/artifact",draft:!1,tags:[],version:"current",frontMatter:{id:"artifact"},sidebar:"manualSidebar",previous:{title:"anon_targets type",permalink:"/docs/api/build/anon_targets"},next:{title:"attrs type",permalink:"/docs/api/build/attrs"}},l={},s=[{value:"artifact.as_output",id:"artifactas_output",level:2},{value:"artifact.basename",id:"artifactbasename",level:2},{value:"artifact.extension",id:"artifactextension",level:2},{value:"artifact.is_source",id:"artifactis_source",level:2},{value:"artifact.owner",id:"artifactowner",level:2},{value:"artifact.project",id:"artifactproject",level:2},{value:"artifact.short_path",id:"artifactshort_path",level:2},{value:"artifact.with_associated_artifacts",id:"artifactwith_associated_artifacts",level:2},{value:"artifact.without_associated_artifacts",id:"artifactwithout_associated_artifacts",level:2}],p={toc:s};function d(t){let{components:e,...a}=t;return(0,n.mdx)("wrapper",(0,r.Z)({},p,a,{components:e,mdxType:"MDXLayout"}),(0,n.mdx)("h1",{id:"artifact-type"},(0,n.mdx)("inlineCode",{parentName:"h1"},"artifact")," type"),(0,n.mdx)("p",null,"A single input or output file for an action."),(0,n.mdx)("p",null,"There is no ",(0,n.mdx)("inlineCode",{parentName:"p"},".parent")," method on ",(0,n.mdx)("inlineCode",{parentName:"p"},"artifact"),", but in most cases\n",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_args(my_artifact).parent()")," can be used to similar effect."),(0,n.mdx)("h2",{id:"artifactas_output"},"artifact.as","_","output"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.as_output() -> output_artifact\n")),(0,n.mdx)("p",null,"Returns a ",(0,n.mdx)("inlineCode",{parentName:"p"},"StarlarkOutputArtifact")," instance, or fails if the artifact is either an ",(0,n.mdx)("inlineCode",{parentName:"p"},"Artifact"),", or is a bound ",(0,n.mdx)("inlineCode",{parentName:"p"},"Artifact")," (You cannot bind twice)"),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactbasename"},"artifact.basename"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.basename: str\n")),(0,n.mdx)("p",null,"The base name of this artifact. e.g. for an artifact at ",(0,n.mdx)("inlineCode",{parentName:"p"},"foo/bar"),", this is ",(0,n.mdx)("inlineCode",{parentName:"p"},"bar")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactextension"},"artifact.extension"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.extension: str\n")),(0,n.mdx)("p",null,"The file extension of this artifact. e.g. for an artifact at foo/bar.sh, this is ",(0,n.mdx)("inlineCode",{parentName:"p"},".sh"),". If no extension is present, ",(0,n.mdx)("inlineCode",{parentName:"p"},'""')," is returned."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactis_source"},"artifact.is","_","source"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.is_source: bool\n")),(0,n.mdx)("p",null,"Whether the artifact represents a source file"),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactowner"},"artifact.owner"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.owner: None | label\n")),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"Label")," of the rule that originally created this artifact. May also be None in the case of source files, or if the artifact has not be used in an action, or if the action was not created by a rule."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactproject"},"artifact.project"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.project(\n path: str,\n /,\n *,\n hide_prefix: bool = False\n) -> artifact\n")),(0,n.mdx)("p",null,"Create an artifact that lives at path relative from this artifact."),(0,n.mdx)("p",null,"For example, if artifact foo is a directory containing a file bar, then ",(0,n.mdx)("inlineCode",{parentName:"p"},'foo.project("bar")'),"\nyields the file bar. It is possible for projected artifacts to hide the prefix in order to\nhave the short name of the resulting artifact only contain the projected path, by passing\n",(0,n.mdx)("inlineCode",{parentName:"p"},"hide_prefix = True")," to ",(0,n.mdx)("inlineCode",{parentName:"p"},"project()"),"."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactshort_path"},"artifact.short","_","path"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"artifact.short_path: str\n")),(0,n.mdx)("p",null,"The interesting part of the path, relative to somewhere in the output directory. For an artifact declared as ",(0,n.mdx)("inlineCode",{parentName:"p"},"foo/bar"),", this is ",(0,n.mdx)("inlineCode",{parentName:"p"},"foo/bar"),"."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactwith_associated_artifacts"},"artifact.with","_","associated","_","artifacts"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.with_associated_artifacts(artifacts: list[artifact]) -> artifact\n")),(0,n.mdx)("p",null,"Returns a ",(0,n.mdx)("inlineCode",{parentName:"p"},"StarlarkArtifact")," instance which is identical to the original artifact, but with potentially additional artifacts. The artifacts must be bound."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"artifactwithout_associated_artifacts"},"artifact.without","_","associated","_","artifacts"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def artifact.without_associated_artifacts() -> artifact\n")),(0,n.mdx)("p",null,"Returns a ",(0,n.mdx)("inlineCode",{parentName:"p"},"StarlarkArtifact")," instance which is identical to the original artifact, except with no associated artifacts"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/04f21c51.4698fd34.js b/assets/js/04f21c51.4698fd34.js new file mode 100644 index 000000000000..9b4f90046fb7 --- /dev/null +++ b/assets/js/04f21c51.4698fd34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3537],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>c,MDXProvider:()=>u,mdx:()=>b,useMDXComponents:()=>s,withMDXComponents:()=>i});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function d(){return d=Object.assign||function(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=r.createContext({}),i=function(e){return function(n){var t=s(n.components);return r.createElement(e,d({},n,{components:t}))}},s=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},u=function(e){var n=s(e.components);return r.createElement(c.Provider,{value:n},e.children)},y="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,d=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),i=s(t),u=a,y=i["".concat(p,".").concat(u)]||i[u]||m[u]||d;return t?r.createElement(y,o(o({ref:n},c),{},{components:t})):r.createElement(y,o({ref:n},c))}));function b(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var d=t.length,p=new Array(d);p[0]=f;var o={};for(var l in n)hasOwnProperty.call(n,l)&&(o[l]=n[l]);o.originalType=e,o[y]="string"==typeof e?e:a,p[1]=o;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>p,default:()=>s,frontMatter:()=>d,metadata:()=>o,toc:()=>c});var r=t(87462),a=(t(67294),t(3905));const d={id:"dependency"},p="dependency type",o={unversionedId:"api/bxl/dependency",id:"api/bxl/dependency",title:"dependency type",description:"Dependency type. In Starlark typing it can be represented with Dependency global.",source:"@site/../docs/api/bxl/dependency.generated.md",sourceDirName:"api/bxl",slug:"/api/bxl/dependency",permalink:"/docs/api/bxl/dependency",draft:!1,tags:[],version:"current",frontMatter:{id:"dependency"},sidebar:"manualSidebar",previous:{title:"cqueryctx type",permalink:"/docs/api/bxl/cqueryctx"},next:{title:"digest_config type",permalink:"/docs/api/bxl/digest_config"}},l={},c=[{value:"dependency.get",id:"dependencyget",level:2},{value:"dependency.label",id:"dependencylabel",level:2},{value:"dependency.providers",id:"dependencyproviders",level:2},{value:"dependency.sub_target",id:"dependencysub_target",level:2}],i={toc:c};function s(e){let{components:n,...t}=e;return(0,a.mdx)("wrapper",(0,r.Z)({},i,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("h1",{id:"dependency-type"},(0,a.mdx)("inlineCode",{parentName:"h1"},"dependency")," type"),(0,a.mdx)("p",null,"Dependency type. In Starlark typing it can be represented with ",(0,a.mdx)("inlineCode",{parentName:"p"},"Dependency")," global."),(0,a.mdx)("h2",{id:"dependencyget"},"dependency.get"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-python"},"def dependency.get(index) -> None | provider\n")),(0,a.mdx)("p",null,"Gets a provider by indexing on a ",(0,a.mdx)("inlineCode",{parentName:"p"},"ProviderCallable")," object."),(0,a.mdx)("p",null,"e.g."),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-ignore"},'FooInfo = provider(fields=["bar"])\n....\ncollection.get(FooInfo) # None if absent, a FooInfo instance if present\n')),(0,a.mdx)("hr",null),(0,a.mdx)("h2",{id:"dependencylabel"},"dependency.label"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-python"},"dependency.label: label\n")),(0,a.mdx)("hr",null),(0,a.mdx)("h2",{id:"dependencyproviders"},"dependency.providers"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-python"},"dependency.providers: list[typing.Any]\n")),(0,a.mdx)("hr",null),(0,a.mdx)("h2",{id:"dependencysub_target"},"dependency.sub","_","target"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-python"},"def dependency.sub_target(subtarget: str, /) -> dependency\n")),(0,a.mdx)("p",null,"Obtain the dependency representing a subtarget. In most cases you will want to use ",(0,a.mdx)("inlineCode",{parentName:"p"},'x[DefaultInfo].sub_targets["foo"]')," to get the ",(0,a.mdx)("em",{parentName:"p"},"providers")," of the subtarget, but if you need a real ",(0,a.mdx)("inlineCode",{parentName:"p"},"Dependency")," type (e.g. for use with ",(0,a.mdx)("inlineCode",{parentName:"p"},"ctx.action.anon_target"),") then use this method."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/064ea4d5.a0c3a975.js b/assets/js/064ea4d5.a0c3a975.js new file mode 100644 index 000000000000..e75e8025cf17 --- /dev/null +++ b/assets/js/064ea4d5.a0c3a975.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5827],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>u,MDXProvider:()=>c,mdx:()=>x,useMDXComponents:()=>p,withMDXComponents:()=>d});var a=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(){return i=Object.assign||function(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var u=a.createContext({}),d=function(e){return function(n){var t=p(n.components);return a.createElement(e,i({},n,{components:t}))}},p=function(e){var n=a.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(u.Provider,{value:n},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},f=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,o=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=p(t),c=r,m=d["".concat(o,".").concat(c)]||d[c]||h[c]||i;return t?a.createElement(m,s(s({ref:n},u),{},{components:t})):a.createElement(m,s({ref:n},u))}));function x(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,o=new Array(i);o[0]=f;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[m]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var a=t(87462),r=(t(67294),t(3905));const i={id:"bxl_basics",title:"BXL Basics"},o=void 0,s={unversionedId:"developers/bxl_basics",id:"developers/bxl_basics",title:"BXL Basics",description:"This page is a primer on common BXL functionalities and data types. Ramping up",source:"@site/../docs/developers/bxl_basics.md",sourceDirName:"developers",slug:"/developers/bxl_basics",permalink:"/docs/developers/bxl_basics",draft:!1,tags:[],version:"current",frontMatter:{id:"bxl_basics",title:"BXL Basics"},sidebar:"manualSidebar",previous:{title:"Getting Started",permalink:"/docs/developers/bxl_getting_started"},next:{title:"Common How-Tos",permalink:"/docs/developers/bxl_how_tos"}},l={},u=[{value:"Common BXL functionalities",id:"common-bxl-functionalities",level:2},{value:"Build",id:"build",level:3},{value:"Analysis",id:"analysis",level:3},{value:"Query",id:"query",level:3},{value:"Uquery",id:"uquery",level:4},{value:"Cquery",id:"cquery",level:4},{value:"Aquery",id:"aquery",level:4},{value:"Actions",id:"actions",level:3},{value:"Ensure",id:"ensure",level:3}],d={toc:u};function p(e){let{components:n,...t}=e;return(0,r.mdx)("wrapper",(0,a.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,r.mdx)("p",null,"This page is a primer on common BXL functionalities and data types. Ramping up\nin BXL may be challenging without much prior knowledge of Buck2 building blocks\n(ex: targets, configurations, queries), so please take a look at the\n",(0,r.mdx)("a",{parentName:"p",href:"/docs/concepts/concept_map"},"Concepts")," documentation before reading on."),(0,r.mdx)("h2",{id:"common-bxl-functionalities"},"Common BXL functionalities"),(0,r.mdx)("h3",{id:"build"},"Build"),(0,r.mdx)("p",null,"You can build targets within BXL with\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/bxl_ctx/#bxl_ctxbuild"},(0,r.mdx)("inlineCode",{parentName:"a"},"ctx.build()")),". The result is a\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/bxl_build_result"},(0,r.mdx)("inlineCode",{parentName:"a"},"bxl_build_result")),", which has ",(0,r.mdx)("inlineCode",{parentName:"p"},"artifacts()"),"\nand ",(0,r.mdx)("inlineCode",{parentName:"p"},"failures()")," functions that provide iterators to the artifacts or failures,\nrespectively. You can pass in a single target or target pattern to build."),(0,r.mdx)("h3",{id:"analysis"},"Analysis"),(0,r.mdx)("p",null,"You can run analysis on targets within BXL via\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/bxl_ctx/#bxl_ctxanalysis"},(0,r.mdx)("inlineCode",{parentName:"a"},"ctx.analysis()")),". Analysis means to\nevaluate the underlying rule implementation for the inputted targets, and\nproduce the providers that the rule defined for the target. A common workflow is\nto inspect the resulting providers, and perhaps ensure parts of these providers\nor run actions using information from the providers (see ",(0,r.mdx)("a",{parentName:"p",href:"#actions"},"Actions"),"\nbelow)."),(0,r.mdx)("h3",{id:"query"},"Query"),(0,r.mdx)("p",null,"Buck2 supports a couple different query types: querying the unconfigured graph\n(",(0,r.mdx)("inlineCode",{parentName:"p"},"buck2 uquery"),"), the configured graph (",(0,r.mdx)("inlineCode",{parentName:"p"},"buck2 cquery"),"), or the action graph\n(",(0,r.mdx)("inlineCode",{parentName:"p"},"buck2 aquery"),"). These queries are all available in BXL as well:"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("inlineCode",{parentName:"li"},"ctx.uquery()")," returns a ",(0,r.mdx)("a",{parentName:"li",href:"../../api/bxl/uqueryctx"},(0,r.mdx)("inlineCode",{parentName:"a"},"uqueryctx"))),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("inlineCode",{parentName:"li"},"ctx.cquery()")," returns a ",(0,r.mdx)("a",{parentName:"li",href:"../../api/bxl/cqueryctx"},(0,r.mdx)("inlineCode",{parentName:"a"},"cqueryctx"))),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("inlineCode",{parentName:"li"},"ctx.aquery()")," returns a ",(0,r.mdx)("a",{parentName:"li",href:"../../api/bxl/aqueryctx"},(0,r.mdx)("inlineCode",{parentName:"a"},"aqueryctx")))),(0,r.mdx)("p",null,"You can read more about the individual queries in the API docs. There are many\nqueries that are common between uquery, cquery, and aquery, but cquery and\naquery will have extra queries unique to the configured graph or the action\ngraph. One more thing to call out is the ",(0,r.mdx)("inlineCode",{parentName:"p"},"eval()")," query, which is a special\nquery that takes in the entire query as a string literal. A common use for\n",(0,r.mdx)("inlineCode",{parentName:"p"},"eval()")," is to migrate a complex query from Buck2 CLI to BXL by dropping the\nentire query string directly into ",(0,r.mdx)("inlineCode",{parentName:"p"},"eval()"),"."),(0,r.mdx)("p",null,"The query results are target sets (iterable container) of\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/unconfigured_target_node"},(0,r.mdx)("inlineCode",{parentName:"a"},"unconfigured_target_node"),"s")," for\nuquery, ",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/target_node"},(0,r.mdx)("inlineCode",{parentName:"a"},"target_node"),"s")," for cquery, and\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/action_query_node"},(0,r.mdx)("inlineCode",{parentName:"a"},"action_query_node"),"s")," for aquery. Each of\nthese node types have accessors on their attributes. A common workflow is to run\nsome query in BXL, and iterate through the resulting nodes to inspect their\nattributes, and use those attributes to inform further computations in BXL."),(0,r.mdx)("h4",{id:"uquery"},"Uquery"),(0,r.mdx)("p",null,"Querying the unconfigured graph means that no configurations (such as platforms\nand transitions) have been applied to the target graph yet. This means that it's\nvery possible that some parts of the target graph is broken due to lack of\nconfigurations. Generally to avoid this problem, cquery may be preferred\ninstead."),(0,r.mdx)("h4",{id:"cquery"},"Cquery"),(0,r.mdx)("p",null,"Querying the configured graph means that configurations have been applied to the\ntarget graph. For cquery, we require that users use a\n",(0,r.mdx)("a",{parentName:"p",href:"/docs/developers/target_universe"},"target universe")," for their query inputs."),(0,r.mdx)("h4",{id:"aquery"},"Aquery"),(0,r.mdx)("p",null,"Aquery is a quite different from uquery and cquery. It is used to query the\naction graph, which is constructed after Buck2 runs analysis on the targets and\nproduces the list of providers and actions needed to build the target."),(0,r.mdx)("h3",{id:"actions"},"Actions"),(0,r.mdx)("p",null,"You can create actions directly within the BXL API. The available action APIs\nare equivalent to the ones found on the ",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/actions"},(0,r.mdx)("inlineCode",{parentName:"a"},"actions"))," type\nfor normal rules, with the caveat that\n",(0,r.mdx)("a",{parentName:"p",href:"/docs/developers/dynamic_output"},"dynamic actions")," use the\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/bxl_ctx"},(0,r.mdx)("inlineCode",{parentName:"a"},"bxl_ctx"))," (which provides richer functionalities)."),(0,r.mdx)("p",null,"A common workflow would be to run analysis on a target, and use some interesting\nbits found in the analysis result to construct an augmented\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/cmd_args"},(0,r.mdx)("inlineCode",{parentName:"a"},"cmd_args"))," to run, and then ensure the action's output\n(see below for ensuring). Also see\n",(0,r.mdx)("a",{parentName:"p",href:"/docs/developers/bxl_how_tos#running-actions"},"Running actions"),"."),(0,r.mdx)("h3",{id:"ensure"},"Ensure"),(0,r.mdx)("p",null,"Ensuring an artifact means that you want the artifact to be materialized\n(meaning, downloaded to your machine) at the end of the BXL execution. There are\ntwo APIs for ensuring: ",(0,r.mdx)("inlineCode",{parentName:"p"},"ctx.output.ensure()")," and ",(0,r.mdx)("inlineCode",{parentName:"p"},"ctx.output.ensure_multiple()"),"\n(see ",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/bxl_output_stream"},(0,r.mdx)("inlineCode",{parentName:"a"},"bxl_output_stream")),"). As the naming\nindicates, the former is for ensuring a single artifact, and the latter is for\nensuring multiple artifact-like inputs. Artifact-like inputs include\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/cmd_args"},(0,r.mdx)("inlineCode",{parentName:"a"},"cmd_args"))," (can be found when inspecting providers),\n",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/bxl_build_result"},(0,r.mdx)("inlineCode",{parentName:"a"},"bxl_build_result"))," (produced when building\nsomething in BXL), or ",(0,r.mdx)("a",{parentName:"p",href:"../../api/bxl/artifact"},(0,r.mdx)("inlineCode",{parentName:"a"},"artifact"))," (can be found when\ninspecting providers, or creating your own actions)."),(0,r.mdx)("p",null,"A common workflow is to ensure an artifact that you created via some custom\nactions defined in your script, or ensuring some artifacts found in the\nproviders after running analysis. Also see\n",(0,r.mdx)("a",{parentName:"p",href:"/docs/developers/bxl_faqs#what-do-i-need-to-know-about-ensured-artifacts"},"What do I need to know about ensured artifacts"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/084ef0a3.3c2aaf26.js b/assets/js/084ef0a3.3c2aaf26.js new file mode 100644 index 000000000000..626f03f83cbf --- /dev/null +++ b/assets/js/084ef0a3.3c2aaf26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5624],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>l,MDXProvider:()=>m,mdx:()=>h,useMDXComponents:()=>d,withMDXComponents:()=>u});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=r.createContext({}),u=function(e){return function(n){var t=d(n.components);return r.createElement(e,a({},n,{components:t}))}},d=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},m=function(e){var n=d(e.components);return r.createElement(l.Provider,{value:n},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},g=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=d(t),m=o,p=u["".concat(s,".").concat(m)]||u[m]||f[m]||a;return t?r.createElement(p,i(i({ref:n},l),{},{components:t})):r.createElement(p,i({ref:n},l))}));function h(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,s=new Array(a);s[0]=g;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i[p]="string"==typeof e?e:o,s[1]=i;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var r=t(87462),o=(t(67294),t(3905));const a={id:"ctargets",title:"ctargets"},s=void 0,i={unversionedId:"users/commands/ctargets",id:"users/commands/ctargets",title:"ctargets",description:"These are the flags/commands under buck2 ctargets and their --help output:",source:"@site/../docs/users/commands/ctargets.generated.md",sourceDirName:"users/commands",slug:"/users/commands/ctargets",permalink:"/docs/users/commands/ctargets",draft:!1,tags:[],version:"current",frontMatter:{id:"ctargets",title:"ctargets"},sidebar:"manualSidebar",previous:{title:"cquery",permalink:"/docs/users/commands/cquery"},next:{title:"docs",permalink:"/docs/users/commands/docs"}},c={},l=[{value:"buck ctargets",id:"buck-ctargets",level:2}],u={toc:l};function d(e){let{components:n,...t}=e;return(0,o.mdx)("wrapper",(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,o.mdx)("p",null,"These are the flags/commands under ",(0,o.mdx)("inlineCode",{parentName:"p"},"buck2 ctargets")," and their ",(0,o.mdx)("inlineCode",{parentName:"p"},"--help")," output:"),(0,o.mdx)("h2",{id:"buck-ctargets"},"buck ctargets"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-text"},"Resolve target patterns to configured targets\n\nUsage: buck2-release ctargets [OPTIONS] [TARGET_PATTERNS]...\n\nArguments:\n [TARGET_PATTERNS]...\n Patterns to interpret\n\nOptions:\n --skip-missing-targets\n Skip missing targets from `BUCK` files when non-glob pattern is specified. This option\n does not skip missing packages and does not ignore errors of `BUCK` file evaluation\n\n -h, --help\n Print help (see a summary with '-h')\n\nTarget Configuration Options:\n --target-platforms \n Configuration target (one) to use to configure targets\n\n --modifier \n A configuration modifier to configure all targets on the command line. This may be a\n constraint value target.\n\nBuckconfig Options:\n -c, --config \n List of config options\n\n --config-file \n List of config file paths\n\n --fake-host \n [possible values: default, linux, macos, windows]\n\n --fake-arch \n [possible values: default, aarch64, x8664]\n\n --fake-xcode-version \n Value must be formatted as: version-build (e.g., 14.3.0-14C18 or 14.1-14B47b)\n\n --reuse-current-config\n Re-uses any `--config` values (inline or via modefiles) if there's a previous command,\n otherwise the flag is ignored.\n \n If there is a previous command and `--reuse-current-config` is set, then the old config is\n used, ignoring any overrides.\n \n If there is no previous command but the flag was set, then the flag is ignored, the\n command behaves as if the flag was not set at all.\n\n --exit-when-different-state\n Used for exiting a concurrent command when a different state is detected\n\n --preemptible \n Used to configure when this command could be preempted by another command\n \n [possible values: never, always, ondifferentstate]\n\nStarlark Options:\n --disable-starlark-types\n Disable runtime type checking in Starlark interpreter.\n \n This option is not stable, and can be used only locally to diagnose evaluation performance\n problems.\n\n --stack\n Record or show target call stacks.\n \n Starlark call stacks will be included in duplicate targets error.\n \n If a command outputs targets (like `targets` command), starlark call stacks will be\n printed after the targets.\n\nConsole Options:\n --console \n Which console to use for this command\n \n [env: BUCK_CONSOLE=]\n [default: auto]\n [possible values: simple, simplenotty, simpletty, super, auto, none]\n\n --ui ...\n Configure additional superconsole ui components.\n \n Accepts a comma-separated list of superconsole components to add. Possible values are:\n \n dice - shows information about evaluated dice nodes debugevents - shows information about\n the flow of events from buckd\n \n These components can be turned on/off interactively. Press 'h' for help when superconsole\n is active.\n\n Possible values:\n - dice\n - debugevents\n - io: I/O panel\n - re: RE panel\n\n --no-interactive-console\n Disable console interactions\n \n [env: BUCK_NO_INTERACTIVE_CONSOLE=]\n\nEvent Log Options:\n --event-log \n Write events to this log file\n\n --write-build-id \n Write command invocation id into this file\n\n --unstable-write-invocation-record \n Write the invocation record (as JSON) to this path. No guarantees whatsoever are made\n regarding the stability of the format\n\nUniversal Options:\n -v, --verbose \n How verbose buck should be while logging.\n \n Values: 0 = Quiet, errors only; 1 = Show status. Default; 2 = more info about errors; 3 =\n more info about everything; 4 = more info about everything + stderr;\n \n It can be combined with specific log items (stderr, full_failed_command, commands,\n actions, status, stats, success) to fine-tune the verbosity of the log. Example usage\n \"-v=1,stderr\"\n \n [default: 1]\n\n --oncall \n The oncall executing this command\n\n --client-metadata \n Metadata key-value pairs to inject into Buck2's logging. Client metadata must be of the\n form `key=value`, where `key` is a snake_case identifier, and will be sent to backend\n datasets\n\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0a7b70f3.eeb5797f.js b/assets/js/0a7b70f3.eeb5797f.js new file mode 100644 index 000000000000..966d8295e710 --- /dev/null +++ b/assets/js/0a7b70f3.eeb5797f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8255],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>u,MDXProvider:()=>d,mdx:()=>x,useMDXComponents:()=>c,withMDXComponents:()=>m});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(){return i=Object.assign||function(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var u=r.createContext({}),m=function(e){return function(n){var t=c(n.components);return r.createElement(e,i({},n,{components:t}))}},c=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d=function(e){var n=c(e.components);return r.createElement(u.Provider,{value:n},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},b=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,o=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=c(t),d=a,p=m["".concat(o,".").concat(d)]||m[d]||f[d]||i;return t?r.createElement(p,l(l({ref:n},u),{},{components:t})):r.createElement(p,l({ref:n},u))}));function x(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,o=new Array(i);o[0]=b;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[p]="string"==typeof e?e:a,o[1]=l;for(var u=2;u{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>u});var r=t(87462),a=(t(67294),t(3905));const i={id:"remote_execution",title:"Remote Execution"},o=void 0,l={unversionedId:"users/remote_execution",id:"users/remote_execution",title:"Remote Execution",description:"Buck2 can use services that expose",source:"@site/../docs/users/remote_execution.md",sourceDirName:"users",slug:"/users/remote_execution",permalink:"/docs/users/remote_execution",draft:!1,tags:[],version:"current",frontMatter:{id:"remote_execution",title:"Remote Execution"},sidebar:"manualSidebar",previous:{title:"Build Report",permalink:"/docs/users/build_observability/build_report"},next:{title:"Aquery Environment",permalink:"/docs/users/query/aquery"}},s={},u=[{value:"RE configuration in .buckconfig",id:"re-configuration-in-buckconfig",level:2},{value:"RE platform configuration",id:"re-platform-configuration",level:2}],m={toc:u};function c(e){let{components:n,...t}=e;return(0,a.mdx)("wrapper",(0,r.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Buck2 can use services that expose\n",(0,a.mdx)("a",{parentName:"p",href:"https://github.com/bazelbuild/remote-apis"},"Bazel's remote execution API")," in\norder to run actions remotely."),(0,a.mdx)("p",null,"Buck2 projects have been successfully tested for remote execution against\n",(0,a.mdx)("a",{parentName:"p",href:"https://www.engflow.com/"},"EngFlow"),",\n",(0,a.mdx)("a",{parentName:"p",href:"https://github.com/buildbarn/bb-remote-execution"},"BuildBarn")," and\n",(0,a.mdx)("a",{parentName:"p",href:"https://www.buildbuddy.io"},"BuildBuddy"),". Sample project configurations for those\nproviders are available under\n",(0,a.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck2/tree/main/examples/remote_execution"},"examples/remote_execution"),"."),(0,a.mdx)("h2",{id:"re-configuration-in-buckconfig"},"RE configuration in ",(0,a.mdx)("inlineCode",{parentName:"h2"},".buckconfig")),(0,a.mdx)("p",null,"Configuration for remote execution can be found under ",(0,a.mdx)("inlineCode",{parentName:"p"},"[buck2_re_client]")," in\n",(0,a.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"."),(0,a.mdx)("p",null,"Keys supported include:"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"engine_address")," - address to your RE's engine."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"action_cache_address")," - address to your action cache endpoint."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"cas_address")," - address to your content-addressable storage (CAS) endpoint."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"tls_ca_certs")," - path to a CA certificates bundle. This must be PEM-encoded.\nIf none is set, a default bundle will be used. This path contains environment\nvariables using shell interpolation syntax (i.e. $VAR). They will be\nsubstituted before reading the file."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"tls_client_cert")," - path to a client certificate (and intermediate chain), as\nwell as its associated private key. This must be PEM-encoded. This path can\ncontain environment variables using shell interpolation syntax (i.e. $VAR).\nThey will be substituted before reading the file."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"http_headers")," - HTTP headers to inject in all requests to RE. This is a\ncomma-separated list of ",(0,a.mdx)("inlineCode",{parentName:"li"},"Header: Value")," pairs. Minimal validation of those\nheaders is done here. This can contain environment variables using shell\ninterpolation syntax ($VAR). They will be substituted before reading the file."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"instance_name")," - an instance name to pass on execution, action cache, and CAS\nrequests.")),(0,a.mdx)("p",null,"Buck2 uses ",(0,a.mdx)("inlineCode",{parentName:"p"},"SHA256")," for all its hashing by default. If your RE engine requires\nsomething else, this can be configured in ",(0,a.mdx)("inlineCode",{parentName:"p"},".buckconfig")," as follows:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-ini"},"[buck2]\n# Accepts BLAKE3, SHA1, or SHA256\ndigest_algorithms = BLAKE3\n")),(0,a.mdx)("h2",{id:"re-platform-configuration"},"RE platform configuration"),(0,a.mdx)("p",null,"Next, your build will need an\n",(0,a.mdx)("a",{parentName:"p",href:"https://buck2.build/docs/concepts/glossary/#execution-platform"},"execution platform"),"\nthat specifies how and where actions should be executed. For a sample platform\ndefinition that sets up an execution platform to utilize RE, take a look at the\n",(0,a.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck2/blob/main/examples/remote_execution/engflow/platforms/defs.bzl"},"EngFlow example"),",\n",(0,a.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck2/blob/main/examples/remote_execution/buildbarn/platforms/defs.bzl"},"BuildBarn example"),",\nor the\n",(0,a.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck2/blob/main/examples/remote_execution/buildbuddy/platforms/defs.bzl"},"BuildBuddy example"),"."),(0,a.mdx)("p",null,"To enable remote execution, configure the following fields in\n",(0,a.mdx)("a",{parentName:"p",href:"https://buck2.build/docs/api/build/globals/#commandexecutorconfig"},"CommandExecutorConfig"),"\nas follows:"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"remote_enabled")," - set to ",(0,a.mdx)("inlineCode",{parentName:"li"},"True"),"."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"local_enabled")," - set to ",(0,a.mdx)("inlineCode",{parentName:"li"},"True")," if you also want to run actions locally."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"use_limited_hybrid")," - set to ",(0,a.mdx)("inlineCode",{parentName:"li"},"False")," unless you want to exclusively run\nremotely when possible."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"remote_execution_properties")," - other additional properties.",(0,a.mdx)("ul",{parentName:"li"},(0,a.mdx)("li",{parentName:"ul"},"If the RE engine requires a container image, this can be done by setting\n",(0,a.mdx)("inlineCode",{parentName:"li"},"container-image")," to an image URL, as is done in the example above.")))))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0c7aced5.696b97dc.js b/assets/js/0c7aced5.696b97dc.js new file mode 100644 index 000000000000..9ed7011725e6 --- /dev/null +++ b/assets/js/0c7aced5.696b97dc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2247],{3905:(e,t,a)=>{a.r(t),a.d(t,{MDXContext:()=>d,MDXProvider:()=>_,mdx:()=>x,useMDXComponents:()=>p,withMDXComponents:()=>m});var i=a(67294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(){return r=Object.assign||function(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var d=i.createContext({}),m=function(e){return function(t){var a=p(t.components);return i.createElement(e,r({},t,{components:a}))}},p=function(e){var t=i.useContext(d),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},_=function(e){var t=p(e.components);return i.createElement(d.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,l=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),m=p(a),_=n,c=m["".concat(l,".").concat(_)]||m[_]||h[_]||r;return a?i.createElement(c,s(s({ref:t},d),{},{components:a})):i.createElement(c,s({ref:t},d))}));function x(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,l=new Array(r);l[0]=u;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s[c]="string"==typeof e?e:n,l[1]=s;for(var d=2;d{a.r(t),a.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var i=a(87462),n=(a(67294),a(3905));const r={id:"rules"},l="Rules",s={unversionedId:"api/rules",id:"api/rules",title:"Rules",description:"These rules are available as standard in Buck2.",source:"@site/../docs/api/rules.generated.md",sourceDirName:"api",slug:"/api/rules",permalink:"/docs/api/rules",draft:!1,tags:[],version:"current",frontMatter:{id:"rules"},sidebar:"manualSidebar",previous:{title:"APIs",permalink:"/docs/api"},next:{title:"globals",permalink:"/docs/api/starlark/globals"}},o={},d=[{value:"Parameters",id:"parameters",level:4},{value:"android_aar",id:"android_aar",level:2},{value:"Parameters",id:"parameters-1",level:4},{value:"Details",id:"details",level:4},{value:"android_app_modularity",id:"android_app_modularity",level:2},{value:"Parameters",id:"parameters-2",level:4},{value:"android_binary",id:"android_binary",level:2},{value:"Parameters",id:"parameters-3",level:4},{value:"android_build_config",id:"android_build_config",level:2},{value:"Parameters",id:"parameters-4",level:4},{value:"Details",id:"details-1",level:4},{value:"android_bundle",id:"android_bundle",level:2},{value:"Parameters",id:"parameters-5",level:4},{value:"android_instrumentation_apk",id:"android_instrumentation_apk",level:2},{value:"Parameters",id:"parameters-6",level:4},{value:"Details",id:"details-2",level:4},{value:"android_instrumentation_test",id:"android_instrumentation_test",level:2},{value:"Parameters",id:"parameters-7",level:4},{value:"Details",id:"details-3",level:4},{value:"android_library",id:"android_library",level:2},{value:"Parameters",id:"parameters-8",level:4},{value:"Details",id:"details-4",level:4},{value:"android_manifest",id:"android_manifest",level:2},{value:"Parameters",id:"parameters-9",level:4},{value:"Details",id:"details-5",level:4},{value:"android_platform",id:"android_platform",level:2},{value:"Parameters",id:"parameters-10",level:4},{value:"android_prebuilt_aar",id:"android_prebuilt_aar",level:2},{value:"Parameters",id:"parameters-11",level:4},{value:"Details",id:"details-6",level:4},{value:"android_resource",id:"android_resource",level:2},{value:"Parameters",id:"parameters-12",level:4},{value:"Details",id:"details-7",level:4},{value:"apk_genrule",id:"apk_genrule",level:2},{value:"Parameters",id:"parameters-13",level:4},{value:"Details",id:"details-8",level:4},{value:"apple_asset_catalog",id:"apple_asset_catalog",level:2},{value:"Parameters",id:"parameters-14",level:4},{value:"Details",id:"details-9",level:4},{value:"apple_binary",id:"apple_binary",level:2},{value:"Parameters",id:"parameters-15",level:4},{value:"Details",id:"details-10",level:4},{value:"apple_bundle",id:"apple_bundle",level:2},{value:"Parameters",id:"parameters-16",level:4},{value:"Details",id:"details-11",level:4},{value:"apple_library",id:"apple_library",level:2},{value:"Parameters",id:"parameters-17",level:4},{value:"Details",id:"details-12",level:4},{value:"apple_package",id:"apple_package",level:2},{value:"Parameters",id:"parameters-18",level:4},{value:"Details",id:"details-13",level:4},{value:"apple_resource",id:"apple_resource",level:2},{value:"Parameters",id:"parameters-19",level:4},{value:"Details",id:"details-14",level:4},{value:"apple_test",id:"apple_test",level:2},{value:"Parameters",id:"parameters-20",level:4},{value:"Details",id:"details-15",level:4},{value:"apple_toolchain",id:"apple_toolchain",level:2},{value:"Parameters",id:"parameters-21",level:4},{value:"apple_toolchain_set",id:"apple_toolchain_set",level:2},{value:"Parameters",id:"parameters-22",level:4},{value:"apple_universal_executable",id:"apple_universal_executable",level:2},{value:"Parameters",id:"parameters-23",level:4},{value:"apple_xcframework",id:"apple_xcframework",level:2},{value:"Parameters",id:"parameters-24",level:4},{value:"apple_xcuitest",id:"apple_xcuitest",level:2},{value:"Parameters",id:"parameters-25",level:4},{value:"cgo_library",id:"cgo_library",level:2},{value:"Parameters",id:"parameters-26",level:4},{value:"Details",id:"details-16",level:4},{value:"command_alias",id:"command_alias",level:2},{value:"Parameters",id:"parameters-27",level:4},{value:"Details",id:"details-17",level:4},{value:"config_setting",id:"config_setting",level:2},{value:"Parameters",id:"parameters-28",level:4},{value:"configuration_alias",id:"configuration_alias",level:2},{value:"Parameters",id:"parameters-29",level:4},{value:"configured_alias",id:"configured_alias",level:2},{value:"Parameters",id:"parameters-30",level:4},{value:"constraint_setting",id:"constraint_setting",level:2},{value:"Parameters",id:"parameters-31",level:4},{value:"constraint_value",id:"constraint_value",level:2},{value:"Parameters",id:"parameters-32",level:4},{value:"core_data_model",id:"core_data_model",level:2},{value:"Parameters",id:"parameters-33",level:4},{value:"Details",id:"details-18",level:4},{value:"csharp_library",id:"csharp_library",level:2},{value:"Parameters",id:"parameters-34",level:4},{value:"Details",id:"details-19",level:4},{value:"cxx_binary",id:"cxx_binary",level:2},{value:"Parameters",id:"parameters-35",level:4},{value:"Details",id:"details-20",level:4},{value:"cxx_genrule",id:"cxx_genrule",level:2},{value:"Parameters",id:"parameters-36",level:4},{value:"Details",id:"details-21",level:4},{value:"cxx_library",id:"cxx_library",level:2},{value:"Parameters",id:"parameters-37",level:4},{value:"Details",id:"details-22",level:4},{value:"Building requires a specified top-level target",id:"building-requires-a-specified-top-level-target",level:4},{value:"Dependencies of the cxx_library also require a top-level target",id:"dependencies-of-the-cxx_library-also-require-a-top-level-target",level:4},{value:"cxx_lua_extension",id:"cxx_lua_extension",level:2},{value:"Parameters",id:"parameters-38",level:4},{value:"Details",id:"details-23",level:4},{value:"cxx_precompiled_header",id:"cxx_precompiled_header",level:2},{value:"Parameters",id:"parameters-39",level:4},{value:"Details",id:"details-24",level:4},{value:"cxx_python_extension",id:"cxx_python_extension",level:2},{value:"Parameters",id:"parameters-40",level:4},{value:"Details",id:"details-25",level:4},{value:"cxx_test",id:"cxx_test",level:2},{value:"Parameters",id:"parameters-41",level:4},{value:"Details",id:"details-26",level:4},{value:"cxx_toolchain",id:"cxx_toolchain",level:2},{value:"Parameters",id:"parameters-42",level:4},{value:"d_binary",id:"d_binary",level:2},{value:"Parameters",id:"parameters-43",level:4},{value:"Details",id:"details-27",level:4},{value:"d_library",id:"d_library",level:2},{value:"Parameters",id:"parameters-44",level:4},{value:"Details",id:"details-28",level:4},{value:"d_test",id:"d_test",level:2},{value:"Parameters",id:"parameters-45",level:4},{value:"Details",id:"details-29",level:4},{value:"erlang_app",id:"erlang_app",level:2},{value:"Parameters",id:"parameters-46",level:4},{value:"Details",id:"details-30",level:4},{value:"Minimal Erlang Application",id:"minimal-erlang-application",level:4},{value:"With priv/ directory",id:"with-priv-directory",level:4},{value:"Using OTP applications and mod field",id:"using-otp-applications-and-mod-field",level:4},{value:"Using Yecc and Leex",id:"using-yecc-and-leex",level:4},{value:"erlang_app_includes",id:"erlang_app_includes",level:2},{value:"Parameters",id:"parameters-47",level:4},{value:"erlang_escript",id:"erlang_escript",level:2},{value:"Parameters",id:"parameters-48",level:4},{value:"Details",id:"details-31",level:4},{value:"erlang_otp_binaries",id:"erlang_otp_binaries",level:2},{value:"Parameters",id:"parameters-49",level:4},{value:"Details",id:"details-32",level:4},{value:"erlang_release",id:"erlang_release",level:2},{value:"Parameters",id:"parameters-50",level:4},{value:"Details",id:"details-33",level:4},{value:"erlang_test",id:"erlang_test",level:2},{value:"Parameters",id:"parameters-51",level:4},{value:"Details",id:"details-34",level:4},{value:"export_file",id:"export_file",level:2},{value:"Parameters",id:"parameters-52",level:4},{value:"Details",id:"details-35",level:4},{value:"external_test_runner",id:"external_test_runner",level:2},{value:"Parameters",id:"parameters-53",level:4},{value:"filegroup",id:"filegroup",level:2},{value:"Parameters",id:"parameters-54",level:4},{value:"Details",id:"details-36",level:4},{value:"gen_aidl",id:"gen_aidl",level:2},{value:"Parameters",id:"parameters-55",level:4},{value:"Details",id:"details-37",level:4},{value:"genrule",id:"genrule",level:2},{value:"Parameters",id:"parameters-56",level:4},{value:"Details",id:"details-38",level:4},{value:"git_fetch",id:"git_fetch",level:2},{value:"Parameters",id:"parameters-57",level:4},{value:"Details",id:"details-39",level:4},{value:"go_binary",id:"go_binary",level:2},{value:"Parameters",id:"parameters-58",level:4},{value:"Details",id:"details-40",level:4},{value:"go_exported_library",id:"go_exported_library",level:2},{value:"Parameters",id:"parameters-59",level:4},{value:"Details",id:"details-41",level:4},{value:"go_library",id:"go_library",level:2},{value:"Parameters",id:"parameters-60",level:4},{value:"Details",id:"details-42",level:4},{value:"go_stdlib",id:"go_stdlib",level:2},{value:"Parameters",id:"parameters-61",level:4},{value:"go_test",id:"go_test",level:2},{value:"Parameters",id:"parameters-62",level:4},{value:"Details",id:"details-43",level:4},{value:"go_test_runner",id:"go_test_runner",level:2},{value:"Parameters",id:"parameters-63",level:4},{value:"groovy_library",id:"groovy_library",level:2},{value:"Parameters",id:"parameters-64",level:4},{value:"Details",id:"details-44",level:4},{value:"groovy_test",id:"groovy_test",level:2},{value:"Parameters",id:"parameters-65",level:4},{value:"gwt_binary",id:"gwt_binary",level:2},{value:"Parameters",id:"parameters-66",level:4},{value:"halide_library",id:"halide_library",level:2},{value:"Parameters",id:"parameters-67",level:4},{value:"Details",id:"details-45",level:4},{value:"haskell_binary",id:"haskell_binary",level:2},{value:"Parameters",id:"parameters-68",level:4},{value:"Details",id:"details-46",level:4},{value:"haskell_ghci",id:"haskell_ghci",level:2},{value:"Parameters",id:"parameters-69",level:4},{value:"haskell_haddock",id:"haskell_haddock",level:2},{value:"Parameters",id:"parameters-70",level:4},{value:"haskell_ide",id:"haskell_ide",level:2},{value:"Parameters",id:"parameters-71",level:4},{value:"haskell_library",id:"haskell_library",level:2},{value:"Parameters",id:"parameters-72",level:4},{value:"Details",id:"details-47",level:4},{value:"haskell_prebuilt_library",id:"haskell_prebuilt_library",level:2},{value:"Parameters",id:"parameters-73",level:4},{value:"Details",id:"details-48",level:4},{value:"http_archive",id:"http_archive",level:2},{value:"Parameters",id:"parameters-74",level:4},{value:"Details",id:"details-49",level:4},{value:"http_file",id:"http_file",level:2},{value:"Parameters",id:"parameters-75",level:4},{value:"Details",id:"details-50",level:4},{value:"jar_genrule",id:"jar_genrule",level:2},{value:"Parameters",id:"parameters-76",level:4},{value:"java_annotation_processor",id:"java_annotation_processor",level:2},{value:"Parameters",id:"parameters-77",level:4},{value:"java_binary",id:"java_binary",level:2},{value:"Parameters",id:"parameters-78",level:4},{value:"java_library",id:"java_library",level:2},{value:"Parameters",id:"parameters-79",level:4},{value:"Details",id:"details-51",level:4},{value:"java_plugin",id:"java_plugin",level:2},{value:"Parameters",id:"parameters-80",level:4},{value:"java_test",id:"java_test",level:2},{value:"Parameters",id:"parameters-81",level:4},{value:"java_test_runner",id:"java_test_runner",level:2},{value:"Parameters",id:"parameters-82",level:4},{value:"js_bundle",id:"js_bundle",level:2},{value:"Parameters",id:"parameters-83",level:4},{value:"js_bundle_genrule",id:"js_bundle_genrule",level:2},{value:"Parameters",id:"parameters-84",level:4},{value:"js_library",id:"js_library",level:2},{value:"Parameters",id:"parameters-85",level:4},{value:"julia_binary",id:"julia_binary",level:2},{value:"Parameters",id:"parameters-86",level:4},{value:"julia_jll_library",id:"julia_jll_library",level:2},{value:"Parameters",id:"parameters-87",level:4},{value:"julia_library",id:"julia_library",level:2},{value:"Parameters",id:"parameters-88",level:4},{value:"julia_test",id:"julia_test",level:2},{value:"Parameters",id:"parameters-89",level:4},{value:"keystore",id:"keystore",level:2},{value:"Parameters",id:"parameters-90",level:4},{value:"kotlin_library",id:"kotlin_library",level:2},{value:"Parameters",id:"parameters-91",level:4},{value:"Details",id:"details-52",level:4},{value:"kotlin_test",id:"kotlin_test",level:2},{value:"Parameters",id:"parameters-92",level:4},{value:"legacy_toolchain",id:"legacy_toolchain",level:2},{value:"Parameters",id:"parameters-93",level:4},{value:"llvm_link_bitcode",id:"llvm_link_bitcode",level:2},{value:"Parameters",id:"parameters-94",level:4},{value:"Details",id:"details-53",level:4},{value:"lua_binary",id:"lua_binary",level:2},{value:"Parameters",id:"parameters-95",level:4},{value:"Details",id:"details-54",level:4},{value:"lua_library",id:"lua_library",level:2},{value:"Parameters",id:"parameters-96",level:4},{value:"Details",id:"details-55",level:4},{value:"matlab_program",id:"matlab_program",level:2},{value:"Parameters",id:"parameters-97",level:4},{value:"ndk_library",id:"ndk_library",level:2},{value:"Parameters",id:"parameters-98",level:4},{value:"Details",id:"details-56",level:4},{value:"ndk_toolchain",id:"ndk_toolchain",level:2},{value:"Parameters",id:"parameters-99",level:4},{value:"ocaml_binary",id:"ocaml_binary",level:2},{value:"Parameters",id:"parameters-100",level:4},{value:"Details",id:"details-57",level:4},{value:"ocaml_library",id:"ocaml_library",level:2},{value:"Parameters",id:"parameters-101",level:4},{value:"Details",id:"details-58",level:4},{value:"ocaml_object",id:"ocaml_object",level:2},{value:"Parameters",id:"parameters-102",level:4},{value:"ocaml_shared",id:"ocaml_shared",level:2},{value:"Parameters",id:"parameters-103",level:4},{value:"platform",id:"platform",level:2},{value:"Parameters",id:"parameters-104",level:4},{value:"prebuilt_apple_framework",id:"prebuilt_apple_framework",level:2},{value:"Parameters",id:"parameters-105",level:4},{value:"Details",id:"details-59",level:4},{value:"prebuilt_cxx_library",id:"prebuilt_cxx_library",level:2},{value:"Parameters",id:"parameters-106",level:4},{value:"Details",id:"details-60",level:4},{value:"prebuilt_cxx_library_group",id:"prebuilt_cxx_library_group",level:2},{value:"Parameters",id:"parameters-107",level:4},{value:"Details",id:"details-61",level:4},{value:"prebuilt_dotnet_library",id:"prebuilt_dotnet_library",level:2},{value:"Parameters",id:"parameters-108",level:4},{value:"Details",id:"details-62",level:4},{value:"prebuilt_go_library",id:"prebuilt_go_library",level:2},{value:"Parameters",id:"parameters-109",level:4},{value:"Details",id:"details-63",level:4},{value:"prebuilt_jar",id:"prebuilt_jar",level:2},{value:"Parameters",id:"parameters-110",level:4},{value:"Details",id:"details-64",level:4},{value:"prebuilt_native_library",id:"prebuilt_native_library",level:2},{value:"Parameters",id:"parameters-111",level:4},{value:"Details",id:"details-65",level:4},{value:"prebuilt_ocaml_library",id:"prebuilt_ocaml_library",level:2},{value:"Parameters",id:"parameters-112",level:4},{value:"prebuilt_python_library",id:"prebuilt_python_library",level:2},{value:"Parameters",id:"parameters-113",level:4},{value:"Details",id:"details-66",level:4},{value:"python_binary",id:"python_binary",level:2},{value:"Parameters",id:"parameters-114",level:4},{value:"Details",id:"details-67",level:4},{value:"python_bootstrap_binary",id:"python_bootstrap_binary",level:2},{value:"Parameters",id:"parameters-115",level:4},{value:"python_bootstrap_library",id:"python_bootstrap_library",level:2},{value:"Parameters",id:"parameters-116",level:4},{value:"python_library",id:"python_library",level:2},{value:"Parameters",id:"parameters-117",level:4},{value:"Details",id:"details-68",level:4},{value:"python_needed_coverage_test",id:"python_needed_coverage_test",level:2},{value:"Parameters",id:"parameters-118",level:4},{value:"python_test",id:"python_test",level:2},{value:"Parameters",id:"parameters-119",level:4},{value:"Details",id:"details-69",level:4},{value:"python_test_runner",id:"python_test_runner",level:2},{value:"Parameters",id:"parameters-120",level:4},{value:"remote_file",id:"remote_file",level:2},{value:"Parameters",id:"parameters-121",level:4},{value:"Details",id:"details-70",level:4},{value:"robolectric_test",id:"robolectric_test",level:2},{value:"Parameters",id:"parameters-122",level:4},{value:"rust_binary",id:"rust_binary",level:2},{value:"Parameters",id:"parameters-123",level:4},{value:"Details",id:"details-71",level:4},{value:"rust_library",id:"rust_library",level:2},{value:"Parameters",id:"parameters-124",level:4},{value:"Details",id:"details-72",level:4},{value:"rust_test",id:"rust_test",level:2},{value:"Parameters",id:"parameters-125",level:4},{value:"Details",id:"details-73",level:4},{value:"scala_library",id:"scala_library",level:2},{value:"Parameters",id:"parameters-126",level:4},{value:"scala_test",id:"scala_test",level:2},{value:"Parameters",id:"parameters-127",level:4},{value:"scene_kit_assets",id:"scene_kit_assets",level:2},{value:"Parameters",id:"parameters-128",level:4},{value:"sh_binary",id:"sh_binary",level:2},{value:"Parameters",id:"parameters-129",level:4},{value:"Details",id:"details-74",level:4},{value:"sh_test",id:"sh_test",level:2},{value:"Parameters",id:"parameters-130",level:4},{value:"Details",id:"details-75",level:4},{value:"supermodule_target_graph",id:"supermodule_target_graph",level:2},{value:"Parameters",id:"parameters-131",level:4},{value:"swift_library",id:"swift_library",level:2},{value:"Parameters",id:"parameters-132",level:4},{value:"swift_toolchain",id:"swift_toolchain",level:2},{value:"Parameters",id:"parameters-133",level:4},{value:"test_suite",id:"test_suite",level:2},{value:"Parameters",id:"parameters-134",level:4},{value:"Details",id:"details-76",level:4},{value:"toolchain_alias",id:"toolchain_alias",level:2},{value:"Parameters",id:"parameters-135",level:4},{value:"Details",id:"details-77",level:4},{value:"versioned_alias",id:"versioned_alias",level:2},{value:"Parameters",id:"parameters-136",level:4},{value:"windows_resource",id:"windows_resource",level:2},{value:"Parameters",id:"parameters-137",level:4},{value:"Details",id:"details-78",level:4},{value:"worker_tool",id:"worker_tool",level:2},{value:"Parameters",id:"parameters-138",level:4},{value:"Details",id:"details-79",level:4},{value:"zip_file",id:"zip_file",level:2},{value:"Parameters",id:"parameters-139",level:4},{value:"Details",id:"details-80",level:4}],m={toc:d};function p(e){let{components:t,...a}=e;return(0,n.mdx)("wrapper",(0,i.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,n.mdx)("h1",{id:"rules"},"Rules"),(0,n.mdx)("p",null,"These rules are available as standard in Buck2."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def alias(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n actual: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_aar"},"android","_","aar"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_aar(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _is_building_android_binary: bool = _,\n _is_force_single_cpu: bool = _,\n _is_force_single_default_cpu: bool = _,\n _java_toolchain: str = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processing_tool: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n build_config_values: list[str] = _,\n build_config_values_file: None | str = _,\n compress_asset_libraries: bool = _,\n contacts: list[str] = _,\n cpu_filters: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n enable_relinker: bool = _,\n excluded_java_deps: list[str] = _,\n extra_arguments: list[str] = _,\n extra_kotlinc_arguments: list[str] = _,\n friend_paths: list[str] = _,\n include_build_config_class: bool = _,\n java_version: None | str = _,\n javac: None | str = _,\n kotlin_compiler_plugins: dict[str, dict[str, str]] = _,\n labels: list[str] = _,\n language: None | str = _,\n licenses: list[str] = _,\n manifest: None | str = _,\n manifest_file: None | str = _,\n manifest_skeleton: str,\n maven_coords: None | str = _,\n min_sdk_version: None | int = _,\n native_library_merge_code_generator: None | str = _,\n native_library_merge_glue: None | str = _,\n native_library_merge_linker_args: None | dict[str, list[str]] = _,\n native_library_merge_localized_symbols: None | list[str] = _,\n native_library_merge_map: None | dict[str, list[str]] = _,\n native_library_merge_sequence: None | list[typing.Any] = _,\n native_library_merge_sequence_blocklist: None | list[str] = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n package_asset_libraries: bool = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n relinker_whitelist: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resource_union_package: None | str = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n strip_libraries: bool = _,\n target: None | str = _,\n use_jvm_abi_gen: None | bool = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_aar()")," rule is used to generate an Android AAR."),(0,n.mdx)("h4",{id:"parameters-1"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"build_config_values"),": See the documentation on the values argument for ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_build\\_config()"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"include_build_config_class"),": Whether to include the ",(0,n.mdx)("inlineCode",{parentName:"li"},"BuildConfig")," class files in the final .aar file. Needs to be set to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True")," if any build","_","config","_","values are specified. This is normally only needed if the build tool that is consuming the .aar file does not generate ",(0,n.mdx)("inlineCode",{parentName:"li"},"BuildConfig")," classes. Note: the AAR format does not specify a way to pass defaults that should be injected into the final ",(0,n.mdx)("inlineCode",{parentName:"li"},"BuildConfig")," class, therefore that information might need to be replicated manually in the build that's consuming the .aar file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"manifest_skeleton"),": The skeleton manifest file used to generate the final ",(0,n.mdx)("inlineCode",{parentName:"li"},"AndroidManifest.xml")," . May either be a file or a ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_manifest()"),"target."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"remove_classes"),": List of classes to remove from the output aar. It removes classes from the target's own sources, and its dependencies.")),(0,n.mdx)("h4",{id:"details"},"Details"),(0,n.mdx)("p",null,"See the ",(0,n.mdx)("a",{parentName:"p",href:"https://developer.android.com/studio/projects/android-library#aar-contents"},"official Android documentation")," for details about the ",(0,n.mdx)("inlineCode",{parentName:"p"},".aar")," format."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_resource(\n name = 'res',\n res = 'res',\n assets = 'assets',\n package = 'com.example',\n)\n\nandroid_library(\n name = 'lib',\n srcs = glob(['**/*.java']),\n)\n\nandroid_aar(\n name = 'app',\n manifest_skeleton = 'AndroidManifestSkeleton.xml',\n deps = [\n ':res',\n ':lib',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_app_modularity"},"android","_","app","_","modularity"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_app_modularity(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n application_module_blacklist: None | list[str] = _,\n application_module_configs: dict[str, list[str]] = _,\n application_module_dependencies: None | dict[str, list[str]] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n no_dx: list[str] = _,\n should_include_classes: bool = _,\n should_include_libraries: bool = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-2"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_binary"},"android","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _is_building_android_binary: bool = _,\n _is_force_single_cpu: bool = _,\n _is_force_single_default_cpu: bool = _,\n _java_toolchain: str = _,\n aapt2_keep_raw_values: bool = _,\n aapt2_locale_filtering: bool = _,\n aapt2_preferred_density: None | str = _,\n aapt_mode: str = _,\n additional_aapt_params: list[str] = _,\n allow_r_dot_java_in_secondary_dex: bool = _,\n allowed_duplicate_resource_types: list[str] = _,\n android_sdk_proguard_config: None | str = _,\n application_module_blacklist: None | list[str] = _,\n application_module_configs: dict[str, list[str]] = _,\n application_module_dependencies: None | dict[str, list[str]] = _,\n asset_compression_algorithm: None | str = _,\n banned_duplicate_resource_types: list[str] = _,\n buck2_compatibility: str = _,\n build_config_values: list[str] = _,\n build_config_values_file: None | str = _,\n build_string_source_map: bool = _,\n compress_asset_libraries: bool = _,\n constraint_overrides: list[str] = _,\n contacts: list[str] = _,\n cpu_filters: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n dex_compression: None | str = _,\n dex_group_lib_limit: int = _,\n dex_tool: str = _,\n disable_pre_dex: bool = _,\n duplicate_resource_behavior: str = _,\n duplicate_resource_whitelist: None | str = _,\n enable_relinker: bool = _,\n exopackage_modes: list[str] = _,\n extra_filtered_resources: list[str] = _,\n extra_no_compress_asset_extensions: list[str] = _,\n field_ref_count_buffer_space: int = _,\n ignore_aapt_proguard_config: bool = _,\n includes_vector_drawables: bool = _,\n is_cacheable: bool = _,\n is_voltron_language_pack_enabled: bool = _,\n keystore: str,\n labels: list[str] = _,\n licenses: list[str] = _,\n linear_alloc_hard_limit: int = _,\n locales: list[str] = _,\n manifest: None | str = _,\n manifest_entries: dict[str, typing.Any] = _,\n manifest_skeleton: None | str = _,\n method_ref_count_buffer_space: int = _,\n min_sdk_version: None | int = _,\n minimize_primary_dex_size: bool = _,\n module_manifest_skeleton: None | str = _,\n native_library_merge_code_generator: None | str = _,\n native_library_merge_glue: None | str = _,\n native_library_merge_linker_args: None | dict[str, list[str]] = _,\n native_library_merge_localized_symbols: None | list[str] = _,\n native_library_merge_map: None | dict[str, list[str]] = _,\n native_library_merge_sequence: None | list[typing.Any] = _,\n native_library_merge_sequence_blocklist: None | list[str] = _,\n no_auto_add_overlay_resources: bool = _,\n no_auto_version_resources: bool = _,\n no_dx: list[str] = _,\n no_version_transitions_resources: bool = _,\n optimization_passes: int = _,\n package_asset_libraries: bool = _,\n package_type: str = _,\n packaged_locales: list[str] = _,\n packaging_options: dict[str, list[str]] = _,\n post_filter_resources_cmd: None | str = _,\n preprocess_java_classes_bash: None | str = _,\n preprocess_java_classes_cmd: None | str = _,\n preprocess_java_classes_deps: list[str] = _,\n primary_dex_patterns: list[str] = _,\n proguard_config: None | str = _,\n proguard_jvm_args: list[str] = _,\n relinker_whitelist: list[str] = _,\n resource_compression: str = _,\n resource_filter: list[str] = _,\n resource_stable_ids: None | str = _,\n resource_union_package: None | str = _,\n secondary_dex_weight_limit: None | int = _,\n skip_crunch_pngs: None | bool = _,\n skip_proguard: bool = _,\n strip_libraries: bool = _,\n trim_resource_ids: bool = _,\n use_split_dex: bool = _,\n validation_deps: list[str] = _,\n xz_compression_level: int = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-3"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_build_config"},"android","_","build","_","config"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_build_config(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _is_building_android_binary: bool = _,\n _java_toolchain: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n package: str = _,\n values: list[str] = _,\n values_file: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_build_config()")," rule is used to generate a ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig")," class with global configuration variables that other ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_library()"),"rules can compile against. Currently, the only variable exposed by ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig")," is a global ",(0,n.mdx)("inlineCode",{parentName:"p"},"boolean")," named ",(0,n.mdx)("inlineCode",{parentName:"p"},"DEBUG"),", much like the ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig.java")," generated by the official Android build tools based on Gradle."),(0,n.mdx)("h4",{id:"parameters-4"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"package"),": Name of the Java package to use in the generated ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig.java")," file. Most developers set this to the application id declared in the manifest via ",(0,n.mdx)("inlineCode",{parentName:"p"},''),". Example: ",(0,n.mdx)("inlineCode",{parentName:"p"},"com.facebook.orca"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"values"),": List of strings that defines additional fields (and values) that should be declared in the generated ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig.java")," file. Like ",(0,n.mdx)("inlineCode",{parentName:"p"},"DEBUG"),", the values will be non-constant-expressions that evaluate to the value specified in the file at compilation time. To override the values in an APK, specify build","_","config","_","values or build","_","config","_","values","_","file in ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_binary()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"values_file"),": Optional path to a file that defines additional fields (and values) that should be declared in the generated ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig.java")," file. Like ",(0,n.mdx)("inlineCode",{parentName:"p"},"DEBUG"),", the values will be non-constant-expressions that evaluate to the value specified in the file at compilation time. To override the values in an APK, specify build","_","config","_","values or build","_","config","_","values","_","file in ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_binary()"),"."),(0,n.mdx)("p",{parentName:"li"},"Note that values","_","file can be a generated file, as can build","_","config","_","values","_","file as\ndemonstrated in the example below."))),(0,n.mdx)("h4",{id:"details-1"},"Details"),(0,n.mdx)("p",null,"The fields in the generated ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig")," class will\nbe non-constant-expressions (see ",(0,n.mdx)("a",{parentName:"p",href:"http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28"},"JLS 15.28"),").\nHowever, if ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig")," is packaged into an APK, it will\nbe replaced with a new version where:"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},"The fields will be set to literal values (i.e., constant expressions)."),(0,n.mdx)("li",{parentName:"ul"},"The ",(0,n.mdx)("inlineCode",{parentName:"li"},"boolean BuildConfig.DEBUG")," field will correspond to\nthat of the ",(0,n.mdx)("inlineCode",{parentName:"li"},"package_type")," argument to the ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_binary()"),"rule\nthat is packaging it.")),(0,n.mdx)("p",null,"This transformation is done before ProGuard is applied (if applicable), so\nthat it can propagate constants from ",(0,n.mdx)("inlineCode",{parentName:"p"},"BuildConfig")," and eliminate\ndead code."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Here is an example of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_build_config()")," rule that\nis transitively included by both ",(0,n.mdx)("em",{parentName:"p"},"debug")," and ",(0,n.mdx)("em",{parentName:"p"},"release")," versions\nof an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_binary()"),"rule. The value\nof ",(0,n.mdx)("inlineCode",{parentName:"p"},"com.example.pkg.BuildConfig.DEBUG")," will be different in each APK\neven though they both transitively depend on the same ",(0,n.mdx)("inlineCode",{parentName:"p"},":build_config")," rule."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_build_config(\n name = 'build_config',\n package = 'com.example.pkg',\n values = [\n 'String COMMIT_ID = \"0000000000000000000000000000000000000000\"',\n ],\n)\n\n# The .java files in this library may contain references to the boolean\n# com.example.pkg.BuildConfig.DEBUG because :build_config is in the deps.\n# It could also reference BuildConfig.COMMIT_ID.\nandroid_library(\n name = 'mylib',\n srcs = glob(['src/**/*.java']),\n deps = [\n ':build_config',\n ],\n)\n\nandroid_binary(\n name = 'debug',\n package_type = 'DEBUG',\n keystore = '//keystores:debug',\n manifest = 'AndroidManifest.xml',\n target = 'Google Inc.:Google APIs:19',\n deps = [\n ':mylib',\n ],\n)\n\n# The contents of the file generated by this rule might be:\n#\n# String COMMIT_ID = \"7bf804bdf71fdbfc99cce3b155b3643f022c6fa4\"\n#\n# Note that the output of :build_config_release_values will be cached by Buck.\n# Assuming that generate_release_build_config.py depends on state that is not\n# expressed by its deps (which violates a fundamental invariant in Buck!), a\n# workaround is to ensure that the inputs to :build_config_release_values are\n# changed in some way before :release is built to ensure that the output from\n# :build_config_release_values is not pulled from cache. For example:\n#\n# $ buck build :release\n# $ uuidgen > dummy_state_file.txt\n# $ buck build :release\n#\n# This makes sure that generate_release_build_config.py is re-run before\n# :release is rebuilt. This is much cheaper than deleting your build cache\n# before rebuilding.\ngenrule(\n name = 'build_config_release_values',\n srcs = [ 'generate_release_build_config.py', 'dummy_state_file.txt' ],\n bash = 'generate_release_build_config.py $OUT',\n out = 'build_config_release_values.txt',\n)\n\nandroid_binary(\n name = 'release',\n package_type = 'RELEASE',\n keystore = '//keystores:release',\n manifest = 'AndroidManifest.xml',\n target = 'Google Inc.:Google APIs:19',\n build_config_values_file = ':build_config_release_values',\n deps = [\n ':mylib',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_bundle"},"android","_","bundle"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_bundle(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _is_building_android_binary: bool = _,\n _is_force_single_cpu: bool = _,\n _is_force_single_default_cpu: bool = _,\n _java_toolchain: str = _,\n aapt2_keep_raw_values: bool = _,\n aapt2_locale_filtering: bool = _,\n aapt2_preferred_density: None | str = _,\n aapt_mode: str = _,\n additional_aapt_params: list[str] = _,\n allow_r_dot_java_in_secondary_dex: bool = _,\n allowed_duplicate_resource_types: list[str] = _,\n android_sdk_proguard_config: None | str = _,\n application_module_blacklist: None | list[str] = _,\n application_module_configs: dict[str, list[str]] = _,\n application_module_dependencies: None | dict[str, list[str]] = _,\n asset_compression_algorithm: None | str = _,\n banned_duplicate_resource_types: list[str] = _,\n buck2_compatibility: str = _,\n build_config_values: list[str] = _,\n build_config_values_file: None | str = _,\n build_string_source_map: bool = _,\n bundle_config_file: None | str = _,\n compress_asset_libraries: bool = _,\n contacts: list[str] = _,\n cpu_filters: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n dex_compression: None | str = _,\n dex_group_lib_limit: int = _,\n dex_tool: str = _,\n disable_pre_dex: bool = _,\n duplicate_resource_behavior: str = _,\n duplicate_resource_whitelist: None | str = _,\n enable_relinker: bool = _,\n exopackage_modes: list[str] = _,\n extra_filtered_resources: list[str] = _,\n extra_no_compress_asset_extensions: list[str] = _,\n field_ref_count_buffer_space: int = _,\n ignore_aapt_proguard_config: bool = _,\n includes_vector_drawables: bool = _,\n is_cacheable: bool = _,\n is_voltron_language_pack_enabled: bool = _,\n keystore: str,\n labels: list[str] = _,\n licenses: list[str] = _,\n linear_alloc_hard_limit: int = _,\n locales: list[str] = _,\n manifest: None | str = _,\n manifest_entries: dict[str, typing.Any] = _,\n manifest_skeleton: None | str = _,\n method_ref_count_buffer_space: int = _,\n min_sdk_version: None | int = _,\n minimize_primary_dex_size: bool = _,\n module_manifest_skeleton: None | str = _,\n native_library_merge_code_generator: None | str = _,\n native_library_merge_glue: None | str = _,\n native_library_merge_linker_args: None | dict[str, list[str]] = _,\n native_library_merge_localized_symbols: None | list[str] = _,\n native_library_merge_map: None | dict[str, list[str]] = _,\n native_library_merge_sequence: None | list[typing.Any] = _,\n native_library_merge_sequence_blocklist: None | list[str] = _,\n no_auto_add_overlay_resources: bool = _,\n no_auto_version_resources: bool = _,\n no_dx: list[str] = _,\n no_version_transitions_resources: bool = _,\n optimization_passes: int = _,\n package_asset_libraries: bool = _,\n package_type: str = _,\n packaged_locales: list[str] = _,\n packaging_options: dict[str, list[str]] = _,\n post_filter_resources_cmd: None | str = _,\n preprocess_java_classes_bash: None | str = _,\n preprocess_java_classes_cmd: None | str = _,\n preprocess_java_classes_deps: list[str] = _,\n primary_dex_patterns: list[str] = _,\n proguard_config: None | str = _,\n proguard_jvm_args: list[str] = _,\n relinker_whitelist: list[str] = _,\n resource_compression: str = _,\n resource_filter: list[str] = _,\n resource_stable_ids: None | str = _,\n resource_union_package: None | str = _,\n secondary_dex_weight_limit: None | int = _,\n skip_crunch_pngs: None | bool = _,\n skip_proguard: bool = _,\n trim_resource_ids: bool = _,\n use_derived_apk: bool = _,\n use_split_dex: bool = _,\n validation_deps: list[str] = _,\n xz_compression_level: int = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-5"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_instrumentation_apk"},"android","_","instrumentation","_","apk"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_instrumentation_apk(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _is_building_android_binary: bool = _,\n _is_force_single_cpu: bool = _,\n _is_force_single_default_cpu: bool = _,\n _java_toolchain: str = _,\n aapt_mode: str = _,\n apk: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cpu_filters: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n dex_tool: str = _,\n disable_pre_dex: bool = _,\n includes_vector_drawables: bool = _,\n is_self_instrumenting: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest: None | str = _,\n manifest_skeleton: None | str = _,\n min_sdk_version: None | int = _,\n native_library_merge_map: None | dict[str, list[str]] = _,\n native_library_merge_sequence: None | list[typing.Any] = _,\n preprocess_java_classes_bash: None | str = _,\n preprocess_java_classes_cmd: None | str = _,\n preprocess_java_classes_deps: list[str] = _,\n primary_dex_patterns: list[str] = _,\n use_split_dex: None | bool = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_instrumentation_apk()")," rule is used to generate an Android Instrumentation APK."),(0,n.mdx)("h4",{id:"parameters-6"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("h4",{id:"details-2"},"Details"),(0,n.mdx)("p",null,"Android's ",(0,n.mdx)("a",{parentName:"p",href:"http://developer.android.com/tools/testing/testing_android.html"},"Testing Fundamentals"),' documentation includes a diagram that shows\nthe relationship between an "application package" and a "test package"\nwhen running a test. This rule corresponds to a test package. Note\nthat a test package has an interesting quirk where it is ',(0,n.mdx)("em",{parentName:"p"},"compiled\nagainst")," an application package, but ",(0,n.mdx)("em",{parentName:"p"},"must not include")," the\nresources or Java classes of the application package. Therefore, this\nclass takes responsibility for making sure the appropriate bits are\nexcluded. Failing to do so will generate mysterious runtime errors\nwhen running the test."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Here is an example of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_instrumentation_apk()")," rule that tests a ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_binary()"),", and depends on a test\npackage."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_library(\n name = 'test',\n srcs = glob(['test/**/*.java']),\n)\n\nandroid_binary(\n name = 'messenger',\n manifest = 'AndroidManifest.xml',\n keystore = '//keystores:prod',\n package_type = 'release',\n proguard_config = 'proguard.cfg',\n deps = [\n ...\n ],\n)\n\n# Building this rule will produce a file named messenger_test.apk\nandroid_instrumentation_apk(\n name = 'messenger_test',\n manifest = 'AndroidInstrumentationManifest.xml',\n apk = ':messenger',\n deps = [\n ':test',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_instrumentation_test"},"android","_","instrumentation","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_instrumentation_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _exec_os_type: str = _,\n _inject_test_env: str = _,\n _java_test_toolchain: str = _,\n _java_toolchain: str = _,\n apk: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n env: dict[str, str] = _,\n extra_instrumentation_args: None | dict[str, str] = _,\n instrumentation_test_listener: None | str = _,\n instrumentation_test_listener_class: None | str = _,\n is_self_instrumenting: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n test_rule_timeout_ms: None | int = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_instrumentation_test()")," rule is used to define apks that should be used to run Android instrumentation tests."),(0,n.mdx)("h4",{id:"parameters-7"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"apk"),": The APK containing the tests. Can be an ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_binary()"),", an ",(0,n.mdx)("inlineCode",{parentName:"li"},"apk\\_genrule()"),"or an ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_instrumentation\\_apk()"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"labels"),": A list of labels to be applied to these tests. These labels are arbitrary text strings and have no meaning within buck itself. They can, however, have meaning for you as a test author (e.g., ",(0,n.mdx)("inlineCode",{parentName:"li"},"smoke")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"fast"),"). A label can be used to filter or include a specific test rule when executing ",(0,n.mdx)("inlineCode",{parentName:"li"},"buck test")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"test_rule_timeout_ms"),": If set specifies the maximum amount of time (in milliseconds) in which all of the tests in this rule should complete. This overrides the default ",(0,n.mdx)("inlineCode",{parentName:"li"},"rule_timeout")," if any has been specified in ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig")," .")),(0,n.mdx)("h4",{id:"details-3"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Here is an example of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_instrumentation_test()"),"\nrule that tests an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_binary()"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_binary(\n name = 'messenger',\n manifest = 'AndroidManifest.xml',\n keystore = '//keystores:prod',\n package_type = 'release',\n proguard_config = 'proguard.cfg',\n deps = [\n ...\n ],\n)\n\nandroid_instrumentation_apk(\n name = 'messenger_test',\n manifest = 'AndroidInstrumentationManifest.xml',\n apk = ':messenger',\n deps = [\n ...\n ],\n)\n\nandroid_instrumentation_test(\n name = 'messenger_instrumentation_test',\n apk = ':messenger_test',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_library"},"android","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _dex_min_sdk_version: None | int = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _is_building_android_binary: bool = _,\n _java_toolchain: str = _,\n _kotlin_toolchain: str = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n android_optional_jars: None | list[str] = _,\n annotation_processing_tool: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n extra_kotlinc_arguments: list[str] = _,\n friend_paths: list[str] = _,\n jar_postprocessor: None | str = _,\n java_version: None | str = _,\n javac: None | str = _,\n k2: bool = _,\n kotlin_compiler_plugins: dict[str, dict[str, str]] = _,\n labels: list[str] = _,\n language: None | str = _,\n licenses: list[str] = _,\n manifest: None | str = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n provided_deps_query: None | str = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resource_union_package: None | str = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n target: None | str = _,\n use_jvm_abi_gen: None | bool = _,\n validation_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_library()")," rule is used to define a set of Java files that can be compiled together against the Android SDK. The main output of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_library()")," rule is a single JAR file containing all of the compiled class files and resources."),(0,n.mdx)("h4",{id:"parameters-8"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"annotation_processing_tool"),': Specifies the tool to use for annotation processing. Possible values: "kapt" or "javac". "kapt" allows running Java annotation processors against Kotlin sources while backporting it for Java sources too. "javac" works only against Java sources, Kotlin sources won\'t have access to generated classes at compile time.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Rules (usually other ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_library")," rules) that are used to generate the classpath required to compile this ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_library"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),": Other rules that depend on this rule will also include its ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," in their classpaths. This is useful when the public API of a rule has return types or checked exceptions that are defined in another rule, which would otherwise require callers to add an extra dependency. It's also useful for exposing e.g. a collection of ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_jar")," rules as a single target for callers to depend on. Targets in ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," are implicitly included in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps")," of this rule, so they don't need to be repeated there.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_provided_deps"),": This is a combination of ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),". Rules listed in this parameter will be added to classpath of rules that depend on this rule, but they will not be included in a binary if binary depends on a such target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_arguments"),": List of additional arguments to pass into the Java compiler. These arguments follow the ones specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_kotlinc_arguments"),": List of additional arguments to pass into the Kotlin compiler.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"k2"),": Enables the Kotlin K2 compiler.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"manifest"),": An optional ",(0,n.mdx)("a",{parentName:"p",href:"http://developer.android.com/guide/topics/manifest/manifest-intro.html"},"Android Manifest")," for the to declare any permissions or intents it may need or want to handle. May either be a file or a ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_manifest()"),"target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps"),": These represent dependencies that are known to be provided at run time, but are required in order for the code to compile. Examples of ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," include the JEE servlet APIs. When this rule is included in a , the ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," will not be packaged into the output.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps_query"),": Status: ",(0,n.mdx)("strong",{parentName:"p"},"experimental/unstable"),". The provided deps query functions in the same way as the deps query, but the referenced deps using ",(0,n.mdx)("inlineCode",{parentName:"p"},"$declared")," are the provided deps of the target, and the results of the query are appended to the declared provided deps.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"remove_classes"),": List of classes to remove from the output jar. It only removes classes from the target's own sources, not from any of its dependencies.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"required_for_source_only_abi"),": Indicates that this rule must be present on the classpath during ",(0,n.mdx)("inlineCode",{parentName:"p"},"source-only ABI generation")," of any rule that depends on it. Typically this is done when a rule contains annotations, enums, constants, or interfaces."),(0,n.mdx)("p",{parentName:"li"},"Having rules present on the classpath during source-only ABI generation prevents Buck from\ncompletely flattening the build graph, thus reducing the performance win from source-only\nABI generation. These rules should be kept small (ideally just containing annotations,\nconstants, enums, and interfaces) and with minimal dependencies of their own.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": Static files to include among the compiled ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files. These files can be loaded via ",(0,n.mdx)("a",{parentName:"p",href:"http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource(java.lang.String)"},"Class.getResource()"),"."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("strong",{parentName:"p"},"Note:")," Buck uses the ",(0,n.mdx)("inlineCode",{parentName:"p"},"src_roots")," property in\n",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nto help determine where resources should be placed within the generated JAR file.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"source"),': Specifies the version of Java (as a string) to interpret source files as. Overrides the value in "source',"_",'level" in the "java" section of ',(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"source_only_abi_deps"),": These are dependencies that must be present during ",(0,n.mdx)("inlineCode",{parentName:"p"},"source-only ABI generation"),". Typically such dependencies are added when some property of the code in this rule prevents source-only ABI generation from being correct without these dependencies being present."),(0,n.mdx)("p",{parentName:"li"},"Having ",(0,n.mdx)("inlineCode",{parentName:"p"},"source_only_abi_deps")," prevents Buck from\ncompletely flattening the build graph, thus reducing the performance win from source-only\nABI generation. They should be avoided when possible. Often only a small code change is needed to avoid them.\nFor more information on such code changes, read about\n",(0,n.mdx)("inlineCode",{parentName:"p"},"source-only ABI generation"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," files to compile for this rule.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target"),': Specifies the version of Java (as a string) for which to generate code. Overrides the value in "target',"_",'level" in the "java" section of ',(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"."))),(0,n.mdx)("h4",{id:"details-4"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_library")," rule used in concert with an\n",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_resource()"),"rule.\nThis would be a common arrangement for a standard Android Library project\nas defined by\n",(0,n.mdx)("a",{parentName:"p",href:"http://developer.android.com/tools/projects/index.html"},"http://developer.android.com/tools/projects/index.html")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_resource(\n name = 'res',\n res = 'res',\n package = 'com.example',\n)\n\nandroid_library(\n name = 'my_library',\n srcs = glob(['src/**/*.java']),\n deps = [\n ':res',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_manifest"},"android","_","manifest"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_manifest(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n skeleton: str\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_manifest()")," rule is used to generate an ",(0,n.mdx)("a",{parentName:"p",href:"http://developer.android.com/guide/topics/manifest/manifest-intro.html"},"Android Manifest")," to be used by ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_binary()"),"and ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_aar()"),"rules. This rule takes a skeleton manifest, and merges it with manifests found in any deps."),(0,n.mdx)("h4",{id:"parameters-9"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": A collection of dependencies that includes android","_","library rules. The manifest files of the ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_library()"),"rules will be filtered out to become dependent source files for the manifest."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"skeleton"),": Either a ",(0,n.mdx)("inlineCode",{parentName:"li"},"build target"),"or a path to a file representing the manifest that will be merged with any manifests associated with this rule's ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),".")),(0,n.mdx)("h4",{id:"details-5"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Here's an example of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_manifest()")," that has no deps."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_manifest(\n name = 'my-manifest',\n skeleton = 'AndroidManifestSkeleton.xml',\n)\n\n")),(0,n.mdx)("p",null," This is what ",(0,n.mdx)("inlineCode",{parentName:"p"},"AndroidManifestSkeleton.xml")," looks like."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n\n\n\n \n \n \n \n \n \n \n \n \n\n\n')),(0,n.mdx)("p",null," You could also use a ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),"to generate the manifest file and reference the\n",(0,n.mdx)("inlineCode",{parentName:"p"},"build target"),"in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"skeleton")," argument."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_platform"},"android","_","platform"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_platform(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n base_platform: str,\n buck2_compatibility: str = _,\n native_platforms: dict[str, str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-10"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_prebuilt_aar"},"android","_","prebuilt","_","aar"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_prebuilt_aar(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _dex_min_sdk_version: None | int = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _java_toolchain: str = _,\n aar: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n desugar_deps: list[str] = _,\n for_primary_apk: bool = _,\n javadoc_url: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n maven_coords: None | str = _,\n required_for_source_only_abi: bool = _,\n source_jar: None | str = _,\n use_system_library_loader: bool = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_prebuilt_aar()")," rule takes an ",(0,n.mdx)("inlineCode",{parentName:"p"},".aar")," file and makes it available as an Android dependency. As expected, an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_binary()"),"that transitively depends on an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_prebuilt_aar()")," will include its contents in the generated APK."),(0,n.mdx)("h4",{id:"parameters-11"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"aar"),": Path to the ",(0,n.mdx)("inlineCode",{parentName:"li"},".aar")," file. This may also be a build target to a rule (such as a ",(0,n.mdx)("inlineCode",{parentName:"li"},"genrule()"),") whose output is an ",(0,n.mdx)("inlineCode",{parentName:"li"},".aar")," file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"javadoc_url"),": URL to the Javadoc for the ",(0,n.mdx)("inlineCode",{parentName:"li"},".class")," files in the ",(0,n.mdx)("inlineCode",{parentName:"li"},"aar"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"source_jar"),": Path to a JAR file that contains the ",(0,n.mdx)("inlineCode",{parentName:"li"},".java")," files to create the ",(0,n.mdx)("inlineCode",{parentName:"li"},".class")," in the ",(0,n.mdx)("inlineCode",{parentName:"li"},"aar"),". This is frequently provided for debugging purposes."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"use_system_library_loader"),": If this ",(0,n.mdx)("inlineCode",{parentName:"li"},".aar")," file contains native prebuilt ",(0,n.mdx)("inlineCode",{parentName:"li"},".so")," libraries and the Java code uses these libraries via a call to ",(0,n.mdx)("inlineCode",{parentName:"li"},"System.loadLibrary()"),", then many optimizations\u2014such as exopackage, compression, or asset packaging\u2014may not be compatible with these prebuilt libs. Setting this parameter to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True")," causes all of these optimizations to skip the prebuilt ",(0,n.mdx)("inlineCode",{parentName:"li"},".so")," files originating from this ",(0,n.mdx)("inlineCode",{parentName:"li"},".aar")," file. The ",(0,n.mdx)("inlineCode",{parentName:"li"},".so")," files will always be packaged directly into the main ",(0,n.mdx)("inlineCode",{parentName:"li"},".apk"),".")),(0,n.mdx)("h4",{id:"details-6"},"Details"),(0,n.mdx)("p",null,"See the ",(0,n.mdx)("a",{parentName:"p",href:"https://developer.android.com/studio/projects/android-library#aar-contents"},"official Android documentation")," for details about the ",(0,n.mdx)("inlineCode",{parentName:"p"},".aar")," format."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_prebuilt_aar(\n name = 'play-services',\n aar = 'play-services-4.0.30.aar',\n source_jar = 'play-services-4.0.30-sources.jar',\n javadoc_url = 'file:///opt/android-sdk/extras/google/google_play_services/docs/reference',\n)\n\nandroid_library(\n name = 'lib',\n # This Java code can compile against Play services and reference its resources.\n srcs = glob(['*.java']),\n deps = [ ':play-services' ],\n)\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"android_resource"},"android","_","resource"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def android_resource(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n allowlisted_locales: None | list[str] = _,\n assets: None | str | dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n has_whitelisted_strings: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest: None | str = _,\n package: None | str = _,\n project_assets: None | str = _,\n project_res: None | str = _,\n res: None | str | dict[str, str] = _,\n resource_union: bool = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_resource()")," rule is used to bundle Android resources that are traditionally stored in ",(0,n.mdx)("inlineCode",{parentName:"p"},"res")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"assets")," directories."),(0,n.mdx)("h4",{id:"parameters-12"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Other ",(0,n.mdx)("inlineCode",{parentName:"li"},"android_resource")," rules to include via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-S")," when running ",(0,n.mdx)("inlineCode",{parentName:"li"},"aapt"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"manifest"),": An optional ",(0,n.mdx)("a",{parentName:"li",href:"http://developer.android.com/guide/topics/manifest/manifest-intro.html"},"Android Manifest")," for the to declare any permissions or intents it may need or want to handle. May either be a file or a ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_manifest()"),"target."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package"),": Java package for the ",(0,n.mdx)("inlineCode",{parentName:"li"},"R.java")," file that will be generated for these resources.")),(0,n.mdx)("h4",{id:"details-7"},"Details"),(0,n.mdx)("p",null,"The output of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_resource()")," is an ",(0,n.mdx)("inlineCode",{parentName:"p"},"R.txt")," file\ngenerated via ",(0,n.mdx)("inlineCode",{parentName:"p"},"aapt --output-text-symbols"),"."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Most of the time, an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_resource")," rule defines only ",(0,n.mdx)("inlineCode",{parentName:"p"},"name"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"res"),", and ",(0,n.mdx)("inlineCode",{parentName:"p"},"package"),". By convention,\nsuch simple rules are often named ",(0,n.mdx)("inlineCode",{parentName:"p"},"res"),":"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_resource(\n name = 'res',\n res = subdir_glob([('res', '**')]),\n package = 'com.example',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apk_genrule"},"apk","_","genrule"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apk_genrule(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _exec_os_type: str = _,\n _genrule_toolchain: str = _,\n _java_toolchain: str = _,\n aab: None | str = _,\n always_print_stderr: bool = _,\n apk: None | str = _,\n bash: None | str = _,\n buck2_compatibility: str = _,\n cacheable: None | bool = _,\n cmd: None | str = _,\n cmd_exe: None | str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n default_outs: None | list[str] = _,\n enable_sandbox: None | bool = _,\n environment_expansion_separator: None | str = _,\n is_cacheable: bool = _,\n keystore: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n metadata_env_var: None | str = _,\n metadata_path: None | str = _,\n need_android_tools: bool = _,\n no_outputs_cleanup: bool = _,\n out: None | str = _,\n outs: None | dict[str, list[str]] = _,\n remote: None | bool = _,\n remote_execution_dependencies: list[dict[str, str]] = _,\n srcs: list[str] | dict[str, str] = _,\n type: str = _,\n use_derived_apk: bool = _,\n weight: None | int = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apk_genrule()")," rule is used to post-process an APK. What separates an apk","_","genrule from a genrule is apk","_","genrules are known by BUCK to produce APKs, so commands like ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck install")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck uninstall")," still work. Additionally, ",(0,n.mdx)("inlineCode",{parentName:"p"},"apk_genrule()")," rules can be inputs to other ",(0,n.mdx)("inlineCode",{parentName:"p"},"apk_genrule()")," rules."),(0,n.mdx)("h4",{id:"parameters-13"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"aab"),": The input ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_binary()")," rule. The path to the AAB can be accessed with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"$AAB")," shell variable. Only one of ",(0,n.mdx)("inlineCode",{parentName:"p"},"apk")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"aab")," can be provided.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"apk"),": The input ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_binary()")," rule. The path to the APK can be accessed with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"$APK")," shell variable. Only one of ",(0,n.mdx)("inlineCode",{parentName:"p"},"apk")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"aab")," can be provided.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"bash"),": A platform-specific version of the shell command parameter ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". It runs on Linux and UNIX systems\u2014including OSX\u2014on which ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," is installed. It has a higher priority than ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". The ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," argument is run with ",(0,n.mdx)("inlineCode",{parentName:"p"},"/usr/bin/env bash -c"),". It has access to the same set of macros and variables as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),": The shell command to run to generate the output file. It is the fallback for ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe")," arguments. The following environment variables are populated by Buck and available to the shell command. They are accessed using the syntax:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"${}\n")),(0,n.mdx)("p",{parentName:"li"}," Example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"${SRCS}\n")),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${SRCS}")),(0,n.mdx)("p",{parentName:"li"}," A string expansion of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," argument delimited\nby the ",(0,n.mdx)("inlineCode",{parentName:"p"},"environment_expansion_separator")," argument\nwhere each element of ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," will be translated\ninto a relative path."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${SRCDIR}")),(0,n.mdx)("p",{parentName:"li"}," The relative path to a directory to which sources are copied\nprior to running the command."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${OUT}")),(0,n.mdx)("p",{parentName:"li"}," The output file or directory for the ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),".\nThis variable will have whatever value is specified by\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"out")," argument if not using named outputs. If\nusing named outputs, this variable will be the output directory."),(0,n.mdx)("p",{parentName:"li"}," The value should be a valid filepath. The semantics of the shell\ncommand determine whether this filepath is treated as a file or a\ndirectory. If the filepath is a directory, then the shell command\nneeds to create it if not using named outputs. Otherwise, it will\nbe automatically created. All outputs (directories and files) must\nbe readable, writable, and (in the case of directories) executable\nby the current user."),(0,n.mdx)("p",{parentName:"li"}," The file or directory specified by this variable must always\nbe written by this command. If not, the execution of this\nrule will be considered a failure, halting the build process."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${TMP}")),(0,n.mdx)("p",{parentName:"li"}," A temporary directory which can be used for intermediate\nresults and will not be bundled into the output.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe"),": A platform-specific version of the shell command parameter ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". It runs on Windows and has a higher priority than ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". The ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe")," argument is run with ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd.exe /v:off /c"),". It has access to the same set of macros and variables as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"environment_expansion_separator"),": The delimiter between paths in environment variables, such as SRCS, that can contain multiple paths. It can be useful to specify this parameter if the paths could contain spaces.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"out"),": The name of the output file or directory. The complete path to this argument is provided to the shell command through the ",(0,n.mdx)("inlineCode",{parentName:"p"},"OUT")," environment variable. Only one of",(0,n.mdx)("inlineCode",{parentName:"p"},"out")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"outs")," may be present."),(0,n.mdx)("p",{parentName:"li"},"For an apk_genrule the output should be a '.apk' or '.aab' file.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": Either a list or a map of the source files which Buck makes available to the shell command at the path in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"SRCDIR")," environment variable. If you specify a list, the source files are the names in the list. If you specify a map, the source files are made available as the names in the keys of the map, where the values of the map are the original source file names.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"weight"),": How many local slots these genrule should take when executing locally."))),(0,n.mdx)("h4",{id:"details-8"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Here is an example of a couple ",(0,n.mdx)("inlineCode",{parentName:"p"},"apk_genrule()")," open up an APK, do\nsome super signing, and then zipalign that APK again."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n\n# Building this rule will produce a file named messenger.apk.\nandroid_binary(\n name = 'messenger',\n manifest = 'AndroidManifest.xml',\n target = 'Google Inc.:Google APIs:16',\n keystore = '//keystores:prod',\n package_type = 'release',\n proguard_config = 'proguard.cfg',\n deps = [\n ':res',\n ':src',\n ],\n)\n\napk_genrule(\n name = 'messenger_super_sign_unalign',\n apk = ':messenger',\n bash = '$(exe //java/com/facebook/sign:super_sign) --input $APK --output $OUT',\n cmd_exe = '$(exe //java/com/facebook/sign:super_sign) --input %APK% --output %OUT%',\n out = 'messenger_super_sign_unalign.apk',\n)\n\napk_genrule(\n name = 'messenger_super_sign',\n apk = ':messenger_super_sign_unalign',\n bash = '$ANDROID_HOME/tools/zipalign -f 4 $APK $OUT',\n cmd_exe = '%ANDROID_HOME%\\tools\\zipalign -f 4 %APK% %OUT%',\n out = 'messenger_super_sign.apk',\n)\n\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_asset_catalog"},"apple","_","asset","_","catalog"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_asset_catalog(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n app_icon: None | str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n dirs: list[str] = _,\n labels: list[str] = _,\n launch_image: None | str = _,\n licenses: list[str] = _,\n skip_universal_resource_dedupe: bool = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_asset_catalog()")," rule contains resources stored in Apple asset catalog directories. This rule does not have any output on its own and can be built only as a dependency (either direct or transitive) of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_bundle()")," rule, in which case all ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_asset_catalog()")," rules that the bundle rule depends on are merged and placed into the final output bundle together."),(0,n.mdx)("h4",{id:"parameters-14"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"app_icon"),": An optional reference to a ",(0,n.mdx)("inlineCode",{parentName:"li"},".appiconset")," containing a image set representing an application icon. (The extension itself should not be included.) This parameter may be specified at most once in a given ",(0,n.mdx)("inlineCode",{parentName:"li"},"apple_bundle"),"'s transitive dependencies."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"launch_image"),": An optional reference to a ",(0,n.mdx)("inlineCode",{parentName:"li"},".launchimage")," containing a image set representing an application launch image. (The extension itself should not be included.) This parameter may be specified at most once in a given ",(0,n.mdx)("inlineCode",{parentName:"li"},"apple_bundle"),"'s transitive dependencies.")),(0,n.mdx)("h4",{id:"details-9"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\napple_asset_catalog(\n name = 'MyAssetCatalog',\n dirs = [\n 'MyResources.xcassets',\n ],\n)\n\n# A asset catalog with a app icon and launch image\napple_asset_catalog(\n name = 'AssetCatalog',\n dirs = [ 'AssetCatalog.xcassets' ],\n app_icon = 'Icon',\n launch_image = 'LaunchImage',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_binary"},"apple","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n _apple_tools: str = _,\n _apple_xctoolchain: str = _,\n _apple_xctoolchain_bundle_id: str = _,\n _dsymutil_extra_flags: list[str],\n _enable_library_evolution: bool = _,\n _stripped_default: bool = _,\n allow_cache_upload: None | bool = _,\n binary_linker_flags: list[str] = _,\n bridging_header: None | str = _,\n buck2_compatibility: str = _,\n can_be_asset: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n devirt_enabled: bool = _,\n diagnostics: dict[str, str] = _,\n enable_cxx_interop: bool = _,\n enable_distributed_thinlto: bool = _,\n entitlements_file: None | str = _,\n executable_name: None | str = _,\n exported_deps: list[str] = _,\n exported_header_style: str = _,\n exported_headers: list[str] | dict[str, str] = _,\n exported_lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n exported_lang_preprocessor_flags: dict[str, list[str]] = _,\n exported_linker_flags: list[str] = _,\n exported_platform_deps: list[(str, list[str])] = _,\n exported_platform_headers: list[(str, list[str] | dict[str, str])] = _,\n exported_platform_linker_flags: list[(str, list[str])] = _,\n exported_platform_preprocessor_flags: list[(str, list[str])] = _,\n exported_post_linker_flags: list[str] = _,\n exported_post_platform_linker_flags: list[(str, list[str])] = _,\n exported_preprocessor_flags: list[str] = _,\n extra_xcode_files: list[str] = _,\n extra_xcode_sources: list[str] = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n force_static: None | bool = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n header_path_prefix: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n import_obj_c_forward_declarations: bool = _,\n include_directories: list[str] = _,\n info_plist: None | str = _,\n info_plist_substitutions: dict[str, str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_public_deps_label: None | str = _,\n link_ordering: None | str = _,\n link_style: None | str = _,\n link_whole: None | bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n modular: bool = _,\n module_name: None | str = _,\n module_requires_cxx: bool = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_objects: bool = _,\n preferred_linkage: str = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n propagated_target_sdk_version: None | str = _,\n public_include_directories: list[str] = _,\n public_system_include_directories: list[str] = _,\n raw_headers: list[str] = _,\n reexport_all_header_dependencies: None | bool = _,\n sanitizer_runtime_enabled: None | bool = _,\n sdk_modules: list[str] = _,\n serialize_debugging_options: bool = _,\n soname: None | str = _,\n srcs: list[str | (str, list[str])] = _,\n static_library_basename: None | str = _,\n stripped: None | bool = _,\n supported_platforms_regex: None | str = _,\n supports_merged_linking: None | bool = _,\n swift_compilation_mode: str = _,\n swift_compiler_flags: list[str] = _,\n swift_package_name: None | str = _,\n swift_version: None | str = _,\n target_sdk_version: None | str = _,\n thin_lto: bool = _,\n use_submodules: bool = _,\n uses_cxx_explicit_modules: bool = _,\n uses_explicit_modules: bool = _,\n uses_modules: bool = _,\n validation_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_binary()")," rule builds a native executable - such as an iOS or OSX app - from the supplied set of Objective-C/C++ source files and dependencies. It is similar to a ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_binary()"),"rule with which it shares many attributes. In addition to those common attributes, ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_binary()")," has a some additional attributes that are specific to binaries intended to be built using the Apple toolchain. Note, however, that ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_binary()")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_binary()")," differ in the way that they import header files, in order to better accommodate existing conventions. See the sections for the ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers")," attributes for more details."),(0,n.mdx)("h4",{id:"parameters-15"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"entitlements_file"),": An optional name of a plist file to be embedded in the binary. Some platforms like ",(0,n.mdx)("inlineCode",{parentName:"p"},"iphonesimulator")," require this to run properly.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers"),": The set of header files that are made available for inclusion to the source files in this target and all targets that transitively depend on this one. These should be specified as either a list of header files or a dictionary of header names to header files. The header names can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). If a list of header files is specified, the headers can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_PATH_PREFIX/$HEADER_NAME"')," or, if a header file that belongs to the same rule is being imported, with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_PATH_PREFIX")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the filename of the header file. If a dictionary is specified, each header can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the key corresponding to this file. In this case, the ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute is ignored. In either case, quotes in the import statements can be replaced with angle brackets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_linker_flags"),": Flags to add to the linker command line when the output from this rule, or the output from any rule that transitively depends on this rule, is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_xcode_files"),': When the project is generated, this is the list of files that will added to the project. Those files won\'t be added to the build phase "Compile Sources".')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"frameworks"),": A list of system frameworks that the code in this target uses. Each entry should be a path starting with ",(0,n.mdx)("inlineCode",{parentName:"p"},"$SDKROOT")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"$PLATFORM_DIR")," to denote that the rest of the path is relative to the root of the SDK used for the build or to the platform toolchain directory.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix"),": A path prefix when including headers of this target. For example, headers from a library defined using"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'apple_library(\n name = "Library",\n headers = glob(["**/*.h"]),\n header_path_prefix = "Lib",\n)\n')),(0,n.mdx)("p",{parentName:"li"},"can be imported using following mapping"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"Library/SubDir/Header1.h -> Lib/Header1.h\nLibrary/Header2.h -> Lib/Header2.h\n")),(0,n.mdx)("p",{parentName:"li"},"Defaults to the short name of the target. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"), but\ncannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header names can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). If a list of header files is specified, the headers can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_PATH_PREFIX/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_PATH_PREFIX")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the filename of the header file. If a dictionary is specified, each header can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the key corresponding to this file. In this case, the ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute is ignored. In either case, quotes in the import statements can be replaced with angle brackets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_execution_preference"),": The execution preference for linking. Options are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},"any : No preference is set, and the link action will be performed based on buck2's executor configuration."),(0,n.mdx)("li",{parentName:"ul"},"full_hybrid : The link action will execute both locally and remotely, regardless of buck2's executor configuration (if\nthe executor is capable of hybrid execution). The use_limited_hybrid setting of the hybrid executor is ignored."),(0,n.mdx)("li",{parentName:"ul"},"local : The link action will execute locally if compatible on current host platform."),(0,n.mdx)("li",{parentName:"ul"},"local_only : The link action will execute locally, and error if the current platform is not compatible."),(0,n.mdx)("li",{parentName:"ul"},"remote : The link action will execute remotely if a compatible remote platform exists, otherwise locally.")),(0,n.mdx)("p",{parentName:"li"},"The default is None, expressing that no preference has been set on the target itself.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_group_public_deps_label"),': Surface nodes with this label as "public" nodes in the main executable when linking with with link groups.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_extra_outputs"),": Declares extra outputs that the linker emits. These identifiers can be used in ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(output ...)")," macros in ",(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags")," to interpolate the output path into the linker command line. Useful for custom linkers that emit extra output files.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_linker_flags"),": Platform-specific linker flags. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_srcs"),": Platform specific source files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of source files or a list of tuples of source files and a list of compilation flags to be preprocessed, compiled and assembled if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"p",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_sdk_version"),": The minimum OS version that the library target should support, overriding the minimum set in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),". When set, Buck will automatically add flags to both Objective-C and Swift compilation that will allow the use of the new APIs without guarding code inside availability checks."))),(0,n.mdx)("h4",{id:"details-10"},"Details"),(0,n.mdx)("p",null,"Buck enables you to override components of the Apple toolchain with\nalternate tools, either from the Xcode search paths or from directories\nthat you specify.\nSee ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nand ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nfor more information."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\napple_binary(\n name = 'MyBinary',\n deps = [\n ':MyLibrary',\n '//Libraries:AnotherLibrary',\n ],\n preprocessor_flags = ['-fobjc-arc'],\n headers = [\n 'MyHeader.h',\n ],\n srcs = [\n 'MySource.m',\n ],\n frameworks = [\n '$SDKROOT/System/Library/Frameworks/UIKit.framework',\n '$SDKROOT/System/Library/Frameworks/Foundation.framework',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_bundle"},"apple","_","bundle"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_bundle(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n _apple_tools: str = _,\n _apple_xctoolchain: str = _,\n _apple_xctoolchain_bundle_id: str = _,\n _bundling_cache_buster: None | str = _,\n _bundling_log_file_enabled: bool = _,\n _bundling_log_file_level: None | str = _,\n _code_signing_configuration: None | str = _,\n _codesign_entitlements: None | str = _,\n _codesign_identities_command_override: None | str = _,\n _codesign_type: None | str = _,\n _compile_resources_locally_override: None | bool = _,\n _dsymutil_extra_flags: list[str],\n _embed_provisioning_profile_when_adhoc_code_signing: None | bool = _,\n _fast_adhoc_signing_enabled_default: bool = _,\n _fast_provisioning_profile_parsing_enabled: bool = _,\n _incremental_bundling_enabled: bool = _,\n _info_plist_identify_build_system_default: bool = _,\n _profile_bundling_enabled: bool = _,\n _provisioning_profiles: str = _,\n _resource_bundle: None | str = _,\n _strict_provisioning_profile_search_default: bool = _,\n _use_entitlements_when_adhoc_code_signing: None | bool = _,\n asset_catalogs_compilation_options: dict[str, typing.Any] = _,\n binary: None | str = _,\n buck2_compatibility: str = _,\n bundle_type: None | str = _,\n codesign_flags: list[str] = _,\n codesign_identity: None | str = _,\n codesign_type: None | str = _,\n contacts: list[str] = _,\n copy_public_framework_headers: None | bool = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n deps: list[str] = _,\n embed_provisioning_profile_when_adhoc_code_signing: bool = _,\n extension: str,\n fast_adhoc_signing_enabled: None | bool = _,\n ibtool_flags: None | list[str] = _,\n ibtool_module_flag: None | bool = _,\n incremental_bundling_enabled: None | bool = _,\n info_plist: str,\n info_plist_identify_build_system: None | bool = _,\n info_plist_substitutions: dict[str, str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n module_map: None | str = _,\n platform_binary: None | list[(str, str)] = _,\n privacy_manifest: None | str = _,\n product_name: None | str = _,\n resource_group: None | str = _,\n resource_group_map: None | str = _,\n selective_debugging: None | str = _,\n skip_copying_swift_stdlib: None | bool = _,\n split_arch_dsym: bool = _,\n strict_provisioning_profile_search: None | bool = _,\n try_skip_code_signing: None | bool = _,\n universal: None | bool = _,\n use_entitlements_when_adhoc_code_signing: bool = _,\n validation_deps: list[str] = _,\n versioned_macos_bundle: bool = _,\n xcode_product_type: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_bundle()")," rule takes an Apple binary and all of the resources and asset catalogs in the rule's transitive dependencies and generates a bundle containing all of those files. Optionally the generated bundle can also be signed using specified provisioning profiles."),(0,n.mdx)("h4",{id:"parameters-16"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"asset_catalogs_compilation_options"),": A dict holding parameters for asset catalogs compiler (actool). Its options include:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"notices")," (defaults to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),")"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"warnings")," (defaults to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),")"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"errors")," (defaults to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),")"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compress_pngs")," (defaults to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),")"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"optimization")," (defaults to ",(0,n.mdx)("inlineCode",{parentName:"li"},"'space'"),")"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"output_format")," (defaults to ",(0,n.mdx)("inlineCode",{parentName:"li"},"'human-readable-text'"),")"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"extra_flags")," (defaults to ",(0,n.mdx)("inlineCode",{parentName:"li"},"[]"),")"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": A list of dependencies of this bundle as build targets. You can embed application extensions by specifying the extension's bundle target. To include a WatchKit app, append the flavor ",(0,n.mdx)("inlineCode",{parentName:"p"},"#watch")," to the target specification. Buck will automatically substitute the appropriate platform flavor (either ",(0,n.mdx)("inlineCode",{parentName:"p"},"watchsimulator")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"watchos"),") based on the parent.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extension"),": The extension of the generated bundle. For example ",(0,n.mdx)("inlineCode",{parentName:"p"},"'app'")," for an application bundle or ",(0,n.mdx)("inlineCode",{parentName:"p"},"'appex'")," for an application extension bundle.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"ibtool_flags"),": List of flags to be passed to ibtool during interface builder file compilation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist"),": A path to an ",(0,n.mdx)("inlineCode",{parentName:"p"},"Info.plist")," file that will be placed in the bundle. The specified file will be processed by substituting variable names with their values (see ",(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist_substitutions")," for more information).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist_substitutions"),": A dictionary that assigns variable names to their values. It is used for variable substitution when processing the file specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist"),". For example if this argument is set to ",(0,n.mdx)("inlineCode",{parentName:"p"},"{'VAR': 'MyValue'}"),", then each occurrence of ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(VAR)")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"${VAR}")," in the file will be replaced by ",(0,n.mdx)("inlineCode",{parentName:"p"},"MyValue"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"privacy_manifest"),": A path to an ",(0,n.mdx)("inlineCode",{parentName:"p"},".xcprivacy")," file that will be placed in the bundle.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"product_name"),": The name of the resulting bundle and binary. The setting behaves like PRODUCT","_",'NAME Xcode build setting. For example, if your rule is named "MyApp" and extension is "app", by default buck will generate MyApp.app bundle. But if you will set product name to "SuperApp", bundle will get "SuperApp.app" name.'))),(0,n.mdx)("h4",{id:"details-11"},"Details"),(0,n.mdx)("p",null,"Code signing will embed entitlements pointed to by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"entitlements_file")," arg in\nthe bundle's ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_binary"),". This is the preferred way to specify entitlements\nwhen building with Buck."),(0,n.mdx)("p",null,"If the entitlements file is not present, it falls back to the ",(0,n.mdx)("inlineCode",{parentName:"p"},"CODE_SIGN_ENTITLEMENTS")," entry in\n",(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist_substitutions"),"."),(0,n.mdx)("p",null,"If after these checks, an entitlements file is still not specified, it will be derived based\non the entitlements of the selected provisioning profile. Provisioning profiles will be selected\nfrom profiles pointed to by ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple.provisioning_profile_search_path"),", based on a\nnon-expired profile that matches the bundle id and entitlements."),(0,n.mdx)("p",null,"Code signing will embed entitlements pointed to by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"CODE_SIGN_ENTITLEMENTS")," entry in\n",(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist_substitutions"),". If an entitlements file is omitted, it will be derived based\non the entitlements of the selected provisioning profile. Provisioning profiles will be selected\nfrom profiles pointed to by ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple.provisioning_profile_search_path"),", based on a\nnon-expired profile that matches the bundle id and entitlements."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\napple_bundle(\n name = 'AppBundle',\n binary = ':MyBinary',\n extension = 'app',\n info_plist = 'Info.plist',\n)\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# iOS app with embedded WatchOS 2.0 app/extension\napple_bundle(\n name = 'DemoWatchAppExtension',\n binary = ':DemoWatchAppExtensionBinary',\n extension = 'appex',\n info_plist = 'WatchExtension/Resources/Info.plist',\n)\n\napple_bundle(\n name = 'DemoWatchApp',\n binary = ':DemoWatchAppBinary',\n deps = [':DemoWatchAppResources', ':DemoWatchAppExtension'],\n extension = 'app',\n info_plist = 'WatchApplication/Info.plist',\n)\n\napple_bundle(\n name = 'DemoApp',\n binary = ':DemoAppBinary',\n deps = [':DemoWatchApp#watch'],\n extension = 'app',\n info_plist = 'Info.plist',\n)\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# iOS app using safeAreaInsets delivering to iOS 9.x\napple_bundle(\n name = 'DemoIBApp',\n binary = ':DemoIBAppBinary',\n deps = [':DemoIBAppResources'],\n extension = 'app',\n ibtool_flags = [\"--minimum-deployment-target\", \"9.0\"],\n info_plist = 'Info.plist',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_library"},"apple","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n _apple_tools: str = _,\n _apple_xctoolchain: str = _,\n _apple_xctoolchain_bundle_id: str = _,\n _archive_objects_locally_override: None | bool = _,\n _dsymutil_extra_flags: list[str],\n _enable_library_evolution: bool = _,\n _stripped_default: bool = _,\n allow_cache_upload: None | bool = _,\n bridging_header: None | str = _,\n buck2_compatibility: str = _,\n can_be_asset: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n devirt_enabled: bool = _,\n diagnostics: dict[str, str] = _,\n enable_cxx_interop: bool = _,\n enable_distributed_thinlto: bool = _,\n executable_name: None | str = _,\n exported_deps: list[str] = _,\n exported_header_style: str = _,\n exported_headers: list[str] | dict[str, str] = _,\n exported_lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n exported_lang_preprocessor_flags: dict[str, list[str]] = _,\n exported_linker_flags: list[str] = _,\n exported_platform_deps: list[(str, list[str])] = _,\n exported_platform_headers: list[(str, list[str] | dict[str, str])] = _,\n exported_platform_linker_flags: list[(str, list[str])] = _,\n exported_platform_preprocessor_flags: list[(str, list[str])] = _,\n exported_post_linker_flags: list[str] = _,\n exported_post_platform_linker_flags: list[(str, list[str])] = _,\n exported_preprocessor_flags: list[str] = _,\n extra_xcode_files: list[str] = _,\n extra_xcode_sources: list[str] = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n force_static: None | bool = _,\n frameworks: list[str] = _,\n header_mode: None | str = _,\n header_namespace: None | str = _,\n header_path_prefix: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n import_obj_c_forward_declarations: bool = _,\n include_directories: list[str] = _,\n info_plist: None | str = _,\n info_plist_substitutions: dict[str, str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_ordering: None | str = _,\n link_style: None | str = _,\n link_whole: None | bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n modular: bool = _,\n module_name: None | str = _,\n module_requires_cxx: bool = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n preferred_linkage: str = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n public_framework_headers: list[str] | dict[str, str] = _,\n public_include_directories: list[str] = _,\n public_system_include_directories: list[str] = _,\n raw_headers: list[str] = _,\n reexport_all_header_dependencies: None | bool = _,\n sdk_modules: list[str] = _,\n serialize_debugging_options: bool = _,\n shared_library_macho_file_type: str = _,\n soname: None | str = _,\n srcs: list[str | (str, list[str])] = _,\n static_library_basename: None | str = _,\n stripped: None | bool = _,\n supported_platforms_regex: None | str = _,\n supports_header_symlink_subtarget: bool = _,\n supports_merged_linking: None | bool = _,\n supports_shlib_interfaces: bool = _,\n swift_compilation_mode: str = _,\n swift_compiler_flags: list[str] = _,\n swift_package_name: None | str = _,\n swift_version: None | str = _,\n target_sdk_version: None | str = _,\n thin_lto: bool = _,\n use_archive: None | bool = _,\n use_submodules: bool = _,\n uses_cxx_explicit_modules: bool = _,\n uses_explicit_modules: bool = _,\n uses_modules: bool = _,\n validation_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_library()")," rule represents a set of Objective-C/C++/Swift source files and is similar to a ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library()")," rule with which it shares many attributes. In addition to those common attributes, ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_library()")," has a some additional attributes that are specific to binaries intended to be built using the Apple toolchain. Note, however, that ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_library()")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library()")," differ in the way that they import header files, in order to better accommodate existing conventions. See the sections for the ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers")," attributes for more details."),(0,n.mdx)("h4",{id:"parameters-17"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),": Dependencies that will also appear to belong to any rules that depend on this one. This has two effects: ",(0,n.mdx)("em",{parentName:"p"}," Exported dependencies will also be included in the link line of dependents of this rules, but normal dependencies will not. ")," When ",(0,n.mdx)("inlineCode",{parentName:"p"},"reexport_all_header_dependencies = False"),", only exported headers of the rules specified here are re-exported.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers"),": The set of header files that are made available for inclusion to the source files in this target and all targets that transitively depend on this one. These should be specified as either a list of header files or a dictionary of header names to header files. The header names can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). If a list of header files is specified, the headers can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_PATH_PREFIX/$HEADER_NAME"')," or, if a header file that belongs to the same rule is being imported, with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_PATH_PREFIX")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the filename of the header file. If a dictionary is specified, each header can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the key corresponding to this file. In this case, the ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute is ignored. In either case, quotes in the import statements can be replaced with angle brackets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_linker_flags"),": Flags to add to the linker command line when the output from this rule, or the output from any rule that transitively depends on this rule, is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_platform_linker_flags"),": Platform-specific linker flags for this rule and for all rules that transitively depend on this rule. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule, or the output from any rule that transitively depends on this rule, is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_xcode_files"),': When the project is generated, this is the list of files that will added to the project. Those files won\'t be added to the build phase "Compile Sources".')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"frameworks"),": A list of system frameworks that the code in this target uses. Each entry should be a path starting with ",(0,n.mdx)("inlineCode",{parentName:"p"},"$SDKROOT")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"$PLATFORM_DIR")," to denote that the rest of the path is relative to the root of the SDK used for the build or to the platform toolchain directory.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace"),": A path prefix when including headers of this target. Defaults to the path from the root of the repository to the directory where this target is defined. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"), but cannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix"),": A path prefix when including headers of this target. For example, headers from a library defined using"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'apple_library(\n name = "Library",\n headers = glob(["**/*.h"]),\n header_path_prefix = "Lib",\n)\n')),(0,n.mdx)("p",{parentName:"li"},"can be imported using following mapping"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"Library/SubDir/Header1.h -> Lib/Header1.h\nLibrary/Header2.h -> Lib/Header2.h\n")),(0,n.mdx)("p",{parentName:"li"},"Defaults to the short name of the target. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"), but\ncannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header names can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). If a list of header files is specified, the headers can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_PATH_PREFIX/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_PATH_PREFIX")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the filename of the header file. If a dictionary is specified, each header can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the key corresponding to this file. In this case, the ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute is ignored. In either case, quotes in the import statements can be replaced with angle brackets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_execution_preference"),": The execution preference for linking. Options are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},"any : No preference is set, and the link action will be performed based on buck2's executor configuration."),(0,n.mdx)("li",{parentName:"ul"},"full_hybrid : The link action will execute both locally and remotely, regardless of buck2's executor configuration (if\nthe executor is capable of hybrid execution). The use_limited_hybrid setting of the hybrid executor is ignored."),(0,n.mdx)("li",{parentName:"ul"},"local : The link action will execute locally if compatible on current host platform."),(0,n.mdx)("li",{parentName:"ul"},"local_only : The link action will execute locally, and error if the current platform is not compatible."),(0,n.mdx)("li",{parentName:"ul"},"remote : The link action will execute remotely if a compatible remote platform exists, otherwise locally.")),(0,n.mdx)("p",{parentName:"li"},"The default is None, expressing that no preference has been set on the target itself.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_extra_outputs"),": Declares extra outputs that the linker emits. These identifiers can be used in ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(output ...)")," macros in ",(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags")," to interpolate the output path into the linker command line. Useful for custom linkers that emit extra output files.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_srcs"),": Platform specific source files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of source files or a list of tuples of source files and a list of compilation flags to be preprocessed, compiled and assembled if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"reexport_all_header_dependencies"),": Whether to automatically re-export the exported headers of all dependencies."),(0,n.mdx)("p",{parentName:"li"},"When this is set to false, only exported headers from\n",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," are re-exported.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"p",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_sdk_version"),": The minimum OS version that the library target should support, overriding the minimum set in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),". When set, Buck will automatically add flags to both Objective-C and Swift compilation that will allow the use of the new APIs without guarding code inside availability checks."))),(0,n.mdx)("h4",{id:"details-12"},"Details"),(0,n.mdx)("p",null,"Buck enables you to override components of the Apple toolchain with\nalternate tools, either from the Xcode search paths or from directories\nthat you specify.\nSee ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nand ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nfor more information."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\napple_library(\n name = 'MyLibrary',\n deps = [\n ':OtherLibrary',\n '//Libraries:YetAnotherLibrary',\n ],\n preprocessor_flags = ['-fobjc-arc'],\n headers = [\n 'MyHeader.h',\n ],\n srcs = [\n 'MySource.m',\n 'MySource.swift',\n ],\n frameworks = [\n '$SDKROOT/System/Library/Frameworks/UIKit.framework',\n '$SDKROOT/System/Library/Frameworks/Foundation.framework',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_package"},"apple","_","package"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_package(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n _apple_tools: str = _,\n _ipa_compression_level: str,\n buck2_compatibility: str = _,\n bundle: str,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n ext: str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n need_android_tools: bool = _,\n package_name: None | str = _,\n packager: None | str = _,\n packager_args: list[str] = _,\n prepackaged_validators: list[str | (str, list[str])] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_package()")," rule takes the output of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_bundle()")," rule and compresses it in an IPA (iOS App Store Package) file."),(0,n.mdx)("h4",{id:"parameters-18"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("h4",{id:"details-13"},"Details"),(0,n.mdx)("p",null,"This rule can be customized using the config options ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nand ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\n."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\napple_package(\n name = 'AppPackage',\n bundle = ':AppBundle',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_resource"},"apple","_","resource"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_resource(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n codesign_entitlements: None | str = _,\n codesign_flags_override: None | list[str] = _,\n codesign_on_copy: bool = _,\n contacts: list[str] = _,\n content_dirs: list[str] = _,\n default_host_platform: None | str = _,\n destination: None | str = _,\n dirs: list[str] = _,\n files: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n named_variants: dict[str, list[str]] = _,\n resources_from_deps: list[str] = _,\n skip_universal_resource_dedupe: bool = _,\n variants: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_resource()")," rule contains sets of resource directories, files and file variants that can be bundled in an application bundle. This rule does not have any output on its own and can be built only as a dependency (either direct or transitive) of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_bundle()")," rule."),(0,n.mdx)("h4",{id:"parameters-19"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"destination"),': Specifies the destination in the final application bundle where resource will be copied. Possible values: "resources", "frameworks", "executables", "plugins", "xpcservices".')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"named_variants"),": Mapping from a variant name to the list of resource file paths which should be placed in an application bundle. Those files will be placed in a directory with name equal to the corresponding key in this mapping. Keys should end with ",(0,n.mdx)("inlineCode",{parentName:"p"},".lproj")," suffix. (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"Base.lproj"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"en.lproj"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources_from_deps"),": Set of build targets whose transitive ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_resource"),"s should be considered as part of the current resource when collecting resources for bundles."),(0,n.mdx)("p",{parentName:"li"},"Usually, an ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_bundle")," collects all ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_resource")," rules transitively\nreachable through apple","_","library rules. This field allows for resources which are not reachable\nusing the above traversal strategy to be considered for inclusion in the bundle.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"variants"),": Set of paths of resource file variants that should be placed in an application bundle. The files mentioned here should be placed in a directory named ",(0,n.mdx)("inlineCode",{parentName:"p"},"$VARIANT_NAME.lproj"),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$VARIANT_NAME")," is the name of the variant (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"Base"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"en"),"). This argument makes it possible to use different resource files based on the active locale."))),(0,n.mdx)("h4",{id:"details-14"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\napple_resource(\n name = 'Images',\n files = glob([\n '*.png',\n ]),\n dirs = [\n 'PrettyImages',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_test"},"apple","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n _apple_tools: str = _,\n _apple_xctoolchain: str = _,\n _apple_xctoolchain_bundle_id: str = _,\n _bundling_cache_buster: None | str = _,\n _bundling_log_file_enabled: bool = _,\n _bundling_log_file_level: None | str = _,\n _code_signing_configuration: None | str = _,\n _codesign_identities_command_override: None | str = _,\n _codesign_type: None | str = _,\n _compile_resources_locally_override: None | bool = _,\n _dsymutil_extra_flags: list[str],\n _embed_provisioning_profile_when_adhoc_code_signing: None | bool = _,\n _enable_library_evolution: bool = _,\n _fast_adhoc_signing_enabled_default: bool = _,\n _fast_provisioning_profile_parsing_enabled: bool = _,\n _incremental_bundling_enabled: bool = _,\n _info_plist_identify_build_system_default: bool = _,\n _inject_test_env: str = _,\n _ios_booted_simulator: str = _,\n _ios_unbooted_simulator: str = _,\n _macos_idb_companion: str = _,\n _profile_bundling_enabled: bool = _,\n _provisioning_profiles: str = _,\n _resource_bundle: None | str = _,\n _strict_provisioning_profile_search_default: bool = _,\n _use_entitlements_when_adhoc_code_signing: None | bool = _,\n allow_cache_upload: None | bool = _,\n asset_catalogs_compilation_options: dict[str, typing.Any] = _,\n binary: None | str = _,\n bridging_header: None | str = _,\n buck2_compatibility: str = _,\n can_be_asset: None | bool = _,\n codesign_flags: list[str] = _,\n codesign_identity: None | str = _,\n codesign_type: None | str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n destination_specifier: dict[str, str] = _,\n devirt_enabled: bool = _,\n diagnostics: dict[str, str] = _,\n embed_provisioning_profile_when_adhoc_code_signing: bool = _,\n enable_cxx_interop: bool = _,\n entitlements_file: None | str = _,\n env: None | dict[str, str] = _,\n executable_name: None | str = _,\n exported_deps: list[str] = _,\n exported_header_style: str = _,\n exported_headers: list[str] | dict[str, str] = _,\n exported_lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n exported_lang_preprocessor_flags: dict[str, list[str]] = _,\n exported_linker_flags: list[str] = _,\n exported_platform_deps: list[(str, list[str])] = _,\n exported_platform_headers: list[(str, list[str] | dict[str, str])] = _,\n exported_platform_linker_flags: list[(str, list[str])] = _,\n exported_platform_preprocessor_flags: list[(str, list[str])] = _,\n exported_post_linker_flags: list[str] = _,\n exported_post_platform_linker_flags: list[(str, list[str])] = _,\n exported_preprocessor_flags: list[str] = _,\n extension: str,\n extra_xcode_files: list[str] = _,\n extra_xcode_sources: list[str] = _,\n fast_adhoc_signing_enabled: None | bool = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n force_static: None | bool = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n header_path_prefix: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n import_obj_c_forward_declarations: bool = _,\n include_directories: list[str] = _,\n incremental_bundling_enabled: None | bool = _,\n info_plist: str,\n info_plist_identify_build_system: None | bool = _,\n info_plist_substitutions: dict[str, str] = _,\n is_ui_test: bool = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_ordering: None | str = _,\n link_style: str = _,\n link_whole: None | bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n modular: bool = _,\n module_name: None | str = _,\n module_requires_cxx: bool = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n preferred_linkage: str = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n public_include_directories: list[str] = _,\n public_system_include_directories: list[str] = _,\n raw_headers: list[str] = _,\n reexport_all_header_dependencies: None | bool = _,\n resource_group: None | str = _,\n resource_group_map: None | str = _,\n run_test_separately: bool = _,\n runner: None | str = _,\n sanitizer_runtime_enabled: None | bool = _,\n sdk_modules: list[str] = _,\n serialize_debugging_options: bool = _,\n skip_copying_swift_stdlib: None | bool = _,\n snapshot_reference_images_path: None | str = _,\n soname: None | str = _,\n specs: None | str = _,\n srcs: list[str | (str, list[str])] = _,\n static_library_basename: None | str = _,\n strict_provisioning_profile_search: None | bool = _,\n stripped: bool = _,\n supported_platforms_regex: None | str = _,\n supports_merged_linking: None | bool = _,\n swift_compilation_mode: str = _,\n swift_compiler_flags: list[str] = _,\n swift_package_name: None | str = _,\n swift_version: None | str = _,\n target_sdk_version: None | str = _,\n test_host_app: None | str = _,\n test_rule_timeout_ms: None | int = _,\n thin_lto: bool = _,\n try_skip_code_signing: None | bool = _,\n ui_test_target_app: None | str = _,\n use_entitlements_when_adhoc_code_signing: bool = _,\n use_submodules: bool = _,\n uses_cxx_explicit_modules: bool = _,\n uses_explicit_modules: bool = _,\n uses_modules: bool = _,\n validation_deps: list[str] = _,\n versioned_macos_bundle: bool = _,\n xcode_product_type: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_test()")," rule contains Objective-C/C++ code which can be built and used to test code contained in other rules. The tests can be executed by running ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck test"),"."),(0,n.mdx)("h4",{id:"parameters-20"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_xcode_files"),': When the project is generated, this is the list of files that will added to the project. Those files won\'t be added to the build phase "Compile Sources".')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"frameworks"),": A list of system frameworks that the code in this target uses. Each entry should be a path starting with ",(0,n.mdx)("inlineCode",{parentName:"p"},"$SDKROOT")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"$PLATFORM_DIR")," to denote that the rest of the path is relative to the root of the SDK used for the build or to the platform toolchain directory.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix"),": A path prefix when including headers of this target. For example, headers from a library defined using"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'apple_library(\n name = "Library",\n headers = glob(["**/*.h"]),\n header_path_prefix = "Lib",\n)\n')),(0,n.mdx)("p",{parentName:"li"},"can be imported using following mapping"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"Library/SubDir/Header1.h -> Lib/Header1.h\nLibrary/Header2.h -> Lib/Header2.h\n")),(0,n.mdx)("p",{parentName:"li"},"Defaults to the short name of the target. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"), but\ncannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header names can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). If a list of header files is specified, the headers can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_PATH_PREFIX/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_PATH_PREFIX")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the filename of the header file. If a dictionary is specified, each header can be imported with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#import "$HEADER_NAME"'),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the key corresponding to this file. In this case, the ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_path_prefix")," attribute is ignored. In either case, quotes in the import statements can be replaced with angle brackets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist"),": A path to an ",(0,n.mdx)("inlineCode",{parentName:"p"},"Info.plist")," file that will be placed in the bundle. The specified file will be processed by substituting variable names with their values (see ",(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist_substitutions")," for more information).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist_substitutions"),": A dictionary that assigns variable names to their values. It is used for variable substitution when processing the file specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},"info_plist"),". For example if this argument is set to ",(0,n.mdx)("inlineCode",{parentName:"p"},"{'VAR': 'MyValue'}"),", then each occurrence of ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(VAR)")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"${VAR}")," in the file will be replaced by ",(0,n.mdx)("inlineCode",{parentName:"p"},"MyValue"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"labels"),": A list of labels to be applied to these tests. These labels are arbitrary text strings and have no meaning within buck itself. They can, however, have meaning for you as a test author (e.g., ",(0,n.mdx)("inlineCode",{parentName:"p"},"smoke")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"fast"),"). A label can be used to filter or include a specific test rule when executing ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck test"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_execution_preference"),": The execution preference for linking. Options are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},"any : No preference is set, and the link action will be performed based on buck2's executor configuration."),(0,n.mdx)("li",{parentName:"ul"},"full_hybrid : The link action will execute both locally and remotely, regardless of buck2's executor configuration (if\nthe executor is capable of hybrid execution). The use_limited_hybrid setting of the hybrid executor is ignored."),(0,n.mdx)("li",{parentName:"ul"},"local : The link action will execute locally if compatible on current host platform."),(0,n.mdx)("li",{parentName:"ul"},"local_only : The link action will execute locally, and error if the current platform is not compatible."),(0,n.mdx)("li",{parentName:"ul"},"remote : The link action will execute remotely if a compatible remote platform exists, otherwise locally.")),(0,n.mdx)("p",{parentName:"li"},"The default is None, expressing that no preference has been set on the target itself.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_srcs"),": Platform specific source files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of source files or a list of tuples of source files and a list of compilation flags to be preprocessed, compiled and assembled if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"p",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_sdk_version"),": The minimum OS version that the library target should support, overriding the minimum set in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),". When set, Buck will automatically add flags to both Objective-C and Swift compilation that will allow the use of the new APIs without guarding code inside availability checks.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_host_app"),": A build target identifying an ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_bundle()")," rule that builds an application bundle. Output of the specified rule will be used as a test host of this test. This implies ",(0,n.mdx)("inlineCode",{parentName:"p"},"run_test_separately"),". Since symbols that are defined in the test host application and its dependencies will not be linked into the test binary, to make those symbols accessible to the test target they need to be specified as a dependency of this target and ",(0,n.mdx)("inlineCode",{parentName:"p"},"['-undefined', 'dynamic_lookup']")," needs to be added to this target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags")," (this will suppress undefined reference errors during compilation, but if the symbols do not exist, it might result in runtime crashes)."))),(0,n.mdx)("h4",{id:"details-15"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\napple_test(\n name = 'MyTest',\n info_plist = 'MyTest-Info.plist',\n preprocessor_flags = ['-fobjc-arc'],\n srcs = [\n 'MyTest.m',\n ],\n deps = [\n ':MyLibrary',\n ],\n frameworks = [\n '$SDKROOT/System/Library/Frameworks/Foundation.framework',\n '$SDKROOT/System/Library/Frameworks/UIKit.framework',\n '$PLATFORM_DIR/Developer/Library/Frameworks/XCTest.framework',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_toolchain"},"apple","_","toolchain"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_toolchain(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _internal_platform_path: None | str = _,\n _internal_sdk_path: None | str = _,\n actool: str,\n architecture: str = _,\n buck2_compatibility: str = _,\n build_version: None | str = _,\n codesign: str,\n codesign_allocate: str,\n codesign_identities_command: None | str = _,\n compile_resources_locally: bool = _,\n contacts: list[str] = _,\n copy_scene_kit_assets: str,\n cxx_toolchain: str,\n default_host_platform: None | str = _,\n developer_path: None | str = _,\n dsymutil: str,\n dwarfdump: None | str = _,\n extra_linker_outputs: list[str] = _,\n ibtool: str,\n installer: str = _,\n labels: list[str] = _,\n libtool: str,\n licenses: list[str] = _,\n lipo: str,\n mapc: None | str = _,\n min_version: str,\n momc: str,\n objdump: None | str = _,\n placeholder_tool: None | str = _,\n platform_path: None | str = _,\n requires_xcode_version_match: bool = _,\n sdk_environment: None | str = _,\n sdk_name: str = _,\n sdk_path: None | str = _,\n swift_toolchain: None | str = _,\n target_sdk_version: None | str = _,\n version: None | str = _,\n watch_kit_stub_binary: None | str = _,\n work_around_dsymutil_lto_stack_overflow_bug: None | bool = _,\n xcode_build_version: None | str = _,\n xcode_version: None | str = _,\n xctest: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-21"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_toolchain_set"},"apple","_","toolchain","_","set"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_toolchain_set(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n apple_toolchains: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-22"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_universal_executable"},"apple","_","universal","_","executable"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_universal_executable(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n _apple_tools: str = _,\n _dsymutil_extra_flags: list[str],\n buck2_compatibility: str = _,\n executable: str,\n executable_name: None | str = _,\n labels: list[str] = _,\n split_arch_dsym: bool = _,\n universal: None | bool = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-23"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_xcframework"},"apple","_","xcframework"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_xcframework(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_tools: str = _,\n buck2_compatibility: str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-24"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"apple_xcuitest"},"apple","_","xcuitest"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def apple_xcuitest(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n _apple_tools: str = _,\n _apple_xctoolchain: str = _,\n _apple_xctoolchain_bundle_id: str = _,\n _bundling_cache_buster: None | str = _,\n _bundling_log_file_enabled: bool = _,\n _bundling_log_file_level: None | str = _,\n _code_signing_configuration: None | str = _,\n _codesign_identities_command_override: None | str = _,\n _codesign_type: None | str = _,\n _compile_resources_locally_override: None | bool = _,\n _embed_provisioning_profile_when_adhoc_code_signing: None | bool = _,\n _enable_library_evolution: bool = _,\n _fast_adhoc_signing_enabled_default: bool = _,\n _fast_provisioning_profile_parsing_enabled: bool = _,\n _incremental_bundling_enabled: bool = _,\n _info_plist_identify_build_system_default: bool = _,\n _profile_bundling_enabled: bool = _,\n _provisioning_profiles: str = _,\n _resource_bundle: None | str = _,\n _strict_provisioning_profile_search_default: bool = _,\n _use_entitlements_when_adhoc_code_signing: None | bool = _,\n binary: None | str = _,\n buck2_compatibility: str = _,\n codesign_identity: None | str = _,\n codesign_type: None | str = _,\n embed_provisioning_profile_when_adhoc_code_signing: bool = _,\n entitlements_file: None | str = _,\n extension: str = _,\n fast_adhoc_signing_enabled: None | bool = _,\n incremental_bundling_enabled: bool = _,\n info_plist: str,\n info_plist_identify_build_system: None | bool = _,\n info_plist_substitutions: dict[str, str] = _,\n strict_provisioning_profile_search: None | bool = _,\n target_sdk_version: None | str = _,\n test_bundle: str,\n use_entitlements_when_adhoc_code_signing: bool = _,\n validation_deps: list[str] = _,\n versioned_macos_bundle: bool = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-25"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cgo_library"},"cgo","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cgo_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _asan: bool = _,\n _compile_shared: bool = _,\n _coverage_mode: None | str = _,\n _cxx_toolchain: str = _,\n _exec_os_type: str = _,\n _go_stdlib: str = _,\n _go_toolchain: str = _,\n _race: bool = _,\n _tags: list[str] = _,\n allow_cache_upload: None | bool = _,\n buck2_compatibility: str = _,\n cgo_compiler_flags: list[str] = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n devirt_enabled: bool = _,\n embedcfg: None | str = _,\n executable_name: None | str = _,\n exported_deps: list[str] = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n frameworks: list[str] = _,\n go_assembler_flags: list[str] = _,\n go_compiler_flags: list[str] = _,\n go_srcs: list[str] = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_style: None | str = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n package_name: None | str = _,\n package_root: None | str = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_objects: bool = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n raw_headers: list[str] = _,\n srcs: list[str | (str, list[str])] = _,\n thin_lto: bool = _,\n version_universe: None | str = _,\n weak_framework_names: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A cgo","_","library() rule builds an object from the supplied set of Go/C source files and dependencies. The outputs are linked into go executable in the last step (compile)."),(0,n.mdx)("h4",{id:"parameters-26"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"cgo_compiler_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool cgo"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"go_assembler_flags"),": The set of additional assembler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool asm"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"go_compiler_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool compile"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"go_srcs"),": The set of source files to be compiled by this rule. Go (",(0,n.mdx)("inlineCode",{parentName:"li"},".go"),") files are compiled with the Go compiler. In contrast to the ",(0,n.mdx)("inlineCode",{parentName:"li"},"srcs")," argument, these files ",(0,n.mdx)("em",{parentName:"li"},"cannot")," have ",(0,n.mdx)("inlineCode",{parentName:"li"},'import "C"')," declared."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"). The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"li"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>")," , where ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"li"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_extra_outputs"),": Declares extra outputs that the linker emits. These identifiers can be used in ",(0,n.mdx)("inlineCode",{parentName:"li"},"$(output ...)")," macros in ",(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags")," to interpolate the output path into the linker command line. Useful for custom linkers that emit extra output files."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_name"),': Sets the full name of the package being compiled. This defaults to the path from the buck root. (e.g. given a ./.buckconfig, a rule in ./a/b/BUCK defaults to package "a/b")'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_root"),": Sets Go package direactory (relative to BUCK file). By default (or if None passes) package_root is being detected automatically. Empty string of Go package is on the same level as BUCK file otherwise the subdirectory name. Example for srcs = ",'["foo/bar.go"]',', package_root = "foo"'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_linker_flags"),": Platform-specific linker flags. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"li"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule is used in a link operation."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_preprocessor_flags"),": Platform specific preprocessor flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when preprocessing the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"raw_headers"),": The set of header files that can be used for inclusion to the source files in the target and all targets that transitively depend on it. Buck doesn't add raw headers to the search path of a compiler/preprocessor automatically. ",(0,n.mdx)("inlineCode",{parentName:"li"},"include_directories")," and ",(0,n.mdx)("inlineCode",{parentName:"li"},"public_include_directories")," are the recommended way to add raw headers to the search path (they will be added via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-I"),"). ",(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags")," and ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_preprocessor_flags")," can also be used to add such raw headers to the search path if inclusion via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-isystem")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"-iquote")," is needed. ",(0,n.mdx)("inlineCode",{parentName:"li"},"raw_headers")," cannot be used together with ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_headers")," in the same target."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of source files to be compiled by this rule. .go files will be compiled with the CGO compiler. Each file needs to have ",(0,n.mdx)("inlineCode",{parentName:"li"},'import "C"')," declared.")),(0,n.mdx)("h4",{id:"details-16"},"Details"),(0,n.mdx)("p",null,"The 'go build' command would collect the cgo directives from the source files, however\nwith buck the flags needs to be passed in the cgo","_","library manually"),(0,n.mdx)("p",null,"This rule borrows from ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_binary()"),"since C/C++ sources are being compiled."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# A rule that builds a Go native executable with linked cgo library based on\n# C/C++ util library.\ngo_binary(\n name = "bin",\n srcs = ["main.go"],\n deps = [":lib"]\n)\n\ncgo_library(\n name = "lib",\n srcs = ["cgo_source.go"],\n deps = [":util"],\n)\n\ncxx_library(\n name = "util",\n srcs = ["util.c"],\n headers = ["util.h"],\n)\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"command_alias"},"command","_","alias"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def command_alias(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _exec_os_type: str = _,\n _target_os_type: str = _,\n args: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n env: dict[str, str] = _,\n exe: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n platform_exe: dict[str, str] = _,\n resources: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"command_alias")," rule enables you to wrap build rules that create binaries and to pre-apply command-line arguments and environment variables."),(0,n.mdx)("h4",{id:"parameters-27"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"args"),": A string of arguments that is passed to the executable specified by ",(0,n.mdx)("inlineCode",{parentName:"p"},"exe")," at startup. These arguments support a subset of Buck's ",(0,n.mdx)("inlineCode",{parentName:"p"},"string parameter macros")," . Only the ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(location ...)")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(exe ...)")," macros are supported currently.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": A map of environment variables that will be passed to the executable represented by ",(0,n.mdx)("inlineCode",{parentName:"p"},"exe")," on startup. Environment variables support the same macros as arguments.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exe"),": A ",(0,n.mdx)("inlineCode",{parentName:"p"},"build target")," for a rule that outputs an executable, such as an ",(0,n.mdx)("inlineCode",{parentName:"p"},"sh\\_binary()"),", or an executable source file.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_exe"),": A mapping from platforms to ",(0,n.mdx)("inlineCode",{parentName:"p"},"build target"),". enables you to override ",(0,n.mdx)("inlineCode",{parentName:"p"},"exe")," per host platform."),(0,n.mdx)("p",{parentName:"li"},"If present, ",(0,n.mdx)("inlineCode",{parentName:"p"},"exe")," will be used as a fallback on host platforms that are not\nspecified in ",(0,n.mdx)("inlineCode",{parentName:"p"},"platform_exe"),"."),(0,n.mdx)("p",{parentName:"li"},"It is possible to omit ",(0,n.mdx)("inlineCode",{parentName:"p"},"exe")," when providing ",(0,n.mdx)("inlineCode",{parentName:"p"},"platform_exe"),".\nIn that case, the build will fail if the command is invoked on a platform not specified in\nthe mapping."),(0,n.mdx)("p",{parentName:"li"},"Valid platforms are all values of the ",(0,n.mdx)("a",{parentName:"p",href:"https://dev.buck.build/javadoc/com/facebook/buck/util/environment/Platform.html"},(0,n.mdx)("inlineCode",{parentName:"a"},"Platform")," enum")," :"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"FREEBSD")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"LINUX")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"MACOS")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"WINDOWS"))))),(0,n.mdx)("h4",{id:"details-17"},"Details"),(0,n.mdx)("p",null,"Example uses include running a command written in a scripting\nlanguage with a specific interpreter, and transparently wrapping\nsub-commands of a binary."),(0,n.mdx)("p",null," You can reference a ",(0,n.mdx)("inlineCode",{parentName:"p"},"command_alias")," target in\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," parameter of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),"by\nusing the ",(0,n.mdx)("inlineCode",{parentName:"p"},"exe")," macro:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n\n$(exe //path/to:target)\n\n")),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# Combining an interpreter and a script\n\ncxx_binary(\n name = "node-js",\n srcs = [\n # ...\n ],\n headers = [\n # ...\n ],\n)\n\nexport_file(\n name = "scripts"\n)\n\ncommand_alias(\n name = "server",\n exe = ":node-js",\n args = [\n "$(location :scripts)/start-server.js",\n ],\n)\n\n')),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# Exposing sub commands\n\nexport_file(\n name = "yarn",\n src = "yarn.sh",\n)\n\ncommand_alias(\n name = "add",\n exe = ":yarn",\n args = ["add"],\n)\n\ncommand_alias(\n name = "install",\n exe = ":yarn",\n args = ["install"],\n)\n\ncommand_alias(\n name = "run",\n exe = ":yarn",\n args = ["run"],\n)\n\n')),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# Platform specific commands\n\nexport_file(\n name = "node-windows",\n src = "windows/node.exe",\n)\n\nexport_file(\n name = "node-linux",\n src = "linux/node",\n)\n\nexport_file(\n name = "node-macos",\n src = "macos/node",\n)\n\ncommand_alias(\n name = "node",\n platform_exe = {\n "windows": ":node-windows",\n "linux": ":node-linux",\n "macos": ":node-macos",\n },\n)\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"config_setting"},"config","_","setting"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def config_setting(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n constraint_values: list[str] = _,\n values: dict[str, str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-28"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configuration_alias"},"configuration","_","alias"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def configuration_alias(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n actual: str,\n buck2_compatibility: str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-29"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configured_alias"},"configured","_","alias"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def configured_alias(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n actual: str,\n buck2_compatibility: str = _,\n configured_actual: None | (str, str) = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n fallback_actual: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n platform: None | str = _,\n propagate_flavors: bool = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-30"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"constraint_setting"},"constraint","_","setting"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def constraint_setting(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-31"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"constraint_value"},"constraint","_","value"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def constraint_value(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n constraint_setting: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-32"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"core_data_model"},"core","_","data","_","model"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def core_data_model(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n module: None | str = _,\n path: str\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"core_data_model()")," rule contains models for Apple's Core Data framework. This rule does not have any output on its own and can be built only as a dependency (either direct or transitive) of an ",(0,n.mdx)("inlineCode",{parentName:"p"},"apple_bundle()")," rule in which case all ",(0,n.mdx)("inlineCode",{parentName:"p"},"core_data_model()")," rules that the bundle rule depends on are merged and placed into the final output bundle together."),(0,n.mdx)("h4",{id:"parameters-33"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("h4",{id:"details-18"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ncore_data_model(\n name = 'MyCoreDataModel',\n path = 'MyCoreDataModel.xcdatamodeld',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"csharp_library"},"csharp","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def csharp_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _csharp_toolchain: str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n dll_name: str = _,\n framework_ver: str,\n labels: list[str] = _,\n licenses: list[str] = _,\n resources: dict[str, str] = _,\n srcs: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A csharp","_","library() rule builds a .Net library from the supplied set of C# source files and dependencies by invoking csc."),(0,n.mdx)("h4",{id:"parameters-34"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": The set of additional compiler flags to pass to the compiler."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of targets or system-provided assemblies to rely on. Any values that are targets must be either csharp","_","library or ",(0,n.mdx)("inlineCode",{parentName:"li"},"prebuilt_dotnet_library")," instances."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"dll_name"),": The output name of the dll. This allows you to specify the name of the dll exactly. When this is not set, the dll will be named after the short name of the target."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"framework_ver"),": The version of the .Net framework that this library targets. This is one of 'net35', 'net40', 'net45' and 'net46'."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"resources"),": Resources that should be embedded within the built DLL. The format is the name of the resource once mapped into the DLL as the key, and the value being the resource that should be merged. This allows non-unique keys to be identified quickly."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The collection of source files to compile.")),(0,n.mdx)("h4",{id:"details-19"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/rust/testdata/"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ncsharp_library(\n name = 'simple',\n dll_name = 'Cake.dll',\n framework_ver = 'net46',\n srcs = [\n 'Hello.cs',\n ],\n resources = {\n 'greeting.txt': '//some:target',\n },\n deps=[\n ':other',\n 'System.dll',\n ],\n)\n\nprebuilt_dotnet_library(\n name = 'other',\n assembly = 'other-1.0.dll',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_binary"},"cxx","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_hacks: str = _,\n _cxx_toolchain: str = _,\n allow_cache_upload: None | bool = _,\n anonymous_link_groups: bool = _,\n auto_link_groups: bool = _,\n binary_linker_flags: list[str] = _,\n bolt_flags: list[str] = _,\n bolt_profile: None | str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n constraint_overrides: list[str] = _,\n contacts: list[str] = _,\n coverage_instrumentation_compiler_flags: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n devirt_enabled: bool = _,\n distributed_thinlto_partial_split_dwarf: bool = _,\n enable_distributed_thinlto: bool = _,\n executable_name: None | str = _,\n exported_needs_coverage_instrumentation: bool = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_deps: list[str] = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_min_binary_node_count: None | int = _,\n link_group_public_deps_label: None | str = _,\n link_ordering: None | str = _,\n link_style: None | str = _,\n link_whole: bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_objects: bool = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n raw_headers: list[str] = _,\n resources: list[str] | dict[str, str] = _,\n srcs: list[str | (str, list[str])] = _,\n thin_lto: bool = _,\n version_universe: None | str = _,\n weak_framework_names: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A cxx","_","binary() rule builds a native executable from the supplied set of C/C++ source files and dependencies. If C/C++ library dependencies are listed, the generated native executable will request and link against their static archives (which are ","*","not","*"," built using ",(0,n.mdx)("a",{parentName:"p",href:"http://en.wikipedia.org/wiki/Position-independent_code"},"PIC"),")."),(0,n.mdx)("h4",{id:"parameters-35"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps_query"),": Status: ",(0,n.mdx)("strong",{parentName:"p"},"experimental/unstable"),". The deps query takes a query string that accepts the following query functions, and appends the output of the query to the declared deps:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"attrfilter")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"except")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"intersect")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"filter")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"kind")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"set")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"union"))),(0,n.mdx)("p",{parentName:"li"}," The macro ",(0,n.mdx)("inlineCode",{parentName:"p"},"$declared_deps")," may be used anywhere a target literal pattern is expected\nin order to refer to the explicit deps of this rule as they appear in the rule's definition.\nFor example, if your build rule declares"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n android_library(\n name = 'lib',\n deps = ['//foo:foo'],\n deps_query = '$declared_deps',\n )\n")),(0,n.mdx)("p",{parentName:"li"}," then the macro ",(0,n.mdx)("inlineCode",{parentName:"p"},"$declared_deps")," would be expanded to a\nliteral ",(0,n.mdx)("inlineCode",{parentName:"p"},"set(//foo:foo)"),".\nSome example queries:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\n "filter({name_regex}, $declared_deps)".format(name_regex=\'//.*\')\n "attrfilter(annotation_processors, com.foo.Processor, $declared_deps)"\n "deps(\'//foo:foo\', 1)"\n')),(0,n.mdx)("p",{parentName:"li"}," Note: any targets included in this query must also be present in ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace"),": A path prefix when including headers of this target. Defaults to the path from the root of the repository to the directory where this target is defined. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"), but cannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>")," , where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"include_directories"),": A list of include directories (with ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),") to be added to the compile command for compiling this target (via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),"). An include directory is relative to the current package.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_execution_preference"),": The execution preference for linking. Options are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},"any : No preference is set, and the link action will be performed based on buck2's executor configuration."),(0,n.mdx)("li",{parentName:"ul"},"full_hybrid : The link action will execute both locally and remotely, regardless of buck2's executor configuration (if\nthe executor is capable of hybrid execution). The use_limited_hybrid setting of the hybrid executor is ignored."),(0,n.mdx)("li",{parentName:"ul"},"local : The link action will execute locally if compatible on current host platform."),(0,n.mdx)("li",{parentName:"ul"},"local_only : The link action will execute locally, and error if the current platform is not compatible."),(0,n.mdx)("li",{parentName:"ul"},"remote : The link action will execute remotely if a compatible remote platform exists, otherwise locally.")),(0,n.mdx)("p",{parentName:"li"},"The default is None, expressing that no preference has been set on the target itself.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_group_deps"),": Additional targets to traverse when building link groups, but which should not be direct dependencies of the main executable.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_group_public_deps_label"),': Surface nodes with this label as "public" nodes in the main executable when linking with with link groups.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_extra_outputs"),": Declares extra outputs that the linker emits. These identifiers can be used in ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(output ...)")," macros in ",(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags")," to interpolate the output path into the linker command line. Useful for custom linkers that emit extra output files.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_headers"),": Platform specific header files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of header files or a dictionary of header names to header files that will be made available for inclusion to the source files in the target if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_linker_flags"),": Platform-specific linker flags. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_preprocessor_flags"),": Platform specific preprocessor flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when preprocessing the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_srcs"),": Platform specific source files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of source files or a list of tuples of source files and a list of compilation flags to be preprocessed, compiled and assembled if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),": The set of header files that can be used for inclusion to the source files in the target and all targets that transitively depend on it. Buck doesn't add raw headers to the search path of a compiler/preprocessor automatically. ",(0,n.mdx)("inlineCode",{parentName:"p"},"include_directories")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"public_include_directories")," are the recommended way to add raw headers to the search path (they will be added via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),"). ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_preprocessor_flags")," can also be used to add such raw headers to the search path if inclusion via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-isystem")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"-iquote")," is needed. ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers")," cannot be used together with ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers")," in the same target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"p",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable)."))),(0,n.mdx)("h4",{id:"details-20"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that builds a C/C++ native executable from a single .cpp file\n# its corresponding header, and a C/C++ library dependency.\ncxx_binary(\n name = 'echo',\n srcs = [\n 'echo.cpp',\n ],\n headers = [\n 'echo.h',\n ],\n deps = [\n ':util',\n ],\n)\n\ncxx_library(\n name = 'util',\n srcs = [\n 'util.cpp',\n ],\n headers = [\n 'util.h',\n ],\n)\n\n# To build without stripping:\nbuck build :echo\n\n# To build with stripping debug symbols only:\nbuck build :echo#strip-debug\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_genrule"},"cxx","_","genrule"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_genrule(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _cxx_toolchain: str = _,\n _exec_os_type: str = _,\n _genrule_toolchain: str = _,\n always_print_stderr: bool = _,\n bash: None | str = _,\n buck2_compatibility: str = _,\n cacheable: None | bool = _,\n cmd: None | str = _,\n cmd_exe: None | str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n default_outs: None | list[str] = _,\n enable_sandbox: None | bool = _,\n environment_expansion_separator: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n metadata_env_var: None | str = _,\n metadata_path: None | str = _,\n need_android_tools: bool = _,\n no_outputs_cleanup: bool = _,\n out: None | str = _,\n outs: None | dict[str, list[str]] = _,\n remote: None | bool = _,\n remote_execution_dependencies: list[dict[str, str]] = _,\n srcs: list[str] | dict[str, str] = _,\n type: None | str = _,\n weight: None | int = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule()")," enables you to run shell commands as part of the Buck build process. A ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule()")," exposes - through a set of string parameter macros and variables - information about the tools and configuration options used by the Buck environment, specifically those related to the C/C++ toolchain."),(0,n.mdx)("h4",{id:"parameters-36"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"bash"),": A platform-specific version of the shell command parameter ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". It runs on Linux and UNIX systems\u2014including OSX\u2014on which ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," is installed. It has a higher priority than ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". The ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," argument is run with ",(0,n.mdx)("inlineCode",{parentName:"p"},"/usr/bin/env bash -c"),". It has access to the same set of macros and variables as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),": The shell command to run to generate the output file. It is the fallback of ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe"),". The shell command can access information about the buck build environment through a set of ",(0,n.mdx)("em",{parentName:"p"},"macros"),", ",(0,n.mdx)("em",{parentName:"p"},"parameterized macros"),", and ",(0,n.mdx)("em",{parentName:"p"},"variables"),"."),(0,n.mdx)("h4",{parentName:"li",id:"macros"},"Macros"),(0,n.mdx)("p",{parentName:"li"}," The following macros are available to the shell command and are\naccessed using the following syntax."),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"$()\n")),(0,n.mdx)("p",{parentName:"li"}," Example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"$(cc)\n")),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(cc)"),"\nPath to the C compiler."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(cxx)"),"\nPath to the C++ compiler."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(cflags)"),"\nFlags passed to the C compiler."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(cppflags)"),"\nFlags passed to the C preprocessor."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(cxxflags)"),"\nFlags passed to the C++ compiler."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(cxxppflags)"),"\nFlags to pass to the C++ preprocessor."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(ld)"),"\nPath to the linker."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(ldflags-pic)"),"\nFlags passed to the linker for binaries that use\nposition-independent code (PIC)."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(ldflags-pic-filter )"),"\nFlags passed to the linker for binaries that use position-independent code (PIC).\nUse the ",(0,n.mdx)("em",{parentName:"p"},"pattern")," parameter to specify a regular expression that matches the build targets that use these flags."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(ldflags-shared)"),"\nFlags passed to the linker for shared libraries, such as dynamic-link libraries (DLLs)."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(ldflags-shared-filter )"),"\nFlags passed to the linker for shared libraries, such as dynamic-link libraries (DLLs).\nUse the ",(0,n.mdx)("em",{parentName:"p"},"pattern")," parameter to specify a regular expression that matches the build targets that use these flags."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(ldflags-static)"),"\nFlags passed to the linker for statically-linked libraries."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(ldflags-static-filter )"),"\nFlags passed to the linker for statically-linked libraries.\nUse the ",(0,n.mdx)("em",{parentName:"p"},"pattern")," parameter to specify a regular expression that matches the build targets that use these flags."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(platform-name)"),"\nThe platform flavor with which this ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule")," was specified."),(0,n.mdx)("h4",{parentName:"li",id:"parameterized-macros"},"Parameterized Macros"),(0,n.mdx)("p",{parentName:"li"}," It is also possible to expand references to other rules within the\nshell command, using the following subset of the\nbuiltin ",(0,n.mdx)("inlineCode",{parentName:"p"},"string parameter macros"),"\n.\nNote that all build rules expanded in the command are automatically\nconsidered to be dependencies of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),"."),(0,n.mdx)("p",{parentName:"li"}," Note that the paths returned by these macros are ",(0,n.mdx)("em",{parentName:"p"},"absolute")," paths. You should convert these paths to be relative paths before\nembedding them in, for example, a shell script or batch file. Using\nrelative paths ensures that your builds are ",(0,n.mdx)("em",{parentName:"p"},"hermetic"),", that\nis, they are reproducible across different machine environments."),(0,n.mdx)("p",{parentName:"li"}," Additionally, if you embed these paths in a shell script, you should\nexecute that script using the ",(0,n.mdx)("inlineCode",{parentName:"p"},"sh\\_binary()"),"rule and include\nthe targets for these paths in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources")," argument of\nthat ",(0,n.mdx)("inlineCode",{parentName:"p"},"sh_binary")," rule. These are the same targets that you\npass to the string parameter macros."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(exe //path/to:target)"),"\nExpands to the commands necessary to run the executable\ngenerated by the specified build rule. For a C++ executable, this\nwill typically just be the name of the output executable itself,\nsuch as ",(0,n.mdx)("inlineCode",{parentName:"p"},"main"),". If the specified build rule does not generate an\nexecutable output, an exception will be thrown and the build will\nfail."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(location //path/to:target)"),"\nExpands to the path of the output of the build rule. This\nmeans that you can refer to these without needing to be aware of\nhow Buck is storing data on the disk mid-build."),(0,n.mdx)("h4",{parentName:"li",id:"variables"},"Variables"),(0,n.mdx)("p",{parentName:"li"}," Finally, Buck adds the following variables to the environment in\nwhich the shell command runs. They are accessed using the following syntax.\nNote the use of braces rather than parentheses."),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"${}\n")),(0,n.mdx)("p",{parentName:"li"}," Example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"${SRCS}\n")),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${SRCS}"),"\nA string expansion of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," argument delimited by\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"environment_expansion_separator")," argument where each element\nof ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," will be translated into an absolute path."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${SRCDIR}"),"\nThe absolute path to the to which sources are copied\nprior to running the command."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${OUT}"),"\nThe output file for the ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),". The file\nspecified by this variable must always be written by this\ncommand. If not, the execution of this rule will be considered a\nfailure, halting the build process."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${TMP}"),"\nA temporary directory which can be used for intermediate results and will not be\nbundled into the output.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe"),": A platform-specific version of the shell command parameter ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". It runs on Windows and has a higher priority than ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". The ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe")," argument is run with ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd.exe /v:off /c"),". It has access to the same set of macros and variables as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"enable_sandbox"),": Whether this target should be executed in a sandbox or not.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"environment_expansion_separator"),": The delimiter between paths in environment variables, such as SRCS, that can contain multiple paths. It can be useful to specify this parameter if the paths could contain spaces.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"out"),": The name of the output file or directory. The complete path to this argument is provided to the shell command through the ",(0,n.mdx)("inlineCode",{parentName:"p"},"OUT")," environment variable.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": Either a list or a map of the source files which Buck makes available to the shell command at the path in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"SRCDIR")," environment variable. If you specify a list, the source files are the names in the list. If you specify a map, the source files are made available as the names in the keys of the map, where the values of the map are the original source file names.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"type"),": Specifies the ",(0,n.mdx)("em",{parentName:"p"},"type"),' of this genrule. This is used for logging and is particularly useful for grouping genrules that share an underlying logical "type".'),(0,n.mdx)("p",{parentName:"li"},"For example, if you have the following ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule")," defined\nin the root directory of your Buck project"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n\ncxx_genrule(\n name = 'cxx_gen',\n type = 'epilog',\n cmd = 'touch finish.txt; cp finish.txt $OUT',\n out = 'finish.txt'\n)\n\n")),(0,n.mdx)("p",{parentName:"li"}," then the following ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck query")," command"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n\nbuck query \"attrfilter( type, 'epilog', '//...' )\"\n\n")),(0,n.mdx)("p",{parentName:"li"}," returns"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n\n//:cxx_gen\n\n"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"weight"),": How many local slots these genrule should take when executing locally."))),(0,n.mdx)("h4",{id:"details-21"},"Details"),(0,n.mdx)("p",null,"The information exposed through these tools and configuration options is a reflection of:\nBuck's built-in settings,\nthe settings in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nand ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig.local"),",\nand the result of various command-line overrides specified through\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"common\\_parameters"),"command-line option."),(0,n.mdx)("p",null,"This information is available only\nto the shell commands specified in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule"),".\nThe information is not available to other arguments of the rule."),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule()")," can be an input to\nanother ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule()"),"."),(0,n.mdx)("p",null,"Note that if you specify the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule")," as a command-line\ntarget to ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck build"),", you must include a platform flavor.\nFor example:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n\nbuck build :cxx_gr_name#iphonesimulator-x86_64\n\n")),(0,n.mdx)("p",null,"You could also just specify the default platform flavor explicitly:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n\nbuck build :cxx_gr_name#default\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_library"},"cxx","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_hacks: str = _,\n _cxx_toolchain: str = _,\n _is_building_android_binary: bool = _,\n allow_cache_upload: None | bool = _,\n auto_link_groups: bool = _,\n bridging_header: None | str = _,\n buck2_compatibility: str = _,\n can_be_asset: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n coverage_instrumentation_compiler_flags: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n devirt_enabled: bool = _,\n diagnostics: dict[str, str] = _,\n executable_name: None | str = _,\n exported_deps: list[str] = _,\n exported_header_style: str = _,\n exported_headers: list[str] | dict[str, str] = _,\n exported_lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n exported_lang_preprocessor_flags: dict[str, list[str]] = _,\n exported_linker_flags: list[str] = _,\n exported_needs_coverage_instrumentation: bool = _,\n exported_platform_deps: list[(str, list[str])] = _,\n exported_platform_headers: list[(str, list[str] | dict[str, str])] = _,\n exported_platform_linker_flags: list[(str, list[str])] = _,\n exported_platform_preprocessor_flags: list[(str, list[str])] = _,\n exported_post_linker_flags: list[str] = _,\n exported_post_platform_linker_flags: list[(str, list[str])] = _,\n exported_preprocessor_flags: list[str] = _,\n extra_xcode_files: list[str] = _,\n extra_xcode_sources: list[str] = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n force_static: None | bool = _,\n frameworks: list[str] = _,\n header_mode: None | str = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n include_in_android_merge_map_output: bool = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_ordering: None | str = _,\n link_style: None | str = _,\n link_whole: None | bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n local_linker_flags: list[str] = _,\n module_name: None | str = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_objects: bool = _,\n preferred_linkage: str = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n public_include_directories: list[str] = _,\n public_system_include_directories: list[str] = _,\n raw_headers: list[str] = _,\n reexport_all_header_dependencies: None | bool = _,\n resources: list[str] | dict[str, str] = _,\n sdk_modules: list[str] = _,\n soname: None | str = _,\n srcs: list[str | (str, list[str])] = _,\n static_library_basename: None | str = _,\n supported_platforms_regex: None | str = _,\n supports_header_symlink_subtarget: bool = _,\n supports_merged_linking: None | bool = _,\n supports_python_dlopen: None | bool = _,\n supports_shlib_interfaces: bool = _,\n thin_lto: bool = _,\n use_archive: None | bool = _,\n used_by_wrap_script: bool = _,\n uses_cxx_explicit_modules: bool = _,\n uses_explicit_modules: bool = _,\n version_universe: None | str = _,\n weak_framework_names: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library()")," rule specifies a set of C/C++ source files and also provides flags that specify how those files should be built."),(0,n.mdx)("h4",{id:"parameters-37"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),": Dependencies that will also appear to belong to any rules that depend on this one. This has two effects: ",(0,n.mdx)("em",{parentName:"p"}," Exported dependencies will also be included in the link line of dependents of this rules, but normal dependencies will not. ")," When ",(0,n.mdx)("inlineCode",{parentName:"p"},"reexport_all_header_dependencies = False"),", only exported headers of the rules specified here are re-exported.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_header_style"),": How dependents should include exported headers from this rule. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"local")," (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),") or ",(0,n.mdx)("inlineCode",{parentName:"p"},"system")," (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"-isystem"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers"),": The set of header files that are made available for inclusion to the source files in the target and all targets that transitively depend on it. These should be specified as either a list of header files or a dictionary of header names to header files. The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>"),", where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. Note that the header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). See ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_lang_platform_preprocessor_flags"),": Just as ",(0,n.mdx)("inlineCode",{parentName:"p"},"lang_platform_preprocessor_flags"),", but these flags also apply to rules that transitively depend on this rule.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_lang_preprocessor_flags"),": Just as ",(0,n.mdx)("inlineCode",{parentName:"p"},"lang_preprocessor_flags"),", but these flags also apply to rules that transitively depend on this rule.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_linker_flags"),": Flags to add to the linker command line when the output from this rule, or the output from any rule that transitively depends on this rule, is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_platform_deps"),": Platform specific dependencies that will also appear to belong to any rules that depend on this one. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of external dependencies (same format as ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),") that are exported if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_platform_headers"),": Platform specific header files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of header files or a dictionary of header names to header files that will be made available for inclusion to the source files in the target and all targets that transitively depend on it if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_platform_linker_flags"),": Platform-specific linker flags for this rule and for all rules that transitively depend on this rule. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule, or the output from any rule that transitively depends on this rule, is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_platform_preprocessor_flags"),": Platform specific exported preprocessor flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when preprocessing the source files in the target and all targets that transitively depend on it if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_preprocessor_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_post_linker_flags"),": Flags to add to the linker command line when the output from this rule, or the output from any rule that transitively depends on this rule, is used in a link operation\u2014with the additional feature that these flags are guaranteed to be placed ",(0,n.mdx)("em",{parentName:"p"},"after")," the compiled object (",(0,n.mdx)("inlineCode",{parentName:"p"},".o"),") files on the linker command line.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_post_platform_linker_flags"),": Platform-specific linker flags for this rule and for all rules that transitively depend on this rule\u2014and that are guaranteed to be placed ",(0,n.mdx)("em",{parentName:"p"},"after")," the compiled object (",(0,n.mdx)("inlineCode",{parentName:"p"},".o"),") files on the linker command line. In other respects, the syntax and semantics of this argument are the same as for the ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_platform_linker_flags")," argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_xcode_files"),': When the project is generated, this is the list of files that will added to the project. Those files won\'t be added to the build phase "Compile Sources".')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace"),": A path prefix when including headers of this target. Defaults to the path from the root of the repository to the directory where this target is defined. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"), but cannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>")," , where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"include_directories"),": A list of include directories (with ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),") to be added to the compile command for compiling this target (via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),"). An include directory is relative to the current package.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"lang_compiler_flags"),": Language-specific compiler flags. These should be specified as a map of C-family language short names to lists of flags and is used to target flags to sources files for a specific language in the C-family (C, C++, assembler, etc.). The keys in the map can be: ",(0,n.mdx)("em",{parentName:"p"}," ",(0,n.mdx)("inlineCode",{parentName:"em"},"cpp-output")," for C ")," ",(0,n.mdx)("inlineCode",{parentName:"p"},"c++-cpp-output")," for C++ ",(0,n.mdx)("em",{parentName:"p"}," ",(0,n.mdx)("inlineCode",{parentName:"em"},"objective-c-cpp-output")," for Objective-C ")," ",(0,n.mdx)("inlineCode",{parentName:"p"},"objective-c++-cpp-output")," for Objective-C++ ",(0,n.mdx)("em",{parentName:"p"}," ",(0,n.mdx)("inlineCode",{parentName:"em"},"cuda-cpp-output")," for Cuda ")," ",(0,n.mdx)("inlineCode",{parentName:"p"},"assembler")," for Assembly * ",(0,n.mdx)("inlineCode",{parentName:"p"},"asm")," for ASM")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"lang_platform_compiler_flags"),": Language- and platform-specific compiler flags. These should be specified as a map of C-family language short names, as described in ",(0,n.mdx)("inlineCode",{parentName:"p"},"lang_compiler_flags"),", to lists of pairs, as described in ",(0,n.mdx)("inlineCode",{parentName:"p"},"platform_compiler_flags"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"lang_platform_preprocessor_flags"),": Language- and platform-specific preprocessor flags. These should be specified as a map of C-family language short names, as described in ",(0,n.mdx)("inlineCode",{parentName:"p"},"lang_preprocessor_flags"),", to lists of pairs, as described in ",(0,n.mdx)("inlineCode",{parentName:"p"},"platform_preprocessor_flags"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"lang_preprocessor_flags"),": Language-specific preprocessor flags. These should be specified as a map of C-family language short names to lists of flags and is used to target flags to sources files for a specific language in the C-family (C, C++, assembler, etc.). The keys in the map can be: ",(0,n.mdx)("em",{parentName:"p"}," ",(0,n.mdx)("inlineCode",{parentName:"em"},"c")," for C ")," ",(0,n.mdx)("inlineCode",{parentName:"p"},"c++")," for C++ ",(0,n.mdx)("em",{parentName:"p"}," ",(0,n.mdx)("inlineCode",{parentName:"em"},"objective-c")," for Objective-C ")," ",(0,n.mdx)("inlineCode",{parentName:"p"},"objective-c++")," for Objective-C++ ",(0,n.mdx)("em",{parentName:"p"}," ",(0,n.mdx)("inlineCode",{parentName:"em"},"cuda")," for Cuda ")," ",(0,n.mdx)("inlineCode",{parentName:"p"},"assembler-with-cpp")," for Assembly * ",(0,n.mdx)("inlineCode",{parentName:"p"},"asm-with-cpp")," for ASM")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_execution_preference"),": The execution preference for linking. Options are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},"any : No preference is set, and the link action will be performed based on buck2's executor configuration."),(0,n.mdx)("li",{parentName:"ul"},"full_hybrid : The link action will execute both locally and remotely, regardless of buck2's executor configuration (if\nthe executor is capable of hybrid execution). The use_limited_hybrid setting of the hybrid executor is ignored."),(0,n.mdx)("li",{parentName:"ul"},"local : The link action will execute locally if compatible on current host platform."),(0,n.mdx)("li",{parentName:"ul"},"local_only : The link action will execute locally, and error if the current platform is not compatible."),(0,n.mdx)("li",{parentName:"ul"},"remote : The link action will execute remotely if a compatible remote platform exists, otherwise locally.")),(0,n.mdx)("p",{parentName:"li"},"The default is None, expressing that no preference has been set on the target itself.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_extra_outputs"),": Declares extra outputs that the linker emits. These identifiers can be used in ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(output ...)")," macros in ",(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags")," to interpolate the output path into the linker command line. Useful for custom linkers that emit extra output files.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"local_linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation ",(0,n.mdx)("em",{parentName:"p"},"driven by this rule")," (e.g. when this rule links a shared library, but ",(0,n.mdx)("em",{parentName:"p"},"not")," when the output is linked into a shared library by another rule's link group links).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_headers"),": Platform specific header files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of header files or a dictionary of header names to header files that will be made available for inclusion to the source files in the target if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_linker_flags"),": Platform-specific linker flags. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule is used in a link operation.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_preprocessor_flags"),": Platform specific preprocessor flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when preprocessing the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_srcs"),": Platform specific source files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of source files or a list of tuples of source files and a list of compilation flags to be preprocessed, compiled and assembled if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"public_include_directories"),": A list of include directories (with ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),") to be added to the compile command for compiling this target and every target that depends on it (via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),"). An include directory is relative to the current package.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"public_system_include_directories"),": A list of include directories (with ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),") to be added to the compile command for compiling this target and every target that depends on it (via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-isystem")," if the compiler supports it of via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I")," otherwise). An include directory is relative to the current package.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),": The set of header files that can be used for inclusion to the source files in the target and all targets that transitively depend on it. Buck doesn't add raw headers to the search path of a compiler/preprocessor automatically. ",(0,n.mdx)("inlineCode",{parentName:"p"},"include_directories")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"public_include_directories")," are the recommended way to add raw headers to the search path (they will be added via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),"). ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_preprocessor_flags")," can also be used to add such raw headers to the search path if inclusion via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-isystem")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"-iquote")," is needed. ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers")," cannot be used together with ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers")," in the same target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"reexport_all_header_dependencies"),": Whether to automatically re-export the exported headers of all dependencies."),(0,n.mdx)("p",{parentName:"li"},"When this is set to false, only exported headers from\n",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," are re-exported.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"soname"),': Sets the soname ("shared object name") of any shared library produced from this rule. The default value is based on the full rule name. The macro ',(0,n.mdx)("inlineCode",{parentName:"p"},"$(ext)")," will be replaced with a platform-appropriate extension. An argument can be provided, which is a library version. For example ",(0,n.mdx)("inlineCode",{parentName:"p"},"soname = 'libfoo.$(ext 2.3)'")," will be ",(0,n.mdx)("inlineCode",{parentName:"p"},"libfoo.2.3.dylib")," on Mac and ",(0,n.mdx)("inlineCode",{parentName:"p"},"libfoo.so.2.3")," on Linux.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"p",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"supported_platforms_regex"),": If present, an un-anchored regex (in java.util.regex.Pattern syntax) that matches all platforms that this library supports. It will not be built for other platforms.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"used_by_wrap_script"),": When using an exopackage Android, if this parameter is set to ",(0,n.mdx)("inlineCode",{parentName:"p"},"True"),", then the library is included in the primary APK even if native libraries would otherwise not be placed in it. This is intended for native libraries that are used by a ",(0,n.mdx)("a",{parentName:"p",href:"https://developer.android.com/ndk/guides/wrap-script"},"wrap.sh")," script, which must be placed in the primary APK. Only one of ",(0,n.mdx)("inlineCode",{parentName:"p"},"can_be_asset")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"used_by_wrap_script")," can be set for a rule."))),(0,n.mdx)("h4",{id:"details-22"},"Details"),(0,n.mdx)("h4",{id:"building-requires-a-specified-top-level-target"},"Building requires a specified top-level target"),(0,n.mdx)("p",null,"Whether a Buck command builds the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library")," is\ndetermined by the inclusion of a top-level target, such as\na ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_binary()"),"or ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_binary()"),", that\ntransitively depends on the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library"),". The set of\ntargets specified to the Buck command (",(0,n.mdx)("inlineCode",{parentName:"p"},"buck build"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck run"),", etc) must\ninclude one of these top-level targets in order for Buck to build\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library"),". Note that you could specify the top-level target\nimplicitly using a ",(0,n.mdx)("inlineCode",{parentName:"p"},"build target pattern"),"or you could also specify\nthe top-level target using an buckconfig#",(0,n.mdx)("inlineCode",{parentName:"p"},"alias"),"defined in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"."),(0,n.mdx)("p",null,(0,n.mdx)("em",{parentName:"p"},"How")," Buck builds the library also depends on the specified top-level target.\nFor example, a C/C++ binary (",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_binary"),") would require a static non-PIC build of the library,\nwhereas an Android APK (",(0,n.mdx)("inlineCode",{parentName:"p"},"android_binary"),") would require a shared PIC-enabled build.\n(PIC stands for position-independent code.)"),(0,n.mdx)("h4",{id:"dependencies-of-the-cxx_library-also-require-a-top-level-target"},"Dependencies of the cxx","_","library also require a top-level target"),(0,n.mdx)("p",null,"Similarly, in order for Buck to build a target that\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library")," depends on, such as a ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_genrule()"),",\nyou must specify in the Buck command a top-level target that depends on\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library"),". For example, you could specify\nto ",(0,n.mdx)("inlineCode",{parentName:"p"},"build"),"a ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_binary")," that\ndepends on the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library"),". If you specify as\nyour build target the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library")," itself, the build targets\nthat the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library")," depends on ",(0,n.mdx)("em",{parentName:"p"},"might not be built"),"."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that includes a single .cpp file and its corresponding header and\n# also supplies an additional flag for compilation.\ncxx_library(\n name = 'fileutil',\n srcs = [\n 'fileutil.cpp',\n ],\n exported_headers = [\n 'fileutil.h',\n ],\n compiler_flags = [\n '-fno-omit-frame-pointer',\n ],\n)\n\n# A rule that defines explicit names for its headers\ncxx_library(\n name = 'mathutils',\n header_namespace = 'math',\n srcs = [\n 'trig/src/cos.cpp',\n 'trig/src/tan.cpp',\n ],\n exported_headers = {\n # These are included as and \n 'trig/cos.h': 'trig/include/cos.h',\n 'trig/tan.h': 'trig/include/tan.h',\n },\n compiler_flags = [\n '-fno-omit-frame-pointer',\n ],\n)\n\n# A rule that uses different headers and sources per platform\ncxx_library(\n name = 'vector',\n # Because of platform_headers, this file can include \"config.h\"\n # and get the architecture specific header\n srcs = ['vector.cpp'],\n platform_srcs = [\n ('.*armv7$', 'armv7.S'),\n ('.*x86_64$', 'x86_64.S'),\n ],\n exported_headers = [\n 'vector.h',\n ],\n platform_headers = [\n (\n '.*armv7$',\n {\n 'config.h': 'config-armv7.h',\n }\n ),\n (\n '.*x86_64$',\n {\n 'config.h': 'config-x86_64.h',\n }\n ),\n ],\n)\n\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_lua_extension"},"cxx","_","lua","_","extension"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_lua_extension(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n base_module: None | str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n executable_name: None | str = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n raw_headers: list[str] = _,\n srcs: list[str | (str, list[str])] = _,\n version_universe: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A cxx","_","lua","_","extension() rule is a variant of a C/C++ library which is built as a Lua module. As such, it has a module name formed by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"base_module")," parameter and the rule name and implicitly depends on Lua C library (configured via the ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," parameter."),(0,n.mdx)("h4",{id:"parameters-38"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"base_module"),": The package for which the given specified sources and resources should reside in their final location in the top-level binary. If unset, the project relative directory that houses the BUCK file is used."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace"),": A path prefix when including headers of this target. Defaults to the path from the root of the repository to the directory where this target is defined. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"), but cannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"). The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"li"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>")," , where ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_headers"),": Platform specific header files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of header files or a dictionary of header names to header files that will be made available for inclusion to the source files in the target if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_linker_flags"),": Platform-specific linker flags. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"li"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule is used in a link operation."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_preprocessor_flags"),": Platform specific preprocessor flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when preprocessing the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_srcs"),": Platform specific source files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of source files or a list of tuples of source files and a list of compilation flags to be preprocessed, compiled and assembled if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"srcs")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"li",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("h4",{id:"details-23"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that builds a Lua extension from a single .cpp file.\ncxx_lua_extension(\n name = 'mymodule',\n base_module = 'foo.bar',\n srcs = [\n 'mymodule.cpp',\n ],\n compiler_flags = [\n '-fno-omit-frame-pointer',\n ],\n)\n\n# A library rule which has a single source importing the above extension.\nlua_library(\n name = 'utils',\n srcs = [\n 'utils.lua',\n ],\n deps = [\n ':mymodule',\n ],\n)\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n-- The `utils.lua` source, wrapped by the `utils` rule above.\n\n-- Import the C/C++ extension build above.\nrequire "foo.bar.mymodule"\n\n...\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_precompiled_header"},"cxx","_","precompiled","_","header"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_precompiled_header(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n src: str,\n version_universe: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_precompiled_header")," rule specifies a single header file that can be precompiled and made available for use in other build rules such as a ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_library()"),"or a ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_binary()"),"."),(0,n.mdx)("h4",{id:"parameters-39"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Dependency rules which export headers used by the header specified in ",(0,n.mdx)("inlineCode",{parentName:"li"},"src"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"src"),": The path to the header file that should be precompiled. Only one header file can be specified. But of course this header could include any number of other headers. The included headers could belong to -- that is, be ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_headers")," from -- another rule, in which case, the rule would have to be added to ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps")," as usual.")),(0,n.mdx)("h4",{id:"details-24"},"Details"),(0,n.mdx)("p",null,"This header file is precompiled by the preprocessor on behalf of the\nC, C++, Objective-C, or Objective-C++ rule using it, via its ",(0,n.mdx)("inlineCode",{parentName:"p"},"precompiled_header")," parameter.\nAfterwards the precompiled header is applied during the rule's own compilation\n(often with an appreciable reduction in build time, the main benefit of PCH)."),(0,n.mdx)("p",null,' This PCH is built once per combination of build flags which might affect the PCH\'s compatibility.\nFor example, a distinct pre-compilation of the header occurs per combination of flags related to\noptimization, debug, architecture, and so on, used by rules which employ PCH.\nThe flags used during the build of the dependent rule (that is, the "PCH-using rule")\nare in effect while building the PCH itself. Similarly, to the same end, the include paths used\nwhen building the PCH are applied to the dependent rule. For example, ',(0,n.mdx)("inlineCode",{parentName:"p"},"deps")," in the\nPCH rule are propagated back to the dependent rule, and the PCH's header search paths\n(e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"-isystem")," options) are prefixed onto the list of\ninclude paths for the dependent rule."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"The best way to see how the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_precompiled_header()")," rule works is with an\nexample. Let there be a header called ",(0,n.mdx)("inlineCode",{parentName:"p"},"common.h")," which has the following:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n#pragma once\n\n/* Include common C++ files. */\n#include \n#include \n#include \n#include \n#include \n\n/* Some frequently-used headers from the Folly project. */\n#include \n#include \n#include \n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ncxx_precompiled_header(\n name = 'common_pch',\n src = 'common.h',\n deps = [\n # Needed for standard C++ headers:\n '//external/libcxx:headers',\n # Needed for the Folly includes:\n '//folly:folly',\n '//folly/io/async:async',\n ],\n)\n\ncxx_binary(\n name = 'main',\n srcs = ['main.cpp'],\n precompiled_header = ':common_pch',\n deps = [ ... ],\n compiler_flags = ['-g', '-O2', '-fPIC'],\n)\n\n")),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_precompiled_header"),' rule declares a precompiled header "template"\ncontaining the header file path, and dependencies.\nIn this example we indicate that ',(0,n.mdx)("inlineCode",{parentName:"p"},"common.h")," is to be precompiled when used by another build rule."),(0,n.mdx)("p",null,"Note that, by itself, this ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_precompiled_header")," rule will not result\nin anything being built. The ",(0,n.mdx)("em",{parentName:"p"},"usage"),' of this rule from another rule --\nan "instantiation" of this precompiled header template -- is what will trigger the\nPCH build.'),(0,n.mdx)("p",null,"In the example above, the build for the binary named ",(0,n.mdx)("inlineCode",{parentName:"p"},'"main"')," will depend on\nthe header being precompiled in a separate step, prior to compiling ",(0,n.mdx)("inlineCode",{parentName:"p"},"main.cpp"),",\nand the resulting PCH will be used in ",(0,n.mdx)("inlineCode",{parentName:"p"},"main"),"'s compilation."),(0,n.mdx)("p",null,"The dependencies specified in this precompiled header rule's ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps")," are transitive; they\nwill propagate to rules using this PCH, so that during link time, any libraries which are\nrequired by the code made available in the header will be included in the final binary build."),(0,n.mdx)("p",null,'The precompiled header dynamically created from the "template" will be built with flags\nwhich would be used in the dependent rule. In this case, ',(0,n.mdx)("inlineCode",{parentName:"p"},"main"),"'s use of specific\ncompiler flags ",(0,n.mdx)("inlineCode",{parentName:"p"},"-g -O2 -fPIC")," will result in the production of a precompiled header\nwith the same flags. This is so the precompiled code fully jives with rules using the PCH,\ni.e. they will have the same debug, optimization, CPU, etc. options. (The compiler is usually\nsmart enough to reject a bad PCH, fortunately. But we want to ensure we take the appropriate\nsteps to ensure we ",(0,n.mdx)("em",{parentName:"p"},"always have")," a PCH which works with any build that uses it.)"),(0,n.mdx)("p",null,"Another effect of a rule using a precompiled header is that the rule's list of\nbuild flags will change; not just to employ PCH with e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"-include-pch"),' (if using Clang), but also, to alter the sequence of header search paths.\nThe rule using the precompiled header will "inherit" the lists of paths used\nduring the PCH build, applying them ',(0,n.mdx)("em",{parentName:"p"},"first")," in its own search paths.\nThis is to ensure that an ",(0,n.mdx)("inlineCode",{parentName:"p"},"#include")," directive will resolve in exactly\nthe same way in this build as it would have in the PCH, to ensure full compatibility\nbetween the PCH and other rule's builds. For example, if the PCH were to use one version\nof ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdcxx")," and another rule use a different version, the version differences\nwon't clash, thereby avoiding different versions of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"")," header\nused between the precompiled header and the dependent rule, and preventing confused\nstructure definitions, ABI incompatibility, and so on (catastrophe, in other words)."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_python_extension"},"cxx","_","python","_","extension"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_python_extension(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_hacks: str = _,\n _cxx_toolchain: str = _,\n _python_toolchain: str = _,\n _target_os_type: str = _,\n allow_cache_upload: None | bool = _,\n allow_embedding: bool = _,\n allow_suffixing: bool = _,\n auto_link_groups: bool = _,\n base_module: None | str = _,\n bridging_header: None | str = _,\n buck2_compatibility: str = _,\n can_be_asset: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n coverage_instrumentation_compiler_flags: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n devirt_enabled: bool = _,\n diagnostics: dict[str, str] = _,\n executable_name: None | str = _,\n exported_deps: list[str] = _,\n exported_header_style: str = _,\n exported_headers: list[str] | dict[str, str] = _,\n exported_lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n exported_lang_preprocessor_flags: dict[str, list[str]] = _,\n exported_linker_flags: list[str] = _,\n exported_needs_coverage_instrumentation: bool = _,\n exported_platform_deps: list[(str, list[str])] = _,\n exported_platform_headers: list[(str, list[str] | dict[str, str])] = _,\n exported_platform_linker_flags: list[(str, list[str])] = _,\n exported_platform_preprocessor_flags: list[(str, list[str])] = _,\n exported_post_linker_flags: list[str] = _,\n exported_post_platform_linker_flags: list[(str, list[str])] = _,\n exported_preprocessor_flags: list[str] = _,\n extra_xcode_files: list[str] = _,\n extra_xcode_sources: list[str] = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n force_static: None | bool = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n include_in_android_merge_map_output: bool = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_ordering: None | str = _,\n link_style: None | str = _,\n link_whole: bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n local_linker_flags: list[str] = _,\n module_name: None | str = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n preferred_linkage: str = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n public_include_directories: list[str] = _,\n public_system_include_directories: list[str] = _,\n raw_headers: list[str] = _,\n reexport_all_header_dependencies: None | bool = _,\n resources: list[str] | dict[str, str] = _,\n sdk_modules: list[str] = _,\n soname: None | str = _,\n srcs: list[str | (str, list[str])] = _,\n static_library_basename: None | str = _,\n suffix_all: bool = _,\n support_shlib_interfaces: bool = _,\n supported_platforms_regex: None | str = _,\n supports_merged_linking: None | bool = _,\n thin_lto: bool = _,\n type_stub: None | str = _,\n use_archive: None | bool = _,\n used_by_wrap_script: bool = _,\n uses_cxx_explicit_modules: bool = _,\n uses_explicit_modules: bool = _,\n version_universe: None | str = _,\n weak_framework_names: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_python_extension()")," rule is a variant of a C/C++ library which is built as a Python module. As such, it has a module name formed by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"base_module")," parameter and the rule name."),(0,n.mdx)("h4",{id:"parameters-40"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"base_module"),": The package in which the specified source files and resources should reside in their final location in the top-level binary. If unset, Buck uses the project-relative directory that contains the BUCK file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Other rules that list ",(0,n.mdx)("inlineCode",{parentName:"li"},"srcs")," from which this rule imports."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace"),": A path prefix when including headers of this target. Defaults to the path from the root of the repository to the directory where this target is defined. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"), but cannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"). The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"li"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>")," , where ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"labels"),": Set of arbitrary strings which allow you to annotate a ",(0,n.mdx)("inlineCode",{parentName:"li"},"build rule"),"with tags that can be searched for over an entire dependency tree using ",(0,n.mdx)("inlineCode",{parentName:"li"},"buck query()")," ."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"li"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared"),". Note: since shared libraries re-export its dependencies, depending on multiple shared libraries which themselves have overlapping static dependencies may cause problems if they init using global state."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_extra_outputs"),": Declares extra outputs that the linker emits. These identifiers can be used in ",(0,n.mdx)("inlineCode",{parentName:"li"},"$(output ...)")," macros in ",(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags")," to interpolate the output path into the linker command line. Useful for custom linkers that emit extra output files."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"local_linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation ",(0,n.mdx)("em",{parentName:"li"},"driven by this rule")," (e.g. when this rule links a shared library, but ",(0,n.mdx)("em",{parentName:"li"},"not")," when the output is linked into a shared library by another rule's link group links)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_headers"),": Platform specific header files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of header files or a dictionary of header names to header files that will be made available for inclusion to the source files in the target if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_linker_flags"),": Platform-specific linker flags. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"li"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule is used in a link operation."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_preprocessor_flags"),": Platform specific preprocessor flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when preprocessing the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_srcs"),": Platform specific source files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of source files or a list of tuples of source files and a list of compilation flags to be preprocessed, compiled and assembled if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"srcs")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"li",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("h4",{id:"details-25"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that builds a Python extension from a single .cpp file.\ncxx_python_extension(\n name = 'mymodule',\n base_module = 'foo.bar',\n srcs = [\n 'mymodule.cpp',\n ],\n)\n\n# A library rule which has a single source importing the above extension.\npython_library(\n name = 'utils',\n srcs = [\n 'utils.py',\n ],\n deps = [\n ':mymodule',\n ],\n)\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n## The `utils.py` source, wrapped by the `utils` rule above.\n\n## Import the C/C++ extension build above.\nfrom foo.bar import mymodule\n\n...\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_test"},"cxx","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_hacks: str = _,\n _cxx_toolchain: str = _,\n _inject_test_env: str = _,\n _remote_test_execution_toolchain: str = _,\n additional_coverage_targets: list[str] = _,\n allow_cache_upload: None | bool = _,\n anonymous_link_groups: bool = _,\n args: list[str] = _,\n auto_link_groups: bool = _,\n binary_linker_flags: list[str] = _,\n bolt_flags: list[str] = _,\n bolt_profile: None | str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n constraint_overrides: list[str] = _,\n contacts: list[str] = _,\n coverage_instrumentation_compiler_flags: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n devirt_enabled: bool = _,\n distributed_thinlto_partial_split_dwarf: bool = _,\n enable_distributed_thinlto: bool = _,\n env: dict[str, str] = _,\n executable_name: None | str = _,\n exported_needs_coverage_instrumentation: bool = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n framework: None | str = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_deps: list[str] = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_min_binary_node_count: None | int = _,\n link_group_public_deps_label: None | str = _,\n link_ordering: None | str = _,\n link_style: None | str = _,\n link_whole: bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_objects: bool = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n raw_headers: list[str] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n resources: list[str] | dict[str, str] = _,\n run_test_separately: None | bool = _,\n srcs: list[str | (str, list[str])] = _,\n test_rule_timeout_ms: None | int = _,\n thin_lto: bool = _,\n use_default_test_main: None | bool = _,\n version_universe: None | str = _,\n weak_framework_names: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A cxx","_","test() rule builds a C/C++ binary against a C/C++ testing framework and runs it as part of ",(0,n.mdx)("inlineCode",{parentName:"p"},"test"),"."),(0,n.mdx)("h4",{id:"parameters-41"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"args"),": A list of additional arguments to pass to the test when it's run."),(0,n.mdx)("p",{parentName:"li"},"It is also possible to expand references to other rules within these\narguments, using builtin ",(0,n.mdx)("inlineCode",{parentName:"p"},"string parameter macros"),"\n:"),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(location //path/to:target)"),"\nExpands to the location of the output of the build rule. This\nmeans that you can refer to these without needing to be aware of how\nBuck is storing data on the disk mid-build.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps_query"),": Status: ",(0,n.mdx)("strong",{parentName:"p"},"experimental/unstable"),". The deps query takes a query string that accepts the following query functions, and appends the output of the query to the declared deps:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"attrfilter")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"except")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"intersect")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"filter")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"kind")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"set")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"union"))),(0,n.mdx)("p",{parentName:"li"}," The macro ",(0,n.mdx)("inlineCode",{parentName:"p"},"$declared_deps")," may be used anywhere a target literal pattern is expected\nin order to refer to the explicit deps of this rule as they appear in the rule's definition.\nFor example, if your build rule declares"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n android_library(\n name = 'lib',\n deps = ['//foo:foo'],\n deps_query = '$declared_deps',\n )\n")),(0,n.mdx)("p",{parentName:"li"}," then the macro ",(0,n.mdx)("inlineCode",{parentName:"p"},"$declared_deps")," would be expanded to a\nliteral ",(0,n.mdx)("inlineCode",{parentName:"p"},"set(//foo:foo)"),".\nSome example queries:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\n "filter({name_regex}, $declared_deps)".format(name_regex=\'//.*\')\n "attrfilter(annotation_processors, com.foo.Processor, $declared_deps)"\n "deps(\'//foo:foo\', 1)"\n')),(0,n.mdx)("p",{parentName:"li"}," Note: any targets included in this query must also be present in ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": A map of environment names and values to set when running the test."),(0,n.mdx)("p",{parentName:"li"},"It is also possible to expand references to other rules within the ",(0,n.mdx)("strong",{parentName:"p"},"values")," of\nthese environment variables, using builtin ",(0,n.mdx)("inlineCode",{parentName:"p"},"string parameter macros"),"\n:"),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(location //path/to:target)"),"\nExpands to the location of the output of the build rule. This\nmeans that you can refer to these without needing to be aware of how\nBuck is storing data on the disk mid-build.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"framework"),": Unused.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"p"},"/"),"). The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>")," , where ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. See ",(0,n.mdx)("inlineCode",{parentName:"p"},"header_namespace")," for more information.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"include_directories"),": A list of include directories (with ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),") to be added to the compile command for compiling this target (via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),"). An include directory is relative to the current package.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_execution_preference"),": The execution preference for linking. Options are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},"any : No preference is set, and the link action will be performed based on buck2's executor configuration."),(0,n.mdx)("li",{parentName:"ul"},"full_hybrid : The link action will execute both locally and remotely, regardless of buck2's executor configuration (if\nthe executor is capable of hybrid execution). The use_limited_hybrid setting of the hybrid executor is ignored."),(0,n.mdx)("li",{parentName:"ul"},"local : The link action will execute locally if compatible on current host platform."),(0,n.mdx)("li",{parentName:"ul"},"local_only : The link action will execute locally, and error if the current platform is not compatible."),(0,n.mdx)("li",{parentName:"ul"},"remote : The link action will execute remotely if a compatible remote platform exists, otherwise locally.")),(0,n.mdx)("p",{parentName:"li"},"The default is None, expressing that no preference has been set on the target itself.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_group_deps"),": Additional targets to traverse when building link groups, but which should not be direct dependencies of the main executable.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_group_public_deps_label"),': Surface nodes with this label as "public" nodes in the main executable when linking with with link groups.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags"),": Flags to use when preprocessing any of the above sources (which require preprocessing).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers"),": The set of header files that can be used for inclusion to the source files in the target and all targets that transitively depend on it. Buck doesn't add raw headers to the search path of a compiler/preprocessor automatically. ",(0,n.mdx)("inlineCode",{parentName:"p"},"include_directories")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"public_include_directories")," are the recommended way to add raw headers to the search path (they will be added via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-I"),"). ",(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"preprocessor_flags")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_preprocessor_flags")," can also be used to add such raw headers to the search path if inclusion via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-isystem")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"-iquote")," is needed. ",(0,n.mdx)("inlineCode",{parentName:"p"},"raw_headers")," cannot be used together with ",(0,n.mdx)("inlineCode",{parentName:"p"},"headers")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_headers")," in the same target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"p",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_rule_timeout_ms"),": If set specifies the maximum amount of time (in milliseconds) in which all of the tests in this rule should complete. This overrides the default ",(0,n.mdx)("inlineCode",{parentName:"p"},"rule_timeout")," if any has been specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," ."))),(0,n.mdx)("h4",{id:"details-26"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that builds and runs C/C++ test using gtest.\ncxx_test(\n name = 'echo_test',\n srcs = [\n 'echo_test.cpp',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"cxx_toolchain"},"cxx","_","toolchain"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def cxx_toolchain(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _dep_files_processor: str = _,\n _dumpbin_toolchain_path: None | str = _,\n _mk_comp_db: str = _,\n _mk_hmap: str = _,\n _msvc_hermetic_exec: str = _,\n archive_contents: str = _,\n archiver: str,\n archiver_flags: list[str] = _,\n archiver_supports_argfiles: bool = _,\n archiver_type: str,\n asm_compiler: None | str = _,\n asm_compiler_flags: list[str] = _,\n asm_compiler_type: None | str = _,\n asm_preprocessor: None | str = _,\n asm_preprocessor_flags: list[str] = _,\n asm_preprocessor_type: None | str = _,\n assembler: str,\n assembler_flags: list[str] = _,\n assembler_preprocessor: None | str = _,\n assembler_preprocessor_flags: list[str] = _,\n assembler_preprocessor_type: None | str = _,\n assembler_type: None | str = _,\n binary_extension: None | str = _,\n bolt_enabled: bool = _,\n buck2_compatibility: str = _,\n c_compiler: str,\n c_compiler_allow_cache_upload: None | bool = _,\n c_compiler_flags: list[str] = _,\n c_compiler_type: None | str = _,\n c_preprocessor_flags: list[str] = _,\n cache_links: bool = _,\n clang_remarks: None | str = _,\n clang_trace: None | bool = _,\n compiler_type: None | str = _,\n conflicting_header_basename_exemptions: list[str] = _,\n contacts: list[str] = _,\n cpp_dep_tracking_mode: str = _,\n cuda_compiler: None | str = _,\n cuda_compiler_flags: list[str] = _,\n cuda_compiler_type: None | str = _,\n cuda_dep_tracking_mode: str = _,\n cuda_preprocessor_flags: list[str] = _,\n cvtres_compiler: None | str = _,\n cvtres_compiler_flags: list[str] = _,\n cvtres_compiler_type: None | str = _,\n cvtres_preprocessor_flags: list[str] = _,\n cxx_compiler: str,\n cxx_compiler_allow_cache_upload: None | bool = _,\n cxx_compiler_flags: list[str] = _,\n cxx_compiler_type: None | str = _,\n cxx_preprocessor_flags: list[str] = _,\n debug_path_prefix_map_sanitizer_format: None | str = _,\n default_host_platform: None | str = _,\n detailed_untracked_header_messages: bool = _,\n dist_lto_tools: str = _,\n filepath_length_limited: bool = _,\n gcno_files: bool = _,\n generate_linker_maps: bool = _,\n headers_as_raw_headers_mode: None | str = _,\n headers_whitelist: list[str] = _,\n hip_compiler: None | str = _,\n hip_compiler_flags: list[str] = _,\n hip_compiler_type: None | str = _,\n hip_preprocessor_flags: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_ordering: str = _,\n link_path_normalization_args_enabled: bool = _,\n link_style: str = _,\n link_weight: int = _,\n linker: str,\n linker_flags: list[str] = _,\n linker_type: str,\n llvm_link: None | str = _,\n lto_mode: str = _,\n min_sdk_version: None | str = _,\n nm: str,\n objcopy_for_shared_library_interface: str,\n objcopy_recalculates_layout: bool = _,\n objdump: None | str = _,\n object_file_extension: str = _,\n object_format: str = _,\n pic_behavior: str = _,\n pic_type_for_shared_linking: str = _,\n placeholder_tool: None | str = _,\n platform_name: None | str = _,\n post_linker_flags: list[str] = _,\n private_headers_symlinks_enabled: bool = _,\n public_headers_symlinks_enabled: bool = _,\n ranlib: None | str = _,\n ranlib_flags: list[str] = _,\n rc_compiler: None | str = _,\n rc_compiler_flags: list[str] = _,\n rc_compiler_type: None | str = _,\n rc_preprocessor_flags: list[str] = _,\n requires_archives: bool = _,\n requires_objects: bool = _,\n sanitizer_runtime_enabled: bool = _,\n sanitizer_runtime_files: list[str] = _,\n shared_dep_runtime_ld_flags: list[str] = _,\n shared_library_extension: str = _,\n shared_library_interface_flags: list[str] = _,\n shared_library_interface_mode: str = _,\n shared_library_interface_producer: None | str = _,\n shared_library_interface_type: str,\n shared_library_versioned_extension_format: str = _,\n split_debug_mode: str = _,\n static_dep_runtime_ld_flags: list[str] = _,\n static_library_extension: str = _,\n static_pic_dep_runtime_ld_flags: list[str] = _,\n strip: str,\n strip_all_flags: None | list[str] = _,\n strip_debug_flags: None | list[str] = _,\n strip_non_global_flags: None | list[str] = _,\n supports_distributed_thinlto: bool = _,\n target_sdk_version: None | str = _,\n use_archiver_flags: bool = _,\n use_arg_file: bool = _,\n use_dep_files: None | bool = _,\n use_header_map: bool = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-42"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"c_compiler_allow_cache_upload"),": Whether to allow uploading of object files to cache when the compile action is executed locally and the configuration allows uploads (i.e., there is a cache configured and the client has permission to write to it)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"cxx_compiler_allow_cache_upload"),": Whether to allow uploading of object files to cache when the compile action is executed locally and the configuration allows uploads (i.e., there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"d_binary"},"d","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def d_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n srcs: list[str] | dict[str, str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A d","_","binary() rule builds a native executable from the supplied set of D source files and dependencies."),(0,n.mdx)("h4",{id:"parameters-43"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. Each element should be a string specifying a d","_","library rule defined elsewhere (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"':foo'")," or '//foo:bar')."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": The list of flags to be passed to the linker. Each element should be a string specifying a linker flag (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"'--as-needed'"),")."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of D source files to be compiled by this rule. Each element should be a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"'foo/bar.d'"),").")),(0,n.mdx)("h4",{id:"details-27"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that builds a D native executable from a single .d file\n# and a library dependency.\nd_binary(\n name='greet',\n srcs=[\n 'greet.d',\n ],\n deps=[\n ':greeting',\n ],\n)\n\nd_library(\n name='greeting',\n srcs=[\n 'greeting.d',\n ],\n deps=[\n ':join',\n ],\n)\n\nd_library(\n name='join',\n srcs=[\n 'join.d',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"d_library"},"d","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def d_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n srcs: list[str] | dict[str, str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A d","_","library() rule represents a set of D source files."),(0,n.mdx)("h4",{id:"parameters-44"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. Each element should be a string specifying a d","_","library rule defined elsewhere (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"':foo'")," or '//foo:bar')."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of D source files to be compiled by this rule. Each element should be a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"'foo/bar.d'"),").")),(0,n.mdx)("h4",{id:"details-28"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A simple library with a single source file and a single dependency.\nd_library(\n name='greeting',\n srcs=[\n 'greeting.d',\n ],\n deps=[\n ':join',\n ],\n)\n\nd_library(\n name='join',\n srcs=[\n 'join.d',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"d_test"},"d","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def d_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n srcs: list[str] | dict[str, str] = _,\n test_rule_timeout_ms: None | int = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"d_test()")," rule is used to define a set of D source files that contain tests to run via D's unittest support. The source code of the test must provide a main() function."),(0,n.mdx)("h4",{id:"parameters-45"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. Each element should be a string specifying a d","_","library rule defined elsewhere (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"':foo'")," or '//foo:bar')."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"labels"),": A list of labels to be applied to these tests. These labels are arbitrary text strings and have no meaning within buck itself. They can, however, have meaning for you as a test author (e.g., ",(0,n.mdx)("inlineCode",{parentName:"li"},"smoke")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"fast"),"). A label can be used to filter or include a specific ",(0,n.mdx)("inlineCode",{parentName:"li"},"d_test()")," rule when executing ",(0,n.mdx)("inlineCode",{parentName:"li"},"buck test")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of D source files to be compiled by this rule. Each element should be a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"'foo/bar.d'"),")."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"test_rule_timeout_ms"),": If set specifies the maximum amount of time (in milliseconds) in which all of the tests in this rule should complete. This overrides the default ",(0,n.mdx)("inlineCode",{parentName:"li"},"rule_timeout")," if any has been specified in ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig")," .")),(0,n.mdx)("h4",{id:"details-29"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that builds and runs D test with a single source file.\nd_test(\n name = 'test',\n srcs = [\n 'test.d',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"erlang_app"},"erlang","_","app"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def erlang_app(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _toolchain: str = _,\n app_src: None | str = _,\n applications: list[str] = _,\n buck2_compatibility: str = _,\n build_edoc_chunks: bool = _,\n contacts: list[str] = _,\n env: None | dict[str, str] = _,\n erl_opts: None | list[str] = _,\n extra_includes: list[str] = _,\n extra_properties: None | dict[str, str | list[str]] = _,\n include_src: bool = _,\n included_applications: list[str] = _,\n includes: list[str] = _,\n labels: list[str] = _,\n mod: None | (str, list[str]) = _,\n os_env: None | dict[str, str] = _,\n peek_private_includes: bool = _,\n resources: list[str] = _,\n shell_configs: list[str] = _,\n shell_libs: list[str] = _,\n srcs: list[str] = _,\n use_global_parse_transforms: bool = _,\n version: str = _\n) -> None\n")),(0,n.mdx)("p",null,"This rule is the main rule for Erlang applications. It gets generated by using the ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_application")," macro, that takes as attributes the same attributes as this rule. You should always use the ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_application")," macro instead of using this rule directly."),(0,n.mdx)("h4",{id:"parameters-46"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"app_src"),": The ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_src")," field allows to optionally reference a ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app.src")," template file. This template file will then be used by buck2 to generate the ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app")," output file in the applications ",(0,n.mdx)("inlineCode",{parentName:"p"},"ebin/")," directory. This is useful during the migration from rebar3 to buck2 to avoid duplicated entries, of e.g. the ",(0,n.mdx)("inlineCode",{parentName:"p"},"version"),"."),(0,n.mdx)("p",{parentName:"li"},"Buck2 will use or check all fields present in the template, and fill out the fields with the information provided in the\ntarget, e.g. if the ",(0,n.mdx)("inlineCode",{parentName:"p"},"version")," is specified in both, buck2 will check that they are identical. Otherwise, it uses the\ninformation from the template if the target doesn't specify it, and vice versa."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("strong",{parentName:"p"},"NOTE"),": ",(0,n.mdx)("em",{parentName:"p"},"If you use the ",(0,n.mdx)("inlineCode",{parentName:"em"},"app_src")," field and the references application resource file template specifies ",(0,n.mdx)("inlineCode",{parentName:"em"},"applications"),"\nor ",(0,n.mdx)("inlineCode",{parentName:"em"},"included_applications")," buck2 checks that the target definitions and information in the template are equivalent to\nprevent these definitions from drifting apart during migration."))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"applications"),": Equivalent to the corresponding ",(0,n.mdx)("inlineCode",{parentName:"p"},"applications")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"included_applications")," fields you will find in ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app.src")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app")," files and specify the application dependencies. Contrary to the fields in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app.src")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app")," files, ",(0,n.mdx)("strong",{parentName:"p"},"it is necessary to use target paths to the application")," where a dependency is desired. These fields will be used to construct equally named fields in the generated ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app")," file for the application."),(0,n.mdx)("p",{parentName:"li"},"OTP applications are specified with the target path ",(0,n.mdx)("inlineCode",{parentName:"p"},"prelude//erlang/applications:"),"."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("strong",{parentName:"p"},"NOTE"),": ",(0,n.mdx)("em",{parentName:"p"},"If you use the ",(0,n.mdx)("inlineCode",{parentName:"em"},"app_src")," field and the references application resource file template specifies\n",(0,n.mdx)("inlineCode",{parentName:"em"},"applications")," or ",(0,n.mdx)("inlineCode",{parentName:"em"},"included_applications")," buck2 checks that the target definitions and information in the template are\nequivalent to prevent these definitions from drifting apart during migration."))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"build_edoc_chunks"),": This attribute controls if the output of the builds also create edoc chunks.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": The ",(0,n.mdx)("inlineCode",{parentName:"p"},"env")," field allows to set the application env variables. The key value pairs will materialise in the application's ",(0,n.mdx)("inlineCode",{parentName:"p"},".app")," file and can then be accessed by ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/man/application.html#get_env-2"},(0,n.mdx)("inlineCode",{parentName:"a"},"application:get_env/2")),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"erl_opts"),": Typically compile options are managed by global config files, however, sometimes it is desirable to overwrite the pre-defined compile options. The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erl_opts")," field allows developers to do so for individual applications."),(0,n.mdx)("p",{parentName:"li"},"The main use-case are the applications listed in ",(0,n.mdx)("inlineCode",{parentName:"p"},"third-party/"),". This option should not be used by other applications\nwithout consultation. Please ask in the ",(0,n.mdx)("a",{parentName:"p",href:"https://fb.workplace.com/groups/728545201114362"},"WhatsApp Dev Infra Q&A"),"\nworkplace group for support.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_includes"),": In some cases we might have the situation, where an application ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_a")," depends through the ",(0,n.mdx)("inlineCode",{parentName:"p"},"applications")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"included_applications")," fields on application ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_b")," and a source file in ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_b")," includes a header file from ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_a")," (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},'-include_lib("app_a/include/header.hrl'),"). This technically creates circular dependency from ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_a")," to ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_b")," (e.g. via ",(0,n.mdx)("inlineCode",{parentName:"p"},"applications")," field) and back from ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_b")," to ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_a")," (via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-include_lib"),"). To break the dependency developers can specify targets in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"extra_includes")," field, whose public include files are accessible to the application target during build time."),(0,n.mdx)("p",{parentName:"li"},"Only the includes of the specified application are available and eventual transitive dependencies need to be managed\nmanually."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("strong",{parentName:"p"},"NOTE"),": ",(0,n.mdx)("em",{parentName:"p"},"It is not possible (or even desired) to add OTP applications with this field.")),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("strong",{parentName:"p"},"NOTE"),": ",(0,n.mdx)("em",{parentName:"p"},"This mechanism is added to circumvent unclean dependency relationships and the goal for\ndevelopers should be to reduce usages of this field.")," ",(0,n.mdx)("strong",{parentName:"p"},"DO NOT ADD ANY MORE USAGES!!"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_properties"),": The extra_properties field can be used to specify extra key-value pairs which is are not defined in ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/man/application.html#load-2"},"application_opt()"),". The key-value pair will be stored in the applications ",(0,n.mdx)("inlineCode",{parentName:"p"},".app")," file and can be accessed by ",(0,n.mdx)("inlineCode",{parentName:"p"},"file:consult/1"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"include_src"),": This field controls if the generated application directory contains a src/ directory with the Erlang code or not.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"included_applications"),": Check the documentation for ",(0,n.mdx)("inlineCode",{parentName:"p"},"applications"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"includes"),": The public header files accessible via ",(0,n.mdx)("inlineCode",{parentName:"p"},'-include_lib("appname/include/header.hrl")')," from other erlang files.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"mod"),": The ",(0,n.mdx)("inlineCode",{parentName:"p"},"mod")," field specifies the equivalent field in the generated ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app")," files. The format is similar, with the difference, that the module name, and the individual start arguments need to be given as the string representation of the corresponding Erlang terms.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"os_env"),": This attribute allows to set additional values for the operating system environment for invocations to the Erlang toolchain.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"peek_private_includes"),": This attribute allows you to use the private includes of the application's dependencies. This can be useful for test applications, to create shared abstractions for tests. It's not advisable to use this attribute for prodution code. All private includes transitively must be non-ambiguous.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": The ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources")," field specifies targets whose default output are placed in the applications ",(0,n.mdx)("inlineCode",{parentName:"p"},"priv/")," directory. For regular files this field is typically combined with ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"filegroup"),", or similar targets. However, it is general, and any target can be used, e.g. if you want to place a built escript in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"priv/")," directory, you can use an ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_escript")," target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"shell_configs"),": This attribute allows to set config files for the shell. The dependencies that are typically used here are ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file")," targets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"shell_libs"),": This attribute allows to define additional dependencies for the shell. By default this is set to ",(0,n.mdx)("inlineCode",{parentName:"p"},'["prelude//erlang/shell:buck2_shell_utils"]')," which includes a ",(0,n.mdx)("inlineCode",{parentName:"p"},"user_default")," module that loads and compiles modules with buck2 mechanisms.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": A list of ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.erl"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.hrl"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.xrl"),", or ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.yrl")," source inputs that are typically located in an application's ",(0,n.mdx)("inlineCode",{parentName:"p"},"src/")," folder. Header files (i.e. ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.hrl")," files) specified in this field are considered application private headers, and can only be accessed by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.erl")," files of the application itself. ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.xrl")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.yrl")," files are processed into ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.erl")," files before all ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.erl")," files are compiled into ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.beam")," files.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"use_global_parse_transforms"),": This field indicates if global parse_tranforms should be applied to this application as well. It often makes sense for third-party dependencies to not be subjected to global parse_transforms, similar to OTP applications.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"version"),": The ",(0,n.mdx)("inlineCode",{parentName:"p"},"version")," field specifies the applications version that is materialized as ",(0,n.mdx)("inlineCode",{parentName:"p"},"vsn")," field in the generated ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app")," file. If you use the the ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_src")," field and specify a version in the referenced template in addition to the version field, the versions need to be identical."),(0,n.mdx)("p",{parentName:"li"},"If no version is specified in either the ",(0,n.mdx)("inlineCode",{parentName:"p"},"app_src")," template or the ",(0,n.mdx)("inlineCode",{parentName:"p"},"version")," field, a fallback version string of\n",(0,n.mdx)("inlineCode",{parentName:"p"},'"1.0.0"')," is used."))),(0,n.mdx)("h4",{id:"details-30"},"Details"),(0,n.mdx)("p",null,"Erlang Applications are the basic building block of our buck2 integration and used by many other Erlang\ntargets, e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_escript"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_test"),", or ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_release"),"."),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_application")," targets build OTP applications and as such many attributes that are used have\nequivalent meaning to the fields in the currently (by rebar3) used ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app.src")," files and OTP ",(0,n.mdx)("inlineCode",{parentName:"p"},"*.app"),"\nfiles. Please familiarize yourself with the semantics of these fields by consulting the\n",(0,n.mdx)("a",{parentName:"p",href:"https://erlang.org/doc/man/app.html"},"OTP documentation"),"."),(0,n.mdx)("p",null,"The target enforces uniqueness during builds, and fails to build if duplicated artifacts in the\nglobal namespaces are detected:"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},"duplicated application names in the dependencies"),(0,n.mdx)("li",{parentName:"ul"},"duplicated module names across any of the applications or dependencies modules"),(0,n.mdx)("li",{parentName:"ul"},"ambiguity when resolving header files")),(0,n.mdx)("p",null,"The default output of this rule is the application folder of the target application and all transitive dependencies."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("h4",{id:"minimal-erlang-application"},"Minimal Erlang Application"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'erlang_application(\n name = "minimal",\n)\n')),(0,n.mdx)("h4",{id:"with-priv-directory"},"With ",(0,n.mdx)("inlineCode",{parentName:"h4"},"priv/")," directory"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'erlang_application(\n name = "app_a",\n srcs = [\n "src/app_a.erl",\n ],\n includes = [],\n applications = [\n ":app_b",\n ],\n app_src = "src/app_a.app.src",\n resources = [\n ":readme",\n ],\n)\n\nexport_file(\n name = "readme",\n src = "README.md",\n)\n')),(0,n.mdx)("h4",{id:"using-otp-applications-and-mod-field"},"Using OTP applications and ",(0,n.mdx)("inlineCode",{parentName:"h4"},"mod")," field"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'erlang_application(\n name = "app_b",\n srcs = [\n "src/app_b.erl",\n "src/app_b.hrl",\n ],\n includes = [],\n applications = [\n "kernel",\n "stdlib",\n ":app_c",\n ],\n mod = ("app_b", [\n "some_atom",\n ""some string"",\n "{tagged_tuple, 42}",\n ]),\n)\n')),(0,n.mdx)("h4",{id:"using-yecc-and-leex"},"Using Yecc and Leex"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'erlang_application(\n name = "yecc_leex",\n srcs = [\n "src/leex_stub.xrl",\n "src/yecc_stub.yrl",\n ],\n)\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"erlang_app_includes"},"erlang","_","app","_","includes"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def erlang_app_includes(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _toolchain: str = _,\n application_name: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n includes: list[str] = _,\n labels: list[str] = _,\n os_env: None | dict[str, str] = _\n) -> None\n")),(0,n.mdx)("p",null,"This rule is a supplementary rule for Erlang applications. It gets generated by using the ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_application")," macro, that takes as attributes the same attributes as this rule. You should always use the ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_application")," macro instead of using this rule directly."),(0,n.mdx)("h4",{id:"parameters-47"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"os_env"),": This attribute allows to set additional values for the operating system environment for invocations to the Erlang toolchain.")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"erlang_escript"},"erlang","_","escript"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def erlang_escript(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _toolchain: str = _,\n buck2_compatibility: str = _,\n bundled: bool = _,\n configs: list[str] = _,\n contacts: list[str] = _,\n deps: list[str],\n emu_args: list[str] = _,\n include_priv: bool = _,\n labels: list[str] = _,\n main_module: None | str = _,\n os_env: None | dict[str, str] = _,\n resources: list[str] = _,\n script_name: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_escript")," target builds and runs bundled escripts. Please refer to the ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/man/escript.html"},"OTP documentation")," for more details about escripts."),(0,n.mdx)("h4",{id:"parameters-48"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"bundled"),": Setting bundled to ",(0,n.mdx)("inlineCode",{parentName:"p"},"True")," does generate a folder structure and escript trampoline instead of an archive.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"configs"),": This attribute allows to set config files for the escript. The dependencies that are typically used here are ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file")," targets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": List of Erlang applications that are bundled in the escript. This includes all transitive dependencies as well.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"emu_args"),": This field specifies the emulator flags that the escript uses on execution. It is often desirable to specify the number of threads and schedulers the escript uses. Please refer to the ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/man/erl.html#emu_flags"},"OTP documentation")," for details.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"include_priv"),": Setting this flag, will package the applications ",(0,n.mdx)("inlineCode",{parentName:"p"},"priv")," directory in the escript. Similar to files added through the ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources")," field, the ",(0,n.mdx)("inlineCode",{parentName:"p"},"priv")," folders files can then be accessed by ",(0,n.mdx)("inlineCode",{parentName:"p"},'escript"extract/2'),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"main_module"),": Overrides the default main module. Instead of deferring the main module from the scripts filename, the specified module is used. That module needs to export a ",(0,n.mdx)("inlineCode",{parentName:"p"},"main/1")," function that is called as entry point.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"os_env"),": This attribute allows to set additional values for the operating system environment for invocations to the Erlang toolchain.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": This adds the targets default output to the escript archive. To access these files, you need to use ",(0,n.mdx)("inlineCode",{parentName:"p"},"escript:extract/2"),", which will extract the entire escript in memory. The relevant files can then be accessed through the ",(0,n.mdx)("inlineCode",{parentName:"p"},"archive")," section."),(0,n.mdx)("p",{parentName:"li"},"Please refer to the ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/man/escript.html"},(0,n.mdx)("inlineCode",{parentName:"a"},"escript:extract/2"))," for more details.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"script_name"),": Overrides the filename of the produced escript."))),(0,n.mdx)("h4",{id:"details-31"},"Details"),(0,n.mdx)("p",null,"Escripts by default always try to use the module that has the same name as the escripts basename as entry point, e.g. if\nthe escript is called ",(0,n.mdx)("inlineCode",{parentName:"p"},"script.escript")," then running the escript will try to call ",(0,n.mdx)("inlineCode",{parentName:"p"},"script:main/1"),". Both name and\nmain module can be overwritten though."),(0,n.mdx)("p",null,"The target name doubles as the default escript name. If the ",(0,n.mdx)("inlineCode",{parentName:"p"},"main_module")," attribute is not used, the escript filename will\nbe ",(0,n.mdx)("inlineCode",{parentName:"p"},".escript"),"."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'erlang_escript(\n name = "script",\n main_module = "main_module",\n script_name = "the_script",\n deps = [\n ":escript_app",\n ],\n emu_args = ["+sbtu", "+A1"],\n)\n\nerlang_application(\n name = "escript_app",\n srcs = ["src/main_module.erl"],\n applications = [\n "kernel",\n "stdlib",\n ],\n)\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"erlang_otp_binaries"},"erlang","_","otp","_","binaries"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def erlang_otp_binaries(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n erl: str,\n erlc: str,\n escript: str,\n labels: list[str] = _,\n os_env: None | dict[str, str] = _\n) -> None\n")),(0,n.mdx)("p",null,"This target defines the executables for the Erlang toolchains, and is required to defined a toolchain."),(0,n.mdx)("h4",{id:"parameters-49"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"erl"),": Reference to ",(0,n.mdx)("inlineCode",{parentName:"li"},"erl")," binary"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"erlc"),": Reference to ",(0,n.mdx)("inlineCode",{parentName:"li"},"erlc")," binary"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"escript"),": Reference to ",(0,n.mdx)("inlineCode",{parentName:"li"},"escript")," binary"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"os_env"),": This attribute allows to set additional values for the operating system environment for invocations to the Erlang toolchain.")),(0,n.mdx)("h4",{id:"details-32"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,'erlang_otp_binaries(\nname = "local",\nerl = "local/erl",\nerlc = "local/erlc",\nescript = "local/escript",\n)'),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"erlang_release"},"erlang","_","release"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def erlang_release(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _toolchain: str = _,\n applications: list[str | (str, str)],\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n include_erts: bool = _,\n labels: list[str] = _,\n multi_toolchain: None | list[str] = _,\n os_env: None | dict[str, str] = _,\n overlays: dict[str, list[str]] = _,\n release_name: None | str = _,\n version: str = _\n) -> None\n")),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_release")," target builds OTP releases. Please refer to the ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/design_principles/release_structure.html"},"OTP documentation")," for more details about releases."),(0,n.mdx)("h4",{id:"parameters-50"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"applications"),": This field specifies the list of applications that the release should start in the given order, and optionally the start type. Top-level applications without given start type are started with type ",(0,n.mdx)("a",{parentName:"li",href:"https://www.erlang.org/doc/man/application.html#type-restart_type"},(0,n.mdx)("inlineCode",{parentName:"a"},"permanent")),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"include_erts"),": This field controls whether OTP applications and the Erlang runtime system should be included as part of the release. Please note, that at the moment the erts folder is just ",(0,n.mdx)("inlineCode",{parentName:"li"},"erts/"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"multi_toolchain"),": This field controls whether the release should be built with a single toolchain, or multiple toolchains. In the latter case, all output paths are prefixed with the toolchain name."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"os_env"),": This attribute allows to set additional values for the operating system environment for invocations to the Erlang toolchain."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"overlays"),": Overlays can be used to add files to the release. They are specified as mapping from path (from the release root) to list of targets. The targets files are places ",(0,n.mdx)("strong",{parentName:"li"},"flat")," at the target location with their basename."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"release_name"),": The release name can explicitly be set by this field. This overwrites the default from the target name."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"version"),": The ",(0,n.mdx)("inlineCode",{parentName:"li"},"version")," field specifies the release version. The release version is used in the release resource file, and is part of the path for the folder containing the boot scripts.")),(0,n.mdx)("h4",{id:"details-33"},"Details"),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_release")," target does by default (without overlays) package:"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},"applications that are required to start the release"),(0,n.mdx)("li",{parentName:"ul"},"release resource file ",(0,n.mdx)("inlineCode",{parentName:"li"},".rel")," (see ",(0,n.mdx)("a",{parentName:"li",href:"https://www.erlang.org/doc/man/rel.html"},"rel(4)"),")"),(0,n.mdx)("li",{parentName:"ul"},"boot script ",(0,n.mdx)("inlineCode",{parentName:"li"},"start.script")," (see ",(0,n.mdx)("a",{parentName:"li",href:"https://www.erlang.org/doc/man/script.html"},"rel(4)"),")"),(0,n.mdx)("li",{parentName:"ul"},"binary boot script ",(0,n.mdx)("inlineCode",{parentName:"li"},"start.boot")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"bin/release_variables"))),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"release_variables")," file contains release name, version, and erts version in shell syntax, e.g."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'ERTS_VSN="12.1.2"\nREL_NAME="rel1"\nREL_VSN="1.0.0"\n')),(0,n.mdx)("p",null,"The target name doubles as the default release name. If the ",(0,n.mdx)("inlineCode",{parentName:"p"},"release_name")," attribute is used, the release name will be\nsources from there instead."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'erlang_release(\n name = "world",\n version = "1.0.0",\n applications = [\n "//apps//app_a:app_a",\n "//apps//app_b:app_b",\n ],\n overlays = {\n "releases/1.0.0": [\n ":sys.config.src",\n ],\n "bin": [\n ":start.sh",\n ],\n },\n)\n\nexport_file(\n name = "sys.config.src",\n src = "sys.config",\n)\n\nexport_file(\n name = "start.sh",\n src = "start.sh",\n)\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"erlang_test"},"erlang","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def erlang_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _artifact_annotation_mfa: str = _,\n _cli_lib: str = _,\n _ct_opts: str = _,\n _providers: str = _,\n _test_binary: str = _,\n _test_binary_lib: str = _,\n _toolchain: str = _,\n _trampoline: None | str = _,\n buck2_compatibility: str = _,\n common_app_env: dict[str, str] = _,\n config_files: list[str] = _,\n contacts: list[str] = _,\n deps: list[str] = _,\n env: dict[str, str] = _,\n extra_ct_hooks: list[str] = _,\n extra_erl_flags: list[str] = _,\n labels: list[str] = _,\n os_env: None | dict[str, str] = _,\n preamble: str = _,\n property_tests: list[str] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n resources: list[str] = _,\n shell_configs: list[str] = _,\n shell_libs: list[str] = _,\n suite: str\n) -> None\n")),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_test")," ruls defines a test target for a single test suite. In most cases you want to define multiple suites in one go. The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_tests")," macro allows users to generate ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_test")," targets for multiple test suites. Each suite ",(0,n.mdx)("inlineCode",{parentName:"p"},"_SUITE.erl")," will have a generated hidden ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_test")," target whose name is ",(0,n.mdx)("inlineCode",{parentName:"p"},"_SUITE"),"."),(0,n.mdx)("h4",{id:"parameters-51"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"common_app_env"),": Application environment variables for the ",(0,n.mdx)("inlineCode",{parentName:"p"},"common")," application.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"config_files"),": Will specify what config files the erlang beam machine running test with should load, for reference look at ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/man/config.html"},"OTP documentation"),". These ones should consist of default_output of some targets. In general, this field is filled with target coming from then ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file")," rule, as in the example below.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": The set of dependencies needed for all suites included in the target to compile and run. They could be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_app(lication)")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_test")," targets, although the latter is discouraged. If some suites need to access common methods, a common helper file should be created and included in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," field of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_tests")," target. If some applications are included as dependencies of this target, their private include will automatically be pulled and made available for the test. That allows tests to access the private header files from the applications under test.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": Add the given values to the environment variables with which the test is executed.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_ct_hooks"),": List of additional Common Test hooks. The strings are interpreted as Erlang terms.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_erl_flags"),": List of additional command line arguments given to the erl command invocation. These arguments are added to the front of the argument list.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"os_env"),": This attribute allows to set additional values for the operating system environment for invocations to the Erlang toolchain.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": The ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources")," field specifies targets whose default output are placed in the test ",(0,n.mdx)("inlineCode",{parentName:"p"},"data_dir")," directory for all the suites present in the macro target. Additionally, if data directory are present in the directory along the suite, this one will be pulled automatically for the relevant suite."),(0,n.mdx)("p",{parentName:"li"},"Any target can be used, e.g. if you want to place a built escript in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"data_dir")," directory, you can use\nan ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_escript")," target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"shell_configs"),": This attribute allows to set config files for the shell. The dependencies that are typically used here are ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file")," targets.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"shell_libs"),": This attribute allows to define additional dependencies for the shell. By default this is set to ",(0,n.mdx)("inlineCode",{parentName:"p"},'["prelude//erlang/shell:buck2_shell_utils"]')," which includes a ",(0,n.mdx)("inlineCode",{parentName:"p"},"user_default")," module that loads and compiles modules with buck2 mechanisms.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"suite"),": The source file for the test suite. If you are using the macro, you should use the ",(0,n.mdx)("inlineCode",{parentName:"p"},"suites")," attribute instead."),(0,n.mdx)("p",{parentName:"li"},"The suites attribute specifies which erlang_test targets should be generated. For each suite \"path_to_suite/suite_SUITE.erl\" an\nimplicit 'erlang_test' target suite_SUITE will be generated."))),(0,n.mdx)("h4",{id:"details-34"},"Details"),(0,n.mdx)("p",null,"Each ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_test")," target implements tests using the Common Test library\n",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/man/common_test.html"},"OTP documentation"),". They can,\nalthough ",(0,n.mdx)("strong",{parentName:"p"},"it is not recommended"),', also act as dependencies of other tests. The\ndefault output of this rule is a "test_folder", consisting of the compiled test suite\nand the data directory.'),(0,n.mdx)("p",null,"For each suite ",(0,n.mdx)("inlineCode",{parentName:"p"},"_SUITE.erl"),", if a data_dir ",(0,n.mdx)("inlineCode",{parentName:"p"},"_SUITE_data")," is present along the suite,\n(as per ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/apps/common_test/write_test_chapter.html#data-and-private-directories"},"the data_dir naming scheme for ct"),"),\nit will automatically adds the corresponding resource target to the generated test target of the suite.\nResources will be placed in the ",(0,n.mdx)("a",{parentName:"p",href:"https://www.erlang.org/doc/apps/common_test/write_test_chapter.html#data_priv_dir"},"Data directory (data_dir)"),"\nof each of the suite."),(0,n.mdx)("p",null,"It allows the writer of the rule to add global configuration files and global default\ndependencies (e.g ",(0,n.mdx)("inlineCode",{parentName:"p"},"meck"),"). These ones should be specified using global\nvariables ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang.erlang_tests_default_apps")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang.erlang_tests_default_config"),"\nrespectively."),(0,n.mdx)("p",null,"The ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_tests")," macro forwards all attributes to the ",(0,n.mdx)("inlineCode",{parentName:"p"},"erlang_test"),". It defines some attributes\nthat control how the targets get generated:"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs")," (","[source]",'): Set of files that the suites might depend on and that are not part of any specific application.\nA "meta" application having those files as sources will automatically be created, and included in the dependencies\nof the tests.')),(0,n.mdx)("p",null,"One can call"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"buck2 build //my_app:test_SUITE")," to compile the test files together with its dependencies."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"buck2 test //my_app:other_test_SUITE")," to run the test."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"buck2 run //my_app:other_test_SUITE")," to open an interactive test shell, where tests can be run iteratively.")),(0,n.mdx)("p",null,"buck2 test will rely on tpx to run the suite. To get access to tpx commands, add ",(0,n.mdx)("inlineCode",{parentName:"p"},"--")," after the\ntarget. For example:"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"buck2 test //my_app:other_test_SUITE -- --help")," will print the list of tpx available\ncommand line parameters."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"buck2 test //my_app:other_test_SUITE -- group.mycase")," will only run those test cases\nthat match the pattern ",(0,n.mdx)("inlineCode",{parentName:"li"},"group.mycase"))),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,'erlang_test(\nname = "unit_test_SUITE",\nsuite = "unit_test_SUTIE.erl",\ndeps = ','[":my_other_app"]',",\ncontacts = ",'["author@email.com"]',",\n)"),(0,n.mdx)("p",null,"erlang_tests(\nsuites = ",'["test_SUITE.erl", "other_test_SUITE".erl]',",\ndeps = ",'[":my_app"]',",\ncontacts = ",'["author@email.com"]',",\n)"),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"export_file"},"export","_","file"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def export_file(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n mode: None | str = _,\n out: None | str = _,\n src: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file()")," takes a single file or folder and exposes it so other rules can use it."),(0,n.mdx)("h4",{id:"parameters-52"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"mode"),": How files are referenced internally in buck. If set to 'copy', then a full copy will be made into the new location in buck-out. If set to 'reference', the original file will be used by internal build rules in-place. However, this mode does not work across repositories or if the 'out' property is set. For read-only operations, 'reference' can be more performant."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"out"),": The name which the file will be called if another rule depends on it instead of the name it already has."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"src"),": The path to the file that should be exported.")),(0,n.mdx)("h4",{id:"details-35"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"The best way to see how the ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file()")," rule works is with some examples. The\ncommon case is:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nexport_file(\n name = 'example.html',\n)\n\n# This is equivalent to\n\nexport_file(\n name = 'example.html',\n src = 'example.html',\n out = 'example.html',\n)\n\n")),(0,n.mdx)("p",null," It is sometimes useful to refer to the file not by its path, but by a more logical name:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nexport_file(\n name = 'example',\n src = 'example.html',\n)\n\n# This is equivalent to\n\nexport_file(\n name = 'example',\n src = 'example.html',\n out = 'example.html',\n)\n\n")),(0,n.mdx)("p",null," Finally, there are occasions where you want to export a file more than once but want to copy it to\na different name for each output:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nexport_file(\n name = 'runner',\n src = 'RemoteRunner.html',\n)\n\nexport_file(\n name = 'runner_hta',\n src = 'RemoteRunner.html',\n out = 'RemoteRunner.hta',\n)\n\n")),(0,n.mdx)("p",null," Using the ",(0,n.mdx)("inlineCode",{parentName:"p"},"export_file()")," rule is also simple:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nexport_file(\n name = 'example',\n src = 'example.html',\n)\n\ngenrule(\n name = 'demo',\n out = 'result.html',\n cmd = 'cp $(location :example) $OUT',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"external_test_runner"},"external","_","test","_","runner"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def external_test_runner(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n binary: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-53"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"filegroup"},"filegroup"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def filegroup(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n copy: bool = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n srcs: list[str] | dict[str, str] = _\n) -> None\n")),(0,n.mdx)("p",null,"This rule provides access to a set of files."),(0,n.mdx)("h4",{id:"parameters-54"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of files to include in this rule.")),(0,n.mdx)("h4",{id:"details-36"},"Details"),(0,n.mdx)("p",null,"Files are accessible to ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),"s by using their relative path\nafter a ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(location)")," string parameter macro."),(0,n.mdx)("p",null," Other rules may handle ",(0,n.mdx)("inlineCode",{parentName:"p"},"filegroup()")," rules natively for attributes\nsuch as resources."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"In this example a target exports ",(0,n.mdx)("inlineCode",{parentName:"p"},".xml")," files from all subdirectories\nin ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nfilegroup(\n name = 'example',\n srcs = glob(['resources/**/*.xml']),\n)\n\ngenrule(\n name = 'process_xml',\n out = 'processed.xml',\n cmd = '$(exe //example:tool) -in $(location :example)/resources/file.xml > $OUT',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"gen_aidl"},"gen","_","aidl"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def gen_aidl(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _exec_os_type: str = _,\n _java_toolchain: str = _,\n aidl: str,\n aidl_srcs: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n import_path: str = _,\n import_paths: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"gen_aidl()")," rule is used to generate ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," files from ",(0,n.mdx)("inlineCode",{parentName:"p"},".aidl")," files."),(0,n.mdx)("h4",{id:"parameters-55"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"aidl"),": The path to an ",(0,n.mdx)("inlineCode",{parentName:"li"},".aidl")," file to convert to a ",(0,n.mdx)("inlineCode",{parentName:"li"},".java")," file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"aidl_srcs"),": Path to ",(0,n.mdx)("inlineCode",{parentName:"li"},".aidl")," files the target ",(0,n.mdx)("inlineCode",{parentName:"li"},"aidl")," file imports."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": A list of rules that must be built before this rule."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"import_path"),": The search path for import statements for the aidl command. (This is the ",(0,n.mdx)("inlineCode",{parentName:"li"},"-I")," argument when invoking aidl from the command line. For many apps it will be the base dir where all aidl files are, with project root as its parent, e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"app/src/main/aidl"),".). This is the same as the path to the ",(0,n.mdx)("inlineCode",{parentName:"li"},"aidl")," file relative to what would be returned from ",(0,n.mdx)("inlineCode",{parentName:"li"},"root"),".")),(0,n.mdx)("h4",{id:"details-37"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nandroid_library(\n name = 'lib',\n srcs = glob(['**/*.java']) + [':aidl'],\n manifest = '//res/org/opencv:manifest',\n deps = [\n '//res/org/opencv:res',\n ],\n visibility = [ 'PUBLIC' ],\n)\n\ngen_aidl(\n name = 'aidl',\n aidl = 'engine/OpenCVEngineInterface.aidl',\n import_path = 'java/',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"genrule"},"genrule"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def genrule(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _exec_os_type: str = _,\n _genrule_toolchain: str = _,\n always_print_stderr: bool = _,\n bash: None | str = _,\n buck2_compatibility: str = _,\n cacheable: None | bool = _,\n cmd: None | str = _,\n cmd_exe: None | str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n default_outs: None | list[str] = _,\n enable_sandbox: None | bool = _,\n env: dict[str, str] = _,\n environment_expansion_separator: None | str = _,\n executable: None | bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n metadata_env_var: None | str = _,\n metadata_path: None | str = _,\n need_android_tools: bool = _,\n no_outputs_cleanup: bool = _,\n out: None | str = _,\n outs: None | dict[str, list[str]] = _,\n remote: None | bool = _,\n remote_execution_dependencies: list[dict[str, str]] = _,\n srcs: list[str] | dict[str, str] = _,\n type: None | str = _,\n weight: None | int = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()")," is used to generate files from a shell command. It must produce a single output file or folder."),(0,n.mdx)("h4",{id:"parameters-56"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"bash"),": A platform-specific version of the shell command parameter ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". It runs on Linux and UNIX systems\u2014including OSX\u2014on which ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," is installed. It has a higher priority than ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". The ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," argument is run with ",(0,n.mdx)("inlineCode",{parentName:"p"},"/usr/bin/env bash -c"),". It has access to the same set of macros and variables as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),": The shell command to run to generate the output file. It is the fallback for ",(0,n.mdx)("inlineCode",{parentName:"p"},"bash")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe")," arguments. The following environment variables are populated by Buck and available to the shell command. They are accessed using the syntax:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"${}\n")),(0,n.mdx)("p",{parentName:"li"}," Example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"${SRCS}\n")),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${SRCS}")),(0,n.mdx)("p",{parentName:"li"}," A string expansion of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," argument delimited\nby the ",(0,n.mdx)("inlineCode",{parentName:"p"},"environment_expansion_separator")," argument\nwhere each element of ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," will be translated\ninto a relative path."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${SRCDIR}")),(0,n.mdx)("p",{parentName:"li"}," The relative path to a directory to which sources are copied\nprior to running the command."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${OUT}")),(0,n.mdx)("p",{parentName:"li"}," The output file or directory for the ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),".\nThis variable will have whatever value is specified by\nthe ",(0,n.mdx)("inlineCode",{parentName:"p"},"out")," argument if not using named outputs. If\nusing named outputs, this variable will be the output directory."),(0,n.mdx)("p",{parentName:"li"}," The value should be a valid filepath. The semantics of the shell\ncommand determine whether this filepath is treated as a file or a\ndirectory. If the filepath is a directory, then the shell command\nneeds to create it if not using named outputs. Otherwise, it will\nbe automatically created. All outputs (directories and files) must\nbe readable, writable, and (in the case of directories) executable\nby the current user."),(0,n.mdx)("p",{parentName:"li"}," The file or directory specified by this variable must always\nbe written by this command. If not, the execution of this\nrule will be considered a failure, halting the build process."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"${TMP}")),(0,n.mdx)("p",{parentName:"li"}," A temporary directory which can be used for intermediate\nresults and will not be bundled into the output.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe"),": A platform-specific version of the shell command parameter ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". It runs on Windows and has a higher priority than ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd"),". The ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd_exe")," argument is run with ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd.exe /v:off /c"),". It has access to the same set of macros and variables as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_outs"),": Default output which must be present if the ",(0,n.mdx)("inlineCode",{parentName:"p"},"outs")," arg is present. Otherwise does not apply."),(0,n.mdx)("p",{parentName:"li"},"If a rule with ",(0,n.mdx)("inlineCode",{parentName:"p"},"outs")," is consumed without an output label, the default output is returned. The\ndefault output does not need to be present in any of the named outputs defined in ",(0,n.mdx)("inlineCode",{parentName:"p"},"outs"),"."),(0,n.mdx)("p",{parentName:"li"}," Note that a maximum of one value may be present in this list. For example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'default_outs = [ "output_one", ]\n')),(0,n.mdx)("p",{parentName:"li"},"is valid, whereas"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'default_outs = [ "output_one", "output_two", ]\n')),(0,n.mdx)("p",{parentName:"li"},"is not.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"enable_sandbox"),": Whether this target should be executed in a sandbox or not.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"environment_expansion_separator"),": The delimiter between paths in environment variables, such as SRCS, that can contain multiple paths. It can be useful to specify this parameter if the paths could contain spaces.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"executable"),": Whether the output of the genrule is itself executable. Marking an output as executable makes ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck run")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(exe ...)")," macro expansion work with this target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"out"),": The name of the output file or directory. The complete path to this argument is provided to the shell command through the ",(0,n.mdx)("inlineCode",{parentName:"p"},"OUT")," environment variable. Only one of",(0,n.mdx)("inlineCode",{parentName:"p"},"out")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"outs")," may be present.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"outs"),": Mapping defining ",(0,n.mdx)("inlineCode",{parentName:"p"},"named outputs")," to output paths relative to the rule's output directory. Only one of ",(0,n.mdx)("inlineCode",{parentName:"p"},"out")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"outs")," may be present."),(0,n.mdx)("p",{parentName:"li"},"Example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\ngenrule(\n name = "named_outputs",\n outs = {\n "output1": [\n "out1.txt",\n ],\n "output2": [\n "out2.txt",\n ],\n },\n default_outs = [ "out1.txt" ],\n cmd = "echo something> $OUT/out1.txt && echo another> $OUT/out2.txt",\n)\n\n')),(0,n.mdx)("p",{parentName:"li"}," Note that a maximum of one value may be present in the list in this map. For example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\nouts = {\n "output1": [\n "out1.txt",\n ],\n},\n\n')),(0,n.mdx)("p",{parentName:"li"},"is valid, whereas"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\nouts = {\n "output1": [\n "out1.txt",\n "out2.txt",\n ],\n},\n\n')),(0,n.mdx)("p",{parentName:"li"},"is not.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"remote"),": Opts this genrule in to remote execution. Note that it is only safe to execute a genrule remotely if it is completely hermetic and completely and correctly describes its dependencies. Defaults to false. This parameter is unstable. It is subject to removal, default reversal, and other arbitrary changes in the future.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": Either a list or a map of the source files which Buck makes available to the shell command at the path in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"SRCDIR")," environment variable. If you specify a list, the source files are the names in the list. If you specify a map, the source files are made available as the names in the keys of the map, where the values of the map are the original source file names.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"type"),": Specifies the ",(0,n.mdx)("em",{parentName:"p"},"type"),' of this genrule. This is used for logging and is particularly useful for grouping genrules that share an underlying logical "type".'),(0,n.mdx)("p",{parentName:"li"},"For example, if you have the following ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_genrule")," defined\nin the root directory of your Buck project"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n\ncxx_genrule(\n name = 'cxx_gen',\n type = 'epilog',\n cmd = 'touch finish.txt; cp finish.txt $OUT',\n out = 'finish.txt'\n)\n\n")),(0,n.mdx)("p",{parentName:"li"}," then the following ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck query")," command"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n\nbuck query \"attrfilter( type, 'epilog', '//...' )\"\n\n")),(0,n.mdx)("p",{parentName:"li"}," returns"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n\n//:cxx_gen\n\n"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"weight"),": How many local slots these genrule should take when executing locally."))),(0,n.mdx)("h4",{id:"details-38"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"This genrule() uses a Python script to derive a new\n",(0,n.mdx)("inlineCode",{parentName:"p"},"AndroidManifest.xml")," from an\n",(0,n.mdx)("inlineCode",{parentName:"p"},"AndroidManifest.xml")," in the source tree.\nNote you don't need to prepend execution commands with\n",(0,n.mdx)("inlineCode",{parentName:"p"},"python"),": Buck knows how to execute different\nkinds of binaries using ",(0,n.mdx)("inlineCode",{parentName:"p"},"$(exe)")," command."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ngenrule(\n name = 'generate_manifest',\n srcs = [\n 'AndroidManifest.xml',\n ],\n bash = '$(exe //python/android:basic_to_full) ' '$SRCDIR/AndroidManifest.xml > $OUT',\n cmd_exe = '$(exe //python/android:basic_to_full) ' '%SRCDIR%\\AndroidManifest.xml > %OUT%',\n out = 'AndroidManifest.xml',\n)\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ngenrule(\n name = 'generate_manifest_with_named_outputs',\n srcs = [\n 'AndroidManifest.xml',\n ],\n bash = '$(exe //python/android:basic_to_full) ' '$SRCDIR/AndroidManifest.xml > $OUT/AndroidManifest.xml',\n cmd_exe = '$(exe //python/android:basic_to_full) ' '%SRCDIR%\\AndroidManifest.xml > %OUT%\\AndroidManifest.xml',\n outs = {\n \"manifest\": [ \"AndroidManifest.xml\" ],\n },\n default_outs = [ \"AndroidManifest.xml\" ],\n)\n\n")),(0,n.mdx)("p",null,"For named outputs, build with any of the following:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n buck build //:generate_manifest_with_named_outputs\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n buck build //:generate_manifest_with_named_outputs[manifest]\n\n")),(0,n.mdx)("p",null,"Consume in ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," with:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\nexport_file(\n name = "magic1",\n src = ":generate_manifest_with_named_outputs",\n out = "some_dir_to_copy_to/AndroidManifest.xml",\n)\n\n')),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\nexport_file(\n name = "magic2",\n src = ":generate_manifest_with_named_outputs[manifest]",\n out = "some_dir_to_copy_to/AndroidManifest.xml",\n)\n\n')),(0,n.mdx)("p",null,"Note that ",(0,n.mdx)("inlineCode",{parentName:"p"},"magic1")," consumes ",(0,n.mdx)("inlineCode",{parentName:"p"},"generate_manifest_with_named_outputs"),"'s default\noutput. ",(0,n.mdx)("inlineCode",{parentName:"p"},"magic2")," consumes ",(0,n.mdx)("inlineCode",{parentName:"p"},"generate_manifest_with_named_outputs"),'\'s named\noutput "manifest," which happen to be pointing to the same output as the default output in this\ncase, but they do not have to point to the same output.'),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"git_fetch"},"git","_","fetch"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def git_fetch(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _git_fetch_tool: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n repo: str,\n rev: str\n) -> None\n")),(0,n.mdx)("p",null,"Checkout a commit from a git repository."),(0,n.mdx)("h4",{id:"parameters-57"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"repo"),": Url suitable as a git remote."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"rev"),": 40-digit hex SHA-1 of the git commit.")),(0,n.mdx)("h4",{id:"details-39"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'git_fetch(\n name = "serde.git",\n repo = "https://github.com/serde-rs/serde",\n rev = "fccb9499bccbaca0b7eef91a3a82dfcb31e0b149",\n)\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"go_binary"},"go","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def go_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _asan: bool = _,\n _exec_os_type: str = _,\n _go_stdlib: str = _,\n _go_toolchain: str = _,\n _race: bool = _,\n _tags: list[str] = _,\n asan: bool = _,\n assembler_flags: list[str] = _,\n buck2_compatibility: str = _,\n cgo_enabled: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n embedcfg: None | str = _,\n external_linker_flags: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_mode: None | str = _,\n link_style: None | str = _,\n linker_flags: list[str] = _,\n package_root: None | str = _,\n platform: None | str = _,\n platform_external_linker_flags: list[(str, list[str])] = _,\n race: bool = _,\n resources: list[str] = _,\n srcs: list[str] = _,\n tags: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A go","_","binary() rule builds a native executable from the supplied set of Go source files and dependencies. The files supplied are expected to be in the main package, implicitly."),(0,n.mdx)("h4",{id:"parameters-58"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"asan"),": If true, enable ASAN."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"assembler_flags"),": The set of additional assembler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool asm"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"cgo_enabled"),": Experimental: Analog of CGO_ENABLED environment-variable. None will be converted to True if cxx_toolchain available for current configuration, otherwise False."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool compile"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. Currently, this only supports go","_","library rules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"external_linker_flags"),": Extra external linker flags passed to go link via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-extld")," argument. If argument is non-empty or ",(0,n.mdx)("inlineCode",{parentName:"li"},"cgo_library")," is used, the link mode will switch to ",(0,n.mdx)("inlineCode",{parentName:"li"},"external"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_mode"),": Determines the link mode (equivalent of ",(0,n.mdx)("inlineCode",{parentName:"li"},"-mode"),"). Can be one of the following values: ",(0,n.mdx)("inlineCode",{parentName:"li"},"internal"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"external"),". If no value is provided, the mode is set automatically depending on the other args."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be one of the following values: ",(0,n.mdx)("inlineCode",{parentName:"li"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared"),". This argument is relevant only if the cgo extension is enabled. Otherwise, Buck ignores this argument."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": Extra linker flags passed to go link"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_root"),": Sets Go package direactory (relative to BUCK file). By default (or if None passes) package_root is being detected automatically. Empty string of Go package is on the same level as BUCK file otherwise the subdirectory name. Example for srcs = ",'["foo/bar.go"]',', package_root = "foo"'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"race"),": If true, enable data race detection."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of source files to be compiled by this rule. .go files will be compiled with the Go compiler, .s files will be compiled with the assembler, and everything else is assumed to be files that may be ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include"),"d by the assembler."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tags"),": Build tags to apply to this target and its dependencies.")),(0,n.mdx)("h4",{id:"details-40"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/go/testdata"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ngo_binary(\n name='greet',\n srcs=[\n 'main.go',\n ],\n deps=[\n ':greeting',\n ],\n)\n\ngo_library(\n name='greeting',\n srcs=[\n 'greeting.go',\n ],\n deps=[\n ':join',\n ],\n)\n\ngo_library(\n name='join',\n srcs=[\n 'join.go',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"go_exported_library"},"go","_","exported","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def go_exported_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _asan: bool = _,\n _exec_os_type: str = _,\n _go_stdlib: str = _,\n _go_toolchain: str = _,\n _race: bool = _,\n _tags: list[str] = _,\n asan: bool = _,\n assembler_flags: list[str] = _,\n buck2_compatibility: str = _,\n build_mode: str,\n cgo_enabled: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n embedcfg: None | str = _,\n external_linker_flags: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_mode: None | str = _,\n link_style: None | str = _,\n linker_flags: list[str] = _,\n package_root: None | str = _,\n platform: None | str = _,\n platform_external_linker_flags: list[(str, list[str])] = _,\n race: bool = _,\n resources: list[str] = _,\n srcs: list[str] = _,\n tags: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A go","_","exported","_","library() rule builds a C library from the supplied set of Go source files and dependencies. This is done via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-buildmode"),' flag and "//export" annotations in the code.'),(0,n.mdx)("h4",{id:"parameters-59"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"asan"),": If true, enable ASAN."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"assembler_flags"),": The set of additional assembler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool asm"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"build_mode"),": Determines the build mode (equivalent of ",(0,n.mdx)("inlineCode",{parentName:"li"},"-buildmode"),"). Can be one of the following values: ",(0,n.mdx)("inlineCode",{parentName:"li"},"c_archive"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"c_shared"),". This argument is valid only if at there is at least one ",(0,n.mdx)("inlineCode",{parentName:"li"},"cgo_library declared in deps. In addition you should make sure that "),"-shared",(0,n.mdx)("inlineCode",{parentName:"li"},"flag is added to"),"compiler_flags",(0,n.mdx)("inlineCode",{parentName:"li"},"and go version under"),"go.goroot",(0,n.mdx)("inlineCode",{parentName:"li"},"is compiled with that flag present in:"),"gcflags",(0,n.mdx)("inlineCode",{parentName:"li"},", "),"ldflags",(0,n.mdx)("inlineCode",{parentName:"li"},"and"),"asmflags``"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"cgo_enabled"),": Experimental: Analog of CGO_ENABLED environment-variable. None will be converted to True if cxx_toolchain available for current configuration, otherwise False."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool compile"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. Currently, this only supports go","_","library rules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"external_linker_flags"),": Extra external linker flags passed to go link via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-extld")," argument. If argument is non-empty or ",(0,n.mdx)("inlineCode",{parentName:"li"},"cgo_library")," is used, the link mode will switch to ",(0,n.mdx)("inlineCode",{parentName:"li"},"external"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_mode"),": Determines the link mode (equivalent of ",(0,n.mdx)("inlineCode",{parentName:"li"},"-mode"),"). Can be one of the following values: ",(0,n.mdx)("inlineCode",{parentName:"li"},"internal"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"external"),". If no value is provided, the mode is set automatically depending on the other args."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be one of the following values: ",(0,n.mdx)("inlineCode",{parentName:"li"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared"),". This argument is relevant only if the cgo extension is enabled. Otherwise, Buck ignores this argument."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": Extra linker flags passed to go link"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_root"),": Sets Go package direactory (relative to BUCK file). By default (or if None passes) package_root is being detected automatically. Empty string of Go package is on the same level as BUCK file otherwise the subdirectory name. Example for srcs = ",'["foo/bar.go"]',', package_root = "foo"'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"race"),": If true, enable data race detection."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"resources"),": Static files to be symlinked into the working directory of the test. You can access these in your by opening the files as relative paths, e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},'ioutil.ReadFile("testdata/input")'),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of source files to be compiled by this rule. .go files will be compiled with the Go compiler, .s files will be compiled with the assembler, and everything else is assumed to be files that may be ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include"),"d by the assembler."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tags"),": Build tags to apply to this target and its dependencies.")),(0,n.mdx)("h4",{id:"details-41"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/go/testdata"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\ngo_exported_library(\n name = "shared",\n srcs = ["main.go"],\n build_mode = "c_shared",\n compiler_flags = ["-shared"],\n deps = [":example"],\n)\n\ncgo_library(\n name = "example",\n package_name = "cgo",\n srcs = [\n "export-to-c.go", # file with //export annotations\n ],\n cgo_compiler_flags = [],\n compiler_flags = [],\n headers = [],\n)\n\ncxx_genrule(\n name = "cgo_exported_headers",\n out = "includes",\n cmd = (\n "mkdir -p $OUT && " +\n "cat `dirname $(location :shared)`/includes/*.h > $OUT/_cgo_export.h"\n ),\n)\n\nprebuilt_cxx_library(\n name = "cxx_so_with_header",\n header_dirs = [":cgo_exported_headers"],\n shared_lib = ":shared",\n)\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"go_library"},"go","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def go_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _asan: bool = _,\n _cgo_enabled: None | bool = _,\n _compile_shared: bool = _,\n _coverage_mode: None | str = _,\n _go_stdlib: str = _,\n _go_toolchain: str = _,\n _race: bool = _,\n _tags: list[str] = _,\n assembler_flags: list[str] = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n embedcfg: None | str = _,\n exported_deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n package_name: None | str = _,\n package_root: None | str = _,\n srcs: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A go","_","library() rule builds a native library from the supplied set of Go source files and dependencies."),(0,n.mdx)("h4",{id:"parameters-60"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"assembler_flags"),": The set of additional assembler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool asm"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"li"},"go tool compile"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. Currently, this only supports go","_","library rules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_name"),': Sets the full name of the package being compiled. This defaults to the path from the buck root. (e.g. given a ./.buckconfig, a rule in ./a/b/BUCK defaults to package "a/b")'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_root"),": Sets Go package direactory (relative to BUCK file). By default (or if None passes) package_root is being detected automatically. Empty string of Go package is on the same level as BUCK file otherwise the subdirectory name. Example for srcs = ",'["foo/bar.go"]',', package_root = "foo"'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of source files to be compiled by this rule. .go files will be compiled with the Go compiler, .s files will be compiled with the assembler, and everything else is assumed to be files that may be ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include"),"d by the assembler.")),(0,n.mdx)("h4",{id:"details-42"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/go/testdata"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ngo_library(\n name='greeting',\n srcs=[\n 'greeting.go',\n ],\n deps=[\n ':join',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"go_stdlib"},"go","_","stdlib"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def go_stdlib(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _asan: bool = _,\n _cgo_enabled: None | bool = _,\n _compile_shared: bool = _,\n _exec_os_type: str = _,\n _go_toolchain: str = _,\n _race: bool = _,\n _tags: list[str] = _,\n buck2_compatibility: str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-61"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"go_test"},"go","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def go_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _asan: bool = _,\n _coverage_mode: None | str = _,\n _exec_os_type: str = _,\n _go_stdlib: str = _,\n _go_toolchain: str = _,\n _inject_test_env: str = _,\n _race: bool = _,\n _remote_test_execution_toolchain: str = _,\n _tags: list[str] = _,\n _testmaingen: str = _,\n asan: bool = _,\n assembler_flags: list[str] = _,\n buck2_compatibility: str = _,\n cgo_enabled: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n coverage_mode: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n embedcfg: None | str = _,\n env: dict[str, str] = _,\n external_linker_flags: list[str] = _,\n labels: list[str] = _,\n library: None | str = _,\n licenses: list[str] = _,\n link_mode: None | str = _,\n link_style: None | str = _,\n linker_flags: list[str] = _,\n package_name: None | str = _,\n package_root: None | str = _,\n platform: None | str = _,\n race: bool = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n resources: list[str] = _,\n run_test_separately: bool = _,\n runner: None | str = _,\n specs: None | str = _,\n srcs: list[str] = _,\n tags: list[str] = _,\n test_rule_timeout_ms: None | int = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"go_test()")," rule builds a native binary from the specified Go source and resource files\u2014and a generated main file. It's similar to the ",(0,n.mdx)("inlineCode",{parentName:"p"},"go test")," command."),(0,n.mdx)("h4",{id:"parameters-62"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"asan"),": If true, enable ASAN.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"assembler_flags"),": The set of additional assembler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"p"},"go tool asm"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cgo_enabled"),": Experimental: Analog of CGO_ENABLED environment-variable. None will be converted to True if cxx_toolchain available for current configuration, otherwise False.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compiler_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"p"},"go tool compile"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": The set of dependencies of this rule. Currently, this only supports go","_","library rules.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": A map of environment variables and values to set when running the test.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"external_linker_flags"),": Extra external linker flags passed to go link via ",(0,n.mdx)("inlineCode",{parentName:"p"},"-extld")," argument. If argument is non-empty or ",(0,n.mdx)("inlineCode",{parentName:"p"},"cgo_library")," is used, the link mode will switch to ",(0,n.mdx)("inlineCode",{parentName:"p"},"external"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"labels"),": A list of labels to be applied to these tests. These labels are arbitrary text strings and have no meaning within buck itself. They can, however, have meaning for you as a test author (e.g., ",(0,n.mdx)("inlineCode",{parentName:"p"},"smoke")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"fast"),"). A label can be used to filter or include a specific test rule when executing ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck test"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"library"),": Specify the library that this internal test is testing. This will copy the ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"package_name")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps")," from the target specified so you don't have to duplicate them.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_mode"),": Determines the link mode (equivalent of ",(0,n.mdx)("inlineCode",{parentName:"p"},"-mode"),"). Can be one of the following values: ",(0,n.mdx)("inlineCode",{parentName:"p"},"internal"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"external"),". If no value is provided, the mode is set automatically depending on the other args.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be one of the following values: ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),". This argument is relevant only if the cgo extension is enabled. Otherwise, Buck ignores this argument.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Extra linker flags passed to go link")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"package_name"),': Sets the full name of the test package being compiled. This defaults to the path from the buck root with "',"_",'test" appended. (e.g. given a ./.buckconfig, a rule in ./a/b/BUCK defaults to package "a/b',"_",'test")'),(0,n.mdx)("p",{parentName:"li"},"Note: if you want to test packages internally (i.e. same package name), use the ",(0,n.mdx)("inlineCode",{parentName:"p"},"library"),"\nparameter instead of setting ",(0,n.mdx)("inlineCode",{parentName:"p"},"package_name")," to include the tested source files.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"package_root"),": Sets Go package direactory (relative to BUCK file). By default (or if None passes) package_root is being detected automatically. Empty string of Go package is on the same level as BUCK file otherwise the subdirectory name. Example for srcs = ",'["foo/bar.go"]',', package_root = "foo"')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"race"),": If true, enable data race detection.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of source files to be compiled by this rule. .go files will be compiled with the Go compiler, .s files will be compiled with the assembler, and everything else is assumed to be files that may be ",(0,n.mdx)("inlineCode",{parentName:"p"},"#include"),"d by the assembler.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tags"),": Build tags to apply to this target and its dependencies.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_rule_timeout_ms"),": If set specifies the maximum amount of time (in milliseconds) in which all of the tests in this rule should complete. This overrides the default ",(0,n.mdx)("inlineCode",{parentName:"p"},"rule_timeout")," if any has been specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," ."))),(0,n.mdx)("h4",{id:"details-43"},"Details"),(0,n.mdx)("p",null,"If your test requires static files you should specify these in\nthe ",(0,n.mdx)("strong",{parentName:"p"},"resources")," argument. If you do not specify these\nfiles, they won't be available when your test runs."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/go/testdata"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ngo_library(\n name='greeting',\n srcs=[\n 'greeting.go',\n ],\n deps=[\n ':join',\n ],\n)\n\ngo_test(\n name='greeting-test',\n srcs=[\n 'greeting_ext_test.go',\n ],\n deps=[\n ':greeting'\n ],\n)\n\ngo_test(\n name='greeting-internal-test',\n package_name='greeting',\n srcs=[\n 'greeting.go',\n 'greeting_test.go',\n ],\n deps=[\n ':join',\n ],\n)\n\n# Or\n\ngo_test(\n name='greeting-better-internal-test',\n srcs=['greeting_test.go'],\n library=':greeting',\n)\n\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"go_test_runner"},"go","_","test","_","runner"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def go_test_runner(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n test_runner_generator: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-63"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"groovy_library"},"groovy","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def groovy_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n extra_groovyc_arguments: list[str] = _,\n java_version: None | str = _,\n javac: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n target: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"groovy_library()")," rule is used to define a set of Groovy files that can be compiled together. It can also be used to cross compile a set of Groovy and Java files. The main output of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"groovy_library()")," rule is a single JAR file containing all of the compiled class files and resources."),(0,n.mdx)("h4",{id:"parameters-64"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Rules (usually other ",(0,n.mdx)("inlineCode",{parentName:"p"},"groovy_library")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()")," rules) that are used to generate the classpath required to compile this ",(0,n.mdx)("inlineCode",{parentName:"p"},"groovy_library"),"."),(0,n.mdx)("p",{parentName:"li"},"This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),": Other ",(0,n.mdx)("inlineCode",{parentName:"p"},"groovy_library")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()")," rules that depend on this rule will also include its ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," in their classpaths."),(0,n.mdx)("p",{parentName:"li"},"This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_arguments"),": Only used during cross compilation."),(0,n.mdx)("p",{parentName:"li"},"This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_groovyc_arguments"),": List of additional arguments to pass into the Groovy compiler.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"java_version"),": Only used during cross compilation."),(0,n.mdx)("p",{parentName:"li"},"This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps"),": This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"source"),": Only used during cross compilation."),(0,n.mdx)("p",{parentName:"li"},"This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of files to compile for this rule. Usually these will all end in ",(0,n.mdx)("inlineCode",{parentName:"p"},".groovy"),", but if any of the files end in ",(0,n.mdx)("inlineCode",{parentName:"p"},".java"),", cross compilation using the jdk found in ",(0,n.mdx)("inlineCode",{parentName:"p"},"JAVA_HOME")," will occur.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target"),": Only used during cross compilation."),(0,n.mdx)("p",{parentName:"li"},"This is the same as in ",(0,n.mdx)("inlineCode",{parentName:"p"},"java\\_library()"),"."))),(0,n.mdx)("h4",{id:"details-44"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that compiles a single .groovy file.\ngroovy_library(\n name = 'example',\n srcs = ['MySourceFile.groovy'],\n)\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that compiles all of the .groovy files under the directory in\n# which the rule is defined using glob()\ngroovy_library(\n name = 'groovy-only',\n srcs = glob(['**/*.groovy']),\n)\n\n")),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that cross compiles all of the .groovy and .java files under\n# the directory in which the rule is defined, failing if compiling the\n# java files generates any compiler warnings\ngroovy_library(\n name = 'cross-compilation',\n srcs = glob(['**/*.groovy', '**/*.java']),\n java_version = 8,\n extra_arguments = [\n '-Werror',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"groovy_test"},"groovy","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def groovy_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_library_whitelist: list[str] = _,\n default_cxx_platform: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n env: dict[str, str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n extra_groovyc_arguments: list[str] = _,\n fork_mode: str = _,\n java_version: None | str = _,\n javac: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n run_test_separately: bool = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n std_err_log_level: None | int | str = _,\n std_out_log_level: None | int | str = _,\n target: None | str = _,\n test_case_timeout_ms: None | int = _,\n test_rule_timeout_ms: None | int = _,\n test_type: None | str = _,\n use_cxx_libraries: None | bool = _,\n use_dependency_order_classpath: None | bool = _,\n vm_args: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-65"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"gwt_binary"},"gwt","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def gwt_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _exec_os_type: str = _,\n _java_toolchain: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n draft_compile: bool = _,\n experimental_args: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n local_workers: int = _,\n module_deps: list[str] = _,\n modules: list[str] = _,\n optimize: int = _,\n strict: bool = _,\n style: str = _,\n vm_args: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-66"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"halide_library"},"halide","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def halide_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n compiler_deps: list[str] = _,\n compiler_flags: list[str] = _,\n compiler_invocation_flags: list[str] = _,\n configs: dict[str, dict[str, str]] = _,\n contacts: list[str] = _,\n cxx_runtime_type: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n devirt_enabled: bool = _,\n executable_name: None | str = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n frameworks: list[str] = _,\n function_name: None | str = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_style: None | str = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_objects: bool = _,\n prefix_header: None | str = _,\n preprocessor_flags: list[str] = _,\n raw_headers: list[str] = _,\n srcs: list[str | (str, list[str])] = _,\n supported_platforms_regex: None | str = _,\n thin_lto: bool = _,\n version_universe: None | str = _,\n weak_framework_names: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A halide","_",'library() rule represents a set of Halide sources, along with the "compiler" code needed to compile them into object format (see ',(0,n.mdx)("a",{parentName:"p",href:"http://halide-lang.org"},"the Halide site")," for information about Halide and about static compilation of Halide pipelines). The object code will be generated for the target architecture."),(0,n.mdx)("h4",{id:"parameters-67"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_deps"),": The dependencies of the halide compiler itself. Targets that depend on the halide","_","library rule will not include or link the outputs of these targets."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": Flags to use when compiling any of the above sources (which require compilation)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The dependencies of the generated halide pipeline code. This is useful if, for example, your pipeline calls an external function using Halide::Func::define","_","extern."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation, such as linked into an executable or a shared library."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_compiler_flags"),": Platform specific compiler flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when compiling the target's sources. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_linker_flags"),": Platform-specific linker flags. This argument is specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"li"},"java.util.regex.Pattern")," syntax. The second element in each pair is a list of linker flags. If the regex matches the platform, these flags are added to the linker command line when the output from this rule is used in a link operation."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of halide sources to compile for this rule. The sources will be compiled and linked for the host architecture, and the resulting binary will be run to produce the object code for the Halide pipeline."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"supported_platforms_regex"),": If present, an un-anchored regex (in java.util.regex.Pattern syntax) that matches all platforms that this library supports. It will not be built for other platforms.")),(0,n.mdx)("h4",{id:"details-45"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nhalide_library(\n # Your library name.\n name = 'brighter',\n\n # Your pipeline + compiler sources.\n srcs = ['halide/main.cpp'],\n\n # Any dependencies for your compiler. Note that targets that depend on\n # this rule WILL NOT include or link the output(s) of these targets.\n compiler_deps = [\n # You'll need libHalide to use this rule; in our example, we assume it's\n # located in the 'third-party/halide' directory.\n '//third-party/halide:halide'\n ],\n\n # Any dependencies for your generated shader. Targets that depend on this\n # rule will include and/or link the output(s) of these targets.\n deps = [\n # ...\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"haskell_binary"},"haskell","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def haskell_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _haskell_toolchain: str = _,\n auto_link_groups: bool = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n enable_profiling: bool = _,\n ghci_platform_preload_deps: list[(str, list[str])] = _,\n ghci_preload_deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_group_deps: list[str] = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_public_deps_label: None | str = _,\n link_style: None | str = _,\n linker_flags: list[str] = _,\n main: None | str = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n srcs: list[str] | dict[str, str] = _,\n template_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"haskell_binary()")," rule represents a groups of Haskell sources and deps which build an executable."),(0,n.mdx)("h4",{id:"parameters-68"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": Flags to pass to the Haskell compiler when compiling this rule's sources."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Either ",(0,n.mdx)("inlineCode",{parentName:"li"},"haskell\\_library()"),"or ",(0,n.mdx)("inlineCode",{parentName:"li"},"prebuilt\\_haskell\\_library()"),"rules from which this rules sources import modules or native linkable rules exporting symbols this rules sources call into."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_group_deps"),": Additional targets to traverse when building link groups, but which should not be direct dependencies of the main executable."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_group_public_deps_label"),': Surface nodes with this label as "public" nodes in the main executable when linking with with link groups.'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"li"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"main"),": The main module serving as the entry point into the binary. If not specified, the compiler default is used."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_deps"),": Platform specific dependencies. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of dependencies (same format as ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),") that are exported if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": A list of Haskell sources to be built by this rule. The dictionary option is deprecated.")),(0,n.mdx)("h4",{id:"details-46"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nhaskell_binary(\n name = 'foo',\n srcs = [\n 'Foo.hs',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"haskell_ghci"},"haskell","_","ghci"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def haskell_ghci(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _haskell_toolchain: str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n enable_profiling: bool = _,\n extra_script_templates: list[str] = _,\n ghci_bin_dep: None | str = _,\n ghci_init: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n platform_preload_deps: list[(str, list[str])] = _,\n preload_deps: list[str] = _,\n srcs: list[str] | dict[str, str] = _,\n template_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-69"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"haskell_haddock"},"haskell","_","haddock"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def haskell_haddock(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _haskell_toolchain: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n haddock_flags: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-70"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"haskell_ide"},"haskell","_","ide"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def haskell_ide(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _haskell_toolchain: str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n extra_script_templates: list[str] = _,\n include_projects: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_style: str,\n linker_flags: list[str] = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n srcs: list[str] | dict[str, str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-71"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"haskell_library"},"haskell","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def haskell_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _haskell_toolchain: str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n enable_profiling: bool = _,\n ghci_platform_preload_deps: list[(str, list[str])] = _,\n ghci_preload_deps: list[str] = _,\n haddock_flags: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_whole: bool = _,\n linker_flags: list[str] = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n preferred_linkage: str = _,\n srcs: list[str] | dict[str, str] = _,\n template_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"haskell_library()")," rule is used to identity a group of Haskell sources."),(0,n.mdx)("h4",{id:"parameters-72"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": Flags to pass to the Haskell compiler when compiling this rule's sources."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Either ",(0,n.mdx)("inlineCode",{parentName:"li"},"haskell\\_library()"),"or ",(0,n.mdx)("inlineCode",{parentName:"li"},"prebuilt\\_haskell\\_library()"),"rules from which this rules sources import modules or native linkable rules exporting symbols this rules sources call into."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_deps"),": Platform specific dependencies. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of dependencies (same format as ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),") that are exported if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": A list of Haskell sources to be built by this rule. The dictionary option is deprecated.")),(0,n.mdx)("h4",{id:"details-47"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nhaskell_library(\n name = 'fileutil',\n srcs = [\n 'FileUtil.hs',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"haskell_prebuilt_library"},"haskell","_","prebuilt","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def haskell_prebuilt_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_header_dirs: list[str] = _,\n db: str,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n enable_profiling: bool = _,\n exported_compiler_flags: list[str] = _,\n exported_linker_flags: list[str] = _,\n id: str = _,\n import_dirs: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n pic_profiled_static_libs: list[str] = _,\n pic_static_libs: list[str] = _,\n profiled_static_libs: list[str] = _,\n shared_libs: dict[str, str] = _,\n static_libs: list[str] = _,\n version: str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_haskell_library()")," rule is used to identify Haskell prebuilt libraries and their associated interface files."),(0,n.mdx)("h4",{id:"parameters-73"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Other ",(0,n.mdx)("inlineCode",{parentName:"li"},"prebuilt_haskell_library()")," rules from which this library imports modules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_compiler_flags"),": Compiler flags used by dependent rules when compiling with this library."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_linker_flags"),": Linker flags used by dependent rules when linking with this library."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"shared_libs"),": A map of shared library names to shared library paths to use when building a dynamically linked top-level target."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"static_libs"),": The libraries to use when building a statically linked top-level target.")),(0,n.mdx)("h4",{id:"details-48"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_haskell_library(\n name = 'file',\n static_interfaces = [\n 'interfaces',\n ],\n shared_interfaces = [\n 'interfaces_dyn',\n ],\n static_libs = [\n 'libFileUtil.a',\n ],\n shared_libs = {\n 'libFileUtil.so': 'libFileUtil.so',\n },\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"http_archive"},"http","_","archive"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def http_archive(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n excludes: list[str] = _,\n exec_deps: str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n out: None | str = _,\n sha1: None | str = _,\n sha256: None | str = _,\n strip_prefix: None | str = _,\n sub_targets: list[str] = _,\n type: None | str = _,\n urls: list[str] = _,\n vpnless_urls: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"http_archive()")," rule is used to download and extract archives from the Internet to be used as dependencies for other rules. These rules are downloaded by running ",(0,n.mdx)("inlineCode",{parentName:"p"},"fetch"),", or can be downloaded as part of ",(0,n.mdx)("inlineCode",{parentName:"p"},"build"),"by setting ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")),(0,n.mdx)("h4",{id:"parameters-74"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"excludes"),": An optional list of regex patterns. All file paths in the extracted archive which match any of the given patterns will be omitted.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_deps"),": When using http_archive as an anon target, the rule invoking the anon target needs to mirror this attribute into its own attributes, and forward the provider into the anon target invocation."),(0,n.mdx)("p",{parentName:"li"},"When using http_archive normally not as an anon target, the\ndefault value is always fine.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"out"),": An optional name to call the directory that the downloaded artifact is extracted into. Buck will generate a default name if one is not provided that uses the ",(0,n.mdx)("inlineCode",{parentName:"p"},"name")," of the rule.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"sha256"),": The ",(0,n.mdx)("a",{parentName:"p",href:"//wikipedia.org/wiki/SHA-2"},(0,n.mdx)("inlineCode",{parentName:"a"},"SHA-256"))," hash of the downloaded artifact. Buck verifies this is correct and fails the fetch command if it doesn't match in order to guarantee repeatable builds.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"strip_prefix"),": If set, files under this path will be extracted to the root of the output directory. Siblings or cousins to this prefix will not be extracted at all."),(0,n.mdx)("p",{parentName:"li"},"For example, if a tarball has the layout:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},"foo/bar/bar-0.1.2/data.dat")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},"foo/baz/baz-0.2.3")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},"foo","_","prime/bar-0.1.2"),(0,n.mdx)("p",{parentName:"li"},"Only ",(0,n.mdx)("inlineCode",{parentName:"p"},"data.dat")," will be extracted, and it will be extracted into the output\ndirectory specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},"out"),".")))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"sub_targets"),": A list of filepaths within the archive to be made accessible as sub-targets. For example if we have an http_archive with ",(0,n.mdx)("inlineCode",{parentName:"p"},'name = "archive"')," and ",(0,n.mdx)("inlineCode",{parentName:"p"},'sub_targets = ["src/lib.rs"]'),", then other targets would be able to refer to that file as ",(0,n.mdx)("inlineCode",{parentName:"p"},'":archive[src/lib.rs]"'),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"type"),": Normally, archive type is determined by the file's extension. If ",(0,n.mdx)("inlineCode",{parentName:"p"},"type")," is set, then autodetection is overridden, and the specified type is used instead."),(0,n.mdx)("p",{parentName:"li"},"Supported values are: ",(0,n.mdx)("inlineCode",{parentName:"p"},"zip"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"tar"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"tar.gz"),",\n",(0,n.mdx)("inlineCode",{parentName:"p"},"tar.bz2"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"tar.xz"),", and ",(0,n.mdx)("inlineCode",{parentName:"p"},"tar.zst"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"urls"),': A list of urls to attempt to download from. They are tried in order, and subsequent ones are only tried if the download fails. If validation fails, a new URL is not used. Supported protocols are "http", "https", and "mvn".')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"vpnless_urls"),": Additional URLs from which this resource can be downloaded when off VPN. Meta-internal only."))),(0,n.mdx)("h4",{id:"details-49"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Using ",(0,n.mdx)("inlineCode",{parentName:"p"},"http_archive()"),", third party packages can be downloaded from\nan ",(0,n.mdx)("inlineCode",{parentName:"p"},"https")," URL and used in other library types."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nhttp_archive(\n name = 'thrift-archive',\n urls = [\n 'https://internal-mirror.example.com/bin/thrift-compiler-0.1.tar.gz.badextension',\n ],\n sha256 = '7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',\n type='tar.gz',\n strip_prefix='thrift-compiler-0.1'\n)\n\ngenrule(\n name = 'thrift-compiler-bin',\n out = 'thrift',\n cmd = 'cp $(location :thrift-archive)/bin/thrift $OUT',\n executable = True,\n)\n\ngenrule(\n name=\"my-thrift-lib-cpp2\",\n cmd=\"$(exe :thrift-compiler-bin) --gen cpp2 -o $OUT $(location //:thrift-file)\",\n out=\"gen-cpp2\",\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"http_file"},"http","_","file"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def http_file(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n executable: None | bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n out: None | str = _,\n sha1: None | str = _,\n sha256: None | str = _,\n urls: list[str] = _,\n vpnless_urls: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"http_file()")," rule is used to download files from the Internet to be used as dependencies for other rules. This rule only downloads single files, and can optionally make them executable (see ",(0,n.mdx)("inlineCode",{parentName:"p"},"http\\_file()executable"),") These rules are downloaded by running ",(0,n.mdx)("inlineCode",{parentName:"p"},"fetch"),", or can be downloaded as part of ",(0,n.mdx)("inlineCode",{parentName:"p"},"build"),"by setting ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")),(0,n.mdx)("h4",{id:"parameters-75"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"executable"),": Whether or not the file should be made executable after downloading. If true, this can also be used via ",(0,n.mdx)("inlineCode",{parentName:"li"},"run"),"and the ",(0,n.mdx)("inlineCode",{parentName:"li"},"$(exe )"),"\xa0",(0,n.mdx)("inlineCode",{parentName:"li"},"string parameter macros")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"out"),": An optional name to call the downloaded artifact. Buck will generate a default name if one is not provided that uses the ",(0,n.mdx)("inlineCode",{parentName:"li"},"name")," of the rule."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"sha256"),": The ",(0,n.mdx)("a",{parentName:"li",href:"//wikipedia.org/wiki/SHA-2"},(0,n.mdx)("inlineCode",{parentName:"a"},"SHA-256"))," hash of the downloaded artifact. Buck verifies this is correct and fails the fetch command if it doesn't match in order to guarantee repeatable builds."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"urls"),': A list of urls to attempt to download from. They are tried in order, and subsequent ones are only tried if the download fails. If validation fails, a new URL is not used. Supported protocols are "http", "https", and "mvn".'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"vpnless_urls"),": Additional URLs from which this resource can be downloaded when off VPN. Meta-internal only.")),(0,n.mdx)("h4",{id:"details-50"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Using ",(0,n.mdx)("inlineCode",{parentName:"p"},"http_file()"),", third party packages can be downloaded from\nan ",(0,n.mdx)("inlineCode",{parentName:"p"},"https")," URL and used in java libraries."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nhttp_file(\n name = 'guava-23-bin',\n urls = [\n 'http://search.maven.org/remotecontent?filepath=com/google/guava/guava/23.0/guava-23.0.jar',\n ],\n sha256 = '7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',\n)\nhttp_file(\n name = 'guava-23-sources',\n urls = [\n 'http://search.maven.org/remotecontent?filepath=com/google/guava/guava/23.0/guava-23.0-sources.jar',\n ],\n sha256 = '37fe8ba804fb3898c3c8f0cbac319cc9daa58400e5f0226a380ac94fb2c3ca14',\n)\n\nprebuilt_java_library(\n name = 'guava-23',\n binary_jar = ':guava-23-bin',\n source_jar = ':guava-23-source',\n)\n\n")),(0,n.mdx)("p",null," Tooling can also be fetched with ",(0,n.mdx)("inlineCode",{parentName:"p"},"http_file()")," and used by a ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ngenrule(\n name=\"my-thrift-lib-cpp2\",\n cmd=\"$(exe :thrift-compiler-bin) --gen cpp2 -o $OUT $(location //:thrift-file)\",\n out=\"gen-cpp2\",\n)\n\nhttp_file(\n name = 'thrift-compiler-bin',\n url = 'https://internal-mirror.example.com/bin/thrift-compiler',\n sha256 = 'c24932ccabb66fffb2d7122298f7f1f91e0b1f14e05168e3036333f84bdf58dc',\n executable = True,\n)\n\n")),(0,n.mdx)("p",null," Here's an example of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"http_file()")," using a mvn URI which uses a Maven classifier."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nhttp_file(\n name = 'guava-23-bin',\n urls = [\n 'mvn:com.google.guava:guava:jar:23.0',\n ],\n sha256 = '7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"jar_genrule"},"jar","_","genrule"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def jar_genrule(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _genrule_toolchain: str = _,\n _java_toolchain: str = _,\n always_print_stderr: bool = _,\n bash: None | str = _,\n buck2_compatibility: str = _,\n cacheable: None | bool = _,\n cmd: None | str = _,\n cmd_exe: None | str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n enable_sandbox: None | bool = _,\n environment_expansion_separator: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n metadata_env_var: None | str = _,\n metadata_path: None | str = _,\n need_android_tools: bool = _,\n no_outputs_cleanup: bool = _,\n remote: None | bool = _,\n remote_execution_dependencies: list[dict[str, str]] = _,\n srcs: list[str] | dict[str, str] = _,\n type: None | str = _,\n weight: None | int = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-76"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"java_annotation_processor"},"java","_","annotation","_","processor"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def java_annotation_processor(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n does_not_affect_abi: bool = _,\n isolate_class_loader: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n processor_class: str = _,\n supports_abi_generation_from_source: bool = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-77"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"java_binary"},"java","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def java_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _exec_os_type: str = _,\n _is_building_android_binary: bool = _,\n _java_toolchain: str = _,\n blacklist: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_cxx_platform: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n do_not_create_inner_jar: bool = _,\n generate_wrapper: bool = _,\n java_args_for_run_info: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n main_class: None | str = _,\n manifest_file: None | str = _,\n meta_inf_directory: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_binary()")," rule is used to create a JAR file of the compiled .class files and resources of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()")," rules on which it depends."),(0,n.mdx)("h4",{id:"parameters-78"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"blacklist"),": A list of patterns that identify files to exclude from the final generated JAR file. Example:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\njava_binary(\n name = 'example',\n blacklist = [\n # Excludes com.example.A and com.example.Alligator,\n # as well as their inner classes and any non-class files that happen to match\n # the pattern\n 'com.example.A',\n\n # Excludes all files from org/slf4j/**/*.\n 'org.slf4j',\n ],\n deps = [\n ':example1',\n ':third-party-stuff',\n ],\n)\n\n"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Rules (normally of type ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library"),") that should be compiled and whose ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files and resources should be included in the generated JAR file.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"main_class"),": If provided, this will be the value specified as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"Main-Class")," attribute of the ",(0,n.mdx)("inlineCode",{parentName:"p"},"META-INF/MANIFEST.MF")," file in the generated JAR file. Also, when this rule is used as an executable in a ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"main_class")," will indicate the class whose ",(0,n.mdx)("inlineCode",{parentName:"p"},"main()")," method will be invoked to process the command-line arguments. This is consistent with the expected usage of ",(0,n.mdx)("inlineCode",{parentName:"p"},"java -jar ** **"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"manifest_file"),": If provided, this manifest will be used when generating the JAR file. If combined with ",(0,n.mdx)("inlineCode",{parentName:"p"},"main_class"),", the specified manifest file will be used but the ",(0,n.mdx)("inlineCode",{parentName:"p"},"main_class")," will override the main class in the manifest."))),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"java_library"},"java","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def java_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _dex_min_sdk_version: None | int = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _is_building_android_binary: bool = _,\n _java_toolchain: str = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n jar_postprocessor: None | str = _,\n java_version: None | str = _,\n javac: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n target: None | str = _,\n validation_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()")," rule defines a set of Java files that can be compiled together. The main output of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()")," rule is a single JAR file containing all of the compiled class files, as well as the static files specified in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources")," argument."),(0,n.mdx)("h4",{id:"parameters-79"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Rules (usually other ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library")," rules) that are used to generate the classpath required to compile this ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),": Other rules that depend on this rule will also include its ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," in their classpaths. This is useful when the public API of a rule has return types or checked exceptions that are defined in another rule, which would otherwise require callers to add an extra dependency. It's also useful for exposing e.g. a collection of ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_jar")," rules as a single target for callers to depend on. Targets in ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," are implicitly included in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps")," of this rule, so they don't need to be repeated there.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_provided_deps"),": This is a combination of ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),". Rules listed in this parameter will be added to classpath of rules that depend on this rule, but they will not be included in a binary if binary depends on a such target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_arguments"),": List of additional arguments to pass into the Java compiler. These arguments follow the ones specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"java_version"),": Equivalent to setting both ",(0,n.mdx)("inlineCode",{parentName:"p"},"source")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"target")," to the given value. Setting this and ",(0,n.mdx)("inlineCode",{parentName:"p"},"source")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"target")," (or both!) is an error.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"on_unused_dependencies"),": Action performed when Buck detects that some dependencies are not used during Java compilation."),(0,n.mdx)("p",{parentName:"li"},"Note that this feature is experimental and does not handle runtime dependencies."),(0,n.mdx)("p",{parentName:"li"},"The valid values are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"ignore")," (default): ignore unused dependencies,"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"warn"),": emit a warning to the console,"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"fail"),": fail the compilation.")),(0,n.mdx)("p",{parentName:"li"},"This option overrides the default value from\n.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps"),": These represent dependencies that are known to be provided at run time, but are required in order for the code to compile. Examples of ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," include the JEE servlet APIs. When this rule is included in a , the ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," will not be packaged into the output.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"remove_classes"),": Specifies a list of ",(0,n.mdx)("inlineCode",{parentName:"p"},"Patterns")," that are used to exclude ",(0,n.mdx)("inlineCode",{parentName:"p"},"classes")," from the ",(0,n.mdx)("inlineCode",{parentName:"p"},"JAR"),". The pattern matching is based on the name of the class. This can be used to exclude a member class or delete a local view of a class that will be replaced during a later stage of the build.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"required_for_source_only_abi"),": Indicates that this rule must be present on the classpath during ",(0,n.mdx)("inlineCode",{parentName:"p"},"source-only ABI generation")," of any rule that depends on it. Typically this is done when a rule contains annotations, enums, constants, or interfaces."),(0,n.mdx)("p",{parentName:"li"},"Having rules present on the classpath during source-only ABI generation prevents Buck from\ncompletely flattening the build graph, thus reducing the performance win from source-only\nABI generation. These rules should be kept small (ideally just containing annotations,\nconstants, enums, and interfaces) and with minimal dependencies of their own.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": Static files to include with the compiled ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files. These files can be loaded via ",(0,n.mdx)("a",{parentName:"p",href:"http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource(java.lang.String)"},"Class.getResource()"),"."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("strong",{parentName:"p"},"Note:")," If ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources_root")," isn't set,\nBuck uses the ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nproperty in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," to\ndetermine where resources should be placed within the generated JAR\nfile.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"source"),': Specifies the version of Java (as a string) to interpret source files as. Overrides the value in "source',"_",'level" in the "java" section of ',(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"source_only_abi_deps"),": These are dependencies that must be present during ",(0,n.mdx)("inlineCode",{parentName:"p"},"source-only ABI generation"),". Typically such dependencies are added when some property of the code in this rule prevents source-only ABI generation from being correct without these dependencies being present."),(0,n.mdx)("p",{parentName:"li"},"Having ",(0,n.mdx)("inlineCode",{parentName:"p"},"source_only_abi_deps")," prevents Buck from\ncompletely flattening the build graph, thus reducing the performance win from source-only\nABI generation. They should be avoided when possible. Often only a small code change is needed to avoid them.\nFor more information on such code changes, read about\n",(0,n.mdx)("inlineCode",{parentName:"p"},"source-only ABI generation"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," files to compile for this rule. If any of the files in this list end in ",(0,n.mdx)("inlineCode",{parentName:"p"},".src.zip"),", then the entries in the ZIP file that end in ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," will be included as ordinary inputs to compilation. This is common when using a ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),"to auto-generate some Java source code that needs to be compiled with some hand-written Java code.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target"),': Specifies the version of Java (as a string) for which to generate code. Overrides the value in "target',"_",'level" in the "java" section of ',(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"."))),(0,n.mdx)("h4",{id:"details-51"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that compiles a single .java file.\njava_library(\n name = 'JsonUtil',\n srcs = ['JsonUtil.java'],\n deps = [\n '//third_party/guava:guava',\n '//third_party/jackson:jackson',\n ],\n)\n\n# A rule that compiles all of the .java files under the directory in\n# which the rule is defined using glob(). It also excludes an\n# individual file that may have additional dependencies, so it is\n# compiled by a separate rule.\njava_library(\n name = 'messenger',\n srcs = glob(['**/*.java'], excludes = ['MessengerModule.java']),\n deps = [\n '//src/com/facebook/base:base',\n '//third_party/guava:guava',\n ],\n)\n\njava_library(\n name = 'MessengerModule',\n srcs = ['MessengerModule.java'],\n deps = [\n '//src/com/facebook/base:base',\n '//src/com/google/inject:inject',\n '//third_party/guava:guava',\n '//third_party/jsr-330:jsr-330',\n ],\n)\n\n# A rule that builds a library with both relative and\n# fully-qualified deps.\njava_library(\n name = 'testutil',\n srcs = glob(['tests/**/*.java'], excludes = 'tests/**/*Test.java'),\n deps = [\n ':lib-fb4a',\n '//java/com/facebook/base:base',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"java_plugin"},"java","_","plugin"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def java_plugin(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n does_not_affect_abi: bool = _,\n isolate_class_loader: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n plugin_name: str = _,\n supports_abi_generation_from_source: bool = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-80"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"java_test"},"java","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def java_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _exec_os_type: str = _,\n _inject_test_env: str = _,\n _is_building_android_binary: bool = _,\n _java_test_toolchain: str = _,\n _java_toolchain: str = _,\n _remote_test_execution_toolchain: str = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_library_whitelist: list[str] = _,\n default_cxx_platform: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n env: dict[str, str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n fork_mode: str = _,\n jar_postprocessor: None | str = _,\n java: None | str = _,\n java_agents: list[str] = _,\n java_version: None | str = _,\n javac: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n run_test_separately: bool = _,\n runner: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n specs: None | str = _,\n srcs: list[str] = _,\n std_err_log_level: None | int | str = _,\n std_out_log_level: None | int | str = _,\n target: None | str = _,\n test_case_timeout_ms: None | int = _,\n test_class_names_file: None | str = _,\n test_rule_timeout_ms: None | int = _,\n test_type: None | str = _,\n unbundled_resources_root: None | str = _,\n use_cxx_libraries: None | bool = _,\n use_dependency_order_classpath: None | bool = _,\n vm_args: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_test()")," rule is used to define a set of ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," files that contain tests to run via JUnit."),(0,n.mdx)("h4",{id:"parameters-81"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"cxx_library_whitelist"),": EXPERIMENTAL. List of cxx","_","libraries to build, if use","_","cxx","_","libraries is true. This can be useful if some dependencies are Android-only and won't build on the default platform.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Same as ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()"),". // org.junit.rules.Timeout was not introduced until 4.7. Must include JUnit (version 4.7 or later) as a dependency for JUnit tests. Must include TestNG (version 6.2 or later) and hamcrest as a dependencies for TestNG tests.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": A map of environment names and values to set when running the test.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"fork_mode"),": Controls whether tests will all be run in the same process or a process will be started for each set of tests in a class."),(0,n.mdx)("p",{parentName:"li"},"(This is mainly useful when porting Java tests to Buck from Apache Ant which\nallows JUnit tasks to set a ",(0,n.mdx)("inlineCode",{parentName:"p"},'fork="yes"')," property. It should not be\nused for new tests since it encourages tests to not cleanup after themselves and\nincreases the tests' computational resources and running time.)"),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"none"),"\nAll tests will run in the same process.\n",(0,n.mdx)("inlineCode",{parentName:"p"},"per_test"),"\nA process will be started for each test class in which all tests of that test class\nwill run.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"labels"),": A list of labels to be applied to these tests. These labels are arbitrary text strings and have no meaning within buck itself. They can, however, have meaning for you as a test author (e.g., ",(0,n.mdx)("inlineCode",{parentName:"p"},"smoke")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"fast"),"). A label can be used to filter or include a specific test rule when executing ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck test"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": Same as ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"source"),": Java language level for compiling. Corresponds to the ",(0,n.mdx)("inlineCode",{parentName:"p"},"-source")," argument for ",(0,n.mdx)("inlineCode",{parentName:"p"},"javac"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": Like ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()"),", all of the ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," files specified by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," argument will be compiled when this rule is built. In addition, all of the corresponding ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files that are built by this rule will be passed as arguments to JUnit when this rule is run as a test. ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files that are passed to JUnit that do not have any methods annotated with ",(0,n.mdx)("inlineCode",{parentName:"p"},"@Test")," are considered failed tests, so make sure that only test case classes are specified as ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),". This is frequently done by specifying ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," as ",(0,n.mdx)("inlineCode",{parentName:"p"},"glob(['**/*Test.java'])"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"std_err_log_level"),": Same as ",(0,n.mdx)("inlineCode",{parentName:"p"},"std_out_log_level"),", but for std err.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"std_out_log_level"),": Log level for messages from the source under test that buck will output to std out. Value must be a valid ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.logging.Level")," value.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target"),": Bytecode target level for compiling. Corresponds to the ",(0,n.mdx)("inlineCode",{parentName:"p"},"-target")," argument for ",(0,n.mdx)("inlineCode",{parentName:"p"},"javac"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_rule_timeout_ms"),": If set specifies the maximum amount of time (in milliseconds) in which all of the tests in this rule should complete. This overrides the default ",(0,n.mdx)("inlineCode",{parentName:"p"},"rule_timeout")," if any has been specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," .")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_type"),": Specifies which test framework to use. The currently supported options are 'junit' and 'testng'.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"use_cxx_libraries"),": Whether or not to build and link against ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_library()"),"dependencies when testing.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"vm_args"),": Runtime arguments to the JVM running the tests."))),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"java_test_runner"},"java","_","test","_","runner"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def java_test_runner(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n java_version: None | str = _,\n javac: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n main_class: str = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n target: None | str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-82"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"js_bundle"},"js","_","bundle"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def js_bundle(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _is_release: bool = _,\n _platform: str = _,\n android_package: None | str = _,\n buck2_compatibility: str = _,\n bundle_name: None | str = _,\n bundle_name_for_flavor: list[(str, str)] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n entry: str | list[str],\n extra_json: None | str = _,\n fallback_transform_profile: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n worker: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-83"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"js_bundle_genrule"},"js","_","bundle","_","genrule"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def js_bundle_genrule(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _exec_os_type: str = _,\n _genrule_toolchain: str = _,\n _is_release: bool = _,\n _platform: str = _,\n always_print_stderr: bool = _,\n bash: None | str = _,\n buck2_compatibility: str = _,\n bundle_name: None | str = _,\n bundle_name_for_flavor: list[(str, str)] = _,\n cacheable: None | bool = _,\n cmd: None | str = _,\n cmd_exe: None | str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n enable_sandbox: None | bool = _,\n environment_expansion_separator: None | str = _,\n js_bundle: str,\n labels: list[str] = _,\n licenses: list[str] = _,\n metadata_env_var: None | str = _,\n metadata_path: None | str = _,\n need_android_tools: bool = _,\n no_outputs_cleanup: bool = _,\n remote: None | bool = _,\n remote_execution_dependencies: list[dict[str, str]] = _,\n rewrite_deps_file: bool = _,\n rewrite_misc: bool = _,\n rewrite_sourcemap: bool = _,\n skip_resources: bool = _,\n srcs: list[str] | dict[str, str] = _,\n type: str = _,\n weight: None | int = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-84"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"js_library"},"js","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def js_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _is_release: bool = _,\n _platform: str = _,\n asset_extensions: None | list[str] = _,\n asset_platforms: None | list[str] = _,\n base_path: None | str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n extra_json: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n srcs: list[str | (str, str)] = _,\n worker: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-85"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"julia_binary"},"julia","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def julia_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _julia_toolchain: str = _,\n buck2_compatibility: str = _,\n deps: list[str] = _,\n julia_args: list[str] = _,\n julia_flags: list[str] = _,\n main: str,\n srcs: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-86"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"julia_jll_library"},"julia","_","jll","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def julia_jll_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _julia_toolchain: str = _,\n buck2_compatibility: str = _,\n jll_name: str,\n lib_mapping: list[str] | dict[str, str],\n uuid: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-87"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"julia_library"},"julia","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def julia_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _julia_toolchain: str = _,\n buck2_compatibility: str = _,\n deps: list[str] = _,\n project_toml: str,\n resources: list[str] = _,\n srcs: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-88"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"julia_test"},"julia","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def julia_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _inject_test_env: str = _,\n _julia_toolchain: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n deps: list[str] = _,\n julia_args: list[str] = _,\n julia_flags: list[str] = _,\n main: str,\n srcs: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-89"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"keystore"},"keystore"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def keystore(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n properties: str,\n store: str\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"keystore()")," contains the data for a key pair created by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"keytool")," executable that comes with the JDK. This is a required input for an ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_binary()"),"rule."),(0,n.mdx)("h4",{id:"parameters-90"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"properties"),": The path to the ",(0,n.mdx)("inlineCode",{parentName:"p"},".properties")," file that contains the following values:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\n# The value that you passed as the argument to -alias\n# when you ran keytool.\nkey.alias=my_alias\n\n# The value that you entered in response to\n# the "Enter keystore password:" prompt.\nkey.store.password=store_password\n\n# The value that you entered in response to\n# the "Enter key password for " prompt.\nkey.alias.password=alias_password\n'))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"store"),": The path to the file that contains the key. This is the path that was passed as the ",(0,n.mdx)("inlineCode",{parentName:"p"},"-keystore")," argument when you ran ",(0,n.mdx)("inlineCode",{parentName:"p"},"keytool"),"."))),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"kotlin_library"},"kotlin","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def kotlin_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _dex_min_sdk_version: None | int = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _is_building_android_binary: bool = _,\n _java_toolchain: str = _,\n _kotlin_toolchain: str = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processing_tool: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n extra_kotlinc_arguments: list[str] = _,\n friend_paths: list[str] = _,\n jar_postprocessor: None | str = _,\n java_version: None | str = _,\n javac: None | str = _,\n k2: bool = _,\n kotlin_compiler_plugins: dict[str, dict[str, str]] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n target: None | str = _,\n use_jvm_abi_gen: None | bool = _,\n validation_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_library()")," rule is used to define a set of Kotlin files that can be compiled together. The main output of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_library()")," rule is a single JAR file containing all of the compiled class files, as well as the static files specified in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources")," argument."),(0,n.mdx)("h4",{id:"parameters-91"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"annotation_processing_tool"),': Specifies the tool to use for annotation processing. Possible values: "kapt" or "javac". "kapt" allows running Java annotation processors against Kotlin sources while backporting it for Java sources too. "javac" works only against Java sources, Kotlin sources won\'t have access to generated classes at compile time.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Rules (usually other ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_library")," rules) that are used to generate the classpath required to compile this ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_library"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),": Other rules that depend on this rule will also include its ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," in their classpaths. This is useful when the public API of a rule has return types or checked exceptions that are defined in another rule, which would otherwise require callers to add an extra dependency. It's also useful for exposing e.g. a collection of ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_jar")," rules as a single target for callers to depend on. Targets in ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps")," are implicitly included in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps")," of this rule, so they don't need to be repeated there.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exported_provided_deps"),": This is a combination of ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"exported_deps"),". Rules listed in this parameter will be added to classpath of rules that depend on this rule, but they will not be included in a binary if binary depends on a such target.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"extra_kotlinc_arguments"),": List of additional arguments to pass into the Kotlin compiler.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"friend_paths"),": List of source paths to pass into the Kotlin compiler as friend-paths, that is, modules you can have access to internal methods.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"k2"),": Enables the Kotlin K2 compiler.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_compiler_plugins"),": Use this to specify ",(0,n.mdx)("a",{parentName:"p",href:"https://kotlinlang.org/docs/reference/compiler-plugins.html"},"Kotlin compiler plugins")," to use when compiling this library. This takes a map, with each entry specify one plugin. Entry's key is plugin source path, and value is a map of plugin option key value pair. Unlike ",(0,n.mdx)("inlineCode",{parentName:"p"},"extra_kotlinc_arguments"),", these can be ",(0,n.mdx)("em",{parentName:"p"},"source paths"),", not just strings."),(0,n.mdx)("p",{parentName:"li"},"A special option value is\n",(0,n.mdx)("inlineCode",{parentName:"p"},"__codegen_dir__"),", in which case Buck will provide a default codegen folder's path as\noption value instead.\nE.g."),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\nkotlin_compiler_plugins = {\n "somePluginSourcePath": {\n "plugin:somePluginId:somePluginOptionKey": "somePluginOptionValue",\n "plugin:somePluginId:someDirectoryRelatedOptionKey": "__codegen_dir__",\n },\n},\n\n')),(0,n.mdx)("p",{parentName:"li"},"Each plugin source path will be prefixed with ",(0,n.mdx)("inlineCode",{parentName:"p"},"-Xplugin=")," and passed as extra\narguments to the compiler. Plugin options will be appended after its plugin with ",(0,n.mdx)("inlineCode",{parentName:"p"},"-P"),"."),(0,n.mdx)("p",{parentName:"li"}," A specific example is, if you want to use ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/Kotlin/kotlinx.serialization"},"kotlinx.serialization"),"\nwith ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_library()"),", you need to specify ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlinx-serialization-compiler-plugin.jar")," under ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_compiler_plugins")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlinx-serialization-runtime.jar")," (which you may have to fetch from Maven) in your ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),":"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\nkotlin_library(\n name = "example",\n srcs = glob(["*.kt"]),\n deps = [\n ":kotlinx-serialization-runtime",\n ],\n kotlin_compiler_plugins = {\n # Likely copied from your $KOTLIN_HOME directory.\n "kotlinx-serialization-compiler-plugin.jar": {},\n },\n)\n\nprebuilt_jar(\n name = "kotlinx-serialization-runtime",\n binary_jar = ":kotlinx-serialization-runtime-0.10.0",\n)\n\n# Note you probably want to set\n# maven_repo=http://jcenter.bintray.com/ in your .buckconfig until\n# https://github.com/Kotlin/kotlinx.serialization/issues/64\n# is closed.\nremote_file(\n name = "kotlinx-serialization-runtime-0.10.0",\n out = "kotlinx-serialization-runtime-0.10.0.jar",\n url = "mvn:org.jetbrains.kotlinx:kotlinx-serialization-runtime:jar:0.10.0",\n sha1 = "23d777a5282c1957c7ce35946374fff0adab114c"\n)\n\n'))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"labels"),": Set of arbitrary strings which allow you to annotate a ",(0,n.mdx)("inlineCode",{parentName:"p"},"build rule"),"with tags that can be searched for over an entire dependency tree using ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck query()")," .")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps"),": These represent dependencies that are known to be provided at run time, but are required in order for the code to compile. Examples of ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," include the JEE servlet APIs. When this rule is included in a , the ",(0,n.mdx)("inlineCode",{parentName:"p"},"provided_deps")," will not be packaged into the output.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"remove_classes"),": Specifies a list of ",(0,n.mdx)("inlineCode",{parentName:"p"},"Patterns")," that are used to exclude ",(0,n.mdx)("inlineCode",{parentName:"p"},"classes")," from the ",(0,n.mdx)("inlineCode",{parentName:"p"},"JAR"),". The pattern matching is based on the name of the class. This can be used to exclude a member class or delete a local view of a class that will be replaced during a later stage of the build.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": Static files to include with the compiled ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files. These files can be loaded via ",(0,n.mdx)("a",{parentName:"p",href:"http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource(java.lang.String)"},"Class.getResource()"),"."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("strong",{parentName:"p"},"Note:")," If ",(0,n.mdx)("inlineCode",{parentName:"p"},"resources_root")," isn't set,\nBuck uses the ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"\nproperty in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," to\ndetermine where resources should be placed within the generated JAR\nfile.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of ",(0,n.mdx)("inlineCode",{parentName:"p"},".kt"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},".kts")," files to compile for this rule. If any of the files in this list end in ",(0,n.mdx)("inlineCode",{parentName:"p"},".src.zip"),", then the entries in the ZIP file that end in ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},".kt")," will be included as ordinary inputs to compilation."))),(0,n.mdx)("h4",{id:"details-52"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that compiles a single .kt file.\nkotlin_library(\n name = 'JsonUtil',\n srcs = ['JsonUtil.kt'],\n deps = [\n '//third_party/guava:guava',\n '//third_party/jackson:jackson',\n ],\n)\n\n# A rule that compiles all of the .kt files under the directory in\n# which the rule is defined using glob(). It also excludes an\n# individual file that may have additional dependencies, so it is\n# compiled by a separate rule.\nkotlin_library(\n name = 'messenger',\n srcs = glob(['**/*.kt'], excludes = ['MessengerModule.kt']),\n deps = [\n '//src/com/facebook/base:base',\n '//third_party/guava:guava',\n ],\n)\n\nkotlin_library(\n name = 'MessengerModule',\n srcs = ['MessengerModule.kt'],\n deps = [\n '//src/com/facebook/base:base',\n '//src/com/google/inject:inject',\n '//third_party/guava:guava',\n '//third_party/jsr-330:jsr-330',\n ],\n)\n\n# A rule that builds a library with both relative and\n# fully-qualified deps.\nkotlin_library(\n name = 'testutil',\n srcs = glob(['tests/**/*.kt'], excludes = 'tests/**/*Test.kt'),\n deps = [\n ':lib-fb4a',\n '//java/com/facebook/base:base',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"kotlin_test"},"kotlin","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def kotlin_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _exec_os_type: str = _,\n _inject_test_env: str = _,\n _is_building_android_binary: bool = _,\n _java_test_toolchain: str = _,\n _java_toolchain: str = _,\n _kotlin_toolchain: str = _,\n _remote_test_execution_toolchain: str = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processing_tool: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_library_whitelist: list[str] = _,\n default_cxx_platform: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n env: dict[str, str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n extra_kotlinc_arguments: list[str] = _,\n fork_mode: str = _,\n friend_paths: list[str] = _,\n java: None | str = _,\n java_agents: list[str] = _,\n java_version: None | str = _,\n javac: None | str = _,\n k2: bool = _,\n kotlin_compiler_plugins: dict[str, dict[str, str]] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n run_test_separately: bool = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n std_err_log_level: None | int | str = _,\n std_out_log_level: None | int | str = _,\n target: None | str = _,\n test_case_timeout_ms: None | int = _,\n test_class_names_file: None | str = _,\n test_rule_timeout_ms: None | int = _,\n test_type: None | str = _,\n unbundled_resources_root: None | str = _,\n use_cxx_libraries: None | bool = _,\n use_dependency_order_classpath: None | bool = _,\n use_jvm_abi_gen: None | bool = _,\n vm_args: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_test()")," rule is used to define a set of ",(0,n.mdx)("inlineCode",{parentName:"p"},".kt")," files that contain tests to run via JUnit."),(0,n.mdx)("h4",{id:"parameters-92"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Same as ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin\\_library()"),". // org.junit.rules.Timeout was not introduced until 4.7. Must include JUnit (version 4.7 or later) as a dependency for JUnit tests. Must include TestNG (version 6.2 or later) and hamcrest as a dependencies for TestNG tests.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": A map of environment names and values to set when running the test.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"fork_mode"),": Controls whether tests will all be run in the same process or a process will be started for each set of tests in a class."),(0,n.mdx)("p",{parentName:"li"},"(This is mainly useful when porting Java tests to Buck from Apache Ant which\nallows JUnit tasks to set a ",(0,n.mdx)("inlineCode",{parentName:"p"},'fork="yes"')," property. It should not be\nused for new tests since it encourages tests to not cleanup after themselves and\nincreases the tests' computational resources and running time.)"),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"none"),"\nAll tests will run in the same process.\n",(0,n.mdx)("inlineCode",{parentName:"p"},"per_test"),"\nA process will be started for each test class in which all tests of that test class\nwill run.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"k2"),": Enables the Kotlin K2 compiler.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"labels"),": A list of labels to be applied to these tests. These labels are arbitrary text strings and have no meaning within buck itself. They can, however, have meaning for you as a test author (e.g., ",(0,n.mdx)("inlineCode",{parentName:"p"},"smoke")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"fast"),"). A label can be used to filter or include a specific test rule when executing ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck test"))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": Same as ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": Like ",(0,n.mdx)("inlineCode",{parentName:"p"},"kotlin_library()"),", all of the ",(0,n.mdx)("inlineCode",{parentName:"p"},".kt")," files specified by the ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," argument will be compiled when this rule is built. In addition, all of the corresponding ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files that are built by this rule will be passed as arguments to JUnit when this rule is run as a test. ",(0,n.mdx)("inlineCode",{parentName:"p"},".class")," files that are passed to JUnit that do not have any methods annotated with ",(0,n.mdx)("inlineCode",{parentName:"p"},"@Test")," are considered failed tests, so make sure that only test case classes are specified as ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),". This is frequently done by specifying ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs")," as ",(0,n.mdx)("inlineCode",{parentName:"p"},"glob(['**/*Test.kt'])"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"std_err_log_level"),": Same as ",(0,n.mdx)("inlineCode",{parentName:"p"},"std_out_log_level"),", but for std err.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"std_out_log_level"),": Log level for messages from the source under test that buck will output to std out. Value must be a valid ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.logging.Level")," value.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_rule_timeout_ms"),": If set specifies the maximum amount of time (in milliseconds) in which all of the tests in this rule should complete. This overrides the default ",(0,n.mdx)("inlineCode",{parentName:"p"},"rule_timeout")," if any has been specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," .")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_type"),": Specifies which test framework to use. The currently supported options are 'junit' and 'testng'.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"vm_args"),": Runtime arguments to the JVM running the tests."))),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"legacy_toolchain"},"legacy","_","toolchain"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def legacy_toolchain(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n toolchain_name: str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-93"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"llvm_link_bitcode"},"llvm","_","link","_","bitcode"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def llvm_link_bitcode(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n buck2_compatibility: str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n srcs: list[str | (str, list[str])] = _\n) -> None\n")),(0,n.mdx)("p",null,"A llvm","_","link","_","bitcode() rule builds a LLVM bitcode object from a given set LLVM bitcode inputs."),(0,n.mdx)("h4",{id:"parameters-94"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps_query"),": Status: ",(0,n.mdx)("strong",{parentName:"p"},"experimental/unstable"),". The deps query takes a query string that accepts the following query functions, and appends the output of the query to the declared deps:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"attrfilter")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"except")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"intersect")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"filter")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"kind")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"set")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"union"))),(0,n.mdx)("p",{parentName:"li"}," The macro ",(0,n.mdx)("inlineCode",{parentName:"p"},"$declared_deps")," may be used anywhere a target literal pattern is expected\nin order to refer to the explicit deps of this rule as they appear in the rule's definition.\nFor example, if your build rule declares"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},"\n android_library(\n name = 'lib',\n deps = ['//foo:foo'],\n deps_query = '$declared_deps',\n )\n")),(0,n.mdx)("p",{parentName:"li"}," then the macro ",(0,n.mdx)("inlineCode",{parentName:"p"},"$declared_deps")," would be expanded to a\nliteral ",(0,n.mdx)("inlineCode",{parentName:"p"},"set(//foo:foo)"),".\nSome example queries:"),(0,n.mdx)("pre",{parentName:"li"},(0,n.mdx)("code",{parentName:"pre"},'\n "filter({name_regex}, $declared_deps)".format(name_regex=\'//.*\')\n "attrfilter(annotation_processors, com.foo.Processor, $declared_deps)"\n "deps(\'//foo:foo\', 1)"\n')),(0,n.mdx)("p",{parentName:"li"}," Note: any targets included in this query must also be present in ",(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"p",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable)."))),(0,n.mdx)("h4",{id:"details-53"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that builds and runs C/C++ test using gtest.\nllvm_link_bitcode(\n name = 'echo_test',\n srcs = [\n 'echo_test.o', // Where this is a LLVM bitcode object.\n 'echo_other.o', // And this is another LLVM bitcode object.\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"lua_binary"},"lua","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def lua_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n main_module: str = _,\n native_starter_library: None | str = _,\n package_style: None | str = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n python_platform: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"lua_library()")," rule is used to group together Lua sources to be packaged into a top-level ",(0,n.mdx)("inlineCode",{parentName:"p"},"lua\\_binary()"),"rule."),(0,n.mdx)("h4",{id:"parameters-95"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": ",(0,n.mdx)("inlineCode",{parentName:"li"},"lua\\_library()"),"rules to this binary will access."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"main_module"),": The module which serves as the entry point for this rule.")),(0,n.mdx)("h4",{id:"details-54"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nlua_binary(\n name = 'tailer',\n main_module = 'tailer',\n deps = [\n ':tailerutils',\n ],\n)\n\nlua_library(\n name = 'tailerutils',\n srcs = glob(['*.lua']),\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"lua_library"},"lua","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def lua_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n base_module: None | str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n platform_deps: list[(str, list[str])] = _,\n srcs: list[str] | dict[str, str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"lua_library()")," rule is used to group together Lua sources to be packaged into a top-level ",(0,n.mdx)("inlineCode",{parentName:"p"},"lua\\_binary()"),"rule."),(0,n.mdx)("h4",{id:"parameters-96"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"base_module"),": The package for which the given specified sources and resources should reside in their final location in the top-level binary. If unset, the project relative directory that houses the BUCK file is used."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Other ",(0,n.mdx)("inlineCode",{parentName:"li"},"lua_library()")," rules which list ",(0,n.mdx)("inlineCode",{parentName:"li"},"srcs")," from which this rule imports modules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of ",(0,n.mdx)("inlineCode",{parentName:"li"},".lua")," files included in this library.")),(0,n.mdx)("h4",{id:"details-55"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that includes a single .py file.\nlua_library(\n name = 'fileutil',\n srcs = ['fileutil.lua'],\n)\n\n# A rule that uses glob() to include all sources in the directory which the\n# rule is defined. It also lists a resource file that gets packaged with\n# the sources in this rule.\nlua_library(\n name = 'testutil',\n srcs = glob(['testutil/**/*.lua'],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"matlab_program"},"matlab","_","program"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def matlab_program(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _matlab_toolchain: str = _,\n buck2_compatibility: str = _,\n main: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-97"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"ndk_library"},"ndk","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def ndk_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n flags: list[str] = _,\n is_asset: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n srcs: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"ndk_library()")," is used to define a set of C/C++ files, an ",(0,n.mdx)("inlineCode",{parentName:"p"},"Android.mk")," and an ",(0,n.mdx)("inlineCode",{parentName:"p"},"Application.mk")," file that are used by the NDK's ",(0,n.mdx)("inlineCode",{parentName:"p"},"ndk-build")," tool to generate one or more shared objects."),(0,n.mdx)("h4",{id:"parameters-98"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": List of build targets to build before this rule."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"flags"),": Array of strings passed verbatim to ",(0,n.mdx)("inlineCode",{parentName:"li"},"ndk-build"),". Normally this is not needed, but in some cases you may want to put something here. For example, this can be used to build the libraries in debug mode (",(0,n.mdx)("inlineCode",{parentName:"li"},"NDK_DEBUG=1"),") or set the number of jobs spawned by ",(0,n.mdx)("inlineCode",{parentName:"li"},"ndk-build")," (by default, the same as the number of cores)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"is_asset"),": Normally native shared objects end up in a directory in the root of the APK named ",(0,n.mdx)("inlineCode",{parentName:"li"},"lib/"),". If this parameter is set to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),", then these objects are placed in ",(0,n.mdx)("inlineCode",{parentName:"li"},"assets/lib/"),". Placing shared objects in a non-standard location prevents Android from extracting them to the device's internal storage."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of files to compile for this rule. If not provided, ",(0,n.mdx)("inlineCode",{parentName:"li"},"buck")," assumes that all files with the following extensions are part of the build: ",(0,n.mdx)("inlineCode",{parentName:"li"},"c, cpp, cc, cxx, h, hpp, mk"),".")),(0,n.mdx)("h4",{id:"details-56"},"Details"),(0,n.mdx)("p",null,"Additional notes:"),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"android_binary()")," that includes this library will\naggregate all of the native shared objects into a directory in the\nroot of the APK named ",(0,n.mdx)("inlineCode",{parentName:"p"},"lib/")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"assets/lib/"),"."),(0,n.mdx)("p",null,"Unlike the default invocation of ",(0,n.mdx)("inlineCode",{parentName:"p"},"ndk-build"),",\n",(0,n.mdx)("inlineCode",{parentName:"p"},"buck")," will put all intermediate files and build output\ninto a subdirectory under ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck-out/gen"),"."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"ndk_toolchain"},"ndk","_","toolchain"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def ndk_toolchain(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_runtime: None | str = _,\n cxx_toolchain: str,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n objdump: str,\n shared_runtime_path: None | str = _,\n strip_apk_libs_flags: None | list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-99"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"ocaml_binary"},"ocaml","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def ocaml_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _ocaml_toolchain: str = _,\n buck2_compatibility: str = _,\n bytecode_only: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n ocamldep_flags: list[str] = _,\n platform: None | str = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n srcs: None | list[str] | dict[str, str] = _,\n warnings_flags: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ocaml","_","binary() rule builds both native and bytecode executables from the supplied set of OCaml and C source files and dependencies."),(0,n.mdx)("h4",{id:"parameters-100"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": The set of additional compiler flags to pass to ocaml compiler. It supports specifying ppx (see ",(0,n.mdx)("a",{parentName:"li",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/compiler_flag_macros/BUCK.fixture"},"for example"),")."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. It could include references to ocaml","_","library and cxx","_","library rules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_deps"),": Platform specific dependencies. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of dependencies (same format as ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),") that are exported if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of source files to be compiled by this rule. It supports ","*",".ml, ","*",".mli, ","*",".mly, ","*",".mll, and ","*",".c files. (see ",(0,n.mdx)("a",{parentName:"li",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/ocaml/clib/BUCK.fixture"},"this test")," as C interop example and ",(0,n.mdx)("a",{parentName:"li",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/ocaml/calc/BUCK.fixture"},"this test")," as parser and lexer example).")),(0,n.mdx)("h4",{id:"details-57"},"Details"),(0,n.mdx)("p",null,"Note: Buck is currently tested with 4.X OCaml series."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nocaml_binary(\n name='greet',\n srcs=[\n 'main.ml',\n 'lex.mll',\n 'parser.mly',\n 'hashtable.c',\n ],\n deps=[\n ':greeting',\n ':bridge',\n ],\n)\n\nocaml_library(\n name='greeting',\n srcs=[\n 'greeting.ml',\n ],\n deps=[\n ':join',\n ],\n)\n\nocaml_library(\n name='join',\n srcs=[\n 'join.ml',\n ],\n)\n\ncxx_library(\n name='bridge',\n srcs=[\n 'bridge.c',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"ocaml_library"},"ocaml","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def ocaml_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _ocaml_toolchain: str = _,\n buck2_compatibility: str = _,\n bytecode_only: bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n native_plugin: bool = _,\n ocamldep_flags: list[str] = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n srcs: None | list[str] | dict[str, str] = _,\n warnings_flags: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ocaml","_","library() rule builds a native and a bytecode libraries from the supplied set of OCaml source files and dependencies."),(0,n.mdx)("h4",{id:"parameters-101"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),": The set of additional compiler flags to pass to ocaml compiler. It supports specifying ppx (see ",(0,n.mdx)("a",{parentName:"li",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/compiler_flag_macros/BUCK.fixture"},"for example"),")."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. It could include references to ocaml","_","library and cxx","_","library rules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_deps"),": Platform specific dependencies. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of dependencies (same format as ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),") that are exported if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"deps")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of source files to be compiled by this rule. It supports ","*",".ml, ","*",".mli, ","*",".mly, ","*",".mll, and ","*",".c files. (see ",(0,n.mdx)("a",{parentName:"li",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/ocaml/clib/BUCK.fixture"},"this test")," as C interop example and ",(0,n.mdx)("a",{parentName:"li",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/ocaml/calc/BUCK.fixture"},"this test")," as parser and lexer example).")),(0,n.mdx)("h4",{id:"details-58"},"Details"),(0,n.mdx)("p",null,"Note: Buck is currently tested with 4.X OCaml series."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/ocaml/testdata/"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nocaml_library(\n name='greeting',\n srcs=[\n 'greeting.ml',\n ],\n deps=[\n ':join',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"ocaml_object"},"ocaml","_","object"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def ocaml_object(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _ocaml_toolchain: str = _,\n buck2_compatibility: str = _,\n bytecode_only: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n ocamldep_flags: list[str] = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n srcs: None | list[str] | dict[str, str] = _,\n warnings_flags: None | str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-102"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"ocaml_shared"},"ocaml","_","shared"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def ocaml_shared(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _ocaml_toolchain: str = _,\n buck2_compatibility: str = _,\n bytecode_only: None | bool = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n linker_flags: list[str] = _,\n ocamldep_flags: list[str] = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n srcs: None | list[str] | dict[str, str] = _,\n warnings_flags: None | str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-103"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"platform"},"platform"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def platform(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n constraint_values: list[str] = _,\n deps: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-104"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_apple_framework"},"prebuilt","_","apple","_","framework"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_apple_framework(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _apple_toolchain: str = _,\n buck2_compatibility: str = _,\n code_sign_on_copy: None | bool = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_linker_flags: list[str] = _,\n exported_platform_linker_flags: list[(str, list[str])] = _,\n framework: None | str = _,\n frameworks: list[str] = _,\n labels: list[str] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n preferred_linkage: str = _,\n supported_platforms_regex: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_apple_framework()")," rule represents a set of Objective-C/C++ source files and is very similar to a ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_cxx_library()")," rule."),(0,n.mdx)("h4",{id:"parameters-105"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("h4",{id:"details-59"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_apple_framework(\n name = 'MyPrebuiltFramework',\n framework = 'myPrebuiltFramework.framework',\n preferred_linkage = 'static',\n visibility = [\n 'PUBLIC'\n ]\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_cxx_library"},"prebuilt","_","cxx","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_cxx_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _target_os_type: str = _,\n allow_cache_upload: None | bool = _,\n buck2_compatibility: str = _,\n can_be_asset: bool = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_header_style: str = _,\n exported_headers: list[str] | dict[str, str] = _,\n exported_lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n exported_lang_preprocessor_flags: dict[str, list[str]] = _,\n exported_linker_flags: list[str] = _,\n exported_platform_deps: list[(str, list[str])] = _,\n exported_platform_headers: list[(str, list[str] | dict[str, str])] = _,\n exported_platform_linker_flags: list[(str, list[str])] = _,\n exported_platform_preprocessor_flags: list[(str, list[str])] = _,\n exported_post_linker_flags: list[str] = _,\n exported_post_platform_linker_flags: list[(str, list[str])] = _,\n exported_preprocessor_flags: list[str] = _,\n extract_soname: bool = _,\n force_static: bool = _,\n frameworks: list[str] = _,\n header_dirs: None | list[str] = _,\n header_namespace: None | str = _,\n header_only: bool = _,\n import_lib: None | str = _,\n include_in_android_merge_map_output: bool = _,\n labels: list[str] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_whole: bool = _,\n link_without_soname: bool = _,\n linker_flags: list[str] = _,\n local_linker_flags: list[str] = _,\n platform_header_dirs: None | list[(str, list[str])] = _,\n platform_import_lib: None | list[(str, str)] = _,\n platform_shared_lib: None | list[(str, str)] = _,\n platform_static_lib: None | list[(str, str)] = _,\n platform_static_pic_lib: None | list[(str, str)] = _,\n post_linker_flags: list[str] = _,\n preferred_linkage: str = _,\n provided: bool = _,\n public_include_directories: list[str] = _,\n public_system_include_directories: list[str] = _,\n raw_headers: list[str] = _,\n shared_lib: None | str = _,\n soname: None | str = _,\n static_lib: None | str = _,\n static_pic_lib: None | str = _,\n supported_platforms_regex: None | str = _,\n supports_merged_linking: None | bool = _,\n supports_python_dlopen: bool = _,\n supports_shared_library_interface: bool = _,\n versioned_exported_lang_platform_preprocessor_flags: list[(dict[str, str], dict[str, list[(str, list[str])]])] = _,\n versioned_exported_lang_preprocessor_flags: list[(dict[str, str], dict[str, list[str]])] = _,\n versioned_exported_platform_preprocessor_flags: list[(dict[str, str], list[(str, list[str])])] = _,\n versioned_exported_preprocessor_flags: list[(dict[str, str], list[str])] = _,\n versioned_header_dirs: None | list[(dict[str, str], list[str])] = _,\n versioned_import_lib: None | list[(dict[str, str], str)] = _,\n versioned_shared_lib: None | list[(dict[str, str], str)] = _,\n versioned_soname: None | list[(dict[str, str], str)] = _,\n versioned_static_lib: None | list[(dict[str, str], str)] = _,\n versioned_static_pic_lib: None | list[(dict[str, str], str)] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_cxx_library()")," rule represents a set of native libraries and C/C++ header files and provides various flags to control how they are linked and exported."),(0,n.mdx)("h4",{id:"parameters-106"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_deps"),": Dependencies that will also appear to belong to any rules that depend on this one. This has two effects: ",(0,n.mdx)("em",{parentName:"li"}," Exported dependencies will also be included in the link line of dependents of this rules, but normal dependencies will not. ")," When ",(0,n.mdx)("inlineCode",{parentName:"li"},"reexport_all_header_dependencies = False"),", only exported headers of the rules specified here are re-exported."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_headers"),": The set of header files that are made available for inclusion to the source files in the target and all targets that transitively depend on it. These should be specified as either a list of header files or a dictionary of header names to header files. The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"li"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>"),", where ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. Note that the header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"). See ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_linker_flags"),": Flags to add to the linker command line when the output from this rule, or the output from any rule that transitively depends on this rule, is used in a link operation."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_platform_deps"),": Platform specific dependencies that will also appear to belong to any rules that depend on this one. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of external dependencies (same format as ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_deps"),") that are exported if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_deps")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_platform_headers"),": Platform specific header files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of header files or a dictionary of header names to header files that will be made available for inclusion to the source files in the target and all targets that transitively depend on it if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_platform_preprocessor_flags"),": Platform specific exported preprocessor flags. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of flags to use when preprocessing the source files in the target and all targets that transitively depend on it if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_preprocessor_flags")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace"),": A path prefix when including headers of this target. Defaults to the path from the root of the repository to the directory where this target is defined. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"), but cannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"header_only"),": Indicates if this library only consists of headers or not. If this is set to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),", Buck will not link this library into any library that depends on it."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"local_linker_flags"),": Flags to add to the linker command line whenever the output from this rule is used in a link operation ",(0,n.mdx)("em",{parentName:"li"},"driven by this rule")," (e.g. when this rule links a shared library, but ",(0,n.mdx)("em",{parentName:"li"},"not")," when the output is linked into a shared library by another rule's link group links)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_shared_lib"),": Platform specific shared library. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element the path to the library. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared_lib")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_static_lib"),": Platform specific static library. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element the path to the library. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_lib")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_static_pic_lib"),": Platform specific static PIC library. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element the path to the library. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic_lib")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"shared_lib"),": The path to the library to use when performing shared linking."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"static_lib"),": The path to the library to use when performing static linking."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic_lib"),": The path to the library to use when performing static PIC linking."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"supported_platforms_regex"),": If present, an un-anchored regex (in java.util.regex.Pattern syntax) that matches all platforms that this library supports. It will not be built for other platforms."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"supports_merged_linking"),": Whether this rule supports building with the merged linking strategy when building for non-native binaries (e.g. when using ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig")," s ",(0,n.mdx)("inlineCode",{parentName:"li"},"merged")," setting).")),(0,n.mdx)("h4",{id:"details-60"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"A prebuilt library containing only headers that other libraries may need."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_cxx_library(\n name = 'stdutil',\n header_only = True,\n header_dirs = [\n 'include',\n ],\n)\n\n")),(0,n.mdx)("p",null," A prebuilt library with static and shared libs."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_cxx_library(\n name = 'mylib',\n soname = 'libmylib.so',\n static_lib = 'libmylib.a',\n static_pic_lib = 'libmylib_pic.a',\n shared_lib = 'libmylib.so',\n exported_headers = [\n 'mylib.h',\n ],\n)\n\n")),(0,n.mdx)("p",null," A prebuilt library with multiple builds for multiple platforms."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_cxx_library(\n name = 'mylib',\n soname = 'libmylib.so',\n platform_shared_lib = [\n ('android-arm', 'android-arm/libmylib.so'),\n ('android-x86', 'android-x86/libmylib.so'),\n ('iphonesimulator-x86_64', 'iphonesimulator-x86_64/libmylib.so'),\n ],\n platform_static_lib = [\n ('android-arm', 'android-arm/libmylib.a'),\n ('android-x86', 'android-x86/libmylib.a'),\n ('iphonesimulator-x86_64', 'iphonesimulator-x86_64/libmylib.a'),\n ],\n exported_headers = [\n 'mylib.h',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_cxx_library_group"},"prebuilt","_","cxx","_","library","_","group"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_cxx_library_group(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_platform_deps: list[(str, list[str])] = _,\n exported_preprocessor_flags: list[str] = _,\n import_libs: dict[str, str] = _,\n include_dirs: list[str] = _,\n include_in_android_merge_map_output: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n provided_shared_libs: dict[str, str] = _,\n shared_libs: dict[str, str] = _,\n shared_link: list[str] = _,\n static_libs: list[str] = _,\n static_link: list[str] = _,\n static_pic_libs: list[str] = _,\n static_pic_link: list[str] = _,\n supported_platforms_regex: None | str = _,\n supports_shared_library_interface: bool = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_cxx_library_group()")," rule represents a group of native libraries which should be handled together in a single rule, perhaps using special link-line construction."),(0,n.mdx)("h4",{id:"parameters-107"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_deps"),": Dependencies that will also appear to belong to any rules that depend on this one. This has two effects: ",(0,n.mdx)("em",{parentName:"li"}," Exported dependencies will also be included in the link line of dependents of this rules, but normal dependencies will not. ")," When ",(0,n.mdx)("inlineCode",{parentName:"li"},"reexport_all_header_dependencies = False"),", only exported headers of the rules specified here are re-exported."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exported_platform_deps"),": Platform specific dependencies that will also appear to belong to any rules that depend on this one. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is a list of external dependencies (same format as ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_deps"),") that are exported if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_deps")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"provided_shared_libs"),": The map of system-provided shared library names to paths used when using the shared link style. The ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared_link")," parameter should refer to these libs using their library name."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"shared_libs"),": The map of shared library names to paths used when using the shared link style. The ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared_link")," parameter should refer to these libs using their library name."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"shared_link"),": The arguments to use when linking this library group using the shared link style. The actual paths to libraries should be listed in the ",(0,n.mdx)("inlineCode",{parentName:"li"},"shared_libs")," parameter, and referenced via the the ",(0,n.mdx)("inlineCode",{parentName:"li"},"$(lib [name])")," macro (or the ",(0,n.mdx)("inlineCode",{parentName:"li"},"$(rel-lib [name])")," macro, when the shared library should be linked using the ",(0,n.mdx)("inlineCode",{parentName:"li"},"-L[dir] -l[name]")," style) in these args."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"static_libs"),": The paths to the libraries used when using the static link style. The ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_link")," parameter should refer to these libs using their index number."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"static_link"),": The arguments to use when linking this library group using the static link style. The actual paths to libraries should be listed in the ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_libs")," parameter, and referenced via the the ",(0,n.mdx)("inlineCode",{parentName:"li"},"$(lib [index])")," macro in these args."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic_libs"),": The paths to the libraries used when using the static link style. The ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic_link")," parameter should refer to these libs using their index number."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic_link"),": The arguments to use when linking this library group using the static-pic link style. The actual paths to libraries should be listed in the ",(0,n.mdx)("inlineCode",{parentName:"li"},"static_pic_libs")," parameter, and referenced via the the ",(0,n.mdx)("inlineCode",{parentName:"li"},"$(lib [index])")," macro in these args.")),(0,n.mdx)("h4",{id:"details-61"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"A prebuilt library group wrapping two libraries that must be linked together."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_cxx_library_group(\n name = 'util',\n static_link = [\n '-Wl,--start-group',\n '$(lib 0)',\n '$(lib 1)',\n '-Wl,--end-group',\n ],\n static_libs = [\n 'lib/liba.a',\n 'lib/libb.a',\n ],\n static_pic_link = [\n '-Wl,--start-group',\n '$(lib 0)',\n '$(lib 1)',\n '-Wl,--end-group',\n ],\n static_libs = [\n 'lib/liba_pic.a',\n 'lib/libb_pic.a',\n ],\n shared_link = [\n '$(rel-lib liba.so)',\n '$(rel-lib libb.so)',\n ],\n shared_libs = {\n 'liba.so': 'lib/liba.so',\n },\n provided_shared_libs = {\n 'libb.so': 'lib/libb.so',\n },\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_dotnet_library"},"prebuilt","_","dotnet","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_dotnet_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n assembly: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_dotnet_library()")," rule is used to include prebuilt .Net assembles into your .Net code."),(0,n.mdx)("h4",{id:"parameters-108"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"assembly"),": The path to the DLL that this rule provides.")),(0,n.mdx)("h4",{id:"details-62"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_dotnet_library(\n name = 'log4net',\n assembly = 'log4net.dll',\n)\n\ncsharp_library(\n name = 'example',\n srcs = [\n 'Hello.cs',\n ],\n framework_ver = 'net46',\n deps = [\n ':log4net',\n 'System.dll',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_go_library"},"prebuilt","_","go","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_go_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n labels: list[str] = _,\n library: str,\n licenses: list[str] = _,\n package_name: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A prebuilt","_","go","_","library() rule provides a native library from the specified file."),(0,n.mdx)("h4",{id:"parameters-109"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": The set of dependencies of this rule. Currently, this only supports go","_","library rules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"library"),": Path to the precompiled Go library - typically of the form 'foo.a'."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_name"),': Sets the full name of the package being compiled. This defaults to the path from the buck root. (e.g. given a ./.buckconfig, a rule in ./a/b/BUCK defaults to package "a/b")')),(0,n.mdx)("h4",{id:"details-63"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/features/go/testdata"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_go_library(\n name='greeting',\n package_name='greeting',\n library='greeting.a',\n deps=[\n ':join',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_jar"},"prebuilt","_","jar"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_jar(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _dex_min_sdk_version: None | int = _,\n _dex_toolchain: str = _,\n _exec_os_type: str = _,\n _prebuilt_jar_toolchain: str = _,\n binary_jar: str,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n desugar_deps: list[str] = _,\n generate_abi: bool = _,\n javadoc_url: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: bool = _,\n required_for_source_only_abi: bool = _,\n source_jar: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_jar()")," rule is used to identify a JAR file that is checked into our repository as a precompiled binary rather than one that is built from source by Buck. Frequently, these are used to reference third-party JAR files (such as junit.jar) and are used as dependencies of ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_library()")," rules."),(0,n.mdx)("h4",{id:"parameters-110"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"binary_jar"),": Path to the pre-built JAR file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Rules that must be built before this rule. Because the ",(0,n.mdx)("inlineCode",{parentName:"li"},"binary_jar")," is already built, there should be nothing to build, so this should be empty."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"javadoc_url"),": URL to the Javadoc for the ",(0,n.mdx)("inlineCode",{parentName:"li"},".class")," files in the ",(0,n.mdx)("inlineCode",{parentName:"li"},"binary_jar"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"source_jar"),": Path to a JAR file that contains the ",(0,n.mdx)("inlineCode",{parentName:"li"},".java")," files to create the ",(0,n.mdx)("inlineCode",{parentName:"li"},".class")," in the ",(0,n.mdx)("inlineCode",{parentName:"li"},"binary_jar"),". This is frequently provided for debugging purposes.")),(0,n.mdx)("h4",{id:"details-64"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_jar(\n name = 'junit',\n binary_jar = 'junit-4.8.2.jar',\n source_jar = 'junit-4.8.2-sources.jar',\n javadoc_url = 'http://kentbeck.github.com/junit/javadoc/4.8/',\n)\n\njava_library(\n name = 'tests',\n srcs = glob(['tests/**/*Test.java']),\n deps = [\n ':junit',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_native_library"},"prebuilt","_","native","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_native_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n has_wrap_script: bool = _,\n is_asset: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n native_libs: str\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_native_library()")," rule is used to bundle native libraries (i.e., ",(0,n.mdx)("inlineCode",{parentName:"p"},".so")," files) for Android."),(0,n.mdx)("h4",{id:"parameters-111"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"has_wrap_script"),": When using an exopackage, if this parameter is set to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),", then the libraries for this rule are included in the primary APK even if native libraries would otherwise not be placed in it. This is intended for a native library directory that contains a ",(0,n.mdx)("a",{parentName:"li",href:"https://developer.android.com/ndk/guides/wrap-script"},"wrap.sh")," script, which must be included in the primary APK to take effect. Only one of ",(0,n.mdx)("inlineCode",{parentName:"li"},"is_asset")," and ",(0,n.mdx)("inlineCode",{parentName:"li"},"has_wrap_script")," can be set for a rule."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"is_asset"),": Normally native shared objects end up in a directory in the root of the APK named ",(0,n.mdx)("inlineCode",{parentName:"li"},"lib/"),". If this parameter is set to ",(0,n.mdx)("inlineCode",{parentName:"li"},"True"),", then these objects are placed in ",(0,n.mdx)("inlineCode",{parentName:"li"},"assets/lib/"),". Placing shared objects in a non-standard location prevents Android from extracting them to the device's internal storage.")),(0,n.mdx)("h4",{id:"details-65"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Most of the time, a ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_native_library")," is private to the ",(0,n.mdx)("inlineCode",{parentName:"p"},"android\\_library()"),"that uses it:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_native_library(\n name = 'native_libs',\n native_libs = 'libs',\n)\n\nandroid_library(\n name = 'my_lib',\n srcs = glob(['*.java']),\n deps = [\n ':native_libs',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_ocaml_library"},"prebuilt","_","ocaml","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_ocaml_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n bytecode_c_libs: list[str] = _,\n bytecode_lib: None | str = _,\n bytecode_only: bool = _,\n c_libs: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n include_dir: None | str = _,\n labels: list[str] = _,\n lib_dir: str = _,\n lib_name: str = _,\n licenses: list[str] = _,\n native_c_libs: list[str] = _,\n native_lib: None | str = _,\n platform_deps: list[(str, list[str])] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-112"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"prebuilt_python_library"},"prebuilt","_","python","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def prebuilt_python_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _create_manifest_for_source_dir: str = _,\n _extract: str = _,\n _python_toolchain: str = _,\n binary_src: str,\n buck2_compatibility: str = _,\n compile: bool = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exclude_deps_from_merged_linking: bool = _,\n ignore_compile_errors: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_python_library()")," rule is used to include prebuilt python packages into the output of a top-level ",(0,n.mdx)("inlineCode",{parentName:"p"},"python_binary()"),"or ",(0,n.mdx)("inlineCode",{parentName:"p"},"python_test()"),"rule."),(0,n.mdx)("h4",{id:"parameters-113"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"binary_src"),": The path to the ",(0,n.mdx)("inlineCode",{parentName:"p"},".whl")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},".egg")," to use."),(0,n.mdx)("p",{parentName:"li"},"Note: ",(0,n.mdx)("inlineCode",{parentName:"p"},".egg")," files have a very particular naming convention\nthat must be followed - otherwise it will not be found at runtime!")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": Other ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt_python_library()")," rules which this library depends on. These may also be ",(0,n.mdx)("inlineCode",{parentName:"p"},"python_library")," rules if you want to depend on a source-based copy of the library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exclude_deps_from_merged_linking"),": When linking the top-level binary with a ",(0,n.mdx)("inlineCode",{parentName:"p"},"merged")," ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),", do not merge or re-link any native transitive deps of this library. This is useful if this library wraps prebuilt native extensions which cannot be re-linked as part of library merging.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"labels"),": Set of arbitrary strings which allow you to annotate a ",(0,n.mdx)("inlineCode",{parentName:"p"},"build rule"),"with tags that can be searched for over an entire dependency tree using ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck query()")," ."))),(0,n.mdx)("h4",{id:"details-66"},"Details"),(0,n.mdx)("p",null,"These prebuilt libraries can either be ",(0,n.mdx)("a",{parentName:"p",href:"https://www.python.org/dev/peps/pep-0427/"},"whl files")," or eggs"),(0,n.mdx)("p",null,"whls for most packages are available for download from ",(0,n.mdx)("a",{parentName:"p",href:"https://pypi.org"},"PyPI"),". The whl used may be\ndownloaded with ",(0,n.mdx)("inlineCode",{parentName:"p"},"remote_file()"),". However, Buck does not attempt to infer dependency information from pip,\nso that information will have to be imparted by the user."),(0,n.mdx)("p",null,"To create an egg for a package, run ",(0,n.mdx)("inlineCode",{parentName:"p"},"python setup.py bdist_egg")," in the package source distribution."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# A simple prebuilt_python_library with no external dependencies.\nremote_file(\n name = "requests-download",\n url = "https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl",\n sha1 = "e1fc28120002395fe1f2da9aacea4e15a449d9ee",\n out = "requests-2.22.0-py2.py3-none-any.whl",\n)\n\nprebuilt_python_library(\n name = "requests",\n binary_src = ":requests-download",\n)\n\n# A slightly more complex example\nprebuilt_python_library(\n name = "greenlet",\n binary_src = "greenlet-0.4.7-py2.7-macosx-10.10-x86_64.egg",\n)\n\nprebuilt_python_library(\n name = "gevent",\n binary_src = "gevent-1.0.2-py2.7-macosx-10.10-x86_64.egg",\n deps = [\n ":greenlet",\n ],\n)\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"python_binary"},"python","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def python_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _create_manifest_for_source_dir: str = _,\n _cxx_hacks: str = _,\n _cxx_toolchain: str = _,\n _exec_os_type: str = _,\n _package_remotely: bool = _,\n _python_toolchain: str = _,\n _target_os_type: str = _,\n allow_cache_upload: None | bool = _,\n anonymous_link_groups: bool = _,\n auto_link_groups: bool = _,\n base_module: None | str = _,\n binary_linker_flags: list[str] = _,\n bolt_flags: list[str] = _,\n bolt_profile: None | str = _,\n buck2_compatibility: str = _,\n build_args: list[str] = _,\n compile: None | bool = _,\n compiler_flags: list[str] = _,\n constraint_overrides: list[str] = _,\n contacts: list[str] = _,\n coverage_instrumentation_compiler_flags: list[str] = _,\n cxx_main: str = _,\n cxx_platform: None | str = _,\n cxx_runtime_type: None | str = _,\n deduplicate_merged_link_roots: None | bool = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n devirt_enabled: bool = _,\n distributed_thinlto_partial_split_dwarf: bool = _,\n dummy_omnibus: None | str = _,\n enable_distributed_thinlto: bool = _,\n executable_deps: list[str] = _,\n executable_name: None | str = _,\n exported_needs_coverage_instrumentation: bool = _,\n extension: None | str = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n inplace_build_args: list[str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_deps: list[str] = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_min_binary_node_count: None | int = _,\n link_group_public_deps_label: None | str = _,\n link_ordering: None | str = _,\n link_style: str = _,\n link_whole: bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n main: None | str = _,\n main_function: None | str = _,\n main_module: None | str = _,\n make_py_package: None | str = _,\n manifest_module_entries: None | dict[str, list[str] | dict[str, typing.Any]] = _,\n native_link_strategy: None | str = _,\n package_split_dwarf_dwp: bool = _,\n package_style: None | str = _,\n par_style: None | str = _,\n platform: None | str = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preload_deps: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_native_objects: bool = _,\n prefer_stripped_objects: bool = _,\n prefix_header: None | str = _,\n preload_deps: list[str] = _,\n preprocessor_flags: list[str] = _,\n py_version_for_type_checking: None | str = _,\n raw_headers: list[str] = _,\n resources: list[str] | dict[str, str] = _,\n run_with_inplace: bool = _,\n runtime_env: None | dict[str, str] = _,\n standalone_build_args: list[str] = _,\n static_extension_finder: str = _,\n static_extension_utils: str = _,\n strip_libpar: str = _,\n strip_stapsdt: bool = _,\n thin_lto: bool = _,\n typing: bool = _,\n version_universe: None | str = _,\n weak_framework_names: list[str] = _,\n zip_safe: None | bool = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"python_binary()")," rule is used to build an executable Python package that includes Python sources and resources from all transitive dependencies."),(0,n.mdx)("h4",{id:"parameters-114"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it)."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"base_module"),": The package in which the main module should reside in its final location in the binary. If unset, Buck uses the project-relative directory that contains the BUCK file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deduplicate_merged_link_roots"),": When linking multiple top-level binaries with the ",(0,n.mdx)("inlineCode",{parentName:"li"},"merged")," ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig"),", coalesce root link rules which are identical across independent merged links."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": A list of ",(0,n.mdx)("inlineCode",{parentName:"li"},"python_library()")," rules that specify Python modules to include in the binary \u2014 including all transitive dependencies of these rules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"labels"),": Set of arbitrary strings which allow you to annotate a ",(0,n.mdx)("inlineCode",{parentName:"li"},"build rule"),"with tags that can be searched for over an entire dependency tree using ",(0,n.mdx)("inlineCode",{parentName:"li"},"buck query()")," ."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_group_deps"),": Additional targets to traverse when building link groups, but which should not be direct dependencies of the main executable."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"link_group_public_deps_label"),': Surface nodes with this label as "public" nodes in the main executable when linking with with link groups.'),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"linker_flags"),": Additional linker flags that should be applied to any linking which is specific to this rule. Note that whether these flags are used is dependent on the native link strategy selected in ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig")," and currently applies only to the ",(0,n.mdx)("inlineCode",{parentName:"li"},"merged")," ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig"),"; the ",(0,n.mdx)("inlineCode",{parentName:"li"},"separate")," link strategy pulls in shared libraries that are linked in the context of the rules that own them, such as ",(0,n.mdx)("inlineCode",{parentName:"li"},"cxx\\_library()"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"main"),": The Python file which serves as the entry point for the binary. The interpreter initiates execution of the binary with the code in this file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"main_function"),": Name of a Python function that will serve as the main entry point of the binary. The name is either a fully qualified name like ",(0,n.mdx)("inlineCode",{parentName:"li"},"foo.bar.baz")," or it starts with a ",(0,n.mdx)("inlineCode",{parentName:"li"},".")," like ",(0,n.mdx)("inlineCode",{parentName:"li"},".bar.baz"),", in which case it is relative to the package containing the target. This should usually be a function defined within one of the dependencies of this target. This attribute should be preferred over ",(0,n.mdx)("inlineCode",{parentName:"li"},"main_module")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"main"),", and it is an error to specify more than one of these."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"main_module"),": The python module that should be the entry point of the binary. This should be a module name within a ",(0,n.mdx)("inlineCode",{parentName:"li"},"python_library")," that this binary depends on. Note that module names take ",(0,n.mdx)("inlineCode",{parentName:"li"},"base_module")," of the library into account. This property is mutually exclusive with ",(0,n.mdx)("inlineCode",{parentName:"li"},"main"),", and should be preferred to ",(0,n.mdx)("inlineCode",{parentName:"li"},"main"),", which is deprecated."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"manifest_module_entries"),": If present, it should be a ",(0,n.mdx)("inlineCode",{parentName:"li"},"string")," -> ",(0,n.mdx)("inlineCode",{parentName:"li"},"entry")," mapping that gets generated into a ",(0,n.mdx)("inlineCode",{parentName:"li"},"__manifest__")," module in the executable. Top level string keys will be the names of variables in this module (so they must be valid Python identifiers). An ",(0,n.mdx)("inlineCode",{parentName:"li"},"entry")," can be a list of ",(0,n.mdx)("inlineCode",{parentName:"li"},"string"),"s, or a further ",(0,n.mdx)("inlineCode",{parentName:"li"},"string"),"-keyed dictionary."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"package_style"),": Used to override the global packaging style that is set in ",(0,n.mdx)("inlineCode",{parentName:"li"},"["),".buckconfig",(0,n.mdx)("inlineCode",{parentName:"li"}," ]"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform"),": The name of the Python platform ",(0,n.mdx)("em",{parentName:"li"},"flavor")," to build against by default as defined in the buckconfig#",(0,n.mdx)("inlineCode",{parentName:"li"},"python"),"section of ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"preload_deps"),": A list of C/C++ library dependencies that need to be loaded before any other libraries when the PEX starts up. This requires dynamic loader support, such as ",(0,n.mdx)("inlineCode",{parentName:"li"},"LD_PRELOAD"),", found on most systems. This list is order- sensitive and the preload libraries listed here are passed down to the dynamic linker in the same order."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"py_version_for_type_checking"),": This option will force the type checker to perform checking under a specific version of Python interpreter."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"typing"),": Determines whether to perform type checking on the given target. Default is False.")),(0,n.mdx)("h4",{id:"details-67"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Build an executable from the Python files in the BUCK directory."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# BUCK\n\npython_binary(\n name = 'tailer',\n main_module = 'tailer',\n deps = [\n ':tailerutils',\n ],\n)\n\npython_library(\n name = 'tailerutils',\n # The main module, tailer.py, is specified here.\n # (Separated out from the glob pattern for clarity.)\n srcs = glob(['tailer.py', '*.py']),\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"python_bootstrap_binary"},"python","_","bootstrap","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def python_bootstrap_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _exec_os_type: str = _,\n _python_bootstrap_toolchain: str = _,\n _win_python_wrapper: None | str = _,\n buck2_compatibility: str = _,\n deps: list[str] = _,\n main: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-115"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"python_bootstrap_library"},"python","_","bootstrap","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def python_bootstrap_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n deps: list[str] = _,\n srcs: list[str]\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-116"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"python_library"},"python","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def python_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _create_manifest_for_source_dir: str = _,\n _cxx_toolchain: str = _,\n _python_toolchain: str = _,\n base_module: None | str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_platform: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exclude_deps_from_merged_linking: bool = _,\n ignore_compile_errors: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n platform: None | str = _,\n platform_deps: list[(str, list[str])] = _,\n platform_resources: list[(str, list[str] | dict[str, str])] = _,\n platform_srcs: list[(str, list[str] | dict[str, str])] = _,\n py_version_for_type_checking: None | str = _,\n resources: list[str] | dict[str, str] = _,\n srcs: list[str] | dict[str, str] = _,\n type_stubs: list[str] | dict[str, str] = _,\n typing: bool = _,\n version_universe: None | str = _,\n versioned_resources: None | list[(dict[str, str], list[str] | dict[str, str])] = _,\n versioned_srcs: None | list[(dict[str, str], list[str] | dict[str, str])] = _,\n zip_safe: None | bool = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"python_library()")," rule is used to group together Python source files and resources to be passed together in as a ",(0,n.mdx)("inlineCode",{parentName:"p"},"dep")," of other rules."),(0,n.mdx)("h4",{id:"parameters-117"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"base_module"),": The package in which the specified source files and resources should reside in their final location in the top-level binary. If unset, Buck uses the project-relative directory that contains the BUCK file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"deps"),": Other ",(0,n.mdx)("inlineCode",{parentName:"li"},"python_library()")," rules that list ",(0,n.mdx)("inlineCode",{parentName:"li"},"srcs")," from which this rule imports modules."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exclude_deps_from_merged_linking"),": When linking the top-level binary with a ",(0,n.mdx)("inlineCode",{parentName:"li"},"merged")," ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig"),", do not merge or re-link any native transitive deps of this library. This is useful if this library wraps prebuilt native extensions which cannot be re-linked as part of library merging."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"labels"),": Set of arbitrary strings which allow you to annotate a ",(0,n.mdx)("inlineCode",{parentName:"li"},"build rule"),"with tags that can be searched for over an entire dependency tree using ",(0,n.mdx)("inlineCode",{parentName:"li"},"buck query()")," ."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_resources"),": Python-platform-specific resource files. These should be specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched, and the second element is a list of resource files. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"li"},"java.util.regex.Pattern")," syntax. The platform name is a Python platform ",(0,n.mdx)("em",{parentName:"li"},"flavor")," defined in the buckconfig#",(0,n.mdx)("inlineCode",{parentName:"li"},"python"),"section of ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_srcs"),": Python-platform-specific source files. These should be specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched, and the second element is a list of source files. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"li"},"java.util.regex.Pattern")," syntax. The platform name is a Python platform ",(0,n.mdx)("em",{parentName:"li"},"flavor")," defined in the buckconfig#",(0,n.mdx)("inlineCode",{parentName:"li"},"python"),"section of ",(0,n.mdx)("inlineCode",{parentName:"li"},".buckconfig"),"."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"py_version_for_type_checking"),": This option will force the type checker to perform checking under a specific version of Python interpreter."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of Python (",(0,n.mdx)("inlineCode",{parentName:"li"},".py"),") files to include in this library."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"typing"),": Determines whether to perform type checking on the given target. Default is False.")),(0,n.mdx)("h4",{id:"details-68"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Include Python source files and resource files."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# BUCK\n\n# A rule that includes a single Python file.\npython_library(\n name = 'fileutil',\n srcs = ['fileutil.py'],\n deps = [\n '//third_party/python-magic:python-magic',\n ],\n)\n\n# A rule that uses glob() to include all Python source files in the\n# directory in which the rule is defined. The rule also specifies a\n# resource file that gets packaged with the source file.\npython_library(\n name = 'testutil',\n srcs = glob(['testutil/**/*.py']),\n resources = [\n 'testdata.dat',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"python_needed_coverage_test"},"python","_","needed","_","coverage","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def python_needed_coverage_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _inject_test_env: str = _,\n _remote_test_execution_toolchain: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n env: dict[str, str] = _,\n labels: list[str] = _,\n needed_coverage: list[(int, str, None | str)] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n test: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-118"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"python_test"},"python","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def python_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _create_manifest_for_source_dir: str = _,\n _cxx_hacks: str = _,\n _cxx_toolchain: str = _,\n _exec_os_type: str = _,\n _inject_test_env: str = _,\n _python_toolchain: str = _,\n _remote_test_execution_toolchain: str = _,\n _target_os_type: str = _,\n _test_main: str = _,\n additional_coverage_targets: list[str] = _,\n anonymous_link_groups: bool = _,\n auto_link_groups: bool = _,\n base_module: None | str = _,\n binary_linker_flags: list[str] = _,\n bolt_flags: list[str] = _,\n bolt_profile: None | str = _,\n buck2_compatibility: str = _,\n build_args: list[str] = _,\n compile: None | bool = _,\n compiler_flags: list[str] = _,\n constraint_overrides: list[str] = _,\n contacts: list[str] = _,\n coverage_instrumentation_compiler_flags: list[str] = _,\n cxx_main: str = _,\n cxx_platform: None | str = _,\n cxx_runtime_type: None | str = _,\n deduplicate_merged_link_roots: None | bool = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n defaults: dict[str, str] = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n devirt_enabled: bool = _,\n distributed_thinlto_partial_split_dwarf: bool = _,\n dummy_omnibus: None | str = _,\n enable_distributed_thinlto: bool = _,\n env: dict[str, str] = _,\n exclude_deps_from_merged_linking: bool = _,\n executable_deps: list[str] = _,\n executable_name: None | str = _,\n exported_needs_coverage_instrumentation: bool = _,\n extension: None | str = _,\n fat_lto: bool = _,\n focused_list_target: None | str = _,\n frameworks: list[str] = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n headers_as_raw_headers_mode: None | str = _,\n include_directories: list[str] = _,\n inplace_build_args: list[str] = _,\n labels: list[str] = _,\n lang_compiler_flags: dict[str, list[str]] = _,\n lang_platform_compiler_flags: dict[str, list[(str, list[str])]] = _,\n lang_platform_preprocessor_flags: dict[str, list[(str, list[str])]] = _,\n lang_preprocessor_flags: dict[str, list[str]] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n link_deps_query_whole: bool = _,\n link_execution_preference: None | str = _,\n link_group: None | str = _,\n link_group_deps: list[str] = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_min_binary_node_count: None | int = _,\n link_group_public_deps_label: None | str = _,\n link_ordering: None | str = _,\n link_style: str = _,\n link_whole: bool = _,\n linker_extra_outputs: list[str] = _,\n linker_flags: list[str] = _,\n main_function: None | str = _,\n main_module: None | str = _,\n make_py_package: None | str = _,\n manifest_module_entries: None | dict[str, list[str] | dict[str, typing.Any]] = _,\n native_link_strategy: None | str = _,\n needed_coverage: list[(int, str, None | str)] = _,\n package_split_dwarf_dwp: bool = _,\n package_style: None | str = _,\n par_style: None | str = _,\n platform: None | str = _,\n platform_compiler_flags: list[(str, list[str])] = _,\n platform_deps: list[(str, list[str])] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n platform_linker_flags: list[(str, list[str])] = _,\n platform_preload_deps: list[(str, list[str])] = _,\n platform_preprocessor_flags: list[(str, list[str])] = _,\n platform_resources: list[(str, list[str] | dict[str, str])] = _,\n platform_srcs: list[(str, list[str | (str, list[str])])] = _,\n post_linker_flags: list[str] = _,\n post_platform_linker_flags: list[(str, list[str])] = _,\n precompiled_header: None | str = _,\n prefer_stripped_native_objects: bool = _,\n prefer_stripped_objects: bool = _,\n prefix_header: None | str = _,\n preload_deps: list[str] = _,\n preprocessor_flags: list[str] = _,\n py_version_for_type_checking: None | str = _,\n raw_headers: list[str] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n resources: list[str] | dict[str, str] = _,\n run_with_inplace: bool = _,\n runner: None | str = _,\n runtime_env: None | dict[str, str] = _,\n specs: None | str = _,\n srcs: list[str] | dict[str, str] = _,\n standalone_build_args: list[str] = _,\n static_extension_finder: str = _,\n static_extension_utils: str = _,\n strip_libpar: str = _,\n strip_stapsdt: bool = _,\n test_rule_timeout_ms: None | int = _,\n thin_lto: bool = _,\n typing: bool = _,\n version_universe: None | str = _,\n versioned_resources: None | list[(dict[str, str], list[str] | dict[str, str])] = _,\n versioned_srcs: None | list[(dict[str, str], list[str] | dict[str, str])] = _,\n weak_framework_names: list[str] = _,\n zip_safe: None | bool = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"python_test()")," rule defines a set of ",(0,n.mdx)("inlineCode",{parentName:"p"},".py")," files that contain tests to run via the ",(0,n.mdx)("a",{parentName:"p",href:"https://docs.python.org/library/unittest.html"},"Python unit testing framework"),"."),(0,n.mdx)("h4",{id:"parameters-119"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"base_module"),": The package in which the specified source files and resources should reside in their final location in the top-level binary. If unset, Buck uses the project-relative directory that contains the BUCK file.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deduplicate_merged_link_roots"),": When linking multiple top-level binaries with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"merged")," ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),", coalesce root link rules which are identical across independent merged links.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": other rules used by the tests in this rule's sources.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": A map of environment names and values to set when running the test."),(0,n.mdx)("p",{parentName:"li"},"It is also possible to expand references to other rules within the ",(0,n.mdx)("strong",{parentName:"p"},"values")," of\nthese environment variables, using builtin ",(0,n.mdx)("inlineCode",{parentName:"p"},"string parameter macros"),"\n:"),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"$(location //path/to:target)"),"\nExpands to the location of the output of the build rule. This\nmeans that you can refer to these without needing to be aware of how\nBuck is storing data on the disk mid-build.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exclude_deps_from_merged_linking"),": When linking the top-level binary with a ",(0,n.mdx)("inlineCode",{parentName:"p"},"merged")," ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),", do not merge or re-link any native transitive deps of this library. This is useful if this library wraps prebuilt native extensions which cannot be re-linked as part of library merging.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"labels"),": Set of arbitrary strings which allow you to annotate a ",(0,n.mdx)("inlineCode",{parentName:"p"},"build rule"),"with tags that can be searched for over an entire dependency tree using ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck query()")," .")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_group_deps"),": Additional targets to traverse when building link groups, but which should not be direct dependencies of the main executable.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_group_public_deps_label"),': Surface nodes with this label as "public" nodes in the main executable when linking with with link groups.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": Additional linker flags that should be applied to any linking which is specific to this rule. Note that whether these flags are used is dependent on the native link strategy selected in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," and currently applies only to the ",(0,n.mdx)("inlineCode",{parentName:"p"},"merged")," ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),"; the ",(0,n.mdx)("inlineCode",{parentName:"p"},"separate")," link strategy pulls in shared libraries that are linked in the context of the rules that own them, such as ",(0,n.mdx)("inlineCode",{parentName:"p"},"cxx\\_library()"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"main_function"),": Name of a Python function that will serve as the main entry point of the binary. The name is either a fully qualified name like ",(0,n.mdx)("inlineCode",{parentName:"p"},"foo.bar.baz")," or it starts with a ",(0,n.mdx)("inlineCode",{parentName:"p"},".")," like ",(0,n.mdx)("inlineCode",{parentName:"p"},".bar.baz"),", in which case it is relative to the package containing the target. This should usually be a function defined within one of the dependencies of this target. This attribute should be preferred over ",(0,n.mdx)("inlineCode",{parentName:"p"},"main_module")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"main"),", and it is an error to specify more than one of these.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"main_module"),": The main module used to run the tests. This parameter is normally not needed, as Buck will provide a default main module that runs all tests. However, you can override this with your own module to perform custom initialization or command line processing. Your custom module can import the standard Buck test main as ",(0,n.mdx)("inlineCode",{parentName:"p"},"__test_main__"),", and can invoke it's normal main function as ",(0,n.mdx)("inlineCode",{parentName:"p"},"__test_main__.main(sys.argv)"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"manifest_module_entries"),": If present, it should be a ",(0,n.mdx)("inlineCode",{parentName:"p"},"string")," -> ",(0,n.mdx)("inlineCode",{parentName:"p"},"entry")," mapping that gets generated into a ",(0,n.mdx)("inlineCode",{parentName:"p"},"__manifest__")," module in the executable. Top level string keys will be the names of variables in this module (so they must be valid Python identifiers). An ",(0,n.mdx)("inlineCode",{parentName:"p"},"entry")," can be a list of ",(0,n.mdx)("inlineCode",{parentName:"p"},"string"),"s, or a further ",(0,n.mdx)("inlineCode",{parentName:"p"},"string"),"-keyed dictionary.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"package_style"),": Used to override the global packaging style that is set in ",(0,n.mdx)("inlineCode",{parentName:"p"},"["),".buckconfig",(0,n.mdx)("inlineCode",{parentName:"p"}," ]"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform"),": The name of the Python platform ",(0,n.mdx)("em",{parentName:"p"},"flavor")," to build against by default as defined in the buckconfig#",(0,n.mdx)("inlineCode",{parentName:"p"},"python"),"section of ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"platform_resources"),": Python-platform-specific resource files. These should be specified as a list of pairs where the first element in each pair is an un-anchored regex against which the platform name is matched, and the second element is a list of resource files. The regex should use ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.regex.Pattern")," syntax. The platform name is a Python platform ",(0,n.mdx)("em",{parentName:"p"},"flavor")," defined in the buckconfig#",(0,n.mdx)("inlineCode",{parentName:"p"},"python"),"section of ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"preload_deps"),": A list of C/C++ library dependencies that need to be loaded before any other libraries when the PEX starts up. This requires dynamic loader support, such as ",(0,n.mdx)("inlineCode",{parentName:"p"},"LD_PRELOAD"),", found on most systems. This list is order- sensitive and the preload libraries listed here are passed down to the dynamic linker in the same order.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"py_version_for_type_checking"),": This option will force the type checker to perform checking under a specific version of Python interpreter.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of Python (",(0,n.mdx)("inlineCode",{parentName:"p"},".py"),") files to include in this library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test_rule_timeout_ms"),": If set specifies the maximum amount of time (in milliseconds) in which all of the tests in this rule should complete. This overrides the default ",(0,n.mdx)("inlineCode",{parentName:"p"},"rule_timeout")," if any has been specified in ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," .")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"typing"),": Determines whether to perform type checking on the given target. Default is False."))),(0,n.mdx)("h4",{id:"details-69"},"Details"),(0,n.mdx)("p",null,"If your test requires static files you should specify these in\nthe ",(0,n.mdx)("strong",{parentName:"p"},"resources")," or ",(0,n.mdx)("strong",{parentName:"p"},"platform","_","resources")," arguments.\nIf you do not specify these files, they won't be available when your\ntest runs."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# A rule that includes a single .py file containing tests.\npython_test(\n name = 'fileutil_test',\n srcs = ['fileutil_tests.py'],\n deps = [\n ':fileutil',\n ],\n)\n\n# A rule that uses glob() to include all sources in the directory which the\n# rule is defined. It also lists a resource file that gets packaged with\n# the sources in this rule.\npython_library(\n name = 'fileutil',\n srcs = glob(['fileutil/**/*.py']),\n resources = [\n 'testdata.dat',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"python_test_runner"},"python","_","test","_","runner"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def python_test_runner(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n main_module: str = _,\n src: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-120"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"labels"),": Set of arbitrary strings which allow you to annotate a ",(0,n.mdx)("inlineCode",{parentName:"li"},"build rule"),"with tags that can be searched for over an entire dependency tree using ",(0,n.mdx)("inlineCode",{parentName:"li"},"buck query()")," .")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"remote_file"},"remote","_","file"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def remote_file(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _unzip_tool: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n out: None | str = _,\n sha1: None | str = _,\n sha256: None | str = _,\n type: None | str = _,\n url: str,\n vpnless_url: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"remote_file()")," rule is used to download files from the Internet to be used as dependencies for other rules. These rules are downloaded by running ",(0,n.mdx)("inlineCode",{parentName:"p"},"fetch"),", or can be downloaded as part of ",(0,n.mdx)("inlineCode",{parentName:"p"},"build"),". See the note there about the ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")," setting to configure that."),(0,n.mdx)("h4",{id:"parameters-121"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"out"),": An optional name to call the downloaded artifact. Buck will generate a default name if one is not provided that uses the ",(0,n.mdx)("inlineCode",{parentName:"p"},"name")," of the rule.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"type"),": An optional type of the downloaded file."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"data"),"\nRegular data file.\n",(0,n.mdx)("inlineCode",{parentName:"p"},"executable")),(0,n.mdx)("p",{parentName:"li"}," Executable file. Buck will ensure that output has appropriate permissions if applicable."),(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exploded_zip")),(0,n.mdx)("p",{parentName:"li"}," Zip archive which will be automatically unzipped into an output directory.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"url"),": You can specify an ",(0,n.mdx)("inlineCode",{parentName:"p"},"http"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"https"),", or a ",(0,n.mdx)("inlineCode",{parentName:"p"},"mvn")," URL. If you specify a ",(0,n.mdx)("inlineCode",{parentName:"p"},"mvn")," URL, it will be decoded as described in the javadocs for MavenUrlDecoder See the example section below.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"vpnless_url"),": An optional additional URL from which this resource can be downloaded when off VPN. Meta-internal only."))),(0,n.mdx)("h4",{id:"details-70"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Here's an example of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"remote_file()")," using an ",(0,n.mdx)("inlineCode",{parentName:"p"},"https")," URL."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nremote_file(\n name = 'android-ndk-r10e-darwin-x86_64',\n url = 'https://dl.google.com/android/ndk/android-ndk-r10e-darwin-x86_64.bin',\n sha1 = 'b57c2b9213251180dcab794352bfc9a241bf2557',\n)\n\n")),(0,n.mdx)("p",null," Here's an example of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"remote_file()")," using a ",(0,n.mdx)("inlineCode",{parentName:"p"},"mvn")," URL being referenced\nby a ",(0,n.mdx)("inlineCode",{parentName:"p"},"prebuilt\\_jar()"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nprebuilt_jar(\n name = 'jetty-all',\n binary_jar = 'jetty-all-9.2.10.v20150310.jar',\n source_jar = ':jetty-source',\n)\n\nremote_file(\n name = 'jetty-source',\n out = 'jetty-all-9.2.10.v20150310-sources.jar',\n url = 'mvn:org.eclipse.jetty.aggregate:jetty-all:src:9.2.10.v20150310',\n sha1 = '311da310416d2feb3de227081d7c3f48742d7075',\n)\n\n")),(0,n.mdx)("p",null," Here's an example of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"remote_file()")," using a ",(0,n.mdx)("inlineCode",{parentName:"p"},"mvn")," URI which uses a\nnon-default maven repository host."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nremote_file(\n name = 'jetty-source',\n out = 'jetty-all-9.2.10.v20150310-sources.jar',\n url = 'mvn:https://maven-repo.com:org.eclipse.jetty.aggregate:jetty-all:src:9.2.10.v20150310',\n sha1 = '311da310416d2feb3de227081d7c3f48742d7075',\n)\n\n")),(0,n.mdx)("p",null," Here's an example of a ",(0,n.mdx)("inlineCode",{parentName:"p"},"remote_file()")," using a ",(0,n.mdx)("inlineCode",{parentName:"p"},"mvn")," URI which uses a\nMaven classifier."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nremote_file(\n name = 'groovy-groovysh-indy',\n out = 'jetty-all-9.2.10.v20150310-sources.jar',\n url = 'mvn:org.codehaus.groovy:groovy-groovysh:jar:indy:2.4.1',\n sha1 = '1600fde728c885cc9506cb102deb1b494bd7c130',\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"robolectric_test"},"robolectric","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def robolectric_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _android_toolchain: str = _,\n _apple_platforms: dict[str, str] = _,\n _build_only_native_code: bool = _,\n _exec_os_type: str = _,\n _inject_test_env: str = _,\n _is_building_android_binary: bool = _,\n _java_test_toolchain: str = _,\n _java_toolchain: str = _,\n _kotlin_toolchain: str = _,\n _remote_test_execution_toolchain: str = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n android_optional_jars: None | list[str] = _,\n annotation_processing_tool: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_library_whitelist: list[str] = _,\n default_cxx_platform: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n env: dict[str, str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n extra_kotlinc_arguments: list[str] = _,\n fork_mode: str = _,\n friend_paths: list[str] = _,\n jar_postprocessor: None | str = _,\n java: None | str = _,\n java_agents: list[str] = _,\n java_version: None | str = _,\n javac: None | str = _,\n k2: bool = _,\n kotlin_compiler_plugins: dict[str, dict[str, str]] = _,\n labels: list[str] = _,\n language: None | str = _,\n licenses: list[str] = _,\n locales_for_binary_resources: list[str] = _,\n manifest: None | str = _,\n manifest_entries: dict[str, typing.Any] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n preferred_density_for_binary_resources: None | str = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n provided_deps_query: None | str = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resource_stable_ids: None | str = _,\n resource_union_package: None | str = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n robolectric_manifest: str,\n robolectric_runtime_dependencies: list[str] = _,\n robolectric_runtime_dependency: None | str = _,\n run_test_separately: bool = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n std_err_log_level: None | int | str = _,\n std_out_log_level: None | int | str = _,\n target: None | str = _,\n test_case_timeout_ms: None | int = _,\n test_class_names_file: None | str = _,\n test_rule_timeout_ms: None | int = _,\n test_type: None | str = _,\n unbundled_resources_root: None | str = _,\n use_cxx_libraries: None | bool = _,\n use_dependency_order_classpath: None | bool = _,\n use_jvm_abi_gen: None | bool = _,\n used_as_dependency_deprecated_do_not_use: bool = _,\n vm_args: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"robolectric_test()")," rule is used to define a set of ",(0,n.mdx)("inlineCode",{parentName:"p"},".java")," files that contain tests to run via JUnit with Robolectric test runner. It extends from ",(0,n.mdx)("inlineCode",{parentName:"p"},"java_test()")," rule."),(0,n.mdx)("h4",{id:"parameters-122"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"extra_kotlinc_arguments"),": List of additional arguments to pass into the Kotlin compiler."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"k2"),": Enables the Kotlin K2 compiler."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"robolectric_manifest"),": An ",(0,n.mdx)("a",{parentName:"li",href:"http://developer.android.com/guide/topics/manifest/manifest-intro.html"},"Android Manifest")," for the rule to declare any permissions or intents it may need or want to handle. May either be a file or a ",(0,n.mdx)("inlineCode",{parentName:"li"},"android\\_manifest()"),"target."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"robolectric_runtime_dependency"),": Robolectric only runs in offline mode with buck. Specify the relative directory containing all the jars Robolectric uses at runtime.")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"rust_binary"},"rust","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def rust_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _exec_os_type: str = _,\n _rust_toolchain: str = _,\n _target_os_type: str = _,\n _workspaces: list[str] = _,\n allow_cache_upload: None | bool = _,\n anonymous_link_groups: bool = _,\n auto_link_groups: bool = _,\n buck2_compatibility: str = _,\n clippy_configuration: None | str = _,\n contacts: list[str] = _,\n coverage: bool = _,\n crate: None | str = _,\n crate_root: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n deps: list[str] = _,\n edition: None | str = _,\n enable_distributed_thinlto: bool = _,\n env: dict[str, str] = _,\n features: list[str] = _,\n flagged_deps: list[(str, list[str])] = _,\n incremental_build_mode: None | str = _,\n incremental_enabled: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_min_binary_node_count: None | int = _,\n link_style: None | str = _,\n linker_flags: list[str] = _,\n mapped_srcs: dict[str, str] = _,\n named_deps: list[(str, str)] | dict[str, str] = _,\n resources: list[str] | dict[str, str] = _,\n rpath: bool = _,\n rustc_flags: list[str] = _,\n rustdoc_flags: list[str] = _,\n srcs: list[str] = _,\n version_universe: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A rust","_","binary() rule builds a native executable from the supplied set of Rust source files and dependencies."),(0,n.mdx)("h4",{id:"parameters-123"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"_workspaces"),": Internal implementation detail of Rust workspaces. This should not be set manually and will be replaced in favor of metadata in a future version of buck2.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"allow_cache_upload"),": Whether to allow uploading the output of this rule to be uploaded to cache when the action is executed locally if the configuration allows (i.e. there is a cache configured and the client has permission to write to it).")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"crate_root"),": Set the name of the top-level source file for the crate, which can be used to override the default (see ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": The set of dependencies of this rule. Currently, this supports rust","_","library and prebuilt","_","rust","_","library rules.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"edition"),": Set the language edition to be used for this rule. Can be set to any edition the compiler supports (",(0,n.mdx)("inlineCode",{parentName:"p"},"2018")," right now). If unset it uses the compiler's default (",(0,n.mdx)("inlineCode",{parentName:"p"},"2015"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": Set environment variables for this rule's invocations of rustc. The environment variable values may include macros which are expanded.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"features"),": The set of features to be enabled for this rule."),(0,n.mdx)("p",{parentName:"li"},"These are passed to ",(0,n.mdx)("inlineCode",{parentName:"p"},"rustc")," with ",(0,n.mdx)("inlineCode",{parentName:"p"},'--cfg feature="{feature}"'),", and can be used in the code with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#[cfg(feature = "{feature}")]'),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": The set of additional flags to pass to the linker.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"mapped_srcs"),": Add source files along with a local path mapping. Rust is sensitive to the layout of source files, as the directory structure follows the module structure. However this is awkward if the source file is, for example, generated by another rule. In this case, you can set up a mapping from the actual source path to something that makes sense locally. For example ",(0,n.mdx)("inlineCode",{parentName:"p"},'mapped_srcs = {":generate-module", "src/generated.rs" }'),". These are added to the regular ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),", so a file should not be listed in both.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"named_deps"),": Add crate dependencies and define a local name by which to use that dependency by. This allows a crate to have multiple dependencies with the same crate name. For example: ",(0,n.mdx)("inlineCode",{parentName:"p"},'named_deps = {"local_name", ":some_rust_crate" }'),". The dependencies may also be non-Rust, but the alias is ignored. It has no effect on the symbols provided by a C/C++ library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"rpath"),': Set the "rpath" in the executable when using a shared link style.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"rustc_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"p"},"rustc"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of Rust source files to be compiled by this rule."),(0,n.mdx)("p",{parentName:"li"},"One of the source files is the root module of the crate. By default this is ",(0,n.mdx)("inlineCode",{parentName:"p"},"lib.rs")," for libraries, ",(0,n.mdx)("inlineCode",{parentName:"p"},"main.rs")," for executables, or\nthe crate's name with ",(0,n.mdx)("inlineCode",{parentName:"p"},".rs")," appended. This can be overridden with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"crate_root")," rule parameter."))),(0,n.mdx)("h4",{id:"details-71"},"Details"),(0,n.mdx)("p",null,"If you invoke a build with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"check")," flavor, then Buck will invoke rustc\nto check the code (typecheck, produce warnings, etc), but won't generate an executable code.\nWhen applied to binaries it produces no output; for libraries it produces metadata for\nconsumers of the library."),(0,n.mdx)("p",null,"Note: Buck is currently tested with (and therefore supports) version 1.32.0 of Rust."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/rust/testdata/"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nrust_binary(\n name='greet',\n srcs=[\n 'greet.rs',\n ],\n deps=[\n ':greeting',\n ],\n)\n\nrust_library(\n name='greeting',\n srcs=[\n 'greeting.rs',\n ],\n deps=[\n ':join',\n ],\n)\n\nrust_library(\n name='join',\n srcs=[\n 'join.rs',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"rust_library"},"rust","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def rust_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _exec_os_type: str = _,\n _rust_toolchain: str = _,\n _target_os_type: str = _,\n _workspaces: list[str] = _,\n buck2_compatibility: str = _,\n clippy_configuration: None | str = _,\n contacts: list[str] = _,\n coverage: bool = _,\n crate: None | str = _,\n crate_dynamic: None | str = _,\n crate_root: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n deps: list[str] = _,\n doc_deps: list[str] = _,\n doc_env: dict[str, str] = _,\n doc_link_style: None | str = _,\n doc_linker_flags: list[str] = _,\n doc_named_deps: list[(str, str)] | dict[str, str] = _,\n doctests: None | bool = _,\n edition: None | str = _,\n env: dict[str, str] = _,\n features: list[str] = _,\n flagged_deps: list[(str, list[str])] = _,\n incremental_build_mode: None | str = _,\n incremental_enabled: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_style: None | str = _,\n linker_flags: list[str] = _,\n mapped_srcs: dict[str, str] = _,\n named_deps: list[(str, str)] | dict[str, str] = _,\n preferred_linkage: str = _,\n proc_macro: bool = _,\n resources: list[str] | dict[str, str] = _,\n rustc_flags: list[str] = _,\n rustdoc_flags: list[str] = _,\n soname: None | str = _,\n srcs: list[str] = _,\n supports_python_dlopen: None | bool = _,\n version_universe: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A rust","_","library() rule builds a native library from the supplied set of Rust source files and dependencies."),(0,n.mdx)("h4",{id:"parameters-124"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"_workspaces"),": Internal implementation detail of Rust workspaces. This should not be set manually and will be replaced in favor of metadata in a future version of buck2.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"crate_root"),": Set the name of the top-level source file for the crate, which can be used to override the default (see ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": The set of dependencies of this rule. Currently, this supports rust","_","library and prebuilt","_","rust","_","library rules.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"doc_deps"),": The set of dependencies of this rule. Currently, this supports rust","_","library and prebuilt","_","rust","_","library rules.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"doc_env"),": Set environment variables for this rule's invocations of rustc. The environment variable values may include macros which are expanded.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"doc_link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"doc_linker_flags"),": The set of additional flags to pass to the linker.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"doc_named_deps"),": Add crate dependencies and define a local name by which to use that dependency by. This allows a crate to have multiple dependencies with the same crate name. For example: ",(0,n.mdx)("inlineCode",{parentName:"p"},'named_deps = {"local_name", ":some_rust_crate" }'),". The dependencies may also be non-Rust, but the alias is ignored. It has no effect on the symbols provided by a C/C++ library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"edition"),": Set the language edition to be used for this rule. Can be set to any edition the compiler supports (",(0,n.mdx)("inlineCode",{parentName:"p"},"2018")," right now). If unset it uses the compiler's default (",(0,n.mdx)("inlineCode",{parentName:"p"},"2015"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": Set environment variables for this rule's invocations of rustc. The environment variable values may include macros which are expanded.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"features"),": The set of features to be enabled for this rule."),(0,n.mdx)("p",{parentName:"li"},"These are passed to ",(0,n.mdx)("inlineCode",{parentName:"p"},"rustc")," with ",(0,n.mdx)("inlineCode",{parentName:"p"},'--cfg feature="{feature}"'),", and can be used in the code with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#[cfg(feature = "{feature}")]'),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": The set of additional flags to pass to the linker.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"mapped_srcs"),": Add source files along with a local path mapping. Rust is sensitive to the layout of source files, as the directory structure follows the module structure. However this is awkward if the source file is, for example, generated by another rule. In this case, you can set up a mapping from the actual source path to something that makes sense locally. For example ",(0,n.mdx)("inlineCode",{parentName:"p"},'mapped_srcs = {":generate-module", "src/generated.rs" }'),". These are added to the regular ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),", so a file should not be listed in both.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"named_deps"),": Add crate dependencies and define a local name by which to use that dependency by. This allows a crate to have multiple dependencies with the same crate name. For example: ",(0,n.mdx)("inlineCode",{parentName:"p"},'named_deps = {"local_name", ":some_rust_crate" }'),". The dependencies may also be non-Rust, but the alias is ignored. It has no effect on the symbols provided by a C/C++ library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"rustc_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"p"},"rustc"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"soname"),': Sets the soname ("shared object name") of any shared library produced from this rule. The default value is based on the full rule name. The macro ',(0,n.mdx)("inlineCode",{parentName:"p"},"$(ext)")," will be replaced with a platform-appropriate extension. An argument can be provided, which is a library version. For example ",(0,n.mdx)("inlineCode",{parentName:"p"},"soname = 'libfoo.$(ext 2.3)'")," will be ",(0,n.mdx)("inlineCode",{parentName:"p"},"libfoo.2.3.dylib")," on Mac and ",(0,n.mdx)("inlineCode",{parentName:"p"},"libfoo.so.2.3")," on Linux.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of Rust source files to be compiled by this rule."),(0,n.mdx)("p",{parentName:"li"},"One of the source files is the root module of the crate. By default this is ",(0,n.mdx)("inlineCode",{parentName:"p"},"lib.rs")," for libraries, ",(0,n.mdx)("inlineCode",{parentName:"p"},"main.rs")," for executables, or\nthe crate's name with ",(0,n.mdx)("inlineCode",{parentName:"p"},".rs")," appended. This can be overridden with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"crate_root")," rule parameter."))),(0,n.mdx)("h4",{id:"details-72"},"Details"),(0,n.mdx)("p",null,"If you invoke a build with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"check")," flavor, then Buck will invoke rustc\nto check the code (typecheck, produce warnings, etc), but won't generate an executable code.\nWhen applied to binaries it produces no output; for libraries it produces metadata for\nconsumers of the library."),(0,n.mdx)("p",null,"Note: Buck is currently tested with (and therefore supports) version 1.32.0 of Rust."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/rust/testdata/"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nrust_library(\n name='greeting',\n srcs=[\n 'greeting.rs',\n ],\n deps=[\n ':join',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"rust_test"},"rust","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def rust_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n _exec_os_type: str = _,\n _inject_test_env: str = _,\n _remote_test_execution_toolchain: str = _,\n _rust_toolchain: str = _,\n _target_os_type: str = _,\n _workspaces: list[str] = _,\n anonymous_link_groups: bool = _,\n auto_link_groups: bool = _,\n buck2_compatibility: str = _,\n clippy_configuration: None | str = _,\n contacts: list[str] = _,\n coverage: bool = _,\n crate: None | str = _,\n crate_root: None | str = _,\n default_host_platform: None | str = _,\n default_platform: None | str = _,\n deps: list[str] = _,\n edition: None | str = _,\n enable_distributed_thinlto: bool = _,\n env: dict[str, str] = _,\n features: list[str] = _,\n flagged_deps: list[(str, list[str])] = _,\n framework: bool = _,\n incremental_build_mode: None | str = _,\n incremental_enabled: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n link_group: None | str = _,\n link_group_map: None | str | list[(str, list[(None | str | list[None | str], str, None | str | list[str], None | str)], None | dict[str, typing.Any])] = _,\n link_group_min_binary_node_count: None | int = _,\n link_style: None | str = _,\n linker_flags: list[str] = _,\n mapped_srcs: dict[str, str] = _,\n named_deps: list[(str, str)] | dict[str, str] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n resources: list[str] | dict[str, str] = _,\n rpath: bool = _,\n rustc_flags: list[str] = _,\n rustdoc_flags: list[str] = _,\n srcs: list[str] = _,\n version_universe: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A rust","_","test() rule builds a Rust test native executable from the supplied set of Rust source files and dependencies and runs this test."),(0,n.mdx)("h4",{id:"parameters-125"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"_workspaces"),": Internal implementation detail of Rust workspaces. This should not be set manually and will be replaced in favor of metadata in a future version of buck2.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"crate_root"),": Set the name of the top-level source file for the crate, which can be used to override the default (see ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"deps"),": The set of dependencies of this rule. Currently, this supports rust","_","library and prebuilt","_","rust","_","library rules.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"edition"),": Set the language edition to be used for this rule. Can be set to any edition the compiler supports (",(0,n.mdx)("inlineCode",{parentName:"p"},"2018")," right now). If unset it uses the compiler's default (",(0,n.mdx)("inlineCode",{parentName:"p"},"2015"),").")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": Set environment variables for this rule's invocations of rustc. The environment variable values may include macros which are expanded.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"features"),": The set of features to be enabled for this rule."),(0,n.mdx)("p",{parentName:"li"},"These are passed to ",(0,n.mdx)("inlineCode",{parentName:"p"},"rustc")," with ",(0,n.mdx)("inlineCode",{parentName:"p"},'--cfg feature="{feature}"'),", and can be used in the code with ",(0,n.mdx)("inlineCode",{parentName:"p"},'#[cfg(feature = "{feature}")]'),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"framework"),": Use the standard test framework. If this is set to false, then the result is a normal executable which requires a ",(0,n.mdx)("inlineCode",{parentName:"p"},"main()"),", etc. It is still expected to accept the same command-line parameters and produce the same output as the test framework.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"link_style"),": Determines whether to build and link this rule's dependencies statically or dynamically. Can be either ",(0,n.mdx)("inlineCode",{parentName:"p"},"static"),", ",(0,n.mdx)("inlineCode",{parentName:"p"},"static_pic")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},"shared"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"linker_flags"),": The set of additional flags to pass to the linker.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"mapped_srcs"),": Add source files along with a local path mapping. Rust is sensitive to the layout of source files, as the directory structure follows the module structure. However this is awkward if the source file is, for example, generated by another rule. In this case, you can set up a mapping from the actual source path to something that makes sense locally. For example ",(0,n.mdx)("inlineCode",{parentName:"p"},'mapped_srcs = {":generate-module", "src/generated.rs" }'),". These are added to the regular ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),", so a file should not be listed in both.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"named_deps"),": Add crate dependencies and define a local name by which to use that dependency by. This allows a crate to have multiple dependencies with the same crate name. For example: ",(0,n.mdx)("inlineCode",{parentName:"p"},'named_deps = {"local_name", ":some_rust_crate" }'),". The dependencies may also be non-Rust, but the alias is ignored. It has no effect on the symbols provided by a C/C++ library.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"rpath"),': Set the "rpath" in the executable when using a shared link style.')),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"rustc_flags"),": The set of additional compiler flags to pass to ",(0,n.mdx)("inlineCode",{parentName:"p"},"rustc"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of Rust source files to be compiled by this rule."),(0,n.mdx)("p",{parentName:"li"},"One of the source files is the root module of the crate. By default this is ",(0,n.mdx)("inlineCode",{parentName:"p"},"lib.rs")," for libraries, ",(0,n.mdx)("inlineCode",{parentName:"p"},"main.rs")," for executables, or\nthe crate's name with ",(0,n.mdx)("inlineCode",{parentName:"p"},".rs")," appended. This can be overridden with the ",(0,n.mdx)("inlineCode",{parentName:"p"},"crate_root")," rule parameter."))),(0,n.mdx)("h4",{id:"details-73"},"Details"),(0,n.mdx)("p",null,"Note: Buck is currently tested with (and therefore supports) version 1.32.0 of Rust."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"For more examples, check out our ",(0,n.mdx)("a",{parentName:"p",href:"https://github.com/facebook/buck/tree/dev/test/com/facebook/buck/rust/testdata/"},"integration tests"),"."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\nrust_test(\n name='greet',\n srcs=[\n 'greet.rs',\n ],\n deps=[\n ':greeting',\n ],\n)\n\nrust_library(\n name='greeting',\n srcs=[\n 'greeting.rs',\n ],\n deps=[\n ':join',\n ],\n)\n\nrust_library(\n name='join',\n srcs=[\n 'join.rs',\n ],\n)\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"scala_library"},"scala","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def scala_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n java_version: None | str = _,\n javac: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n target: None | str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-126"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"scala_test"},"scala","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def scala_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _wip_java_plugin_arguments: dict[str, list[str]] = _,\n abi_generation_mode: None | str = _,\n annotation_processor_deps: list[str] = _,\n annotation_processor_params: list[str] = _,\n annotation_processors: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n cxx_library_whitelist: list[str] = _,\n default_cxx_platform: None | str = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n deps_query: None | str = _,\n env: dict[str, str] = _,\n exported_deps: list[str] = _,\n exported_provided_deps: list[str] = _,\n extra_arguments: list[str] = _,\n fork_mode: str = _,\n java_version: None | str = _,\n javac: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n manifest_file: None | str = _,\n maven_coords: None | str = _,\n never_mark_as_unused_dependency: None | bool = _,\n on_unused_dependencies: None | str = _,\n plugins: list[str] = _,\n proguard_config: None | str = _,\n provided_deps: list[str] = _,\n remove_classes: list[str] = _,\n required_for_source_only_abi: bool = _,\n resources: list[str] = _,\n resources_root: None | str = _,\n run_test_separately: bool = _,\n runtime_deps: list[str] = _,\n source: None | str = _,\n source_abi_verification_mode: None | str = _,\n source_only_abi_deps: list[str] = _,\n srcs: list[str] = _,\n std_err_log_level: None | int | str = _,\n std_out_log_level: None | int | str = _,\n target: None | str = _,\n test_case_timeout_ms: None | int = _,\n test_rule_timeout_ms: None | int = _,\n test_type: None | str = _,\n use_cxx_libraries: None | bool = _,\n use_dependency_order_classpath: None | bool = _,\n vm_args: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-127"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"scene_kit_assets"},"scene","_","kit","_","assets"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def scene_kit_assets(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n path: str\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-128"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"sh_binary"},"sh","_","binary"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def sh_binary(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _target_os_type: str = _,\n append_script_extension: bool = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n main: str,\n resources: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"An ",(0,n.mdx)("inlineCode",{parentName:"p"},"sh_binary()")," is used to execute a shell script."),(0,n.mdx)("h4",{id:"parameters-129"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"append_script_extension"),": By default, sh_binary ensures that the script has an appropriate extension (e.g. ",(0,n.mdx)("inlineCode",{parentName:"p"},".sh")," or ",(0,n.mdx)("inlineCode",{parentName:"p"},".bat"),"), appending one itself if necessary. Setting this to False prevents that behavior and makes the caller responsible for ensuring an existing appropriate extension.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"main"),": Either the path to the script (relative to the build file), or a ",(0,n.mdx)("inlineCode",{parentName:"p"},"build target"),". This file must be executable in order to be run.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"resources"),": A list of files or build rules that this rule requires in order to run. These could be things such as random data files."),(0,n.mdx)("p",{parentName:"li"},"When the script runs, the ",(0,n.mdx)("inlineCode",{parentName:"p"},"$BUCK_DEFAULT_RUNTIME_RESOURCES"),"\nenvironment variable specifies the directory that contains these resources.\nThis directory's location is determined entirely by Buck; the script should\nnot assume the directory's location."),(0,n.mdx)("p",{parentName:"li"},"The resources are also made available in a tree structure that mirrors\ntheir locations in the source and ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck-out")," trees. The\nenvironment variable ",(0,n.mdx)("inlineCode",{parentName:"p"},"$BUCK_PROJECT_ROOT")," specifies a directory\nthat contains all the resources, laid out in their locations relative to\nthe original buck project root."))),(0,n.mdx)("h4",{id:"details-74"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"This sh","_","binary() just cats a sample data file back at the user."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# $REPO/BUCK\nsh_binary(\n name = "script",\n main = "script.sh",\n resources = [\n "data.dat",\n ],\n)\n\n')),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n# Sample data file with data we need at runtime\n$ echo \"I'm a datafile\" > data.dat\n\n# Create a simple script that prints out the resource\n$ cat > script.sh\n#!/bin/sh\ncat $BUCK_DEFAULT_RUNTIME_RESOURCES/data.dat\n\n# Make sure the script is executable\n$ chmod u+x script.sh\n\n# Run the script, and see that it prints out the resource we provided\n$ buck run //:script\nJobs completed: 4. Time elapsed: 0.2s.\nBUILD SUCCEEDED\nI'm a datafile\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"sh_test"},"sh","_","test"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def sh_test(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _inject_test_env: str = _,\n _remote_test_execution_toolchain: str = _,\n args: list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n env: dict[str, str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n list_args: None | list[str] = _,\n list_env: None | dict[str, str] = _,\n remote_execution: None | str | dict[str, None | bool | int | str | list[dict[str, str]] | dict[str, str]] = _,\n remote_execution_action_key_providers: None | str = _,\n resources: list[str] = _,\n run_args: list[str] = _,\n run_env: dict[str, str] = _,\n run_test_separately: bool = _,\n test: None | str = _,\n test_rule_timeout_ms: None | int = _,\n type: None | str = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"sh_test()")," is a test rule that can pass results to the test runner by invoking a shell script."),(0,n.mdx)("h4",{id:"parameters-130"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"args"),": The list of arguments to invoke this script with. These are literal values, and no shell interpolation is done."),(0,n.mdx)("p",{parentName:"li"},"These can contain ",(0,n.mdx)("inlineCode",{parentName:"p"},"string parameter macros"),"\n, for example, to give the location of a generated binary to the test script.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"env"),": Environment variable overrides that should be used when running the script. The key is the variable name, and the value is its value."),(0,n.mdx)("p",{parentName:"li"},"The values can contain ",(0,n.mdx)("inlineCode",{parentName:"p"},"string parameter macros"),"\nsuch as the location of a generated binary to be used by the test script.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"test"),": Either the path to the script (relative to the build file), or a ",(0,n.mdx)("inlineCode",{parentName:"p"},"build target"),". This file must be executable in order to be run.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"type"),": If provided, this will be sent to any configured ",(0,n.mdx)("inlineCode",{parentName:"p"},".buckconfig")))),(0,n.mdx)("h4",{id:"details-75"},"Details"),(0,n.mdx)("p",null,(0,n.mdx)("strong",{parentName:"p"},"NOTE:")," This rule is not currently supported on Windows."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"This sh","_","test() fails if a string does not match a value."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# $REPO/BUCK\nsh_test(\n name = "script_pass",\n test = "script.sh",\n args = ["--pass"],\n)\n\nsh_test(\n name = "script_fail",\n test = "script.sh",\n args = ["--fail"],\n)\n\n\n')),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# Create a simple script that prints out the resource\n$ cat > script.sh\n#!/bin/sh\nfor arg in $@; do\n if [ "$arg" == "--pass" ]; then\n echo "Passed"\n exit 0;\n fi\ndone\necho "Failed"\nexit 1\n\n# Make sure the script is executable\n$ chmod u+x script.sh\n\n# Run the script, and see that one test passes, one fails\n$ buck test //:script_pass //:script_fail\nFAILURE script.sh sh_test\nBuilding: finished in 0.0 sec (100%) 2/2 jobs, 0 updated\n Total time: 0.0 sec\nTesting: finished in 0.0 sec (1 PASS/1 FAIL)\nRESULTS FOR //:script_fail //:script_pass\nFAIL <100ms 0 Passed 0 Skipped 1 Failed //:script_fail\nFAILURE script.sh sh_test\n====STANDARD OUT====\nFailed\n\nPASS <100ms 1 Passed 0 Skipped 0 Failed //:script_pass\nTESTS FAILED: 1 FAILURE\nFailed target: //:script_fail\nFAIL //:script_fail\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"supermodule_target_graph"},"supermodule","_","target","_","graph"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def supermodule_target_graph(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n label_pattern: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n on_duplicate_entry: str = _,\n out: str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-131"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"swift_library"},"swift","_","library"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def swift_library(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n bridging_header: None | str = _,\n buck2_compatibility: str = _,\n compiler_flags: list[str] = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n deps: list[str] = _,\n enable_cxx_interop: bool = _,\n frameworks: list[str] = _,\n import_obj_c_forward_declarations: bool = _,\n labels: list[str] = _,\n libraries: list[str] = _,\n licenses: list[str] = _,\n module_name: None | str = _,\n preferred_linkage: str = _,\n sdk_modules: list[str] = _,\n serialize_debugging_options: bool = _,\n soname: None | str = _,\n srcs: list[str] = _,\n supported_platforms_regex: None | str = _,\n target_sdk_version: None | str = _,\n uses_explicit_modules: bool = _,\n version: None | str = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-132"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"swift_toolchain"},"swift","_","toolchain"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def swift_toolchain(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _internal_platform_path: None | str = _,\n _internal_sdk_path: None | str = _,\n _swiftc_wrapper: str = _,\n architecture: None | str = _,\n buck2_compatibility: str = _,\n can_toolchain_emit_obj_c_header_textually: bool = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n explicit_modules_uses_gmodules: bool = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n make_swift_comp_db: str = _,\n make_swift_interface: str = _,\n object_format: str = _,\n placeholder_tool: None | str = _,\n platform_path: None | str = _,\n prefix_serialized_debug_info: bool = _,\n resource_dir: None | str = _,\n runtime_paths_for_bundling: list[str] = _,\n runtime_paths_for_linking: list[str] = _,\n runtime_run_paths: list[str] = _,\n sdk_dependencies_path: None | str = _,\n sdk_modules: list[str] = _,\n sdk_path: None | str = _,\n static_runtime_paths: list[str] = _,\n supports_cxx_interop_requirement_at_import: bool = _,\n supports_relative_resource_dir: bool = _,\n supports_swift_cxx_interoperability_mode: bool = _,\n supports_swift_importing_obj_c_forward_declarations: bool = _,\n swift_ide_test_tool: None | str = _,\n swift_stdlib_tool: str,\n swift_stdlib_tool_flags: list[str] = _,\n swiftc: str,\n swiftc_flags: list[str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-133"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"test_suite"},"test","_","suite"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def test_suite(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n test_deps: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"test_suite()")," is used to create a grouping of tests that should all be run by just testing this rule."),(0,n.mdx)("h4",{id:"parameters-134"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("h4",{id:"details-76"},"Details"),(0,n.mdx)("p",null,"This rule can then be given to ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck test"),", and all tests that it depends on will be invoked.\nNote that the test","_","suite() target is not tested itself, it just tells buck to run other\ntests. It will not show up in calls to the external runner nor in the normal test output."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"This test","_","suite() sets up two different sets of tests to run, 'all' tests and 'slow' tests. Note that ",(0,n.mdx)("inlineCode",{parentName:"p"},"all_tests")," can depend on ",(0,n.mdx)("inlineCode",{parentName:"p"},"slow_tests"),", and all three tests are run."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# instrumentation_tests/BUCK:\nsh_test(\n name = "instrumentation_tests",\n test = "instrumentation_tests.sh",\n visibility = ["PUBLIC"],\n)\n\n# integration_tests/BUCK:\nsh_test(\n name = "integration_tests",\n test = "integration_tests.sh",\n visibility = ["PUBLIC"],\n)\n\n# unit_tests/BUCK:\nsh_test(\n name = "unit_tests",\n test = "unit_tests.sh",\n visibility = ["PUBLIC"],\n)\n\n# BUCK:\ntest_suite(\n name = "slow_tests",\n tests = [\n "//instrumentation_tests:instrumentation_tests",\n "//integration_tests:integration_tests",\n ],\n)\n\ntest_suite(\n name = "all_tests",\n tests = [\n ":slow_tests",\n "//unit_tests:unit_tests",\n ],\n)\n\n')),(0,n.mdx)("p",null,"Yields output like this when run:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n$ buck test //:slow_tests\n...\nRESULTS FOR //instrumentation_tests:instrumentation_tests //integration_tests:integration_tests\nPASS <100ms 1 Passed 0 Skipped 0 Failed //instrumentation_tests:instrumentation_tests\nPASS <100ms 1 Passed 0 Skipped 0 Failed //integration_tests:integration_tests\nTESTS PASSED\n...\n\n$ buck test //:all_tests\nRESULTS FOR //instrumentation_tests:instrumentation_tests //integration_tests:integration_tests //unit_tests:unit_tests\nPASS <100ms 1 Passed 0 Skipped 0 Failed //instrumentation_tests:instrumentation_tests\nPASS <100ms 1 Passed 0 Skipped 0 Failed //integration_tests:integration_tests\nPASS <100ms 1 Passed 0 Skipped 0 Failed //unit_tests:unit_tests\nTESTS PASSED\n\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"toolchain_alias"},"toolchain","_","alias"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def toolchain_alias(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n actual: str,\n buck2_compatibility: str = _\n) -> None\n")),(0,n.mdx)("p",null,"toolchain_alias acts like alias but for toolchain rules."),(0,n.mdx)("h4",{id:"parameters-135"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"actual"),": The actual toolchain that is being aliased. This should be a toolchain rule.")),(0,n.mdx)("h4",{id:"details-77"},"Details"),(0,n.mdx)("p",null,"The toolchain_alias itself is a toolchain rule and the ",(0,n.mdx)("inlineCode",{parentName:"p"},"actual")," argument is\nexpected to be a toolchain_rule as well."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"versioned_alias"},"versioned","_","alias"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def versioned_alias(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n versions: dict[str, str] = _\n) -> None\n")),(0,n.mdx)("h4",{id:"parameters-136"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"windows_resource"},"windows","_","resource"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def windows_resource(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _cxx_toolchain: str = _,\n buck2_compatibility: str = _,\n header_namespace: None | str = _,\n headers: list[str] | dict[str, str] = _,\n include_directories: list[str] = _,\n labels: list[str] = _,\n platform_headers: list[(str, list[str] | dict[str, str])] = _,\n raw_headers: list[str] = _,\n srcs: list[str | (str, list[str])] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"windows_resource()")," rule specifies a set of Window's Resource File (.rc) that are compiled into object files."),(0,n.mdx)("h4",{id:"parameters-137"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace"),": A path prefix when including headers of this target. Defaults to the path from the root of the repository to the directory where this target is defined. Can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"), but cannot start with one. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"headers"),": The set of header files that are made available for inclusion to the source files in this target. These should be specified as either a list of header files or a dictionary of header names to header files. The header name can contain forward slashes (",(0,n.mdx)("inlineCode",{parentName:"li"},"/"),"). The headers can be included with ",(0,n.mdx)("inlineCode",{parentName:"li"},'#include "$HEADER_NAMESPACE/$HEADER_NAME"')," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"#include <$HEADER_NAMESPACE/$HEADER_NAME>")," , where ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAMESPACE")," is the value of the target's ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," attribute, and ",(0,n.mdx)("inlineCode",{parentName:"li"},"$HEADER_NAME")," is the header name if specified, and the filename of the header file otherwise. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"header_namespace")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"include_directories"),": A list of include directories (with ",(0,n.mdx)("inlineCode",{parentName:"li"},"raw_headers"),") to be added to the compile command for compiling this target (via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-I"),"). An include directory is relative to the current package."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"platform_headers"),": Platform specific header files. These should be specified as a list of pairs where the first element is an un-anchored regex (in java.util.regex.Pattern syntax) against which the platform name is matched, and the second element is either a list of header files or a dictionary of header names to header files that will be made available for inclusion to the source files in the target if the platform matches the regex. See ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," for more information."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"raw_headers"),": The set of header files that can be used for inclusion to the source files in the target and all targets that transitively depend on it. Buck doesn't add raw headers to the search path of a compiler/preprocessor automatically. ",(0,n.mdx)("inlineCode",{parentName:"li"},"include_directories")," and ",(0,n.mdx)("inlineCode",{parentName:"li"},"public_include_directories")," are the recommended way to add raw headers to the search path (they will be added via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-I"),"). ",(0,n.mdx)("inlineCode",{parentName:"li"},"compiler_flags"),", ",(0,n.mdx)("inlineCode",{parentName:"li"},"preprocessor_flags")," and ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_preprocessor_flags")," can also be used to add such raw headers to the search path if inclusion via ",(0,n.mdx)("inlineCode",{parentName:"li"},"-isystem")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"-iquote")," is needed. ",(0,n.mdx)("inlineCode",{parentName:"li"},"raw_headers")," cannot be used together with ",(0,n.mdx)("inlineCode",{parentName:"li"},"headers")," or ",(0,n.mdx)("inlineCode",{parentName:"li"},"exported_headers")," in the same target."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"srcs"),": The set of C, C++, Objective-C, Objective-C++, or assembly source files to be preprocessed, compiled, and assembled by this rule. We determine which stages to run on each input source based on its file extension. See the ",(0,n.mdx)("a",{parentName:"li",href:"https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html"},"GCC documentation")," for more detail on how file extensions are interpreted. Each element can be either a string specifying a source file (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"''"),") or a tuple of a string specifying a source file and a list of compilation flags (e.g. ",(0,n.mdx)("inlineCode",{parentName:"li"},"('', ['-Wall', '-Werror'])")," ). In the latter case the specified flags will be used in addition to the rule's other flags when preprocessing and compiling that file (if applicable).")),(0,n.mdx)("h4",{id:"details-78"},"Details"),(0,n.mdx)("p",null,"The files are compiled into .res files using rc.exe and then compiled into object files\nusing cvtres.exe.\nThey are not part of cxx_library because Microsoft's linker ignores the resources\nunless they are specified as an object file, meaning including them in a possibly static\nlibrary is unintuitive."),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n# A rule that includes a single .rc file and compiles it into an object file.\nwindows_resource(\n name = "resources",\n srcs = [\n "resources.rc",\n ],\n)\n\n# A rule that links against the above windows_resource rule.\ncxx_binary(\n name = "app",\n srcs = [\n "main.cpp",\n ],\n deps = [\n ":resources"\n ],\n)\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"worker_tool"},"worker","_","tool"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def worker_tool(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _worker_tool_runner: str = _,\n args: str | list[str] = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n env: dict[str, str] = _,\n exe: None | str = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n max_workers: None | int = _,\n max_workers_per_thread_percent: None | int = _,\n persistent: None | bool = _\n) -> None\n")),(0,n.mdx)("p",null,"Some external tools have high startup costs. To amortize those costs over the whole build rather than paying them for each rule invocation, use the ",(0,n.mdx)("inlineCode",{parentName:"p"},"worker_tool()")," rule in conjunction with ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule()"),". Buck then starts the external tool once and reuses it by communicating with it over ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdin")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdout")," using a simple JSON protocol."),(0,n.mdx)("h4",{id:"parameters-138"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"name"),": name of the target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"within_view"),": a list of visibility patterns restricting what this target can depend on"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"metadata"),": a key-value map of metadata associated with this target"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"tests"),": a list of targets that provide tests for this one"),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"args"),": A string of args that is passed to the executable represented by ",(0,n.mdx)("inlineCode",{parentName:"li"},"exe")," on initial startup."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"env"),": A map of environment variables that is passed to the executable represented by ",(0,n.mdx)("inlineCode",{parentName:"li"},"exe")," on initial startup."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"exe"),": A ",(0,n.mdx)("inlineCode",{parentName:"li"},"build target"),"for a rule that outputs an executable, such as an ",(0,n.mdx)("inlineCode",{parentName:"li"},"sh\\_binary()"),". Buck runs this executable only once per build."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"max_workers"),": The maximum number of workers of this type that Buck starts. Use ",(0,n.mdx)("inlineCode",{parentName:"li"},"-1")," to allow the creation of as many workers as necessary."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"max_workers_per_thread_percent"),": The maximum ratio of workers of this type that Buck starts per thread, specified as a positive integer percentage (1-100). Must be greater than or equal to ",(0,n.mdx)("inlineCode",{parentName:"li"},"1")," and less than or equal to ",(0,n.mdx)("inlineCode",{parentName:"li"},"100"),". Only one of ",(0,n.mdx)("inlineCode",{parentName:"li"},"max_workers")," and ",(0,n.mdx)("inlineCode",{parentName:"li"},"max_workers_per_thread_percent")," may be specified."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"persistent"),": If set to true, Buck does not restart the tool unless the tool itself changes. This means the tool persists across multiple Buck commands without being shut down and may see the same rule being built more than once. Be careful not to use this setting with tools that don't expect to process the same input\u2014with different contents\u2014twice!")),(0,n.mdx)("h4",{id:"details-79"},"Details"),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"worker_tool")," rule can be referenced in the ",(0,n.mdx)("inlineCode",{parentName:"p"},"cmd")," parameter of\na ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule")," by using the macro:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n\n$(exe //path/to:target)\n\n")),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"Consider the following ",(0,n.mdx)("inlineCode",{parentName:"p"},"build rules"),":"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n#\n# Buck\n#\nworker_tool(\n name = 'ExternalToolWorker',\n exe = ':ExternalTool',\n args = '--arg1 --arg2'\n)\n\nsh_binary(\n name = 'ExternalTool',\n main = 'external_tool.sh',\n)\n\ngenrule(\n name = 'TransformA',\n out = 'OutputA.txt',\n cmd = '$(exe :ExternalToolWorker) argA',\n)\n\ngenrule(\n name = 'TransformB',\n out = 'OutputB.txt',\n cmd = '$(exe :ExternalToolWorker) argB',\n)\n\ngenrule(\n name = 'TransformC',\n out = 'OutputC.txt',\n cmd = '$(exe :ExternalToolWorker) argC',\n)\n")),(0,n.mdx)("p",null," When doing a ",(0,n.mdx)("inlineCode",{parentName:"p"},"buck build")," on all three of the above ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrules"),", Buck\nfirst creates the worker process by invoking:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n\n./external_tool.sh --arg1 --arg2\n\n")),(0,n.mdx)("p",null," Buck then communicates with this process using JSON over ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdin"),",\nstarting with a handshake:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n[\n {\n "id": 0,\n "type": "handshake",\n "protocol_version": "0",\n "capabilities": []\n }\n\n')),(0,n.mdx)("p",null," Buck then waits for the tool to reply on ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdout"),":"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n[\n {\n "id": 0,\n "type": "handshake",\n "protocol_version": "0",\n "capabilities": []\n }\n\n')),(0,n.mdx)("p",null," Then, when building the first ",(0,n.mdx)("inlineCode",{parentName:"p"},"genrule"),", Buck writes to ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdin"),":"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n ,{\n "id": 1,\n "type": "command",\n "args_path": "/tmp/1.args",\n "stdout_path": "/tmp/1.out",\n "stderr_path": "/tmp/1.err"\n }\n\n')),(0,n.mdx)("p",null," The file ",(0,n.mdx)("inlineCode",{parentName:"p"},"/tmp/1.args")," contains ",(0,n.mdx)("inlineCode",{parentName:"p"},"argA"),". The tool should\nperform the necessary work for this job and then write the job's output to the files\nsupplied by Buck\u2014in this case, ",(0,n.mdx)("inlineCode",{parentName:"p"},"/tmp/1.out")," and ",(0,n.mdx)("inlineCode",{parentName:"p"},"/tmp/1.err"),".\nOnce the job is done, the tool should reply to Buck on ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdout")," with:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n ,{\n "id": 1,\n "type": "result",\n "exit_code": 0\n }\n\n')),(0,n.mdx)("p",null," Once Buck hears back from the first genrule's job, it submits the second genrule's job in the\nsame fashion and awaits the response. When the build is all finished,\nBuck closes the JSON by writing to ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdin"),":"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n]\n\n")),(0,n.mdx)("p",null," which signals the tool that it should exit after replying on ",(0,n.mdx)("inlineCode",{parentName:"p"},"stdout")," with:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n]\n\n")),(0,n.mdx)("p",null," In this example, Buck is guaranteed to invoke"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\n\n./external_tool.sh --arg1 --arg2\n\n")),(0,n.mdx)("p",null," only once during the build. The three jobs corresponding to the three genrules are submitted\nsynchronously to the single worker process."),(0,n.mdx)("p",null," Note that the ",(0,n.mdx)("inlineCode",{parentName:"p"},"id")," values in the messages are not necessarily increasing or sequential,\nbut they do have to match between the request message and the response message of a given job as\nwell as in the initial handshake."),(0,n.mdx)("p",null," If the tool receives a message type it cannot interpret it should answer with:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n{\n "id": <n>,\n "type": "error",\n "exit_code": 1\n}\n\n')),(0,n.mdx)("p",null," If the tool receives a message type it can interpret, but the other attributes of the\nmessage are in an inconsistent state, it should answer with:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\n{\n "id": <n>,\n "type": "error",\n "exit_code": 2\n}\n\n')),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"zip_file"},"zip","_","file"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def zip_file(\n *,\n name: str,\n default_target_platform: None | str = _,\n target_compatible_with: list[str] = _,\n compatible_with: list[str] = _,\n exec_compatible_with: list[str] = _,\n visibility: list[str] = _,\n within_view: list[str] = _,\n metadata: opaque_metadata = _,\n tests: list[str] = _,\n _apple_platforms: dict[str, str] = _,\n _zip_file_toolchain: str = _,\n buck2_compatibility: str = _,\n contacts: list[str] = _,\n default_host_platform: None | str = _,\n entries_to_exclude: list[str] = _,\n labels: list[str] = _,\n licenses: list[str] = _,\n on_duplicate_entry: str = _,\n out: str = _,\n srcs: list[str] = _,\n zip_srcs: list[str] = _\n) -> None\n")),(0,n.mdx)("p",null,"A ",(0,n.mdx)("inlineCode",{parentName:"p"},"zip_file()")," allows builds to create basic zip files in a platform-agnostic way."),(0,n.mdx)("h4",{id:"parameters-139"},"Parameters"),(0,n.mdx)("ul",null,(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"name"),": name of the target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"default_target_platform"),": specifies the default target platform, used when no platforms are specified on the command line")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"target_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with a configuration")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"exec_compatible_with"),": a list of constraints that are required to be satisfied for this target to be compatible with an execution platform")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"visibility"),": a list of visibility patterns restricting what targets can depend on this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"within_view"),": a list of visibility patterns restricting what this target can depend on")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"metadata"),": a key-value map of metadata associated with this target")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"tests"),": a list of targets that provide tests for this one")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"entries_to_exclude"),": List of regex expressions that describe entries that should not be included in the output zip file."),(0,n.mdx)("p",{parentName:"li"},"The regexes must be defined using ",(0,n.mdx)("inlineCode",{parentName:"p"},"java.util.regex.Pattern")," syntax.")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"on_duplicate_entry"),": Action performed when Buck detects that zip","_","file input contains multiple entries with the same name."),(0,n.mdx)("p",{parentName:"li"},"The valid values are:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"overwrite")," (default): the last entry overwrites all previous entries with\nthe same name."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"append"),": all entries are added to the output file."),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("inlineCode",{parentName:"li"},"fail"),": fail the build when duplicate entries are present."))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"out"),": The name of the zip file that should be generated. This allows builds to use a meaningful target name coupled with a meaningful zip file name. The default value takes the rule's ",(0,n.mdx)("inlineCode",{parentName:"p"},"name")," and appends ",(0,n.mdx)("inlineCode",{parentName:"p"},".zip"),".")),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),": The set of files to include in the zip."),(0,n.mdx)("p",{parentName:"li"},"Each ",(0,n.mdx)("inlineCode",{parentName:"p"},"src")," will be added to the zip as follows:"),(0,n.mdx)("ul",{parentName:"li"},(0,n.mdx)("li",{parentName:"ul"},"If the ",(0,n.mdx)("inlineCode",{parentName:"li"},"src")," is the output of another rule, the output\nwill be included using just the output's file name."),(0,n.mdx)("li",{parentName:"ul"},"If the ",(0,n.mdx)("inlineCode",{parentName:"li"},"src")," is a file relative to the rule's\ndeclaration, it will be included in the zip with its relative file\nname."))),(0,n.mdx)("li",{parentName:"ul"},(0,n.mdx)("p",{parentName:"li"},(0,n.mdx)("inlineCode",{parentName:"p"},"zip_srcs"),": The set of zip files whose content to include in the output zip file."),(0,n.mdx)("p",{parentName:"li"},"Note that the order of files in ",(0,n.mdx)("inlineCode",{parentName:"p"},"zip_srcs")," matters because the same zip entry can be\nincluded from multiple files. See the ",(0,n.mdx)("inlineCode",{parentName:"p"},"on_duplicate_entry")," argument to learn how to\ncontrol the behavior when there are multiple entries with the same name."),(0,n.mdx)("p",{parentName:"li"},"The entries from ",(0,n.mdx)("inlineCode",{parentName:"p"},"zip_srcs")," are added before files from ",(0,n.mdx)("inlineCode",{parentName:"p"},"srcs"),"."))),(0,n.mdx)("h4",{id:"details-80"},"Details"),(0,n.mdx)("p",null,"Examples:"),(0,n.mdx)("p",null,"This example will create a simple zip file."),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},'\nzip_file(\n # The output will be "example.zip"\n name = \'example\',\n srcs =\n # These files will be found in the zip under "dir/"\n glob([\'dir/**/*\']) +\n [\n # Imagine this generates the output\n # "buck-out/gen/foo/hello.txt". This output will\n # be found in the zip at "hello.txt"\n \'//some/other:target\',\n\n ],\n zip_srcs = [\n # The contents of this zip will be added to the generated zip.\n \'amazing-library-1.0-sources.zip\',\n ],\n entries_to_exclude = [\n "com/example/amazinglibrary/Source1.java",\n ],\n)\n\n')),(0,n.mdx)("p",null,'If you were to examine the generated zip, the contents would look\nsomething like (assuming the output of\n"',(0,n.mdx)("inlineCode",{parentName:"p"},"//some/other:target"),"\" was a file who's path ended with\n",(0,n.mdx)("inlineCode",{parentName:"p"},"hello.txt"),', the "',(0,n.mdx)("inlineCode",{parentName:"p"},"dir"),'" glob found two files,\nand "',(0,n.mdx)("inlineCode",{parentName:"p"},"amazing-library-1.0-sources.zip"),'" contained two Java\nsource files):'),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre"},"\ndir/file1.txt\ndir/subdir/file2.txt\nhello.txt\ncom/example/amazinglibrary/Source2.java\n\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0c924533.3456926a.js b/assets/js/0c924533.3456926a.js new file mode 100644 index 000000000000..e63e8d82bb62 --- /dev/null +++ b/assets/js/0c924533.3456926a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[893],{3905:(e,t,r)=>{r.r(t),r.d(t,{MDXContext:()=>g,MDXProvider:()=>p,mdx:()=>m,useMDXComponents:()=>d,withMDXComponents:()=>u});var a=r(67294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(){return l=Object.assign||function(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var g=a.createContext({}),u=function(e){return function(t){var r=d(t.components);return a.createElement(e,l({},t,{components:r}))}},d=function(e){var t=a.useContext(g),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=d(e.components);return a.createElement(g.Provider,{value:t},e.children)},_="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},b=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,l=e.originalType,o=e.parentName,g=c(e,["components","mdxType","originalType","parentName"]),u=d(r),p=n,_=u["".concat(o,".").concat(p)]||u[p]||f[p]||l;return r?a.createElement(_,i(i({ref:t},g),{},{components:r})):a.createElement(_,i({ref:t},g))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var l=r.length,o=new Array(l);o[0]=b;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[_]="string"==typeof e?e:n,o[1]=i;for(var g=2;g{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>l,metadata:()=>i,toc:()=>g});var a=r(87462),n=(r(67294),r(3905));const l={id:"configured_target_label"},o="configured_target_label type",i={unversionedId:"api/bxl/configured_target_label",id:"api/bxl/configured_target_label",title:"configured_target_label type",description:"configured\\target\\label.cell",source:"@site/../docs/api/bxl/configured_target_label.generated.md",sourceDirName:"api/bxl",slug:"/api/bxl/configured_target_label",permalink:"/docs/api/bxl/configured_target_label",draft:!1,tags:[],version:"current",frontMatter:{id:"configured_target_label"},sidebar:"manualSidebar",previous:{title:"configured_attr type",permalink:"/docs/api/bxl/configured_attr"},next:{title:"context type",permalink:"/docs/api/bxl/context"}},c={},g=[{value:"configured_target_label.cell",id:"configured_target_labelcell",level:2},{value:"configured_target_label.config",id:"configured_target_labelconfig",level:2},{value:"configured_target_label.name",id:"configured_target_labelname",level:2},{value:"configured_target_label.package",id:"configured_target_labelpackage",level:2},{value:"configured_target_label.path",id:"configured_target_labelpath",level:2},{value:"configured_target_label.raw_target",id:"configured_target_labelraw_target",level:2},{value:"configured_target_label.with_sub_target",id:"configured_target_labelwith_sub_target",level:2}],u={toc:g};function d(e){let{components:t,...r}=e;return(0,n.mdx)("wrapper",(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,n.mdx)("h1",{id:"configured_target_label-type"},(0,n.mdx)("inlineCode",{parentName:"h1"},"configured_target_label")," type"),(0,n.mdx)("h2",{id:"configured_target_labelcell"},"configured","_","target","_","label.cell"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"configured_target_label.cell: str\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configured_target_labelconfig"},"configured","_","target","_","label.config"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def configured_target_label.config() -> configuration\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configured_target_labelname"},"configured","_","target","_","label.name"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"configured_target_label.name: str\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configured_target_labelpackage"},"configured","_","target","_","label.package"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"configured_target_label.package: str\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configured_target_labelpath"},"configured","_","target","_","label.path"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"configured_target_label.path: typing.Any\n")),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configured_target_labelraw_target"},"configured","_","target","_","label.raw","_","target"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def configured_target_label.raw_target() -> target_label\n")),(0,n.mdx)("p",null,"Returns the unconfigured underlying target label."),(0,n.mdx)("hr",null),(0,n.mdx)("h2",{id:"configured_target_labelwith_sub_target"},"configured","_","target","_","label.with","_","sub","_","target"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-python"},"def configured_target_label.with_sub_target(subtarget_name = []) -> label\n")),(0,n.mdx)("p",null,"Converts a ",(0,n.mdx)("inlineCode",{parentName:"p"},"ConfiguredTargetLabel")," into its corresponding ",(0,n.mdx)("inlineCode",{parentName:"p"},"Label")," given the subtarget name which is a list for each layer of subtarget"),(0,n.mdx)("p",null,"Sample usage:"),(0,n.mdx)("pre",null,(0,n.mdx)("code",{parentName:"pre",className:"language-text"},'def _impl_sub_target(ctx):\n owners = ctx.cquery().owner("bin/TARGETS.fixture")\n for owner in owners:\n configured_label = owner.label\n ctx.output.print(configured_label.with_sub_target())\n ctx.output.print(configured_label.with_sub_target("subtarget1"))\n ctx.output.print(configured_label.with_sub_target(["subtarget1", "subtarget2"]))\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0f079156.aaf18b45.js b/assets/js/0f079156.aaf18b45.js new file mode 100644 index 000000000000..a99306999c9a --- /dev/null +++ b/assets/js/0f079156.aaf18b45.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3674],{3905:(e,t,r)=>{r.r(t),r.d(t,{MDXContext:()=>i,MDXProvider:()=>u,mdx:()=>y,useMDXComponents:()=>l,withMDXComponents:()=>p});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),p=function(e){return function(t){var r=l(t.components);return n.createElement(e,a({},t,{components:r}))}},l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},v=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,i=f(e,["components","mdxType","originalType","parentName"]),p=l(r),u=o,m=p["".concat(c,".").concat(u)]||p[u]||d[u]||a;return r?n.createElement(m,s(s({ref:t},i),{},{components:r})):n.createElement(m,s({ref:t},i))}));function y(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=v;var s={};for(var f in t)hasOwnProperty.call(t,f)&&(s[f]=t[f]);s.originalType=e,s[m]="string"==typeof e?e:o,c[1]=s;for(var i=2;i{r.r(t),r.d(t,{assets:()=>f,contentTitle:()=>c,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>i});var n=r(87462),o=(r(67294),r(3905));const a={},c="RFC: TestInfo v2",s={unversionedId:"rfcs/drafts/test-info-v2",id:"rfcs/drafts/test-info-v2",title:"RFC: TestInfo v2",description:"A stub RFC for TestInfo v2 to track lessons learned about TestInfo v1. The stack",source:"@site/../docs/rfcs/drafts/test-info-v2.md",sourceDirName:"rfcs/drafts",slug:"/rfcs/drafts/test-info-v2",permalink:"/docs/rfcs/drafts/test-info-v2",draft:!1,tags:[],version:"current",frontMatter:{}},f={},i=[],p={toc:i};function l(e){let{components:t,...r}=e;return(0,o.mdx)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.mdx)("h1",{id:"rfc-testinfo-v2"},"RFC: TestInfo v2"),(0,o.mdx)("p",null,"A stub RFC for TestInfo v2 to track lessons learned about TestInfo v1. The stack\nstarting ",(0,o.mdx)("a",{parentName:"p",href:"https://internalfb.com/D36339960"},"D36339960")," contains the original code for the TestInfo and templated\ntest API experiment."))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0fa06060.3ae2e4a4.js b/assets/js/0fa06060.3ae2e4a4.js new file mode 100644 index 000000000000..851705a49490 --- /dev/null +++ b/assets/js/0fa06060.3ae2e4a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7778],{3905:(e,a,n)=>{n.r(a),n.d(a,{MDXContext:()=>d,MDXProvider:()=>c,mdx:()=>x,useMDXComponents:()=>p,withMDXComponents:()=>u});var t=n(67294);function i(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function r(){return r=Object.assign||function(e){for(var a=1;a=0||(i[n]=e[n]);return i}(e,a);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var d=t.createContext({}),u=function(e){return function(a){var n=p(a.components);return t.createElement(e,r({},a,{components:n}))}},p=function(e){var a=t.useContext(d),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},c=function(e){var a=p(e.components);return t.createElement(d.Provider,{value:a},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},f=t.forwardRef((function(e,a){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=p(n),c=i,m=u["".concat(l,".").concat(c)]||u[c]||h[c]||r;return n?t.createElement(m,o(o({ref:a},d),{},{components:n})):t.createElement(m,o({ref:a},d))}));function x(e,a){var n=arguments,i=a&&a.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=f;var o={};for(var s in a)hasOwnProperty.call(a,s)&&(o[s]=a[s]);o.originalType=e,o[m]="string"==typeof e?e:i,l[1]=o;for(var d=2;d{n.r(a),n.d(a,{assets:()=>s,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var t=n(87462),i=(n(67294),n(3905));const r={id:"build_rule",title:"Build Rule"},l="Build Rule",o={unversionedId:"concepts/build_rule",id:"concepts/build_rule",title:"Build Rule",description:"A build rule is a procedure for producing output files from a set of input",source:"@site/../docs/concepts/build_rule.md",sourceDirName:"concepts",slug:"/concepts/build_rule",permalink:"/docs/concepts/build_rule",draft:!1,tags:[],version:"current",frontMatter:{id:"build_rule",title:"Build Rule"},sidebar:"manualSidebar",previous:{title:"Concept Map",permalink:"/docs/concepts/concept_map"},next:{title:"Build File",permalink:"/docs/concepts/build_file"}},s={},d=[{value:"Buck2's collection of build rules",id:"buck2s-collection-of-build-rules",level:2},{value:"Source files as inputs to build rules",id:"source-files-as-inputs-to-build-rules",level:2},{value:"Package boundaries and access to source files",id:"package-boundaries-and-access-to-source-files",level:3},{value:"Symlinks: Use with caution if at all",id:"symlinks-use-with-caution-if-at-all",level:5},{value:"Dependencies: Output from one rule as input to another rule",id:"dependencies-output-from-one-rule-as-input-to-another-rule",level:2},{value:"Required dependencies are always built first",id:"required-dependencies-are-always-built-first",level:3},{value:"Visibility",id:"visibility",level:3},{value:"Dependencies define a graph",id:"dependencies-define-a-graph",level:3},{value:"How to handle special cases: genrules and macros",id:"how-to-handle-special-cases-genrules-and-macros",level:2},{value:"Multiple output files with genrules",id:"multiple-output-files-with-genrules",level:3},{value:"Macros",id:"macros",level:3},{value:"String parameter macros",id:"string-parameter-macros",level:2}],u={toc:d};function p(e){let{components:a,...n}=e;return(0,i.mdx)("wrapper",(0,t.Z)({},u,n,{components:a,mdxType:"MDXLayout"}),(0,i.mdx)("h1",{id:"build-rule"},"Build Rule"),(0,i.mdx)("p",null,"A ",(0,i.mdx)("em",{parentName:"p"},"build rule")," is a procedure for producing output files from a set of input\nfiles in the context of a specified build configuration. Build rules are\nspecified in ",(0,i.mdx)("a",{parentName:"p",href:"/docs/concepts/build_file"},"build file"),"s\u2014typically named BUCK. ",(0,i.mdx)("strong",{parentName:"p"},"Note:")," A\nbuild rule must explicitly specify, in its arguments, all of its required inputs\nin order for Buck2 to be able to build the rule's output in a way that is\ndeterministic and reproducible."),(0,i.mdx)("h2",{id:"buck2s-collection-of-build-rules"},"Buck2's collection of build rules"),(0,i.mdx)("p",null,"Buck2 comes with a collection of built-in build rules for many common build\nprocedures. For example, compiling Java code against the Android SDK is a common\nprocedure, so Buck2 provides the build rule\n",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#android_library"},(0,i.mdx)("inlineCode",{parentName:"a"},"android_library"))," to do that. Similarly, the\nfinal product of most Android development is an APK, so you can use the build\nrule ",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#android_binary"},(0,i.mdx)("inlineCode",{parentName:"a"},"android_binary"))," to create an APK."),(0,i.mdx)("h2",{id:"source-files-as-inputs-to-build-rules"},"Source files as inputs to build rules"),(0,i.mdx)("p",null,"Most build rules specify source files as inputs. For example, a\n",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#cxx_library"},(0,i.mdx)("inlineCode",{parentName:"a"},"cxx_library"))," rule would specify ",(0,i.mdx)("inlineCode",{parentName:"p"},".cpp")," files as\ninputs. To support specifying these files, a ",(0,i.mdx)("inlineCode",{parentName:"p"},"cxx_library")," rule provides the\n",(0,i.mdx)("inlineCode",{parentName:"p"},"srcs")," argument. Some languages, such as C++, use header files as well. To\nspecify these, ",(0,i.mdx)("inlineCode",{parentName:"p"},"cxx_library")," provides a ",(0,i.mdx)("inlineCode",{parentName:"p"},"headers")," argument. In addition to\n",(0,i.mdx)("inlineCode",{parentName:"p"},"srcs")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"headers"),", some rules provide variants of these arguments, such as\n",(0,i.mdx)("inlineCode",{parentName:"p"},"platform_srcs")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"platform_headers"),". These arguments support groups of source\nfiles that should be used as inputs only when building for specific platforms."),(0,i.mdx)("h3",{id:"package-boundaries-and-access-to-source-files"},"Package boundaries and access to source files"),(0,i.mdx)("p",null,"In Buck2, a BUCK file defines a ",(0,i.mdx)("em",{parentName:"p"},"package"),", which corresponds ",(0,i.mdx)("em",{parentName:"p"},"roughly")," to the\ndirectory that contains the BUCK file and those subdirectories that do not\nthemselves contain BUCK files. (To learn more, see the\n",(0,i.mdx)("a",{parentName:"p",href:"/docs/concepts/key_concepts"},"Key Concepts")," topic.) A rule in a BUCK file cannot specify a\nsource file as an input unless that source file is in that BUCK file's package.\nAn exception to this restriction exists for header files, but only if a rule in\nthe package that contains the header file ",(0,i.mdx)("em",{parentName:"p"},"exports")," that header file using the\n",(0,i.mdx)("inlineCode",{parentName:"p"},"exported_headers")," argument. For more details, see the description for\n",(0,i.mdx)("inlineCode",{parentName:"p"},"exported_headers")," in, for example, the\n",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#cxx_library"},(0,i.mdx)("inlineCode",{parentName:"a"},"cxx_library"))," topic. More commonly though, the\npackage for a BUCK file contains all the source files required for the rules\ndefined in that BUCK file. Functionality in source files from other packages is\nmade available through the artifacts produced by the rules in the BUCK files for\nthose packages. For example, a ",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#cxx_binary"},(0,i.mdx)("inlineCode",{parentName:"a"},"cxx_binary"))," might\nuse the functionality in a ",(0,i.mdx)("inlineCode",{parentName:"p"},"cxx_library")," that is defined in another package. To\naccess that functionality, the ",(0,i.mdx)("inlineCode",{parentName:"p"},"cxx_binary")," would take that ",(0,i.mdx)("inlineCode",{parentName:"p"},"cxx_library")," as a\n",(0,i.mdx)("em",{parentName:"p"},"dependency"),"."),(0,i.mdx)("h5",{id:"symlinks-use-with-caution-if-at-all"},"Symlinks: Use with caution if at all"),(0,i.mdx)("p",null,"We recommend that you do ",(0,i.mdx)("em",{parentName:"p"},"not")," use symlinks\u2014either absolute or relative\u2014to\nspecify input files to build rules. Although using symlinks in this context does\nsometimes work, it can lead to unexpected behavior and errors."),(0,i.mdx)("h2",{id:"dependencies-output-from-one-rule-as-input-to-another-rule"},"Dependencies: Output from one rule as input to another rule"),(0,i.mdx)("p",null,"A build rule can use the output from another build rule as one of its inputs by\nspecifying that rule as a ",(0,i.mdx)("em",{parentName:"p"},"dependency"),". Typically, a build rule specifies its\ndependencies as a list of ",(0,i.mdx)("a",{parentName:"p",href:"/docs/concepts/build_target"},"build target"),"s in its ",(0,i.mdx)("inlineCode",{parentName:"p"},"deps"),"\nargument. However, the rule can also specify dependencies\u2014as build targets\u2014in\nother arguments, such as ",(0,i.mdx)("inlineCode",{parentName:"p"},"srcs"),". ",(0,i.mdx)("strong",{parentName:"p"},"Example:")," The output of a\n",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#java_library"},(0,i.mdx)("inlineCode",{parentName:"a"},"java_library"))," rule is a JAR file. If a\n",(0,i.mdx)("inlineCode",{parentName:"p"},"java_library")," rule specifies another ",(0,i.mdx)("inlineCode",{parentName:"p"},"java_library")," rule as a dependency, the\nJAR file produced by the specified rule is added to the classpath for the\n",(0,i.mdx)("inlineCode",{parentName:"p"},"java_library")," that depends on it. ",(0,i.mdx)("strong",{parentName:"p"},"Example:")," If a\n",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#java_binary"},(0,i.mdx)("inlineCode",{parentName:"a"},"java_binary"))," rule specifies a ",(0,i.mdx)("inlineCode",{parentName:"p"},"java_library"),"\nrule as a dependency, the JAR file for the specified ",(0,i.mdx)("inlineCode",{parentName:"p"},"java_library")," is available\non the classpath for the ",(0,i.mdx)("inlineCode",{parentName:"p"},"java_binary"),". In addition, in the case of\n",(0,i.mdx)("inlineCode",{parentName:"p"},"java_binary"),", the JAR files for any dependencies of the ",(0,i.mdx)("inlineCode",{parentName:"p"},"java_library")," rule\n",(0,i.mdx)("em",{parentName:"p"},"are also")," made available to the ",(0,i.mdx)("inlineCode",{parentName:"p"},"java_binary")," rule\u2014and if those dependencies\nhave dependencies of their own, they are added as well. This exhaustive cascade\nof dependencies is referred to as the rule's ",(0,i.mdx)("em",{parentName:"p"},"transitive closure"),"."),(0,i.mdx)("h3",{id:"required-dependencies-are-always-built-first"},"Required dependencies are always built first"),(0,i.mdx)("p",null,"Buck2 guarantees that any dependencies that a rule lists that are required in\norder to build that rule are built successfully ",(0,i.mdx)("em",{parentName:"p"},"before")," Buck2 builds the rule\nitself. Note though that there can be special cases\u2014such as\n",(0,i.mdx)("a",{parentName:"p",href:"../../api/rules/#apple_bundle"},(0,i.mdx)("inlineCode",{parentName:"a"},"apple_bundle")),"\u2014where a rule's listed\ndependencies do not actually need to be built before the rule."),(0,i.mdx)("h3",{id:"visibility"},"Visibility"),(0,i.mdx)("p",null,"In order for a build rule to take a dependency on another build rule, the build\nrule on which the dependency is taken must be ",(0,i.mdx)("em",{parentName:"p"},"visible")," to the build rule taking\nthe dependency. A build rule's ",(0,i.mdx)("inlineCode",{parentName:"p"},"visibility")," argument is a list of\n",(0,i.mdx)("a",{parentName:"p",href:"/docs/concepts/target_pattern"},"build target pattern"),"s that specify the rules that can take\nthat rule as a dependency. For more information about the concept of visibility\nin Buck2, see the ",(0,i.mdx)("a",{parentName:"p",href:"/docs/concepts/visibility"},"Visibility")," topic."),(0,i.mdx)("h3",{id:"dependencies-define-a-graph"},"Dependencies define a graph"),(0,i.mdx)("p",null,"Build rules and their dependencies define a directed acyclic graph (DAG). Buck2\nrequires this graph to be acyclic to make it possible to build independent\nsubgraphs in parallel."),(0,i.mdx)("h2",{id:"how-to-handle-special-cases-genrules-and-macros"},"How to handle special cases: genrules and macros"),(0,i.mdx)("p",null,'Although Buck2 provides a rich set of built-in build rules for developers, it is\nnot able to address all possible needs. As an "escape hatch," Buck2 provides a\ncategory of generic build rules called ',(0,i.mdx)("em",{parentName:"p"},"genrules"),". With genrules, you can\nperform arbitrary operations using shell scripts. The genrules supported by\nBuck2 are:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{parentName:"li",href:"../../api/rules/#genrule"},(0,i.mdx)("inlineCode",{parentName:"a"},"genrule"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{parentName:"li",href:"../../api/rules/#apk_genrule"},(0,i.mdx)("inlineCode",{parentName:"a"},"apk_genrule"))),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{parentName:"li",href:"../../api/rules/#cxx_genrule"},(0,i.mdx)("inlineCode",{parentName:"a"},"cxx_genrule")))),(0,i.mdx)("h3",{id:"multiple-output-files-with-genrules"},"Multiple output files with genrules"),(0,i.mdx)("p",null,"In most cases, a build rule produces exactly one output file. However, with\ngenrules, you can specify an output ",(0,i.mdx)("em",{parentName:"p"},"directory")," and write arbitrary files to\nthat directory."),(0,i.mdx)("h3",{id:"macros"},"Macros"),(0,i.mdx)("p",null,"Finally, note that you can define functions that generate build rules. In\ngeneral, this should not be something that you need to do, but taking advantage\nof this option might help you add needed functionality to Buck2's without\nediting its source code."),(0,i.mdx)("h2",{id:"string-parameter-macros"},"String parameter macros"),(0,i.mdx)("p",null,"It is also possible to expand references to other rules within the ",(0,i.mdx)("inlineCode",{parentName:"p"},"cmd"),", using\nbuiltin ",(0,i.mdx)("inlineCode",{parentName:"p"},"string parameter macros"),". All build rules expanded in the command are\nautomatically considered to be dependencies of the ",(0,i.mdx)("inlineCode",{parentName:"p"},"genrule()"),"."),(0,i.mdx)("p",null,"Note that the paths returned by these macros are ",(0,i.mdx)("em",{parentName:"p"},"relative")," paths. Using\nrelative paths ensures that your builds are ",(0,i.mdx)("em",{parentName:"p"},"hermetic"),", that is, they are\nreproducible across different machine environments."),(0,i.mdx)("p",null,(0,i.mdx)("inlineCode",{parentName:"p"},"$(classpath //path/to:target)")),(0,i.mdx)("p",null,"Expands to the transitive classpath of the specified build rule, provided that\nthe rule has a Java classpath. If the rule does not have (or contribute to) a\nclasspath, then an exception is thrown and the build breaks."),(0,i.mdx)("p",null,(0,i.mdx)("inlineCode",{parentName:"p"},"$(exe //path/to:target)")),(0,i.mdx)("p",null,"Expands a build rule that results in an executable to the commands necessary to\nrun that executable. For example, a ",(0,i.mdx)("inlineCode",{parentName:"p"},"java_binary()")," might expand to a call to\n",(0,i.mdx)("inlineCode",{parentName:"p"},"java -jar path/to/target.jar")," . Files that are executable (perhaps generated by\na ",(0,i.mdx)("inlineCode",{parentName:"p"},"genrule()"),") are also expanded. If the build rule does not generate an\nexecutable output, then an exception is thrown and the build breaks."),(0,i.mdx)("p",null,"If the ",(0,i.mdx)("inlineCode",{parentName:"p"},"$(exe my_dependency)")," dependency should actually be built with the\ntarget platform, use ",(0,i.mdx)("inlineCode",{parentName:"p"},"$(exe_target my_dependency)")," instead, which will stick to\nthe same platform as the target."),(0,i.mdx)("p",null,(0,i.mdx)("inlineCode",{parentName:"p"},"$(location //path/to:target)")),(0,i.mdx)("p",null,"Expands to the location of the output of the specified build rule. This means\nthat you can refer to the output without needing to be aware of how Buck is\nstoring data on the disk mid-build."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre"},"")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/10cf57ad.1201e32f.js b/assets/js/10cf57ad.1201e32f.js new file mode 100644 index 000000000000..bb7db0eb42ed --- /dev/null +++ b/assets/js/10cf57ad.1201e32f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6618],{3905:(e,t,r)=>{r.r(t),r.d(t,{MDXContext:()=>u,MDXProvider:()=>b,mdx:()=>x,useMDXComponents:()=>s,withMDXComponents:()=>l});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),l=function(e){return function(t){var r=s(t.components);return n.createElement(e,a({},t,{components:r}))}},s=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},b=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},m="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=s(r),b=o,m=l["".concat(c,".").concat(b)]||l[b]||f[b]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function x(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[m]="string"==typeof e?e:o,c[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>s,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var n=r(87462),o=(r(67294),r(3905));const a={id:"buck_regex"},c="buck_regex type",i={unversionedId:"api/bxl/buck_regex",id:"api/bxl/buck_regex",title:"buck_regex type",description:"buck\\_regex.match",source:"@site/../docs/api/bxl/buck_regex.generated.md",sourceDirName:"api/bxl",slug:"/api/bxl/buck_regex",permalink:"/docs/api/bxl/buck_regex",draft:!1,tags:[],version:"current",frontMatter:{id:"buck_regex"},sidebar:"manualSidebar",previous:{title:"audit_ctx type",permalink:"/docs/api/bxl/audit_ctx"},next:{title:"bxl_actions type",permalink:"/docs/api/bxl/bxl_actions"}},p={},u=[{value:"buck_regex.match",id:"buck_regexmatch",level:2}],l={toc:u};function s(e){let{components:t,...r}=e;return(0,o.mdx)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.mdx)("h1",{id:"buck_regex-type"},(0,o.mdx)("inlineCode",{parentName:"h1"},"buck_regex")," type"),(0,o.mdx)("h2",{id:"buck_regexmatch"},"buck","_","regex.match"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-python"},"def buck_regex.match(str: str, /) -> bool\n")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/14372d82.e026ff42.js b/assets/js/14372d82.e026ff42.js new file mode 100644 index 000000000000..6320f430a86a --- /dev/null +++ b/assets/js/14372d82.e026ff42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3353],{3905:(e,r,t)=>{t.r(r),t.d(r,{MDXContext:()=>p,MDXProvider:()=>d,mdx:()=>b,useMDXComponents:()=>s,withMDXComponents:()=>u});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(){return i=Object.assign||function(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=n.createContext({}),u=function(e){return function(r){var t=s(r.components);return n.createElement(e,i({},r,{components:t}))}},s=function(e){var r=n.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},d=function(e){var r=s(e.components);return n.createElement(p.Provider,{value:r},e.children)},m="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},y=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(t),d=o,m=u["".concat(a,".").concat(d)]||u[d]||f[d]||i;return t?n.createElement(m,c(c({ref:r},p),{},{components:t})):n.createElement(m,c({ref:r},p))}));function b(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=y;var c={};for(var l in r)hasOwnProperty.call(r,l)&&(c[l]=r[l]);c.originalType=e,c[m]="string"==typeof e?e:o,a[1]=c;for(var p=2;p{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>s,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=t(87462),o=(t(67294),t(3905));const i={id:"ActionErrorLocation"},a="ActionErrorLocation type",c={unversionedId:"api/bxl/ActionErrorLocation",id:"api/bxl/ActionErrorLocation",title:"ActionErrorLocation type",description:"Methods available on StarlarkActionErrorLocation to help with testing the error handler implementation",source:"@site/../docs/api/bxl/ActionErrorLocation.generated.md",sourceDirName:"api/bxl",slug:"/api/bxl/ActionErrorLocation",permalink:"/docs/api/bxl/ActionErrorLocation",draft:!1,tags:[],version:"current",frontMatter:{id:"ActionErrorLocation"},sidebar:"manualSidebar",previous:{title:"ActionErrorCtx type",permalink:"/docs/api/bxl/ActionErrorCtx"},next:{title:"ActionSubError type",permalink:"/docs/api/bxl/ActionSubError"}},l={},p=[{value:"ActionErrorLocation.file",id:"actionerrorlocationfile",level:2},{value:"ActionErrorLocation.line",id:"actionerrorlocationline",level:2}],u={toc:p};function s(e){let{components:r,...t}=e;return(0,o.mdx)("wrapper",(0,n.Z)({},u,t,{components:r,mdxType:"MDXLayout"}),(0,o.mdx)("h1",{id:"actionerrorlocation-type"},(0,o.mdx)("inlineCode",{parentName:"h1"},"ActionErrorLocation")," type"),(0,o.mdx)("p",null,"Methods available on ",(0,o.mdx)("inlineCode",{parentName:"p"},"StarlarkActionErrorLocation")," to help with testing the error handler implementation"),(0,o.mdx)("h2",{id:"actionerrorlocationfile"},"ActionErrorLocation.file"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-python"},"ActionErrorLocation.file: str\n")),(0,o.mdx)("p",null,"The file of the error location. This is only needed for action error handler unit testing."),(0,o.mdx)("hr",null),(0,o.mdx)("h2",{id:"actionerrorlocationline"},"ActionErrorLocation.line"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-python"},"ActionErrorLocation.line: None | int\n")),(0,o.mdx)("p",null,"The line of the error location. This is only needed for action error handler unit testing."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1500e4bc.ae48f454.js b/assets/js/1500e4bc.ae48f454.js new file mode 100644 index 000000000000..38d990be2cae --- /dev/null +++ b/assets/js/1500e4bc.ae48f454.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2914],{3905:(e,n,r)=>{r.r(n),r.d(n,{MDXContext:()=>l,MDXProvider:()=>d,mdx:()=>h,useMDXComponents:()=>m,withMDXComponents:()=>u});var t=r(67294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function o(){return o=Object.assign||function(e){for(var n=1;n=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=t.createContext({}),u=function(e){return function(n){var r=m(n.components);return t.createElement(e,o({},n,{components:r}))}},m=function(e){var n=t.useContext(l),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},d=function(e){var n=m(e.components);return t.createElement(l.Provider,{value:n},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},y=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=m(r),d=a,p=u["".concat(c,".").concat(d)]||u[d]||f[d]||o;return r?t.createElement(p,i(i({ref:n},l),{},{components:r})):t.createElement(p,i({ref:n},l))}));function h(e,n){var r=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=r.length,c=new Array(o);c[0]=y;var i={};for(var s in n)hasOwnProperty.call(n,s)&&(i[s]=n[s]);i.originalType=e,i[p]="string"==typeof e?e:a,c[1]=i;for(var l=2;l{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>c,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var t=r(87462),a=(r(67294),r(3905));const o={id:"in_memory_cache",title:"In Memory Cache"},c=void 0,i={unversionedId:"users/advanced/in_memory_cache",id:"users/advanced/in_memory_cache",title:"In Memory Cache",description:"Buck2 can maintain an in-memory cache of actions it executed. This allows",source:"@site/../docs/users/advanced/in_memory_cache.md",sourceDirName:"users/advanced",slug:"/users/advanced/in_memory_cache",permalink:"/docs/users/advanced/in_memory_cache",draft:!1,tags:[],version:"current",frontMatter:{id:"in_memory_cache",title:"In Memory Cache"},sidebar:"manualSidebar",previous:{title:"Restarter",permalink:"/docs/users/advanced/restarter"},next:{title:"External Cells",permalink:"/docs/users/advanced/external_cells"}},s={},l=[{value:"Enabling the in-memory cache",id:"enabling-the-in-memory-cache",level:2}],u={toc:l};function m(e){let{components:n,...r}=e;return(0,a.mdx)("wrapper",(0,t.Z)({},u,r,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Buck2 can maintain an in-memory cache of actions it executed. This allows\nactions to skip re-running even when they are (transitively) affected by file\nchanges."),(0,a.mdx)("h2",{id:"enabling-the-in-memory-cache"},"Enabling the in-memory cache"),(0,a.mdx)("p",null,"This feature requires enabling\n",(0,a.mdx)("a",{parentName:"p",href:"/docs/users/advanced/deferred_materialization"},"Deferred Materialization")," first. This is necessary\nso that Buck2 knows what's on disk. This requirement might go away once we\ndecouple keeping track of what's on disk and deferred materialization."),(0,a.mdx)("p",null,"Once done, to enable, add this to your Buckconfig:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre"},"[buck2]\nhash_all_commands = true\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1554.39070c41.js b/assets/js/1554.39070c41.js new file mode 100644 index 000000000000..651ec3b3e73c --- /dev/null +++ b/assets/js/1554.39070c41.js @@ -0,0 +1,2 @@ +/*! For license information please see 1554.39070c41.js.LICENSE.txt */ +(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1554],{3905:(e,t,n)=>{"use strict";n.r(t),n.d(t,{MDXContext:()=>l,MDXProvider:()=>h,mdx:()=>m,useMDXComponents:()=>u,withMDXComponents:()=>c});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){return function(t){var n=u(t.components);return a.createElement(e,i({},t,{components:n}))}},u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},h=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},g="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,l=d(e,["components","mdxType","originalType","parentName"]),c=u(n),h=r,g=c["".concat(s,".").concat(h)]||c[h]||p[h]||i;return n?a.createElement(g,o(o({ref:t},l),{},{components:n})):a.createElement(g,o({ref:t},l))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,s=new Array(i);s[0]=f;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o[g]="string"==typeof e?e:r,s[1]=o;for(var l=2;l{"use strict";const a=n(73325),r=/^[\da-fA-F]+$/,i=/^\d+$/,s=new WeakMap;function o(e){e=e.Parser.acorn||e;let t=s.get(e);if(!t){const n=e.tokTypes,a=e.TokContext,r=e.TokenType,i=new a("...",!0,!0),l={tc_oTag:i,tc_cTag:o,tc_expr:d},c={jsxName:new r("jsxName"),jsxText:new r("jsxText",{beforeExpr:!0}),jsxTagStart:new r("jsxTagStart",{startsExpr:!0}),jsxTagEnd:new r("jsxTagEnd")};c.jsxTagStart.updateContext=function(){this.context.push(d),this.context.push(i),this.exprAllowed=!1},c.jsxTagEnd.updateContext=function(e){let t=this.context.pop();t===i&&e===n.slash||t===o?(this.context.pop(),this.exprAllowed=this.curContext()===d):this.exprAllowed=!0},t={tokContexts:l,tokTypes:c},s.set(e,t)}return t}function d(e){return e?"JSXIdentifier"===e.type?e.name:"JSXNamespacedName"===e.type?e.namespace.name+":"+e.name.name:"JSXMemberExpression"===e.type?d(e.object)+"."+d(e.property):void 0:e}e.exports=function(e){return e=e||{},function(t){return function(e,t){const s=t.acorn||n(1234),l=o(s),c=s.tokTypes,u=l.tokTypes,h=s.tokContexts,g=l.tokContexts.tc_oTag,p=l.tokContexts.tc_cTag,f=l.tokContexts.tc_expr,m=s.isNewLine,R=s.isIdentifierStart,y=s.isIdentifierChar;return class extends t{static get acornJsx(){return l}jsx_readToken(){let e="",t=this.pos;for(;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated JSX contents");let n=this.input.charCodeAt(this.pos);switch(n){case 60:case 123:return this.pos===this.start?60===n&&this.exprAllowed?(++this.pos,this.finishToken(u.jsxTagStart)):this.getTokenFromCode(n):(e+=this.input.slice(t,this.pos),this.finishToken(u.jsxText,e));case 38:e+=this.input.slice(t,this.pos),e+=this.jsx_readEntity(),t=this.pos;break;case 62:case 125:this.raise(this.pos,"Unexpected token `"+this.input[this.pos]+"`. Did you mean `"+(62===n?">":"}")+'` or `{"'+this.input[this.pos]+'"}`?');default:m(n)?(e+=this.input.slice(t,this.pos),e+=this.jsx_readNewLine(!0),t=this.pos):++this.pos}}}jsx_readNewLine(e){let t,n=this.input.charCodeAt(this.pos);return++this.pos,13===n&&10===this.input.charCodeAt(this.pos)?(++this.pos,t=e?"\n":"\r\n"):t=String.fromCharCode(n),this.options.locations&&(++this.curLine,this.lineStart=this.pos),t}jsx_readString(e){let t="",n=++this.pos;for(;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");let a=this.input.charCodeAt(this.pos);if(a===e)break;38===a?(t+=this.input.slice(n,this.pos),t+=this.jsx_readEntity(),n=this.pos):m(a)?(t+=this.input.slice(n,this.pos),t+=this.jsx_readNewLine(!1),n=this.pos):++this.pos}return t+=this.input.slice(n,this.pos++),this.finishToken(c.string,t)}jsx_readEntity(){let e,t="",n=0,s=this.input[this.pos];"&"!==s&&this.raise(this.pos,"Entity must start with an ampersand");let o=++this.pos;for(;this.pos")}let s=r.name?"Element":"Fragment";return n["opening"+s]=r,n["closing"+s]=i,n.children=a,this.type===c.relational&&"<"===this.value&&this.raise(this.start,"Adjacent JSX elements must be wrapped in an enclosing tag"),this.finishNode(n,"JSX"+s)}jsx_parseText(){let e=this.parseLiteral(this.value);return e.type="JSXText",e}jsx_parseElement(){let e=this.start,t=this.startLoc;return this.next(),this.jsx_parseElementAt(e,t)}parseExprAtom(e){return this.type===u.jsxText?this.jsx_parseText():this.type===u.jsxTagStart?this.jsx_parseElement():super.parseExprAtom(e)}readToken(e){let t=this.curContext();if(t===f)return this.jsx_readToken();if(t===g||t===p){if(R(e))return this.jsx_readWord();if(62==e)return++this.pos,this.finishToken(u.jsxTagEnd);if((34===e||39===e)&&t==g)return this.jsx_readString(e)}return 60===e&&this.exprAllowed&&33!==this.input.charCodeAt(this.pos+1)?(++this.pos,this.finishToken(u.jsxTagStart)):super.readToken(e)}updateContext(e){if(this.type==c.braceL){var t=this.curContext();t==g?this.context.push(h.b_expr):t==f?this.context.push(h.b_tmpl):super.updateContext(e),this.exprAllowed=!0}else{if(this.type!==c.slash||e!==u.jsxTagStart)return super.updateContext(e);this.context.length-=2,this.context.push(p),this.exprAllowed=!1}}}}({allowNamespaces:!1!==e.allowNamespaces,allowNamespacedObjects:!!e.allowNamespacedObjects},t)}},Object.defineProperty(e.exports,"tokTypes",{get:function(){return o(n(1234)).tokTypes},configurable:!0,enumerable:!0})},73325:e=>{e.exports={quot:'"',amp:"&",apos:"'",lt:"<",gt:">",nbsp:"\xa0",iexcl:"\xa1",cent:"\xa2",pound:"\xa3",curren:"\xa4",yen:"\xa5",brvbar:"\xa6",sect:"\xa7",uml:"\xa8",copy:"\xa9",ordf:"\xaa",laquo:"\xab",not:"\xac",shy:"\xad",reg:"\xae",macr:"\xaf",deg:"\xb0",plusmn:"\xb1",sup2:"\xb2",sup3:"\xb3",acute:"\xb4",micro:"\xb5",para:"\xb6",middot:"\xb7",cedil:"\xb8",sup1:"\xb9",ordm:"\xba",raquo:"\xbb",frac14:"\xbc",frac12:"\xbd",frac34:"\xbe",iquest:"\xbf",Agrave:"\xc0",Aacute:"\xc1",Acirc:"\xc2",Atilde:"\xc3",Auml:"\xc4",Aring:"\xc5",AElig:"\xc6",Ccedil:"\xc7",Egrave:"\xc8",Eacute:"\xc9",Ecirc:"\xca",Euml:"\xcb",Igrave:"\xcc",Iacute:"\xcd",Icirc:"\xce",Iuml:"\xcf",ETH:"\xd0",Ntilde:"\xd1",Ograve:"\xd2",Oacute:"\xd3",Ocirc:"\xd4",Otilde:"\xd5",Ouml:"\xd6",times:"\xd7",Oslash:"\xd8",Ugrave:"\xd9",Uacute:"\xda",Ucirc:"\xdb",Uuml:"\xdc",Yacute:"\xdd",THORN:"\xde",szlig:"\xdf",agrave:"\xe0",aacute:"\xe1",acirc:"\xe2",atilde:"\xe3",auml:"\xe4",aring:"\xe5",aelig:"\xe6",ccedil:"\xe7",egrave:"\xe8",eacute:"\xe9",ecirc:"\xea",euml:"\xeb",igrave:"\xec",iacute:"\xed",icirc:"\xee",iuml:"\xef",eth:"\xf0",ntilde:"\xf1",ograve:"\xf2",oacute:"\xf3",ocirc:"\xf4",otilde:"\xf5",ouml:"\xf6",divide:"\xf7",oslash:"\xf8",ugrave:"\xf9",uacute:"\xfa",ucirc:"\xfb",uuml:"\xfc",yacute:"\xfd",thorn:"\xfe",yuml:"\xff",OElig:"\u0152",oelig:"\u0153",Scaron:"\u0160",scaron:"\u0161",Yuml:"\u0178",fnof:"\u0192",circ:"\u02c6",tilde:"\u02dc",Alpha:"\u0391",Beta:"\u0392",Gamma:"\u0393",Delta:"\u0394",Epsilon:"\u0395",Zeta:"\u0396",Eta:"\u0397",Theta:"\u0398",Iota:"\u0399",Kappa:"\u039a",Lambda:"\u039b",Mu:"\u039c",Nu:"\u039d",Xi:"\u039e",Omicron:"\u039f",Pi:"\u03a0",Rho:"\u03a1",Sigma:"\u03a3",Tau:"\u03a4",Upsilon:"\u03a5",Phi:"\u03a6",Chi:"\u03a7",Psi:"\u03a8",Omega:"\u03a9",alpha:"\u03b1",beta:"\u03b2",gamma:"\u03b3",delta:"\u03b4",epsilon:"\u03b5",zeta:"\u03b6",eta:"\u03b7",theta:"\u03b8",iota:"\u03b9",kappa:"\u03ba",lambda:"\u03bb",mu:"\u03bc",nu:"\u03bd",xi:"\u03be",omicron:"\u03bf",pi:"\u03c0",rho:"\u03c1",sigmaf:"\u03c2",sigma:"\u03c3",tau:"\u03c4",upsilon:"\u03c5",phi:"\u03c6",chi:"\u03c7",psi:"\u03c8",omega:"\u03c9",thetasym:"\u03d1",upsih:"\u03d2",piv:"\u03d6",ensp:"\u2002",emsp:"\u2003",thinsp:"\u2009",zwnj:"\u200c",zwj:"\u200d",lrm:"\u200e",rlm:"\u200f",ndash:"\u2013",mdash:"\u2014",lsquo:"\u2018",rsquo:"\u2019",sbquo:"\u201a",ldquo:"\u201c",rdquo:"\u201d",bdquo:"\u201e",dagger:"\u2020",Dagger:"\u2021",bull:"\u2022",hellip:"\u2026",permil:"\u2030",prime:"\u2032",Prime:"\u2033",lsaquo:"\u2039",rsaquo:"\u203a",oline:"\u203e",frasl:"\u2044",euro:"\u20ac",image:"\u2111",weierp:"\u2118",real:"\u211c",trade:"\u2122",alefsym:"\u2135",larr:"\u2190",uarr:"\u2191",rarr:"\u2192",darr:"\u2193",harr:"\u2194",crarr:"\u21b5",lArr:"\u21d0",uArr:"\u21d1",rArr:"\u21d2",dArr:"\u21d3",hArr:"\u21d4",forall:"\u2200",part:"\u2202",exist:"\u2203",empty:"\u2205",nabla:"\u2207",isin:"\u2208",notin:"\u2209",ni:"\u220b",prod:"\u220f",sum:"\u2211",minus:"\u2212",lowast:"\u2217",radic:"\u221a",prop:"\u221d",infin:"\u221e",ang:"\u2220",and:"\u2227",or:"\u2228",cap:"\u2229",cup:"\u222a",int:"\u222b",there4:"\u2234",sim:"\u223c",cong:"\u2245",asymp:"\u2248",ne:"\u2260",equiv:"\u2261",le:"\u2264",ge:"\u2265",sub:"\u2282",sup:"\u2283",nsub:"\u2284",sube:"\u2286",supe:"\u2287",oplus:"\u2295",otimes:"\u2297",perp:"\u22a5",sdot:"\u22c5",lceil:"\u2308",rceil:"\u2309",lfloor:"\u230a",rfloor:"\u230b",lang:"\u2329",rang:"\u232a",loz:"\u25ca",spades:"\u2660",clubs:"\u2663",hearts:"\u2665",diams:"\u2666"}},1234:function(e,t){!function(e){"use strict";var t=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,370,1,154,10,50,3,123,2,54,14,32,10,3,1,11,3,46,10,8,0,46,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,87,9,39,4,60,6,26,9,1014,0,2,54,8,3,82,0,12,1,19628,1,4706,45,3,22,543,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,357,0,62,13,1495,6,110,6,6,9,4759,9,787719,239],n=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,13,10,2,14,2,6,2,1,2,10,2,14,2,6,2,1,68,310,10,21,11,7,25,5,2,41,2,8,70,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,349,41,7,1,79,28,11,0,9,21,43,17,47,20,28,22,13,52,58,1,3,0,14,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,38,6,186,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,19,72,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,190,0,80,921,103,110,18,195,2637,96,16,1070,4050,582,8634,568,8,30,18,78,18,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,43,8,8936,3,2,6,2,1,2,290,46,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,1845,30,482,44,11,6,17,0,322,29,19,43,1269,6,2,3,2,1,2,14,2,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42719,33,4152,8,221,3,5761,15,7472,3104,541,1507,4938],a="\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f",r="\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc",i={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"},s="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",o={5:s,"5module":s+" export import",6:s+" const class extends export import super"},d=/^in(stanceof)?$/,l=new RegExp("["+r+"]"),c=new RegExp("["+r+a+"]");function u(e,t){for(var n=65536,a=0;ae)return!1;if((n+=t[a+1])>=e)return!0}}function h(e,t){return e<65?36===e:e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&l.test(String.fromCharCode(e)):!1!==t&&u(e,n)))}function g(e,a){return e<48?36===e:e<58||!(e<65)&&(e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&c.test(String.fromCharCode(e)):!1!==a&&(u(e,n)||u(e,t)))))}var p=function(e,t){void 0===t&&(t={}),this.label=e,this.keyword=t.keyword,this.beforeExpr=!!t.beforeExpr,this.startsExpr=!!t.startsExpr,this.isLoop=!!t.isLoop,this.isAssign=!!t.isAssign,this.prefix=!!t.prefix,this.postfix=!!t.postfix,this.binop=t.binop||null,this.updateContext=null};function f(e,t){return new p(e,{beforeExpr:!0,binop:t})}var m={beforeExpr:!0},R={startsExpr:!0},y={};function b(e,t){return void 0===t&&(t={}),t.keyword=e,y[e]=new p(e,t)}var x={num:new p("num",R),regexp:new p("regexp",R),string:new p("string",R),name:new p("name",R),privateId:new p("privateId",R),eof:new p("eof"),bracketL:new p("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new p("]"),braceL:new p("{",{beforeExpr:!0,startsExpr:!0}),braceR:new p("}"),parenL:new p("(",{beforeExpr:!0,startsExpr:!0}),parenR:new p(")"),comma:new p(",",m),semi:new p(";",m),colon:new p(":",m),dot:new p("."),question:new p("?",m),questionDot:new p("?."),arrow:new p("=>",m),template:new p("template"),invalidTemplate:new p("invalidTemplate"),ellipsis:new p("...",m),backQuote:new p("`",R),dollarBraceL:new p("${",{beforeExpr:!0,startsExpr:!0}),eq:new p("=",{beforeExpr:!0,isAssign:!0}),assign:new p("_=",{beforeExpr:!0,isAssign:!0}),incDec:new p("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new p("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:f("||",1),logicalAND:f("&&",2),bitwiseOR:f("|",3),bitwiseXOR:f("^",4),bitwiseAND:f("&",5),equality:f("==/!=/===/!==",6),relational:f("/<=/>=",7),bitShift:f("<>/>>>",8),plusMin:new p("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:f("%",10),star:f("*",10),slash:f("/",10),starstar:new p("**",{beforeExpr:!0}),coalesce:f("??",1),_break:b("break"),_case:b("case",m),_catch:b("catch"),_continue:b("continue"),_debugger:b("debugger"),_default:b("default",m),_do:b("do",{isLoop:!0,beforeExpr:!0}),_else:b("else",m),_finally:b("finally"),_for:b("for",{isLoop:!0}),_function:b("function",R),_if:b("if"),_return:b("return",m),_switch:b("switch"),_throw:b("throw",m),_try:b("try"),_var:b("var"),_const:b("const"),_while:b("while",{isLoop:!0}),_with:b("with"),_new:b("new",{beforeExpr:!0,startsExpr:!0}),_this:b("this",R),_super:b("super",R),_class:b("class",R),_extends:b("extends",m),_export:b("export"),_import:b("import",R),_null:b("null",R),_true:b("true",R),_false:b("false",R),_in:b("in",{beforeExpr:!0,binop:7}),_instanceof:b("instanceof",{beforeExpr:!0,binop:7}),_typeof:b("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:b("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:b("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},v=/\r\n?|\n|\u2028|\u2029/,_=new RegExp(v.source,"g");function k(e){return 10===e||13===e||8232===e||8233===e}function C(e,t,n){void 0===n&&(n=e.length);for(var a=t;a>10),56320+(1023&e)))}var O=/(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/,N=function(e,t){this.line=e,this.column=t};N.prototype.offset=function(e){return new N(this.line,this.column+e)};var B=function(e,t,n){this.start=t,this.end=n,null!==e.sourceFile&&(this.source=e.sourceFile)};function M(e,t){for(var n=1,a=0;;){var r=C(e,a,t);if(r<0)return new N(n,t-a);++n,a=r}}var P={ecmaVersion:null,sourceType:"script",onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:!1,allowImportExportEverywhere:!1,allowAwaitOutsideFunction:null,allowSuperOutsideMethod:null,allowHashBang:!1,locations:!1,onToken:null,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null,preserveParens:!1},j=!1;function V(e){var t={};for(var n in P)t[n]=e&&D(e,n)?e[n]:P[n];if("latest"===t.ecmaVersion?t.ecmaVersion=1e8:null==t.ecmaVersion?(!j&&"object"==typeof console&&console.warn&&(j=!0,console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.")),t.ecmaVersion=11):t.ecmaVersion>=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),null==e.allowHashBang&&(t.allowHashBang=t.ecmaVersion>=14),L(t.onToken)){var a=t.onToken;t.onToken=function(e){return a.push(e)}}return L(t.onComment)&&(t.onComment=$(t,t.onComment)),t}function $(e,t){return function(n,a,r,i,s,o){var d={type:n?"Block":"Line",value:a,start:r,end:i};e.locations&&(d.loc=new B(this,s,o)),e.ranges&&(d.range=[r,i]),t.push(d)}}var U=1,z=2,H=4,Y=8,W=16,q=32,G=64,X=128,J=256,K=U|z|J;function Z(e,t){return z|(e?H:0)|(t?Y:0)}var Q=0,ee=1,te=2,ne=3,ae=4,re=5,ie=function(e,t,n){this.options=e=V(e),this.sourceFile=e.sourceFile,this.keywords=I(o[e.ecmaVersion>=6?6:"module"===e.sourceType?"5module":5]);var a="";!0!==e.allowReserved&&(a=i[e.ecmaVersion>=6?6:5===e.ecmaVersion?5:3],"module"===e.sourceType&&(a+=" await")),this.reservedWords=I(a);var r=(a?a+" ":"")+i.strict;this.reservedWordsStrict=I(r),this.reservedWordsStrictBind=I(r+" "+i.strictBind),this.input=String(t),this.containsEsc=!1,n?(this.pos=n,this.lineStart=this.input.lastIndexOf("\n",n-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(v).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=x.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.potentialArrowInForAwait=!1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports=Object.create(null),0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(U),this.regexpState=null,this.privateNameStack=[]},se={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},canAwait:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0},allowNewDotTarget:{configurable:!0},inClassStaticBlock:{configurable:!0}};ie.prototype.parse=function(){var e=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(e)},se.inFunction.get=function(){return(this.currentVarScope().flags&z)>0},se.inGenerator.get=function(){return(this.currentVarScope().flags&Y)>0&&!this.currentVarScope().inClassFieldInit},se.inAsync.get=function(){return(this.currentVarScope().flags&H)>0&&!this.currentVarScope().inClassFieldInit},se.canAwait.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e];if(t.inClassFieldInit||t.flags&J)return!1;if(t.flags&z)return(t.flags&H)>0}return this.inModule&&this.options.ecmaVersion>=13||this.options.allowAwaitOutsideFunction},se.allowSuper.get=function(){var e=this.currentThisScope(),t=e.flags,n=e.inClassFieldInit;return(t&G)>0||n||this.options.allowSuperOutsideMethod},se.allowDirectSuper.get=function(){return(this.currentThisScope().flags&X)>0},se.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())},se.allowNewDotTarget.get=function(){var e=this.currentThisScope(),t=e.flags,n=e.inClassFieldInit;return(t&(z|J))>0||n},se.inClassStaticBlock.get=function(){return(this.currentVarScope().flags&J)>0},ie.extend=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var n=this,a=0;a=,?^&]/.test(r)||"!"===r&&"="===this.input.charAt(a+1))}e+=t[0].length,E.lastIndex=e,e+=E.exec(this.input)[0].length,";"===this.input[e]&&e++}},oe.eat=function(e){return this.type===e&&(this.next(),!0)},oe.isContextual=function(e){return this.type===x.name&&this.value===e&&!this.containsEsc},oe.eatContextual=function(e){return!!this.isContextual(e)&&(this.next(),!0)},oe.expectContextual=function(e){this.eatContextual(e)||this.unexpected()},oe.canInsertSemicolon=function(){return this.type===x.eof||this.type===x.braceR||v.test(this.input.slice(this.lastTokEnd,this.start))},oe.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},oe.semicolon=function(){this.eat(x.semi)||this.insertSemicolon()||this.unexpected()},oe.afterTrailingComma=function(e,t){if(this.type===e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0},oe.expect=function(e){this.eat(e)||this.unexpected()},oe.unexpected=function(e){this.raise(null!=e?e:this.start,"Unexpected token")};var le=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1};oe.checkPatternErrors=function(e,t){if(e){e.trailingComma>-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var n=t?e.parenthesizedAssign:e.parenthesizedBind;n>-1&&this.raiseRecoverable(n,t?"Assigning to rvalue":"Parenthesized pattern")}},oe.checkExpressionErrors=function(e,t){if(!e)return!1;var n=e.shorthandAssign,a=e.doubleProto;if(!t)return n>=0||a>=0;n>=0&&this.raise(n,"Shorthand property assignments are valid only in destructuring patterns"),a>=0&&this.raiseRecoverable(a,"Redefinition of __proto__ property")},oe.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos55295&&a<56320)return!0;if(e)return!1;if(123===a)return!0;if(h(a,!0)){for(var r=n+1;g(a=this.input.charCodeAt(r),!0);)++r;if(92===a||a>55295&&a<56320)return!0;var i=this.input.slice(n,r);if(!d.test(i))return!0}return!1},ce.isAsyncFunction=function(){if(this.options.ecmaVersion<8||!this.isContextual("async"))return!1;E.lastIndex=this.pos;var e,t=E.exec(this.input),n=this.pos+t[0].length;return!(v.test(this.input.slice(this.pos,n))||"function"!==this.input.slice(n,n+8)||n+8!==this.input.length&&(g(e=this.input.charCodeAt(n+8))||e>55295&&e<56320))},ce.parseStatement=function(e,t,n){var a,r=this.type,i=this.startNode();switch(this.isLet(e)&&(r=x._var,a="let"),r){case x._break:case x._continue:return this.parseBreakContinueStatement(i,r.keyword);case x._debugger:return this.parseDebuggerStatement(i);case x._do:return this.parseDoStatement(i);case x._for:return this.parseForStatement(i);case x._function:return e&&(this.strict||"if"!==e&&"label"!==e)&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(i,!1,!e);case x._class:return e&&this.unexpected(),this.parseClass(i,!0);case x._if:return this.parseIfStatement(i);case x._return:return this.parseReturnStatement(i);case x._switch:return this.parseSwitchStatement(i);case x._throw:return this.parseThrowStatement(i);case x._try:return this.parseTryStatement(i);case x._const:case x._var:return a=a||this.value,e&&"var"!==a&&this.unexpected(),this.parseVarStatement(i,a);case x._while:return this.parseWhileStatement(i);case x._with:return this.parseWithStatement(i);case x.braceL:return this.parseBlock(!0,i);case x.semi:return this.parseEmptyStatement(i);case x._export:case x._import:if(this.options.ecmaVersion>10&&r===x._import){E.lastIndex=this.pos;var s=E.exec(this.input),o=this.pos+s[0].length,d=this.input.charCodeAt(o);if(40===d||46===d)return this.parseExpressionStatement(i,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),r===x._import?this.parseImport(i):this.parseExport(i,n);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(i,!0,!e);var l=this.value,c=this.parseExpression();return r===x.name&&"Identifier"===c.type&&this.eat(x.colon)?this.parseLabeledStatement(i,l,c,e):this.parseExpressionStatement(i,c)}},ce.parseBreakContinueStatement=function(e,t){var n="break"===t;this.next(),this.eat(x.semi)||this.insertSemicolon()?e.label=null:this.type!==x.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var a=0;a=6?this.eat(x.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")},ce.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&this.canAwait&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(ue),this.enterScope(0),this.expect(x.parenL),this.type===x.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var n=this.isLet();if(this.type===x._var||this.type===x._const||n){var a=this.startNode(),r=n?"let":this.value;return this.next(),this.parseVar(a,!0,r),this.finishNode(a,"VariableDeclaration"),(this.type===x._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&1===a.declarations.length?(this.options.ecmaVersion>=9&&(this.type===x._in?t>-1&&this.unexpected(t):e.await=t>-1),this.parseForIn(e,a)):(t>-1&&this.unexpected(t),this.parseFor(e,a))}var i=this.isContextual("let"),s=!1,o=new le,d=this.parseExpression(!(t>-1)||"await",o);return this.type===x._in||(s=this.options.ecmaVersion>=6&&this.isContextual("of"))?(this.options.ecmaVersion>=9&&(this.type===x._in?t>-1&&this.unexpected(t):e.await=t>-1),i&&s&&this.raise(d.start,"The left-hand side of a for-of loop may not start with 'let'."),this.toAssignable(d,!1,o),this.checkLValPattern(d),this.parseForIn(e,d)):(this.checkExpressionErrors(o,!0),t>-1&&this.unexpected(t),this.parseFor(e,d))},ce.parseFunctionStatement=function(e,t,n){return this.next(),this.parseFunction(e,pe|(n?0:fe),!1,t)},ce.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(x._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")},ce.parseReturnStatement=function(e){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(x.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")},ce.parseSwitchStatement=function(e){var t;this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(x.braceL),this.labels.push(he),this.enterScope(0);for(var n=!1;this.type!==x.braceR;)if(this.type===x._case||this.type===x._default){var a=this.type===x._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),a?t.test=this.parseExpression():(n&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),n=!0,t.test=null),this.expect(x.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")},ce.parseThrowStatement=function(e){return this.next(),v.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var ge=[];ce.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===x._catch){var t=this.startNode();if(this.next(),this.eat(x.parenL)){t.param=this.parseBindingAtom();var n="Identifier"===t.param.type;this.enterScope(n?q:0),this.checkLValPattern(t.param,n?ae:te),this.expect(x.parenR)}else this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0);t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(x._finally)?this.parseBlock():null,e.handler||e.finalizer||this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")},ce.parseVarStatement=function(e,t){return this.next(),this.parseVar(e,!1,t),this.semicolon(),this.finishNode(e,"VariableDeclaration")},ce.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(ue),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")},ce.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")},ce.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")},ce.parseLabeledStatement=function(e,t,n,a){for(var r=0,i=this.labels;r=0;o--){var d=this.labels[o];if(d.statementStart!==e.start)break;d.statementStart=this.start,d.kind=s}return this.labels.push({name:t,kind:s,statementStart:this.start}),e.body=this.parseStatement(a?-1===a.indexOf("label")?a+"label":a:"label"),this.labels.pop(),e.label=n,this.finishNode(e,"LabeledStatement")},ce.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")},ce.parseBlock=function(e,t,n){for(void 0===e&&(e=!0),void 0===t&&(t=this.startNode()),t.body=[],this.expect(x.braceL),e&&this.enterScope(0);this.type!==x.braceR;){var a=this.parseStatement(null);t.body.push(a)}return n&&(this.strict=!1),this.next(),e&&this.exitScope(),this.finishNode(t,"BlockStatement")},ce.parseFor=function(e,t){return e.init=t,this.expect(x.semi),e.test=this.type===x.semi?null:this.parseExpression(),this.expect(x.semi),e.update=this.type===x.parenR?null:this.parseExpression(),this.expect(x.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")},ce.parseForIn=function(e,t){var n=this.type===x._in;return this.next(),"VariableDeclaration"===t.type&&null!=t.declarations[0].init&&(!n||this.options.ecmaVersion<8||this.strict||"var"!==t.kind||"Identifier"!==t.declarations[0].id.type)&&this.raise(t.start,(n?"for-in":"for-of")+" loop variable declaration may not have an initializer"),e.left=t,e.right=n?this.parseExpression():this.parseMaybeAssign(),this.expect(x.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,n?"ForInStatement":"ForOfStatement")},ce.parseVar=function(e,t,n){for(e.declarations=[],e.kind=n;;){var a=this.startNode();if(this.parseVarId(a,n),this.eat(x.eq)?a.init=this.parseMaybeAssign(t):"const"!==n||this.type===x._in||this.options.ecmaVersion>=6&&this.isContextual("of")?"Identifier"===a.id.type||t&&(this.type===x._in||this.isContextual("of"))?a.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(a,"VariableDeclarator")),!this.eat(x.comma))break}return e},ce.parseVarId=function(e,t){e.id=this.parseBindingAtom(),this.checkLValPattern(e.id,"var"===t?ee:te,!1)};var pe=1,fe=2,me=4;function Re(e,t){var n=t.key.name,a=e[n],r="true";return"MethodDefinition"!==t.type||"get"!==t.kind&&"set"!==t.kind||(r=(t.static?"s":"i")+t.kind),"iget"===a&&"iset"===r||"iset"===a&&"iget"===r||"sget"===a&&"sset"===r||"sset"===a&&"sget"===r?(e[n]="true",!1):!!a||(e[n]=r,!1)}function ye(e,t){var n=e.computed,a=e.key;return!n&&("Identifier"===a.type&&a.name===t||"Literal"===a.type&&a.value===t)}ce.parseFunction=function(e,t,n,a,r){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!a)&&(this.type===x.star&&t&fe&&this.unexpected(),e.generator=this.eat(x.star)),this.options.ecmaVersion>=8&&(e.async=!!a),t&pe&&(e.id=t&me&&this.type!==x.name?null:this.parseIdent(),!e.id||t&fe||this.checkLValSimple(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?ee:te:ne));var i=this.yieldPos,s=this.awaitPos,o=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(Z(e.async,e.generator)),t&pe||(e.id=this.type===x.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,n,!1,r),this.yieldPos=i,this.awaitPos=s,this.awaitIdentPos=o,this.finishNode(e,t&pe?"FunctionDeclaration":"FunctionExpression")},ce.parseFunctionParams=function(e){this.expect(x.parenL),e.params=this.parseBindingList(x.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},ce.parseClass=function(e,t){this.next();var n=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var a=this.enterClassBody(),r=this.startNode(),i=!1;for(r.body=[],this.expect(x.braceL);this.type!==x.braceR;){var s=this.parseClassElement(null!==e.superClass);s&&(r.body.push(s),"MethodDefinition"===s.type&&"constructor"===s.kind?(i&&this.raise(s.start,"Duplicate constructor in the same class"),i=!0):s.key&&"PrivateIdentifier"===s.key.type&&Re(a,s)&&this.raiseRecoverable(s.key.start,"Identifier '#"+s.key.name+"' has already been declared"))}return this.strict=n,this.next(),e.body=this.finishNode(r,"ClassBody"),this.exitClassBody(),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")},ce.parseClassElement=function(e){if(this.eat(x.semi))return null;var t=this.options.ecmaVersion,n=this.startNode(),a="",r=!1,i=!1,s="method",o=!1;if(this.eatContextual("static")){if(t>=13&&this.eat(x.braceL))return this.parseClassStaticBlock(n),n;this.isClassElementNameStart()||this.type===x.star?o=!0:a="static"}if(n.static=o,!a&&t>=8&&this.eatContextual("async")&&(!this.isClassElementNameStart()&&this.type!==x.star||this.canInsertSemicolon()?a="async":i=!0),!a&&(t>=9||!i)&&this.eat(x.star)&&(r=!0),!a&&!i&&!r){var d=this.value;(this.eatContextual("get")||this.eatContextual("set"))&&(this.isClassElementNameStart()?s=d:a=d)}if(a?(n.computed=!1,n.key=this.startNodeAt(this.lastTokStart,this.lastTokStartLoc),n.key.name=a,this.finishNode(n.key,"Identifier")):this.parseClassElementName(n),t<13||this.type===x.parenL||"method"!==s||r||i){var l=!n.static&&ye(n,"constructor"),c=l&&e;l&&"method"!==s&&this.raise(n.key.start,"Constructor can't have get/set modifier"),n.kind=l?"constructor":s,this.parseClassMethod(n,r,i,c)}else this.parseClassField(n);return n},ce.isClassElementNameStart=function(){return this.type===x.name||this.type===x.privateId||this.type===x.num||this.type===x.string||this.type===x.bracketL||this.type.keyword},ce.parseClassElementName=function(e){this.type===x.privateId?("constructor"===this.value&&this.raise(this.start,"Classes can't have an element named '#constructor'"),e.computed=!1,e.key=this.parsePrivateIdent()):this.parsePropertyName(e)},ce.parseClassMethod=function(e,t,n,a){var r=e.key;"constructor"===e.kind?(t&&this.raise(r.start,"Constructor can't be a generator"),n&&this.raise(r.start,"Constructor can't be an async method")):e.static&&ye(e,"prototype")&&this.raise(r.start,"Classes may not have a static property named prototype");var i=e.value=this.parseMethod(t,n,a);return"get"===e.kind&&0!==i.params.length&&this.raiseRecoverable(i.start,"getter should have no params"),"set"===e.kind&&1!==i.params.length&&this.raiseRecoverable(i.start,"setter should have exactly one param"),"set"===e.kind&&"RestElement"===i.params[0].type&&this.raiseRecoverable(i.params[0].start,"Setter cannot use rest params"),this.finishNode(e,"MethodDefinition")},ce.parseClassField=function(e){if(ye(e,"constructor")?this.raise(e.key.start,"Classes can't have a field named 'constructor'"):e.static&&ye(e,"prototype")&&this.raise(e.key.start,"Classes can't have a static field named 'prototype'"),this.eat(x.eq)){var t=this.currentThisScope(),n=t.inClassFieldInit;t.inClassFieldInit=!0,e.value=this.parseMaybeAssign(),t.inClassFieldInit=n}else e.value=null;return this.semicolon(),this.finishNode(e,"PropertyDefinition")},ce.parseClassStaticBlock=function(e){e.body=[];var t=this.labels;for(this.labels=[],this.enterScope(J|G);this.type!==x.braceR;){var n=this.parseStatement(null);e.body.push(n)}return this.next(),this.exitScope(),this.labels=t,this.finishNode(e,"StaticBlock")},ce.parseClassId=function(e,t){this.type===x.name?(e.id=this.parseIdent(),t&&this.checkLValSimple(e.id,te,!1)):(!0===t&&this.unexpected(),e.id=null)},ce.parseClassSuper=function(e){e.superClass=this.eat(x._extends)?this.parseExprSubscripts(!1):null},ce.enterClassBody=function(){var e={declared:Object.create(null),used:[]};return this.privateNameStack.push(e),e.declared},ce.exitClassBody=function(){for(var e=this.privateNameStack.pop(),t=e.declared,n=e.used,a=this.privateNameStack.length,r=0===a?null:this.privateNameStack[a-1],i=0;i=11&&(this.eatContextual("as")?(e.exported=this.parseModuleExportName(),this.checkExport(t,e.exported,this.lastTokStart)):e.exported=null),this.expectContextual("from"),this.type!==x.string&&this.unexpected(),e.source=this.parseExprAtom(),this.semicolon(),this.finishNode(e,"ExportAllDeclaration");if(this.eat(x._default)){var n;if(this.checkExport(t,"default",this.lastTokStart),this.type===x._function||(n=this.isAsyncFunction())){var a=this.startNode();this.next(),n&&this.next(),e.declaration=this.parseFunction(a,pe|me,!1,n)}else if(this.type===x._class){var r=this.startNode();e.declaration=this.parseClass(r,"nullableID")}else e.declaration=this.parseMaybeAssign(),this.semicolon();return this.finishNode(e,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement())e.declaration=this.parseStatement(null),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id,e.declaration.id.start),e.specifiers=[],e.source=null;else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==x.string&&this.unexpected(),e.source=this.parseExprAtom();else{for(var i=0,s=e.specifiers;i=13&&this.type===x.string){var e=this.parseLiteral(this.value);return O.test(e.value)&&this.raise(e.start,"An export name cannot include a lone surrogate."),e}return this.parseIdent(!0)},ce.adaptDirectivePrologue=function(e){for(var t=0;t=5&&"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"string"==typeof e.expression.value&&('"'===this.input[e.start]||"'"===this.input[e.start])};var be=ie.prototype;be.toAssignable=function(e,t,n){if(this.options.ecmaVersion>=6&&e)switch(e.type){case"Identifier":this.inAsync&&"await"===e.name&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",n&&this.checkPatternErrors(n,!0);for(var a=0,r=e.properties;a=8&&!s&&"async"===o.name&&!this.canInsertSemicolon()&&this.eat(x._function))return this.overrideContext(ve.f_expr),this.parseFunction(this.startNodeAt(r,i),0,!1,!0,t);if(a&&!this.canInsertSemicolon()){if(this.eat(x.arrow))return this.parseArrowExpression(this.startNodeAt(r,i),[o],!1,t);if(this.options.ecmaVersion>=8&&"async"===o.name&&this.type===x.name&&!s&&(!this.potentialArrowInForAwait||"of"!==this.value||this.containsEsc))return o=this.parseIdent(!1),!this.canInsertSemicolon()&&this.eat(x.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(r,i),[o],!0,t)}return o;case x.regexp:var d=this.value;return(n=this.parseLiteral(d.value)).regex={pattern:d.pattern,flags:d.flags},n;case x.num:case x.string:return this.parseLiteral(this.value);case x._null:case x._true:case x._false:return(n=this.startNode()).value=this.type===x._null?null:this.type===x._true,n.raw=this.type.keyword,this.next(),this.finishNode(n,"Literal");case x.parenL:var l=this.start,c=this.parseParenAndDistinguishExpression(a,t);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(c)&&(e.parenthesizedAssign=l),e.parenthesizedBind<0&&(e.parenthesizedBind=l)),c;case x.bracketL:return n=this.startNode(),this.next(),n.elements=this.parseExprList(x.bracketR,!0,!0,e),this.finishNode(n,"ArrayExpression");case x.braceL:return this.overrideContext(ve.b_expr),this.parseObj(!1,e);case x._function:return n=this.startNode(),this.next(),this.parseFunction(n,0);case x._class:return this.parseClass(this.startNode(),!1);case x._new:return this.parseNew();case x.backQuote:return this.parseTemplate();case x._import:return this.options.ecmaVersion>=11?this.parseExprImport():this.unexpected();default:this.unexpected()}},ke.parseExprImport=function(){var e=this.startNode();this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword import");var t=this.parseIdent(!0);switch(this.type){case x.parenL:return this.parseDynamicImport(e);case x.dot:return e.meta=t,this.parseImportMeta(e);default:this.unexpected()}},ke.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),!this.eat(x.parenR)){var t=this.start;this.eat(x.comma)&&this.eat(x.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")},ke.parseImportMeta=function(e){this.next();var t=this.containsEsc;return e.property=this.parseIdent(!0),"meta"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for import is 'import.meta'"),t&&this.raiseRecoverable(e.start,"'import.meta' must not contain escaped characters"),"module"===this.options.sourceType||this.options.allowImportExportEverywhere||this.raiseRecoverable(e.start,"Cannot use 'import.meta' outside a module"),this.finishNode(e,"MetaProperty")},ke.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),110===t.raw.charCodeAt(t.raw.length-1)&&(t.bigint=t.raw.slice(0,-1).replace(/_/g,"")),this.next(),this.finishNode(t,"Literal")},ke.parseParenExpression=function(){this.expect(x.parenL);var e=this.parseExpression();return this.expect(x.parenR),e},ke.parseParenAndDistinguishExpression=function(e,t){var n,a=this.start,r=this.startLoc,i=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var s,o=this.start,d=this.startLoc,l=[],c=!0,u=!1,h=new le,g=this.yieldPos,p=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==x.parenR;){if(c?c=!1:this.expect(x.comma),i&&this.afterTrailingComma(x.parenR,!0)){u=!0;break}if(this.type===x.ellipsis){s=this.start,l.push(this.parseParenItem(this.parseRestBinding())),this.type===x.comma&&this.raise(this.start,"Comma is not permitted after the rest element");break}l.push(this.parseMaybeAssign(!1,h,this.parseParenItem))}var f=this.lastTokEnd,m=this.lastTokEndLoc;if(this.expect(x.parenR),e&&!this.canInsertSemicolon()&&this.eat(x.arrow))return this.checkPatternErrors(h,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=g,this.awaitPos=p,this.parseParenArrowList(a,r,l,t);l.length&&!u||this.unexpected(this.lastTokStart),s&&this.unexpected(s),this.checkExpressionErrors(h,!0),this.yieldPos=g||this.yieldPos,this.awaitPos=p||this.awaitPos,l.length>1?((n=this.startNodeAt(o,d)).expressions=l,this.finishNodeAt(n,"SequenceExpression",f,m)):n=l[0]}else n=this.parseParenExpression();if(this.options.preserveParens){var R=this.startNodeAt(a,r);return R.expression=n,this.finishNode(R,"ParenthesizedExpression")}return n},ke.parseParenItem=function(e){return e},ke.parseParenArrowList=function(e,t,n,a){return this.parseArrowExpression(this.startNodeAt(e,t),n,!1,a)};var we=[];ke.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode(),t=this.parseIdent(!0);if(this.options.ecmaVersion>=6&&this.eat(x.dot)){e.meta=t;var n=this.containsEsc;return e.property=this.parseIdent(!0),"target"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is 'new.target'"),n&&this.raiseRecoverable(e.start,"'new.target' must not contain escaped characters"),this.allowNewDotTarget||this.raiseRecoverable(e.start,"'new.target' can only be used in functions and class static block"),this.finishNode(e,"MetaProperty")}var a=this.start,r=this.startLoc,i=this.type===x._import;return e.callee=this.parseSubscripts(this.parseExprAtom(),a,r,!0,!1),i&&"ImportExpression"===e.callee.type&&this.raise(a,"Cannot use new with import()"),this.eat(x.parenL)?e.arguments=this.parseExprList(x.parenR,this.options.ecmaVersion>=8,!1):e.arguments=we,this.finishNode(e,"NewExpression")},ke.parseTemplateElement=function(e){var t=e.isTagged,n=this.startNode();return this.type===x.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),n.value={raw:this.value,cooked:null}):n.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),n.tail=this.type===x.backQuote,this.finishNode(n,"TemplateElement")},ke.parseTemplate=function(e){void 0===e&&(e={});var t=e.isTagged;void 0===t&&(t=!1);var n=this.startNode();this.next(),n.expressions=[];var a=this.parseTemplateElement({isTagged:t});for(n.quasis=[a];!a.tail;)this.type===x.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(x.dollarBraceL),n.expressions.push(this.parseExpression()),this.expect(x.braceR),n.quasis.push(a=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(n,"TemplateLiteral")},ke.isAsyncProp=function(e){return!e.computed&&"Identifier"===e.key.type&&"async"===e.key.name&&(this.type===x.name||this.type===x.num||this.type===x.string||this.type===x.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===x.star)&&!v.test(this.input.slice(this.lastTokEnd,this.start))},ke.parseObj=function(e,t){var n=this.startNode(),a=!0,r={};for(n.properties=[],this.next();!this.eat(x.braceR);){if(a)a=!1;else if(this.expect(x.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(x.braceR))break;var i=this.parseProperty(e,t);e||this.checkPropClash(i,r,t),n.properties.push(i)}return this.finishNode(n,e?"ObjectPattern":"ObjectExpression")},ke.parseProperty=function(e,t){var n,a,r,i,s=this.startNode();if(this.options.ecmaVersion>=9&&this.eat(x.ellipsis))return e?(s.argument=this.parseIdent(!1),this.type===x.comma&&this.raise(this.start,"Comma is not permitted after the rest element"),this.finishNode(s,"RestElement")):(s.argument=this.parseMaybeAssign(!1,t),this.type===x.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(s,"SpreadElement"));this.options.ecmaVersion>=6&&(s.method=!1,s.shorthand=!1,(e||t)&&(r=this.start,i=this.startLoc),e||(n=this.eat(x.star)));var o=this.containsEsc;return this.parsePropertyName(s),!e&&!o&&this.options.ecmaVersion>=8&&!n&&this.isAsyncProp(s)?(a=!0,n=this.options.ecmaVersion>=9&&this.eat(x.star),this.parsePropertyName(s,t)):a=!1,this.parsePropertyValue(s,e,n,a,r,i,t,o),this.finishNode(s,"Property")},ke.parsePropertyValue=function(e,t,n,a,r,i,s,o){if((n||a)&&this.type===x.colon&&this.unexpected(),this.eat(x.colon))e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,s),e.kind="init";else if(this.options.ecmaVersion>=6&&this.type===x.parenL)t&&this.unexpected(),e.kind="init",e.method=!0,e.value=this.parseMethod(n,a);else if(t||o||!(this.options.ecmaVersion>=5)||e.computed||"Identifier"!==e.key.type||"get"!==e.key.name&&"set"!==e.key.name||this.type===x.comma||this.type===x.braceR||this.type===x.eq)this.options.ecmaVersion>=6&&!e.computed&&"Identifier"===e.key.type?((n||a)&&this.unexpected(),this.checkUnreserved(e.key),"await"!==e.key.name||this.awaitIdentPos||(this.awaitIdentPos=r),e.kind="init",t?e.value=this.parseMaybeDefault(r,i,this.copyNode(e.key)):this.type===x.eq&&s?(s.shorthandAssign<0&&(s.shorthandAssign=this.start),e.value=this.parseMaybeDefault(r,i,this.copyNode(e.key))):e.value=this.copyNode(e.key),e.shorthand=!0):this.unexpected();else{(n||a)&&this.unexpected(),e.kind=e.key.name,this.parsePropertyName(e),e.value=this.parseMethod(!1);var d="get"===e.kind?0:1;if(e.value.params.length!==d){var l=e.value.start;"get"===e.kind?this.raiseRecoverable(l,"getter should have no params"):this.raiseRecoverable(l,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")}},ke.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(x.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(x.bracketR),e.key;e.computed=!1}return e.key=this.type===x.num||this.type===x.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved)},ke.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)},ke.parseMethod=function(e,t,n){var a=this.startNode(),r=this.yieldPos,i=this.awaitPos,s=this.awaitIdentPos;return this.initFunction(a),this.options.ecmaVersion>=6&&(a.generator=e),this.options.ecmaVersion>=8&&(a.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(Z(t,a.generator)|G|(n?X:0)),this.expect(x.parenL),a.params=this.parseBindingList(x.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(a,!1,!0,!1),this.yieldPos=r,this.awaitPos=i,this.awaitIdentPos=s,this.finishNode(a,"FunctionExpression")},ke.parseArrowExpression=function(e,t,n,a){var r=this.yieldPos,i=this.awaitPos,s=this.awaitIdentPos;return this.enterScope(Z(n,!1)|W),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!n),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1,a),this.yieldPos=r,this.awaitPos=i,this.awaitIdentPos=s,this.finishNode(e,"ArrowFunctionExpression")},ke.parseFunctionBody=function(e,t,n,a){var r=t&&this.type!==x.braceL,i=this.strict,s=!1;if(r)e.body=this.parseMaybeAssign(a),e.expression=!0,this.checkParams(e,!1);else{var o=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);i&&!o||(s=this.strictDirective(this.end))&&o&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list");var d=this.labels;this.labels=[],s&&(this.strict=!0),this.checkParams(e,!i&&!s&&!t&&!n&&this.isSimpleParamList(e.params)),this.strict&&e.id&&this.checkLValSimple(e.id,re),e.body=this.parseBlock(!1,void 0,s&&!i),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=d}this.exitScope()},ke.isSimpleParamList=function(e){for(var t=0,n=e;t-1||r.functions.indexOf(e)>-1||r.var.indexOf(e)>-1,r.lexical.push(e),this.inModule&&r.flags&U&&delete this.undefinedExports[e]}else if(t===ae)this.currentScope().lexical.push(e);else if(t===ne){var i=this.currentScope();a=this.treatFunctionsAsVar?i.lexical.indexOf(e)>-1:i.lexical.indexOf(e)>-1||i.var.indexOf(e)>-1,i.functions.push(e)}else for(var s=this.scopeStack.length-1;s>=0;--s){var o=this.scopeStack[s];if(o.lexical.indexOf(e)>-1&&!(o.flags&q&&o.lexical[0]===e)||!this.treatFunctionsAsVarInScope(o)&&o.functions.indexOf(e)>-1){a=!0;break}if(o.var.push(e),this.inModule&&o.flags&U&&delete this.undefinedExports[e],o.flags&K)break}a&&this.raiseRecoverable(n,"Identifier '"+e+"' has already been declared")},Se.checkLocalExport=function(e){-1===this.scopeStack[0].lexical.indexOf(e.name)&&-1===this.scopeStack[0].var.indexOf(e.name)&&(this.undefinedExports[e.name]=e)},Se.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]},Se.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(t.flags&K)return t}},Se.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(t.flags&K&&!(t.flags&W))return t}};var Te=function(e,t,n){this.type="",this.start=t,this.end=0,e.options.locations&&(this.loc=new B(e,n)),e.options.directSourceFile&&(this.sourceFile=e.options.directSourceFile),e.options.ranges&&(this.range=[t,0])},De=ie.prototype;function Le(e,t,n,a){return e.type=t,e.end=n,this.options.locations&&(e.loc.end=a),this.options.ranges&&(e.range[1]=n),e}De.startNode=function(){return new Te(this,this.start,this.startLoc)},De.startNodeAt=function(e,t){return new Te(this,e,t)},De.finishNode=function(e,t){return Le.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)},De.finishNodeAt=function(e,t,n,a){return Le.call(this,e,t,n,a)},De.copyNode=function(e){var t=new Te(this,e.start,this.startLoc);for(var n in e)t[n]=e[n];return t};var Ie="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",Fe=Ie+" Extended_Pictographic",Oe=Fe+" EBase EComp EMod EPres ExtPict",Ne={9:Ie,10:Fe,11:Fe,12:Oe,13:Oe},Be="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",Me="Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",Pe=Me+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",je=Pe+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho",Ve=je+" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi",$e={9:Me,10:Pe,11:je,12:Ve,13:Ve+" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"},Ue={};function ze(e){var t=Ue[e]={binary:I(Ne[e]+" "+Be),nonBinary:{General_Category:I(Be),Script:I($e[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}for(var He=0,Ye=[9,10,11,12,13];He=6?"uy":"")+(e.options.ecmaVersion>=9?"s":"")+(e.options.ecmaVersion>=13?"d":""),this.unicodeProperties=Ue[e.options.ecmaVersion>=13?13:e.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=[],this.backReferenceNames=[]};function Ge(e){return 36===e||e>=40&&e<=43||46===e||63===e||e>=91&&e<=94||e>=123&&e<=125}function Xe(e){return h(e,!0)||36===e||95===e}function Je(e){return g(e,!0)||36===e||95===e||8204===e||8205===e}function Ke(e){return e>=65&&e<=90||e>=97&&e<=122}function Ze(e){return e>=0&&e<=1114111}function Qe(e){return 100===e||68===e||115===e||83===e||119===e||87===e}function et(e){return Ke(e)||95===e}function tt(e){return et(e)||nt(e)}function nt(e){return e>=48&&e<=57}function at(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function rt(e){return e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:e-48}function it(e){return e>=48&&e<=55}qe.prototype.reset=function(e,t,n){var a=-1!==n.indexOf("u");this.start=0|e,this.source=t+"",this.flags=n,this.switchU=a&&this.parser.options.ecmaVersion>=6,this.switchN=a&&this.parser.options.ecmaVersion>=9},qe.prototype.raise=function(e){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+e)},qe.prototype.at=function(e,t){void 0===t&&(t=!1);var n=this.source,a=n.length;if(e>=a)return-1;var r=n.charCodeAt(e);if(!t&&!this.switchU||r<=55295||r>=57344||e+1>=a)return r;var i=n.charCodeAt(e+1);return i>=56320&&i<=57343?(r<<10)+i-56613888:r},qe.prototype.nextIndex=function(e,t){void 0===t&&(t=!1);var n=this.source,a=n.length;if(e>=a)return a;var r,i=n.charCodeAt(e);return!t&&!this.switchU||i<=55295||i>=57344||e+1>=a||(r=n.charCodeAt(e+1))<56320||r>57343?e+1:e+2},qe.prototype.current=function(e){return void 0===e&&(e=!1),this.at(this.pos,e)},qe.prototype.lookahead=function(e){return void 0===e&&(e=!1),this.at(this.nextIndex(this.pos,e),e)},qe.prototype.advance=function(e){void 0===e&&(e=!1),this.pos=this.nextIndex(this.pos,e)},qe.prototype.eat=function(e,t){return void 0===t&&(t=!1),this.current(t)===e&&(this.advance(t),!0)},We.validateRegExpFlags=function(e){for(var t=e.validFlags,n=e.flags,a=0;a-1&&this.raise(e.start,"Duplicate regular expression flag")}},We.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&e.groupNames.length>0&&(e.switchN=!0,this.regexp_pattern(e))},We.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames.length=0,e.backReferenceNames.length=0,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,n=e.backReferenceNames;t=9&&(n=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!n,!0}return e.pos=t,!1},We.regexp_eatQuantifier=function(e,t){return void 0===t&&(t=!1),!!this.regexp_eatQuantifierPrefix(e,t)&&(e.eat(63),!0)},We.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)},We.regexp_eatBracedQuantifier=function(e,t){var n=e.pos;if(e.eat(123)){var a=0,r=-1;if(this.regexp_eatDecimalDigits(e)&&(a=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(r=e.lastIntValue),e.eat(125)))return-1!==r&&r=9?this.regexp_groupSpecifier(e):63===e.current()&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1},We.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)},We.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1},We.regexp_eatSyntaxCharacter=function(e){var t=e.current();return!!Ge(t)&&(e.lastIntValue=t,e.advance(),!0)},We.regexp_eatPatternCharacters=function(e){for(var t=e.pos,n=0;-1!==(n=e.current())&&!Ge(n);)e.advance();return e.pos!==t},We.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return!(-1===t||36===t||t>=40&&t<=43||46===t||63===t||91===t||94===t||124===t||(e.advance(),0))},We.regexp_groupSpecifier=function(e){if(e.eat(63)){if(this.regexp_eatGroupName(e))return-1!==e.groupNames.indexOf(e.lastStringValue)&&e.raise("Duplicate capture group name"),void e.groupNames.push(e.lastStringValue);e.raise("Invalid group")}},We.regexp_eatGroupName=function(e){if(e.lastStringValue="",e.eat(60)){if(this.regexp_eatRegExpIdentifierName(e)&&e.eat(62))return!0;e.raise("Invalid capture group name")}return!1},We.regexp_eatRegExpIdentifierName=function(e){if(e.lastStringValue="",this.regexp_eatRegExpIdentifierStart(e)){for(e.lastStringValue+=F(e.lastIntValue);this.regexp_eatRegExpIdentifierPart(e);)e.lastStringValue+=F(e.lastIntValue);return!0}return!1},We.regexp_eatRegExpIdentifierStart=function(e){var t=e.pos,n=this.options.ecmaVersion>=11,a=e.current(n);return e.advance(n),92===a&&this.regexp_eatRegExpUnicodeEscapeSequence(e,n)&&(a=e.lastIntValue),Xe(a)?(e.lastIntValue=a,!0):(e.pos=t,!1)},We.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,n=this.options.ecmaVersion>=11,a=e.current(n);return e.advance(n),92===a&&this.regexp_eatRegExpUnicodeEscapeSequence(e,n)&&(a=e.lastIntValue),Je(a)?(e.lastIntValue=a,!0):(e.pos=t,!1)},We.regexp_eatAtomEscape=function(e){return!!(this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e))||(e.switchU&&(99===e.current()&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)},We.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var n=e.lastIntValue;if(e.switchU)return n>e.maxBackReference&&(e.maxBackReference=n),!0;if(n<=e.numCapturingParens)return!0;e.pos=t}return!1},We.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1},We.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e,!1)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)},We.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1},We.regexp_eatZero=function(e){return 48===e.current()&&!nt(e.lookahead())&&(e.lastIntValue=0,e.advance(),!0)},We.regexp_eatControlEscape=function(e){var t=e.current();return 116===t?(e.lastIntValue=9,e.advance(),!0):110===t?(e.lastIntValue=10,e.advance(),!0):118===t?(e.lastIntValue=11,e.advance(),!0):102===t?(e.lastIntValue=12,e.advance(),!0):114===t&&(e.lastIntValue=13,e.advance(),!0)},We.regexp_eatControlLetter=function(e){var t=e.current();return!!Ke(t)&&(e.lastIntValue=t%32,e.advance(),!0)},We.regexp_eatRegExpUnicodeEscapeSequence=function(e,t){void 0===t&&(t=!1);var n=e.pos,a=t||e.switchU;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var r=e.lastIntValue;if(a&&r>=55296&&r<=56319){var i=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var s=e.lastIntValue;if(s>=56320&&s<=57343)return e.lastIntValue=1024*(r-55296)+(s-56320)+65536,!0}e.pos=i,e.lastIntValue=r}return!0}if(a&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&Ze(e.lastIntValue))return!0;a&&e.raise("Invalid unicode escape"),e.pos=n}return!1},We.regexp_eatIdentityEscape=function(e){if(e.switchU)return!!this.regexp_eatSyntaxCharacter(e)||!!e.eat(47)&&(e.lastIntValue=47,!0);var t=e.current();return!(99===t||e.switchN&&107===t||(e.lastIntValue=t,e.advance(),0))},We.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do{e.lastIntValue=10*e.lastIntValue+(t-48),e.advance()}while((t=e.current())>=48&&t<=57);return!0}return!1},We.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(Qe(t))return e.lastIntValue=-1,e.advance(),!0;if(e.switchU&&this.options.ecmaVersion>=9&&(80===t||112===t)){if(e.lastIntValue=-1,e.advance(),e.eat(123)&&this.regexp_eatUnicodePropertyValueExpression(e)&&e.eat(125))return!0;e.raise("Invalid property name")}return!1},We.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var n=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var a=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,n,a),!0}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var r=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,r),!0}return!1},We.regexp_validateUnicodePropertyNameAndValue=function(e,t,n){D(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(n)||e.raise("Invalid property value")},We.regexp_validateUnicodePropertyNameOrValue=function(e,t){e.unicodeProperties.binary.test(t)||e.raise("Invalid property name")},We.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";et(t=e.current());)e.lastStringValue+=F(t),e.advance();return""!==e.lastStringValue},We.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";tt(t=e.current());)e.lastStringValue+=F(t),e.advance();return""!==e.lastStringValue},We.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)},We.regexp_eatCharacterClass=function(e){if(e.eat(91)){if(e.eat(94),this.regexp_classRanges(e),e.eat(93))return!0;e.raise("Unterminated character class")}return!1},We.regexp_classRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var n=e.lastIntValue;!e.switchU||-1!==t&&-1!==n||e.raise("Invalid character class"),-1!==t&&-1!==n&&t>n&&e.raise("Range out of order in character class")}}},We.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var n=e.current();(99===n||it(n))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var a=e.current();return 93!==a&&(e.lastIntValue=a,e.advance(),!0)},We.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)},We.regexp_eatClassControlLetter=function(e){var t=e.current();return!(!nt(t)&&95!==t||(e.lastIntValue=t%32,e.advance(),0))},We.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1},We.regexp_eatDecimalDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;nt(n=e.current());)e.lastIntValue=10*e.lastIntValue+(n-48),e.advance();return e.pos!==t},We.regexp_eatHexDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;at(n=e.current());)e.lastIntValue=16*e.lastIntValue+rt(n),e.advance();return e.pos!==t},We.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var n=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=64*t+8*n+e.lastIntValue:e.lastIntValue=8*t+n}else e.lastIntValue=t;return!0}return!1},We.regexp_eatOctalDigit=function(e){var t=e.current();return it(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)},We.regexp_eatFixedHexDigits=function(e,t){var n=e.pos;e.lastIntValue=0;for(var a=0;a=this.input.length?this.finishToken(x.eof):e.override?e.override(this):void this.readToken(this.fullCharCodeAtPos())},ot.readToken=function(e){return h(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},ot.fullCharCodeAtPos=function(){var e=this.input.charCodeAt(this.pos);if(e<=55295||e>=56320)return e;var t=this.input.charCodeAt(this.pos+1);return t<=56319||t>=57344?e:(e<<10)+t-56613888},ot.skipBlockComment=function(){var e=this.options.onComment&&this.curPosition(),t=this.pos,n=this.input.indexOf("*/",this.pos+=2);if(-1===n&&this.raise(this.pos-2,"Unterminated comment"),this.pos=n+2,this.options.locations)for(var a=void 0,r=t;(a=C(this.input,r,this.pos))>-1;)++this.curLine,r=this.lineStart=a;this.options.onComment&&this.options.onComment(!0,this.input.slice(t+2,n),t,this.pos,e,this.curPosition())},ot.skipLineComment=function(e){for(var t=this.pos,n=this.options.onComment&&this.curPosition(),a=this.input.charCodeAt(this.pos+=e);this.pos8&&e<14||e>=5760&&w.test(String.fromCharCode(e))))break e;++this.pos}}},ot.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var n=this.type;this.type=e,this.value=t,this.updateContext(n)},ot.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===e&&46===t?(this.pos+=3,this.finishToken(x.ellipsis)):(++this.pos,this.finishToken(x.dot))},ot.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===e?this.finishOp(x.assign,2):this.finishOp(x.slash,1)},ot.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),n=1,a=42===e?x.star:x.modulo;return this.options.ecmaVersion>=7&&42===e&&42===t&&(++n,a=x.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(x.assign,n+1):this.finishOp(a,n)},ot.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?this.options.ecmaVersion>=12&&61===this.input.charCodeAt(this.pos+2)?this.finishOp(x.assign,3):this.finishOp(124===e?x.logicalOR:x.logicalAND,2):61===t?this.finishOp(x.assign,2):this.finishOp(124===e?x.bitwiseOR:x.bitwiseAND,1)},ot.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(x.assign,2):this.finishOp(x.bitwiseXOR,1)},ot.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?45!==t||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!v.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(x.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===t?this.finishOp(x.assign,2):this.finishOp(x.plusMin,1)},ot.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),n=1;return t===e?(n=62===e&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+n)?this.finishOp(x.assign,n+1):this.finishOp(x.bitShift,n)):33!==t||60!==e||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===t&&(n=2),this.finishOp(x.relational,n)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},ot.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(x.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===e&&62===t&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(x.arrow)):this.finishOp(61===e?x.eq:x.prefix,1)},ot.readToken_question=function(){var e=this.options.ecmaVersion;if(e>=11){var t=this.input.charCodeAt(this.pos+1);if(46===t){var n=this.input.charCodeAt(this.pos+2);if(n<48||n>57)return this.finishOp(x.questionDot,2)}if(63===t)return e>=12&&61===this.input.charCodeAt(this.pos+2)?this.finishOp(x.assign,3):this.finishOp(x.coalesce,2)}return this.finishOp(x.question,1)},ot.readToken_numberSign=function(){var e=35;if(this.options.ecmaVersion>=13&&(++this.pos,h(e=this.fullCharCodeAtPos(),!0)||92===e))return this.finishToken(x.privateId,this.readWord1());this.raise(this.pos,"Unexpected character '"+F(e)+"'")},ot.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(x.parenL);case 41:return++this.pos,this.finishToken(x.parenR);case 59:return++this.pos,this.finishToken(x.semi);case 44:return++this.pos,this.finishToken(x.comma);case 91:return++this.pos,this.finishToken(x.bracketL);case 93:return++this.pos,this.finishToken(x.bracketR);case 123:return++this.pos,this.finishToken(x.braceL);case 125:return++this.pos,this.finishToken(x.braceR);case 58:return++this.pos,this.finishToken(x.colon);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(x.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(120===t||88===t)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===t||79===t)return this.readRadixNumber(8);if(98===t||66===t)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 63:return this.readToken_question();case 126:return this.finishOp(x.prefix,1);case 35:return this.readToken_numberSign()}this.raise(this.pos,"Unexpected character '"+F(e)+"'")},ot.finishOp=function(e,t){var n=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,n)},ot.readRegexp=function(){for(var e,t,n=this.pos;;){this.pos>=this.input.length&&this.raise(n,"Unterminated regular expression");var a=this.input.charAt(this.pos);if(v.test(a)&&this.raise(n,"Unterminated regular expression"),e)e=!1;else{if("["===a)t=!0;else if("]"===a&&t)t=!1;else if("/"===a&&!t)break;e="\\"===a}++this.pos}var r=this.input.slice(n,this.pos);++this.pos;var i=this.pos,s=this.readWord1();this.containsEsc&&this.unexpected(i);var o=this.regexpState||(this.regexpState=new qe(this));o.reset(n,r,s),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var d=null;try{d=new RegExp(r,s)}catch(l){}return this.finishToken(x.regexp,{pattern:r,flags:s,value:d})},ot.readInt=function(e,t,n){for(var a=this.options.ecmaVersion>=12&&void 0===t,r=n&&48===this.input.charCodeAt(this.pos),i=this.pos,s=0,o=0,d=0,l=null==t?1/0:t;d=97?c-97+10:c>=65?c-65+10:c>=48&&c<=57?c-48:1/0)>=e)break;o=c,s=s*e+u}}return a&&95===o&&this.raiseRecoverable(this.pos-1,"Numeric separator is not allowed at the last of digits"),this.pos===i||null!=t&&this.pos-i!==t?null:s},ot.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var n=this.readInt(e);return null==n&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&110===this.input.charCodeAt(this.pos)?(n=lt(this.input.slice(t,this.pos)),++this.pos):h(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(x.num,n)},ot.readNumber=function(e){var t=this.pos;e||null!==this.readInt(10,void 0,!0)||this.raise(t,"Invalid number");var n=this.pos-t>=2&&48===this.input.charCodeAt(t);n&&this.strict&&this.raise(t,"Invalid number");var a=this.input.charCodeAt(this.pos);if(!n&&!e&&this.options.ecmaVersion>=11&&110===a){var r=lt(this.input.slice(t,this.pos));return++this.pos,h(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(x.num,r)}n&&/[89]/.test(this.input.slice(t,this.pos))&&(n=!1),46!==a||n||(++this.pos,this.readInt(10),a=this.input.charCodeAt(this.pos)),69!==a&&101!==a||n||(43!==(a=this.input.charCodeAt(++this.pos))&&45!==a||++this.pos,null===this.readInt(10)&&this.raise(t,"Invalid number")),h(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var i=dt(this.input.slice(t,this.pos),n);return this.finishToken(x.num,i)},ot.readCodePoint=function(){var e;if(123===this.input.charCodeAt(this.pos)){this.options.ecmaVersion<6&&this.unexpected();var t=++this.pos;e=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,e>1114111&&this.invalidStringToken(t,"Code point out of bounds")}else e=this.readHexChar(4);return e},ot.readString=function(e){for(var t="",n=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var a=this.input.charCodeAt(this.pos);if(a===e)break;92===a?(t+=this.input.slice(n,this.pos),t+=this.readEscapedChar(!1),n=this.pos):8232===a||8233===a?(this.options.ecmaVersion<10&&this.raise(this.start,"Unterminated string constant"),++this.pos,this.options.locations&&(this.curLine++,this.lineStart=this.pos)):(k(a)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(n,this.pos++),this.finishToken(x.string,t)};var ct={};ot.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e!==ct)throw e;this.readInvalidTemplateToken()}this.inTemplateElement=!1},ot.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw ct;this.raise(e,t)},ot.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var n=this.input.charCodeAt(this.pos);if(96===n||36===n&&123===this.input.charCodeAt(this.pos+1))return this.pos!==this.start||this.type!==x.template&&this.type!==x.invalidTemplate?(e+=this.input.slice(t,this.pos),this.finishToken(x.template,e)):36===n?(this.pos+=2,this.finishToken(x.dollarBraceL)):(++this.pos,this.finishToken(x.backQuote));if(92===n)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(k(n)){switch(e+=this.input.slice(t,this.pos),++this.pos,n){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(n)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}},ot.readInvalidTemplateToken=function(){for(;this.pos=48&&t<=55){var a=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],r=parseInt(a,8);return r>255&&(a=a.slice(0,-1),r=parseInt(a,8)),this.pos+=a.length-1,t=this.input.charCodeAt(this.pos),"0"===a&&56!==t&&57!==t||!this.strict&&!e||this.invalidStringToken(this.pos-1-a.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(r)}return k(t)?"":String.fromCharCode(t)}},ot.readHexChar=function(e){var t=this.pos,n=this.readInt(16,e);return null===n&&this.invalidStringToken(t,"Bad character escape sequence"),n},ot.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,n=this.pos,a=this.options.ecmaVersion>=6;this.pos{"use strict";n.r(t),n.d(t,{default:()=>B});var a=n(87462),r=n(67294),i=n(72389),s=n(86010),o=n(66412),d=n(35281),l=n(87594),c=n.n(l);const u=/title=(?["'])(?.*?)\1/,h=/\{(?[\d,-]+)\}/,g={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function p(e,t){const n=e.map((e=>{const{start:n,end:a}=g[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${a})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function f(e,t){let n=e.replace(/\n$/,"");const{language:a,magicComments:r,metastring:i}=t;if(i&&h.test(i)){const e=i.match(h).groups.range;if(0===r.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${i}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=r[0].className,a=c()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(a),code:n}}if(void 0===a)return{lineClassNames:{},code:n};const s=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return p(["js","jsBlock"],t);case"jsx":case"tsx":return p(["js","jsBlock","jsx"],t);case"html":return p(["js","jsBlock","html"],t);case"python":case"py":case"bash":return p(["bash"],t);case"markdown":case"md":return p(["html","jsx","bash"],t);default:return p(Object.keys(g),t)}}(a,r),o=n.split("\n"),d=Object.fromEntries(r.map((e=>[e.className,{start:0,range:""}]))),l=Object.fromEntries(r.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),u=Object.fromEntries(r.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),f=Object.fromEntries(r.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let c=0;cvoid 0!==e));l[t]?d[l[t]].range+=`${c},`:u[t]?d[u[t]].start=c:f[t]&&(d[f[t]].range+=`${d[f[t]].start}-${c-1},`),o.splice(c,1)}n=o.join("\n");const m={};return Object.entries(d).forEach((e=>{let[t,{range:n}]=e;c()(n).forEach((e=>{m[e]??=[],m[e].push(t)}))})),{lineClassNames:m,code:n}}const m="codeBlockContainer_Ckt0";function R(e){let{as:t,...n}=e;const i=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[a,r]=e;const i=t[a];i&&"string"==typeof r&&(n[i]=r)})),n}((0,o.p)());return r.createElement(t,(0,a.Z)({},n,{style:i,className:(0,s.default)(n.className,m,d.k.common.codeBlock)}))}const y={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function b(e){let{children:t,className:n}=e;return r.createElement(R,{as:"pre",tabIndex:0,className:(0,s.default)(y.codeBlockStandalone,"thin-scrollbar",n)},r.createElement("code",{className:y.codeBlockLines},t))}var x=n(86668),v=n(902);const _={attributes:!0,characterData:!0,childList:!0,subtree:!0};function k(e,t){const[n,a]=(0,r.useState)(),i=(0,r.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,r.useEffect)((()=>{i()}),[i]),function(e,t,n){void 0===n&&(n=_);const a=(0,v.zX)(t),i=(0,v.Ql)(n);(0,r.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,i),()=>t.disconnect()}),[e,a,i])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),i())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var C=n(23746);const w="codeLine_lJS_",E="codeLineNumber_Tfdd",S="codeLineContent_feaV";function A(e){let{line:t,classNames:n,showLineNumbers:i,getLineProps:o,getTokenProps:d}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const l=o({line:t,className:(0,s.default)(n,i&&w)}),c=t.map(((e,t)=>r.createElement("span",(0,a.Z)({key:t},d({token:e,key:t})))));return r.createElement("span",l,i?r.createElement(r.Fragment,null,r.createElement("span",{className:E}),r.createElement("span",{className:S},c)):c,r.createElement("br",null))}var T=n(95999);const D={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function L(e){let{code:t,className:n}=e;const[a,i]=(0,r.useState)(!1),o=(0,r.useRef)(void 0),d=(0,r.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;const a=document.createElement("textarea"),r=document.activeElement;a.value=e,a.setAttribute("readonly",""),a.style.contain="strict",a.style.position="absolute",a.style.left="-9999px",a.style.fontSize="12pt";const i=document.getSelection();let s=!1;i.rangeCount>0&&(s=i.getRangeAt(0)),n.append(a),a.select(),a.selectionStart=0,a.selectionEnd=e.length;let o=!1;try{o=document.execCommand("copy")}catch{}a.remove(),s&&(i.removeAllRanges(),i.addRange(s)),r&&r.focus()}(t),i(!0),o.current=window.setTimeout((()=>{i(!1)}),1e3)}),[t]);return(0,r.useEffect)((()=>()=>window.clearTimeout(o.current)),[]),r.createElement("button",{type:"button","aria-label":a?(0,T.translate)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,T.translate)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,T.translate)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,s.default)("clean-btn",n,D.copyButton,a&&D.copyButtonCopied),onClick:d},r.createElement("span",{className:D.copyButtonIcons,"aria-hidden":"true"},r.createElement("svg",{className:D.copyButtonIcon,viewBox:"0 0 24 24"},r.createElement("path",{d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})),r.createElement("svg",{className:D.copyButtonSuccessIcon,viewBox:"0 0 24 24"},r.createElement("path",{d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"}))))}const I="wordWrapButtonIcon_Bwma",F="wordWrapButtonEnabled_EoeP";function O(e){let{className:t,onClick:n,isEnabled:a}=e;const i=(0,T.translate)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return r.createElement("button",{type:"button",onClick:n,className:(0,s.default)("clean-btn",t,a&&F),"aria-label":i,title:i},r.createElement("svg",{className:I,viewBox:"0 0 24 24","aria-hidden":"true"},r.createElement("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})))}function N(e){let{children:t,className:n="",metastring:i,title:d,showLineNumbers:l,language:c}=e;const{prism:{defaultLanguage:h,magicComments:g}}=(0,x.L)(),p=c??n.split(" ").find((e=>e.startsWith("language-")))?.replace(/language-/,"")??h;const m=(0,o.p)(),b=function(){const[e,t]=(0,r.useState)(!1),[n,a]=(0,r.useState)(!1),i=(0,r.useRef)(null),s=(0,r.useCallback)((()=>{const n=i.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[i,e]),o=(0,r.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=i.current,n=e>t||i.current.querySelector("code").hasAttribute("style");a(n)}),[i]);return k(i,o),(0,r.useEffect)((()=>{o()}),[e,o]),(0,r.useEffect)((()=>(window.addEventListener("resize",o,{passive:!0}),()=>{window.removeEventListener("resize",o)})),[o]),{codeBlockRef:i,isEnabled:e,isCodeScrollable:n,toggle:s}}(),v=function(e){return e?.match(u)?.groups.title??""}(i)||d,{lineClassNames:_,code:w}=f(t,{metastring:i,language:p,magicComments:g}),E=l??function(e){return Boolean(e?.includes("showLineNumbers"))}(i);return r.createElement(R,{as:"div",className:(0,s.default)(n,p&&!n.includes(`language-${p}`)&&`language-${p}`)},v&&r.createElement("div",{className:y.codeBlockTitle},v),r.createElement("div",{className:y.codeBlockContent},r.createElement(C.ZP,(0,a.Z)({},C.lG,{theme:m,code:w,language:p??"text"}),(e=>{let{className:t,tokens:n,getLineProps:a,getTokenProps:i}=e;return r.createElement("pre",{tabIndex:0,ref:b.codeBlockRef,className:(0,s.default)(t,y.codeBlock,"thin-scrollbar")},r.createElement("code",{className:(0,s.default)(y.codeBlockLines,E&&y.codeBlockLinesWithNumbering)},n.map(((e,t)=>r.createElement(A,{key:t,line:e,getLineProps:a,getTokenProps:i,classNames:_[t],showLineNumbers:E})))))})),r.createElement("div",{className:y.buttonGroup},(b.isEnabled||b.isCodeScrollable)&&r.createElement(O,{className:y.codeButton,onClick:()=>b.toggle(),isEnabled:b.isEnabled}),r.createElement(L,{className:y.codeButton,code:w}))))}function B(e){let{children:t,...n}=e;const s=(0,i.default)(),o=function(e){return r.Children.toArray(e).some((e=>(0,r.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),d="string"==typeof o?N:b;return r.createElement(d,(0,a.Z)({key:String(s)},n),o)}},93454:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>Le});var a=n(67294),r=n(1944),i=n(902);const s=a.createContext(null);function o(e){let{children:t,content:n}=e;const r=function(e){return(0,a.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return a.createElement(s.Provider,{value:r},t)}function d(){const e=(0,a.useContext)(s);if(null===e)throw new i.i6("DocProvider");return e}function l(){const{metadata:e,frontMatter:t,assets:n}=d();return a.createElement(r.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var c=n(86010),u=n(87524),h=n(87462),g=n(95999),p=n(39960);function f(e){const{permalink:t,title:n,subLabel:r,isNext:i}=e;return a.createElement(p.default,{className:(0,c.default)("pagination-nav__link",i?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},r&&a.createElement("div",{className:"pagination-nav__sublabel"},r),a.createElement("div",{className:"pagination-nav__label"},n))}function m(e){const{previous:t,next:n}=e;return a.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,g.translate)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages navigation",description:"The ARIA label for the docs pagination"})},t&&a.createElement(f,(0,h.Z)({},t,{subLabel:a.createElement(g.default,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),n&&a.createElement(f,(0,h.Z)({},n,{subLabel:a.createElement(g.default,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}function R(){const{metadata:e}=d();return a.createElement(m,{previous:e.previous,next:e.next})}var y=n(52263),b=n(94104),x=n(35281),v=n(60373),_=n(74477);const k={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(g.default,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(g.default,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function C(e){const t=k[e.versionMetadata.banner];return a.createElement(t,e)}function w(e){let{versionLabel:t,to:n,onClick:r}=e;return a.createElement(g.default,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:a.createElement("b",null,a.createElement(p.default,{to:n,onClick:r},a.createElement(g.default,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function E(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:r}}=(0,y.default)(),{pluginId:i}=(0,b.gA)({failfast:!0}),{savePreferredVersionName:s}=(0,v.J)(i),{latestDocSuggestion:o,latestVersionSuggestion:d}=(0,b.Jo)(i),l=o??(u=d).docs.find((e=>e.id===u.mainDocId));var u;return a.createElement("div",{className:(0,c.default)(t,x.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},a.createElement("div",null,a.createElement(C,{siteTitle:r,versionMetadata:n})),a.createElement("div",{className:"margin-top--md"},a.createElement(w,{versionLabel:d.label,to:l.path,onClick:()=>s(d.name)})))}function S(e){let{className:t}=e;const n=(0,_.E)();return n.banner?a.createElement(E,{className:t,versionMetadata:n}):null}function A(e){let{className:t}=e;const n=(0,_.E)();return n.badge?a.createElement("span",{className:(0,c.default)(t,x.k.docs.docVersionBadge,"badge badge--secondary")},a.createElement(g.default,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label}},"Version: {versionLabel}")):null}function T(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return a.createElement(g.default,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:a.createElement("b",null,a.createElement("time",{dateTime:new Date(1e3*t).toISOString()},n))}}," on {date}")}function D(e){let{lastUpdatedBy:t}=e;return a.createElement(g.default,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:a.createElement("b",null,t)}}," by {user}")}function L(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:r}=e;return a.createElement("span",{className:x.k.common.lastUpdated},a.createElement(g.default,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?a.createElement(T,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:r?a.createElement(D,{lastUpdatedBy:r}):""}},"Last updated{atDate}{byUser}"),!1)}var I=n(86121),F=n.n(I);const O="tag_zVej",N="tagRegular_sFm0",B="tagWithCount_h2kH";function M(e){let{permalink:t,label:n,count:r}=e;return a.createElement(p.default,{href:t,className:(0,c.default)(O,r?B:N)},n,r&&a.createElement("span",null,r))}const P="tags_jXut",j="tag_QGVx";function V(e){let{tags:t}=e;return a.createElement(a.Fragment,null,a.createElement("b",null,a.createElement(g.default,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list"},"Tags:")),a.createElement("ul",{className:(0,c.default)(P,"padding--none","margin-left--sm")},t.map((e=>{let{label:t,permalink:n}=e;return a.createElement("li",{key:n,className:j},a.createElement(M,{label:t,permalink:n}))}))))}const $="lastUpdated_vwxv";function U(e){return a.createElement("div",{className:(0,c.default)(x.k.docs.docFooterTagsRow,"row margin-bottom--sm")},a.createElement("div",{className:"col"},a.createElement(V,e)))}function z(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:r,formattedLastUpdatedAt:i}=e;return a.createElement("div",{className:(0,c.default)(x.k.docs.docFooterEditMetaRow,"row")},a.createElement("div",{className:"col"},t&&a.createElement(F(),{editUrl:t})),a.createElement("div",{className:(0,c.default)("col",$)},(n||r)&&a.createElement(L,{lastUpdatedAt:n,formattedLastUpdatedAt:i,lastUpdatedBy:r})))}function H(){const{metadata:e}=d(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:r,lastUpdatedBy:i,tags:s}=e,o=s.length>0,l=!!(t||n||i);return o||l?a.createElement("footer",{className:(0,c.default)(x.k.docs.docFooter,"docusaurus-mt-lg")},o&&a.createElement(U,{tags:s}),l&&a.createElement(z,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:i,formattedLastUpdatedAt:r})):null}var Y=n(86043),W=n(86668);function q(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...r}=e;n>=0?t[n].children.push(r):a.push(r)})),a}function G(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=G({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function X(e){const t=e.getBoundingClientRect();return t.top===t.bottom?X(e.parentNode):t}function J(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>X(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function Z(e){const t=(0,a.useRef)(void 0),n=K();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:r,minHeadingLevel:i,maxHeadingLevel:s}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let r=t;r<=n;r+=1)a.push(`h${r}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:i,maxHeadingLevel:s}),d=J(o,{anchorTopOffset:n.current}),l=e.find((e=>d&&d.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(r),e.classList.add(r),t.current=e):e.classList.remove(r)}(e,e===l)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}function Q(e){let{toc:t,className:n,linkClassName:r,isChild:i}=e;return t.length?a.createElement("ul",{className:i?void 0:n},t.map((e=>a.createElement("li",{key:e.id},a.createElement("a",{href:`#${e.id}`,className:r??void 0,dangerouslySetInnerHTML:{__html:e.value}}),a.createElement(Q,{isChild:!0,toc:e.children,className:n,linkClassName:r}))))):null}const ee=a.memo(Q);function te(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:r="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:s,maxHeadingLevel:o,...d}=e;const l=(0,W.L)(),c=s??l.tableOfContents.minHeadingLevel,u=o??l.tableOfContents.maxHeadingLevel,g=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:r}=e;return(0,a.useMemo)((()=>G({toc:q(t),minHeadingLevel:n,maxHeadingLevel:r})),[t,n,r])}({toc:t,minHeadingLevel:c,maxHeadingLevel:u});return Z((0,a.useMemo)((()=>{if(r&&i)return{linkClassName:r,linkActiveClassName:i,minHeadingLevel:c,maxHeadingLevel:u}}),[r,i,c,u])),a.createElement(ee,(0,h.Z)({toc:g,className:n,linkClassName:r},d))}const ne="tocCollapsibleButton_TO0P",ae="tocCollapsibleButtonExpanded_MG3E";function re(e){let{collapsed:t,...n}=e;return a.createElement("button",(0,h.Z)({type:"button"},n,{className:(0,c.default)("clean-btn",ne,!t&&ae,n.className)}),a.createElement(g.default,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component"},"On this page"))}const ie="tocCollapsible_ETCw",se="tocCollapsibleContent_vkbj",oe="tocCollapsibleExpanded_sAul";function de(e){let{toc:t,className:n,minHeadingLevel:r,maxHeadingLevel:i}=e;const{collapsed:s,toggleCollapsed:o}=(0,Y.u)({initialState:!0});return a.createElement("div",{className:(0,c.default)(ie,!s&&oe,n)},a.createElement(re,{collapsed:s,onClick:o}),a.createElement(Y.z,{lazy:!0,className:se,collapsed:s},a.createElement(te,{toc:t,minHeadingLevel:r,maxHeadingLevel:i})))}const le="tocMobile_ITEo";function ce(){const{toc:e,frontMatter:t}=d();return a.createElement(de,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,c.default)(x.k.docs.docTocMobile,le)})}const ue="tableOfContents_bqdL";function he(e){let{className:t,...n}=e;return a.createElement("div",{className:(0,c.default)(ue,"thin-scrollbar",t)},a.createElement(te,(0,h.Z)({},n,{linkClassName:"table-of-contents__link toc-highlight",linkActiveClassName:"table-of-contents__link--active"})))}function ge(){const{toc:e,frontMatter:t}=d();return a.createElement(he,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:x.k.docs.docTocDesktop})}var pe=n(92503),fe=n(51788),me=n.n(fe);function Re(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=d();return t.hide_title||void 0!==n?null:e.title}();return a.createElement("div",{className:(0,c.default)(x.k.docs.docMarkdown,"markdown")},n&&a.createElement("header",null,a.createElement(pe.Z,{as:"h1"},n)),a.createElement(me(),null,t))}var ye=n(53438),be=n(48596),xe=n(44996);function ve(e){return a.createElement("svg",(0,h.Z)({viewBox:"0 0 24 24"},e),a.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const _e="breadcrumbHomeIcon_YNFT";function ke(){const e=(0,xe.default)("/");return a.createElement("li",{className:"breadcrumbs__item"},a.createElement(p.default,{"aria-label":(0,g.translate)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},a.createElement(ve,{className:_e})))}const Ce="breadcrumbsContainer_Z_bl";function we(e){let{children:t,href:n,isLast:r}=e;const i="breadcrumbs__link";return r?a.createElement("span",{className:i,itemProp:"name"},t):n?a.createElement(p.default,{className:i,href:n,itemProp:"item"},a.createElement("span",{itemProp:"name"},t)):a.createElement("span",{className:i},t)}function Ee(e){let{children:t,active:n,index:r,addMicrodata:i}=e;return a.createElement("li",(0,h.Z)({},i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,c.default)("breadcrumbs__item",{"breadcrumbs__item--active":n})}),t,a.createElement("meta",{itemProp:"position",content:String(r+1)}))}function Se(){const e=(0,ye.s1)(),t=(0,be.Ns)();return e?a.createElement("nav",{className:(0,c.default)(x.k.docs.docBreadcrumbs,Ce),"aria-label":(0,g.translate)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},a.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&a.createElement(ke,null),e.map(((t,n)=>{const r=n===e.length-1;return a.createElement(Ee,{key:n,active:r,index:n,addMicrodata:!!t.href},a.createElement(we,{href:t.href,isLast:r},t.label))})))):null}const Ae="docItemContainer_Djhp",Te="docItemCol_VOVn";function De(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=d(),n=(0,u.i)(),r=e.hide_table_of_contents,i=!r&&t.length>0;return{hidden:r,mobile:i?a.createElement(ce,null):void 0,desktop:!i||"desktop"!==n&&"ssr"!==n?void 0:a.createElement(ge,null)}}();return a.createElement("div",{className:"row"},a.createElement("div",{className:(0,c.default)("col",!n.hidden&&Te)},a.createElement(S,null),a.createElement("div",{className:Ae},a.createElement("article",null,a.createElement(Se,null),a.createElement(A,null),n.mobile,a.createElement(Re,null,t),a.createElement(H,null)),a.createElement(R,null))),n.desktop&&a.createElement("div",{className:"col col--3"},n.desktop))}function Le(e){const t=`docs-doc-id-${e.content.metadata.unversionedId}`,n=e.content;return a.createElement(o,{content:e.content},a.createElement(r.FG,{className:t},a.createElement(l,null),a.createElement(De,null,a.createElement(n,null))))}},46215:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var a=n(67294),r=n(95999),i=n(35281),s=n(56262);function o(e){let{editUrl:t}=e;return a.createElement("a",{href:t,target:"_blank",rel:"noreferrer noopener",className:i.k.common.editThisPage},a.createElement(s.default,null),a.createElement(r.default,{id:"theme.common.editThisPage",description:"The link label to edit the current page"},"Edit this page"))}},92503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var a=n(87462),r=n(67294),i=n(86010),s=n(95999),o=n(86668),d=n(39960);const l="anchorWithStickyNavbar_LWe7",c="anchorWithHideOnScrollNavbar_WYt5";function u(e){let{as:t,id:n,...u}=e;const{navbar:{hideOnScroll:h}}=(0,o.L)();if("h1"===t||!n)return r.createElement(t,(0,a.Z)({},u,{id:void 0}));const g=(0,s.translate)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return r.createElement(t,(0,a.Z)({},u,{className:(0,i.default)("anchor",h?c:l,u.className),id:n}),u.children,r.createElement(d.default,{className:"hash-link",to:`#${n}`,"aria-label":g,title:g},"\u200b"))}},56262:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var a=n(87462),r=n(67294),i=n(86010);const s="iconEdit_Z9Sw";function o(e){let{className:t,...n}=e;return r.createElement("svg",(0,a.Z)({fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,i.default)(s,t),"aria-hidden":"true"},n),r.createElement("g",null,r.createElement("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})))}},42752:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>O});var a=n(87462),r=n(67294),i=n(35742);var s=n(20625),o=n.n(s);var d=n(39960);var l=n(86010),c=n(72389),u=n(86043);const h="details_lb9f",g="isBrowser_bmU9",p="collapsibleContent_i85q";function f(e){return!!e&&("SUMMARY"===e.tagName||f(e.parentElement))}function m(e,t){return!!e&&(e===t||m(e.parentElement,t))}function R(e){let{summary:t,children:n,...i}=e;const s=(0,c.default)(),o=(0,r.useRef)(null),{collapsed:d,setCollapsed:R}=(0,u.u)({initialState:!i.open}),[y,b]=(0,r.useState)(i.open);return r.createElement("details",(0,a.Z)({},i,{ref:o,open:y,"data-collapsed":d,className:(0,l.default)(h,s&&g,i.className),onMouseDown:e=>{f(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;f(t)&&m(t,o.current)&&(e.preventDefault(),d?(R(!1),b(!0)):R(!0))}}),t??r.createElement("summary",null,"Details"),r.createElement(u.z,{lazy:!1,collapsed:d,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{R(e),b(!e)}},r.createElement("div",{className:p},n)))}const y="details_b_Ee";function b(e){let{...t}=e;return r.createElement(R,(0,a.Z)({},t,{className:(0,l.default)("alert alert--info",y,t.className)}))}var x=n(92503);function v(e){return r.createElement(x.Z,e)}const _="containsTaskList_mC6p";const k="img_ev3q";var C=n(35281),w=n(95999);const E="admonition_LlT9",S="admonitionHeading_tbUL",A="admonitionIcon_kALy",T="admonitionContent_S0QG";const D={note:{infimaClassName:"secondary",iconComponent:function(){return r.createElement("svg",{viewBox:"0 0 14 16"},r.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:r.createElement(w.default,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return r.createElement("svg",{viewBox:"0 0 12 16"},r.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:r.createElement(w.default,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return r.createElement("svg",{viewBox:"0 0 12 16"},r.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:r.createElement(w.default,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return r.createElement("svg",{viewBox:"0 0 14 16"},r.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:r.createElement(w.default,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return r.createElement("svg",{viewBox:"0 0 16 16"},r.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:r.createElement(w.default,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},L={secondary:"note",important:"info",success:"tip",warning:"danger"};function I(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=r.Children.toArray(e),n=t.find((e=>r.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=r.createElement(r.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:n,rest:a}}(e.children);return{...e,title:e.title??t,children:n}}var F=n(92969);const O={head:function(e){const t=r.Children.map(e.children,(e=>r.isValidElement(e)?function(e){if(e.props?.mdxType&&e.props.originalType){const{mdxType:t,originalType:n,...a}=e.props;return r.createElement(e.props.originalType,a)}return e}(e):e));return r.createElement(i.Z,e,t)},code:function(e){const t=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return r.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")||(0,r.isValidElement)(e)&&t.includes(e.props?.mdxType)))?r.createElement("code",e):r.createElement(o(),e)},a:function(e){return r.createElement(d.default,e)},pre:function(e){return r.createElement(o(),(0,r.isValidElement)(e.children)&&"code"===e.children.props?.originalType?e.children.props:{...e})},details:function(e){const t=r.Children.toArray(e.children),n=t.find((e=>r.isValidElement(e)&&"summary"===e.props?.mdxType)),i=r.createElement(r.Fragment,null,t.filter((e=>e!==n)));return r.createElement(b,(0,a.Z)({},e,{summary:n}),i)},ul:function(e){return r.createElement("ul",(0,a.Z)({},e,{className:(t=e.className,(0,l.default)(t,t?.includes("contains-task-list")&&_))}));var t},img:function(e){return r.createElement("img",(0,a.Z)({loading:"lazy"},e,{className:(t=e.className,(0,l.default)(t,k))}));var t},h1:e=>r.createElement(v,(0,a.Z)({as:"h1"},e)),h2:e=>r.createElement(v,(0,a.Z)({as:"h2"},e)),h3:e=>r.createElement(v,(0,a.Z)({as:"h3"},e)),h4:e=>r.createElement(v,(0,a.Z)({as:"h4"},e)),h5:e=>r.createElement(v,(0,a.Z)({as:"h5"},e)),h6:e=>r.createElement(v,(0,a.Z)({as:"h6"},e)),admonition:function(e){const{children:t,type:n,title:a,icon:i}=I(e),s=function(e){const t=L[e]??e,n=D[t];return n||(console.warn(`No admonition config found for admonition type "${t}". Using Info as fallback.`),D.info)}(n),o=a??s.label,{iconComponent:d}=s,c=i??r.createElement(d,null);return r.createElement("div",{className:(0,l.default)(C.k.common.admonition,C.k.common.admonitionType(e.type),"alert",`alert--${s.infimaClassName}`,E)},r.createElement("div",{className:S},r.createElement("span",{className:A},c),o),r.createElement("div",{className:T},t))},mermaid:n.n(F)()}},45042:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var a=n(67294),r=n(3905),i=n(75854),s=n.n(i);function o(e){let{children:t}=e;return a.createElement(r.MDXProvider,{components:s()},t)}},85162:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var a=n(67294),r=n(86010);const i="tabItem_Ymn6";function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.default)(i,s),hidden:n},t)}},74866:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>_});var a=n(87462),r=n(67294),i=n(86010),s=n(12466),o=n(16550),d=n(91980),l=n(67392),c=n(50012);function u(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function h(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??u(n);return function(e){const t=(0,l.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function g(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function p(e){let{queryString:t=!1,groupId:n}=e;const a=(0,o.k6)(),i=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,d._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=h(e),[s,o]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!g({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=n.find((e=>e.default))??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:i}))),[d,l]=p({queryString:n,groupId:a}),[u,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),m=(()=>{const e=d??u;return g({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{m&&o(m)}),[m]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!g({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);o(e),l(e),f(e)}),[l,f,i]),tabValues:i}}var m=n(72389);const R="tabList__CuJ",y="tabItem_LNqP";function b(e){let{className:t,block:n,selectedValue:o,selectValue:d,tabValues:l}=e;const c=[],{blockElementScrollPositionUntilNextRender:u}=(0,s.o5)(),h=e=>{const t=e.currentTarget,n=c.indexOf(t),a=l[n].value;a!==o&&(u(t),d(a))},g=e=>{let t=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.default)("tabs",{"tabs--block":n},t)},l.map((e=>{let{value:t,label:n,attributes:s}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>c.push(e),onKeyDown:g,onClick:h},s,{className:(0,i.default)("tabs__item",y,s?.className,{"tabs__item--active":o===t})}),n??t)})))}function x(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=f(e);return r.createElement("div",{className:(0,i.default)("tabs-container",R)},r.createElement(b,(0,a.Z)({},e,t)),r.createElement(x,(0,a.Z)({},e,t)))}function _(e){const t=(0,m.default)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},74477:(e,t,n)=>{"use strict";n.d(t,{E:()=>o,q:()=>s});var a=n(67294),r=n(902);const i=a.createContext(null);function s(e){let{children:t,version:n}=e;return a.createElement(i.Provider,{value:n},t)}function o(){const e=(0,a.useContext)(i);if(null===e)throw new r.i6("DocsVersionProvider");return e}},66412:(e,t,n)=>{"use strict";n.d(t,{p:()=>i});var a=n(92949),r=n(86668);function i(){const{prism:e}=(0,r.L)(),{colorMode:t}=(0,a.I)(),n=e.theme,i=e.darkTheme||n;return"dark"===t?i:n}},81173:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Collapsible:()=>p.z,HtmlClassNameProvider:()=>R.FG,NavbarSecondaryMenuFiller:()=>b.Zo,PageMetadata:()=>R.d,ReactContextError:()=>m.i6,SkipToContentFallbackId:()=>D.u,SkipToContentLink:()=>D.l,ThemeClassNames:()=>f.k,composeProviders:()=>m.Qc,createStorageSlot:()=>r.WA,duplicates:()=>E.l,filterDocCardListItems:()=>s.MN,isMultiColumnFooterLinks:()=>C.a,isRegexpStringMatch:()=>w.F,listStorageKeys:()=>r._f,listTagsByLetters:()=>k,processAdmonitionProps:()=>T,translateTagsPageTitle:()=>_,uniq:()=>E.j,useCollapsible:()=>p.u,useColorMode:()=>y.I,useContextualSearchFilters:()=>i._q,useCurrentSidebarCategory:()=>s.jA,useDocsPreferredVersion:()=>A.J,useEvent:()=>m.zX,useIsomorphicLayoutEffect:()=>m.LI,usePluralForm:()=>g,usePrevious:()=>m.D9,usePrismTheme:()=>S.p,useStorageSlot:()=>r.Nk,useThemeConfig:()=>a.L,useWindowSize:()=>x.i});var a=n(86668),r=n(50012),i=n(43320),s=n(53438),o=n(67294),d=n(52263);const l=["zero","one","two","few","many","other"];function c(e){return l.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:c(["one","other"]),select:e=>1===e?"one":"other"};function h(){const{i18n:{currentLocale:e}}=(0,d.default)();return(0,o.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:c(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function g(){const e=h();return{selectMessage:(t,n)=>function(e,t,n){const a=e.split("|");if(1===a.length)return a[0];a.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${a.length}: ${e}`);const r=n.select(t),i=n.pluralForms.indexOf(r);return a[Math.min(i,a.length-1)]}(n,t,e)}}var p=n(86043),f=n(35281),m=n(902),R=n(1944),y=n(92949),b=n(13102),x=n(87524),v=n(95999);const _=()=>(0,v.translate)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});function k(e){const t={};return Object.values(e).forEach((e=>{const n=function(e){return e[0].toUpperCase()}(e.label);t[n]??=[],t[n].push(e)})),Object.entries(t).sort(((e,t)=>{let[n]=e,[a]=t;return n.localeCompare(a)})).map((e=>{let[t,n]=e;return{letter:t,tags:n.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}var C=n(42489),w=n(98022),E=n(67392),S=n(66412),A=n(60373);function T(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=o.Children.toArray(e),n=t.find((e=>o.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:n?.props.children,rest:a}}(e.children),a=e.title??t;return{...e,...a&&{title:a},children:n}}var D=n(55225)},14732:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAACCgAwAEAAAAAQAAACAAAAAAX7wP8AAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAACexJREFUWAmdV2tsXMUV/uY+d9d3/YqDHUKKSYLzDiIpUAEFB9EUWhApiYOaIgjQJog/ULVQVQVpS6nUltJUiNLmoZZfVMS0lGdBPOzmgSolEIVgEsvkYRLb8Sv2rnfv7t7X9JxZ72YNVJV6tbt37p2Z833nO2fOzAr8jyslU9rSzh6xcWNnyEOllNr2Pfcv8CL/4hBBfWm6MRnXzP6t1/3puBAi4ncduzt0vndOz+P2l13iy16W323fvsXcunWHz89/6P7BFYUwf08U+d8IZTjfjGmaEFINjSIJrxBFGrQTmqa/bZnxvzzU/twB7tyyfbW5Y+sHyoYa/Lmf/0ZApLra9dSa7mDX+w8sTOfT26AHt+iWICAfga/ECCXpwR+AqUhdNwUsW0dQpKdQfz0O54cPrn2uj2wZZIsnlRhXkfgyAiIlIVIC0e+77r3PD3I7zQREPutHEAgRQYeQDKjmUkhK5gS1InpJY6Io0mOOoXmulKYW2/LI2hd2kU0txQTETBJaFRnVpNhpDL7tvc2PGwl/VygDUciFPsWWx5pkQCNIMkP4lS/1MDT3ESbfi27oRzRXd/ydv3prwy9SZLOjs+MLeCpRyiRYqmdveSPc1nX3j61k9ER2Mh8Aao5RHlO6E7hOgujcHVIACL8kSPUwsq1FxaIfJmq19vaNy9ynb3txH+fEB68NqUTlwUpGbkzHKXj6vXuuj0yvu+B6EftUkrokM7VZRHI2QuQmIIs2rwrSpQjdyUJGbI5HlcazXWpLRFJaCUPTfLv9kbWd/ypjcX+ZgJpJxsRv3/3uMc2UbUExCmjytOfnjcqQWJk+Mh/PgduTJCXISMsk6lYNwrJMgqNEmEmAWMjQsIQeeqLv0ZtfXUTh5CEcMqn0JUYqFE+9d+dW29Ha/GLol8DZk/PecJPMQDNIfiOENCkEFq0wahfcEF4xUOFgzz536QEVjlitfukT/7ztfu5LdZcwZyjw67c3HCamK8l7WmLsW0lQviseWoQwnUThdAOK52hJjmvqtZ4MYNZSWJvOId6ShklLkUNTUUKtFFLB1kgF+dFjN79xGVlUqmvTFUv+5t07VgkdK70irSJa06Xp095XiZD5pA7pIyaKE6TfrAxA3yArkD9loXiyHvmMhF8gfcuuKXDFXydlpdDFyl++eesqdomxtWWzR9VQGchr7ZjBgSFtpz0u39UjUSInI/rRYgQwbxTxxQNILBmAcckYhYFyjaizY/lsRAXrPImyEhT7gCooqJJeSwPRMEGFkxt8RSJYwelDAGXupQ76LRtg0ciISjSzMUc9BpEyYDZRm8LDWcX5RV6i6EqEngFDj0EXlrJFYijbRHQFv7iwLSmNpaOzlcAyilrCgChUx05Nq/qhvtBjH6kYZhsgnGEldTjeBBFR3GmF0LZA1YjJ6DiX7gfsPtixZtTobcqQwohkCz8wttE5bT8et2w7YYCCT9dMEUoMyTDJnG/NYLDfR21/LZCLqWj5oyZcN4fkgiycJBdCE/lwBDfN+wnmNbYh441j/9B2MusJu8Yi3TwlCWNrHR0lBqatuXZMpwzW6Esmqr4WtWNxGwUcx7dv2Ii7Nt+JwbMD8IZj8IZsDI8OY936dbhpzTp44hTiiTh0q4BFcy/H8otXYf6sZQjCAqyYIe24BsPW84zK2MYn3aUkpLicUXVPBZx9ZhWU79TS4EUZNJlXY1HD1XDmJpH3snjh+Reh6zrW374BV37tq0qFo2PXIB18inp7CWosWrJeEWPZIbj+AKzipVI6ZFNGp5kAY59PwkgeUvGvJGEJnPkIYZCkZ3BlyybYRgK+TwWnIYf4irNIrByGOScH3wtgGTFcdWEHRgpvY0nTjUjGG7gKYzB9nBKzQPlFS8wjixKHmABfGtrb1cYgwmiPm6FeQSGqpGLpMR8OYb6zAa31y8kQMDR6Gm/1PoU5i220tGk4OLwLI5MDSrS5tQtxzQW/w2Vzr1MrJpefwtHxd0iNVjLmGy5t624+2qvQCZu23lTEx64Hr/9bHzHbE6NEJN/ViUMNoh9W5oqWdbSkTDqM+Nhz9BXYtgM9jJFLcZiWg0PDb5EyVJYpcjct2Yxa8p5D1zPwb4yH+2BqydCqIcGl3PPY2tf6GJOxSyHo7lb3MJTb1LpSmHSCoGzOBcexouEuNDsXk3GJ/rPHsffMw/CjcUwW+1S88/4IjqQfxUjuNBrqGqEbGnTNwGcjfdg39AxqY4voHONJrjpRgN8rx6YxK+utzGjb3g1diTqzvZANaEMKTQ0WNrY9Bceu4wqGIPAxTHJ/NtaLdHFU8a1PzMa8WW1orp0HwzCZPvJuAbs/fhxT2iewtEY/lpSmmwm6Hlnzyg1lLCbyuYMGELji3rzwei0rZk4WDodrLnxSr4s10SooUEXTYcdjWBBfgvkti+nsVYoUHURBJ1SVcL7nYcqdgqSNcvGsdrx/bn+YMJvM/BSthyncx6A9dMrmO1+UUqWr++fdkg8KP7vxjXPfvHP1h4inNzVZV2lfv2hTpOuamJyawEv7/0yMqZDoFnlOZ2BeRJQwfkCguTRODfdiz6edaDDnIhFz0GC3RGfdAd3TB4Fi8taf3vz3A4zBp64yboVJ+UX5tLL5Zdz+8OUHXmxtXC7oAO6/uv95/dW+e7WG+BVojC/CnGSbWmbMwfUnMOb1IYtjCI0DuLz2meiaizbQ1ifNM+ljctexNet3rsdLZdtlLL5/gQBlvE4bTiiLckW2mP2IC81Y5iyefP0O1MVbfdp0RChczUeaRMhTwlEcjThss17aZiKiBJRFccb8ziWUfFoLb260BOsva2x2Pirbriagsr/6BbVVXUgX0judpMNLsLDv0Ds76ZQwYiU004hFhkV7qmM2i6R5iagx5ouE0SIoZzTCN2xHmFEghj881fVHmus6yRpMFcZ3TmMo29V4MwjQBIPPaxMTE3c7Nc5VvL9nc9nOTd/asmVp0z1LJ8ay389lgpe9vN/vB34hiHxKRI9zoFAs+Keyk/4/zo1k72sZX7/0e9f96IF8wf1rFJICNTVXnjx5cjPbZoxqApUQUAf1C3nw4EFz4cKFRxOJxIJsNusODQ0tWLZs2dnqSau3rDavXn5BM9Uf2hKBmK6n39w/NPLBjpl/wbq6uppaW1uPO45Tm8vlTtB3CdnyyljVNllqpcbg4OBXMplMQM+S2g/xICZFN/67Zuye/tM5Y/L0w27ZofMYHkvTlae9vb0P5PN52d/fH504cYKqmapyFeUrcnR2dio1TNOcTSU1ogn3E/tdTIyUUX8u+b/iNJZIpVIV9fgdPcuNovQPmp9pDjvBc589fPhwjsKwIwzDZurqL2PxuMpFg5VBYtnc09OzkDvYQGXA/9ko29i7d+/8I0eOMAG2WyH/H45a9ExgQQ3bAAAAAElFTkSuQmCC"},20625:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var r=Object.getOwnPropertyDescriptor(t,n);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,r)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return r(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(n(67294)),d=s(n(98299)),l=s(n(52263)),c=s(n(72389)),u=n(86341),h=s(n(25510)),g=s(n(14732)),p=s(n(74071)),f=n(28084),m=[{names:["fbsource","fbs"],project:"fbsource",canonicalName:"fbsource"},{names:["www"],project:"facebook-www",canonicalName:"www"}];t.default=e=>{const{siteConfig:t}=(0,l.default)(),n=(0,f.usePluginData)("internaldocs-fb").opts.maxCodeBlockHeight,a=(0,c.default)(),r=(0,o.useRef)(null),i=(0,o.useRef)(null),s=(0,o.useRef)(null),R=(0,o.useRef)(!1),y=(0,o.useCallback)((e=>{R.current||(window.requestAnimationFrame((()=>{i.current&&s.current&&(e.target.scrollTop>0?i.current.style.boxShadow="0 1em 1em -1em black inset":i.current.style.boxShadow="none",e.target.scrollTop===e.target.scrollHeight-e.target.offsetHeight?s.current.style.boxShadow="none":s.current.style.boxShadow="0 -1em 1em -1em black inset"),R.current=!1})),R.current=!0)}),[]);(0,o.useEffect)((()=>{r.current&&(r.current.addEventListener("scroll",y),window.requestAnimationFrame((()=>{y({target:r.current})})))}));const b=function(e){try{return(0,d.default)(e)}catch(t){return o.default.createElement("p",{style:{color:"red",fontWeight:"bold"}},"Could not render codeblock")}}(Object.assign({children:""},e));if(!a)return b;if("string"!=typeof e.file)return b;let x,v,_,k;if((0,u.isInternal)()){if(!t.customFields)return b;const{fbRepoName:n,ossRepoPath:a}=t.customFields;if("string"!=typeof n)return b;x="string"==typeof a&&"string"!=typeof e.repo?function(){for(var e=arguments.length,t=new Array(e),n=0;ne.startsWith("/")?e.slice(1):e)).map((e=>e.endsWith("/")?e.slice(0,e.length-1):e)).join("/")}(a,e.file):e.file;const r=m.find((t=>{var a;return t.names.includes((null!==(a=e.repo)&&void 0!==a?a:n).toLowerCase())}));if(void 0===r)return b;v=function(e,t){const n=new URL("https://www.internalfb.com");return n.pathname=`/code/${e.canonicalName}/${t}`,n.toString()}(r,x),_=function(e,t){const n=new URL("https://www.internalfb.com/intern/nuclide/open/arc");return n.searchParams.append("project",e.project),n.searchParams.append("paths[0]",t),n.toString()}(r,x),k=function(e,t){if("fbsource"!==e.canonicalName||!t.startsWith("fbandroid"))return null;const n=new URL("fb-ide-opener://open");return n.searchParams.append("ide","intellij"),n.searchParams.append("filepath",`/fbsource/${t}`),n.toString()}(r,x)}else{if("string"!=typeof t.organizationName||"string"!=typeof t.projectName)return b;x=e.file,v=function(e,t,n){const a=new URL("https://github.com");return a.pathname=`/${e}/${t}/blob/master/${n}`,a.toString()}(t.organizationName,t.projectName,e.file),_=null,k=null}const C=x.split("/"),w=C[C.length-1];return o.default.createElement("div",null,o.default.createElement("a",{href:v,title:"Browse entire file",target:"_blank",rel:"noreferrer",onClick:()=>u.feedback.reportFeatureUsage({featureName:"browse-file",id:x}),className:p.default.CodeBlockFilenameTab},w),null!==_?o.default.createElement("a",{target:"_blank",rel:"noreferrer",href:_,onClick:()=>u.feedback.reportFeatureUsage({featureName:"open-in-vscode",id:x})},o.default.createElement("img",{style:{padding:"0 6px",height:"16px"},title:"Open in VSCode @ FB",src:h.default})):null,null!==k?o.default.createElement("a",{target:"_blank",rel:"noreferrer",href:k,onClick:()=>u.feedback.reportFeatureUsage({featureName:"open-in-android-studio",id:x})},o.default.createElement("img",{style:{padding:"0 6px",height:"16px"},title:"Open in Android Studio",src:g.default})):null,o.default.createElement("div",{style:{position:"relative"}},o.default.createElement("div",{ref:r,style:{maxHeight:n,overflowY:"auto"}},b),void 0===n?null:[o.default.createElement("div",{key:"shadowtop",ref:i,style:{bottom:0,left:0,right:0,top:0,pointerEvents:"none",transition:"all .2s ease-out",boxShadow:"none",position:"absolute"}}),o.default.createElement("div",{key:"shadowbottom",ref:s,style:{bottom:0,left:0,right:0,top:0,pointerEvents:"none",transition:"all .2s ease-out",boxShadow:"none",position:"absolute"}})]))}},25510:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAG/0lEQVR42r2XbVBU5xXH/yB1mpk6Tqa1k1Fsa9hFzdhJJhknzfRDZ2rHdpx2mklDbdOZ1tpWg0GhgK/4shIBESTaqiNjTaOGoMsCu4ggb8E3UqQUd3mxRUVjaBKbMO7dF5Zl793n9NxnL9wdGMcvJP/ZM+d57of9/8459z57FzMvSkCafZZc2mmWjC9NNlsiDKURzTbXXwaI3W4abG869s0jAw8W1wfPpNb871mwvtiO2NqTjNUs7GxtxJtdlLijnRa3EC1uGCOrS6m2OkZeNKdEiZgxrSv/isxrT85BXvN1FHQRtjePJ21rjVprvGpqfVAsadNBwpTq8jVY7J//YAbNu2PmGZXzsaP5FvL/QdyBcWxrpqStLWSp9lJqXYCNAypHdAl3ZCnDpNZ4Dz6yE3KWRAl4nMoN86yapWz+ALZrXHlLBHmthK1NlLSl2QAIktUZkJHqDERS63kktf7QU4VX5k1/fGySyLxhHld57vmXuN1B7L4szTmIYQhbLlLS5maRUvWQ5x9kw8AEhLDWhchS4/Mml32wAJOKr7jE8yL2t8w1q3zEzLPrfoptTYS894mzym3XM4Nw3tyoJW1poRSHogMIHcAIkVo3xp3xKQuLr803K59QmacU5cOEt/qGUNS1fKITBmDC5N2eU/873VhWvPWiprc8FhdjMDsuUVJOQ9BSpYSszlGyVvvJWhPgYAAXAzhMALP60t5ynPiEcGgggiN3ON8klLgzYCjOPAe7LkszbrUms4zGqNzbPiBkOTvnbji5kiv93OoKc8UBwSGz1TkFQCr92JM42DeOw4OEsn4VZQMaB+H4MPFIKrHG9tWY+YVi7LrKxmwWCzJCxdZmHsclQqbjbwBmLzhy/esWu+Kz1obY0C84ZJb7KsUEmLzxdrf9Hm/9m/RgGA0H+wVHBMc/1qH+iewLZ5DbSsht1DgENjcQh76PgA8d7kwY60//AYYWFLcnW+xexVqjG/oFhwSQe3s8QDzE9oZXUdKr4RB3orRPRWk/8V7F4duEw0NcaauGDTWE7Ho2bBDcEQ07r3DLXf1YfeB56GonOaqFxc3zU84piqU6RCk6gN0vs9yfMwHiIWIzzq5agWJPUDeUMCV9hAN9UZT0MxCPZXcHIb1WIPM8YcdlwkbHaQBzJ+8T4wdpoa15/tNnFSXFwYZ2v0g555dZ7s9OAZj27K/7+3ex330XZdyJ4t4oA+hZBkMI7PsXIaNuFK8dXTOti0QJEwAplV7FUqVXLAFk5r0J8Mhn/OWi7yC9eggFN7gLA1Hs90wC8FrwNT2P8tH7y/gTdBrAewbAWb/gkNli532lCTD9dEuveAGZdT78uZGwvlqD7TqPgCGKPBqKdACOIoYoZohD9wgFPcfij+cJgG9IAEV5hg2XsfHSSj8b650I0dPvTQVIM+jTz/0ImS4VOWyeVacio5awrkrFni5C2R02dmsodBMKPXoIuT/0IfG1buy8vCg2ioHZYG080Zm8pMKroGKUcEoROOOjZZU+8ax9lBZVMIBt6mO4wf4qsupJxianhk0uIWFy2whr3+3Dro5alN3VjTVpXsAQMtwRlN7W8yj2dv4Cpubg1MOHa/l9ILcpIF5z+QnvMMipID3Ho5EAZgf2z8XG2rBhrvI6ypmQ20LcFReWr3oKuvKuHkXpEGGfO2oExeKGisI+eoJBEvO7D4KljEbWf+rTSI0SCf5ENEH3H2qirGOccMKrvPKX9mTEKQGvV57G5jZi8wiyLnB2Ef74Tt70s+LSXhTfIrzp1iNqZErk9bwCt8DeQeq9671PpsTUddPNkBd4e97UH6NE/Ond48huImxwfITVZSsnjOWNFf9zndu0CQUDbOwh5PdoyL9BiwoYJKdbODo+0YgVFfwRMcO6jjCtLg3QuqNBGg2LKLFCofE0sKZCJODXR3+CH77x7Ue8EyRMXstq+A1sPdz+fvpaPo9gdw8tP9BLwXDMX2MCXe7bEcIrCq3cF6C/OkM6gEYx9WLal8tKzZY/9iX0Dccq7Oke+1bRTa6+Sy1x3iWWLN3wpytunvkqhW5+qMq9ECJ+LMtgKt74sa9k5tG99tRLlr3dI8jto4pLw5EJE5XrvPepRif5KcBvfeS8Gqahj1W+Lr0nurBiRl7H03KOP4P0jnsn3x8hloQYiwhChk+af3+Pn/BzhVYUBshQ1Mjfm8H/BMsXppd7PBRTRO/ArWGVys+HCGt8dLZtjIY/0+LNP+OYgxmRebM++WDE3yVdohTW81XPOOHHCt36SJXT4etjBkAhZlJ2ikF0tjcka5r2X8NEa+sej+Bnitp7R43EVX+NIxEzLTIgBgcHF6iquECsrttEeJno/ohBFKW3yfjj+sVBmOvnL3aGM/Ern63nP5F03i+BlGn+f10JyvFCZOA3AAAAAElFTkSuQmCC"},60555:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Button=void 0;const r=a(n(67294)),i=a(n(86010)),s=a(n(43150));t.Button=e=>{let{children:t,className:n,onClick:a,style:o,type:d,disabled:l}=e;return r.default.createElement("button",{className:(0,i.default)(s.default.button,n),onClick:a,style:o,type:d,disabled:l},t)}},92705:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var r=Object.getOwnPropertyDescriptor(t,n);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,r)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return r(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.ClosableDiv=t.EditorTrigger=void 0;const o=i(n(67294)),d=s(n(83253)),l=s(n(39960)),c=n(81173),u=n(28084),h=s(n(44996)),g=n(60555),p=n(6434),f=n(32471),m=n(86341),R=n(19445),y=n(86341),b=n(78641),x=s(n(47181)),v=s(n(10275));function _(e){let{onDecision:t,lastEditTimestamp:n}=e;return o.default.createElement(o.default.Fragment,null,o.default.createElement("h3",null,"Continue"),o.default.createElement("p",null,"Do you want to continue with your last edit?"),n&&o.default.createElement("p",null,"created on: ",new Date(Number(n)).toLocaleString()),o.default.createElement("div",{style:{display:"flex",flexDirection:"row",gap:12,justifyContent:"end"}},o.default.createElement(g.Button,{onClick:()=>{t(!1)}},"No"),o.default.createElement(g.Button,{onClick:()=>{t(!0)}},"Yes")))}function k(){return(0,u.usePluginData)("internaldocs-fb")}const C=e=>/\.mdx?$/i.test(e),w=e=>e.replace(/[\w\d.-_]/gi,"").length>0,E=e=>e.startsWith("../")||e.includes("/../");function S(e){let{onSubmit:t,repoRootToWebsiteRoot:n}=e;const[a,r]=(0,o.useState)(""),i=!a||!C(a)||w(a)||E(a);return o.default.createElement("form",{onSubmit:e=>{e.preventDefault(),i||t(a)}},o.default.createElement("label",{style:{display:"block",marginBottom:12}},o.default.createElement("span",null,"New page file path"),o.default.createElement("div",{style:{display:"flex"}},o.default.createElement("code",null,n,"/"),o.default.createElement("input",{type:"text",value:a,placeholder:"docs/path/to/file.md",onChange:e=>{let{target:t}=e;return r(t.value)},style:{flexGrow:1},autoFocus:!0}))),i&&o.default.createElement("ul",{className:v.default.filepath_validation_list},!C(a)&&o.default.createElement("li",null,"You can only create markdown and mdx files, must end with `.mdx` or `.md`"),w(a)&&o.default.createElement("li",null,"File path contains disallowed symbols. You can use alphanumricals, dot, slash, hyphen and underscore."),E(a)&&o.default.createElement("li",null,"You cannot create files outside of website directory")),o.default.createElement(g.Button,{type:"submit",disabled:i,style:{display:"block",marginLeft:"auto"}},"Continue"))}function A(e){let{isOpen:t,onClose:n,kind:a,editUrl:r}=e;var i,s,u;const[g,f]=(0,o.useState)({type:a===R.DiffKind.modify?"restore-session-prompt":"input-new-page-path"}),y=k(),{repoRootToWebsiteRoot:x}=y,v=(0,o.useMemo)((()=>`pageRawContent-${(0,b.generateHash)(`${(0,m.getEphemeralDiffNumber)()}${r}`)}`),[r]),[C,w]=(0,o.useState)(null),E=(0,o.useMemo)((()=>(0,b.getFilePathRelativeToDocsFolder)(r,y.docsDir)),[r,y.docsDir]),A=(0,h.default)(`_src/${E}`),D=(0,o.useMemo)((()=>(0,c.createStorageSlot)(v)),[v]),L=(0,o.useCallback)((()=>{var e;f({type:"submitting"});const t=null==C?void 0:C.pageRawContent,n=(0,m.hasEphemeralDiffNumber)()?Number(null===(e=(0,m.getEphemeralDiffNumber)())||void 0===e?void 0:e.slice(1)):null;if(null==C)throw new Error("Attempting to submit a diff with null content, report to staticdocs oncall");const i=a===R.DiffKind.add?C.newFilePath:r?(0,b.getFilePathRelativeToRepoRoot)(r):null;if(!i){const e=`The provided url ${r} is invalid`;throw f({type:"failed",reason:e}),new Error(e)}if(null==t)throw f({type:"failed",reason:"The page's raw content cannot be null"}),new Error("The page's raw content cannot be null");m.inpageeditor.submitDiff({file_path:i,new_content:t,project_name:null,diff_number:n,diff_kind:a}).then((e=>{f({type:"success",url:e.xfb_static_docs_editor_create_diff.url,diffId:e.xfb_static_docs_editor_create_diff.number_with_prefix})})).catch((e=>{const t=`Error occurred while trying to create diff from editor. Stack trace ${e}`;throw f({type:"failed",reason:t}),new Error(t)}))}),[f,r,C,a]);(0,o.useEffect)((()=>{if(a===R.DiffKind.add)return;const e=D.get();try{w(e?JSON.parse(e):null)}catch(t){w(null)}}),[D,a]);const I=(0,o.useCallback)((e=>{if(e){const e=D.get();if(null==e)throw new Error("Cannot restore page raw content with no saved state in local storage");const t=JSON.parse(e);f({type:"editing"}),w({pageRawContent:t.pageRawContent,timestamp:t.timestamp,newFilePath:""})}else f({type:"loading-raw-content"}),fetch(A).then((e=>{if(!e.ok){const e="Failed to fetch page raw content from server.";throw f({type:"failed",reason:e}),new Error(e)}return e.text()})).then((e=>{w({pageRawContent:e,timestamp:Date.now().toString(),newFilePath:""}),f({type:"editing"})})).catch((e=>{f({type:"failed",reason:`Error occurred while trying fetch page raw content. Stack trace ${e}`})}))}),[f,A,D]);(0,o.useEffect)((()=>{if(a===R.DiffKind.add)return;null===D.get()?I(!1):f({type:"restore-session-prompt"})}),[]);const F=(0,o.useCallback)((e=>{D.set(JSON.stringify(e)),f({type:"editing"}),w({pageRawContent:e.pageRawContent,timestamp:e.timestamp,newFilePath:e.newFilePath})}),[f,D]),{colorMode:O}=(0,c.useColorMode)(),N=(0,o.useMemo)((()=>{let e="min(80vw, 1916px)";return"restore-session-prompt"!==g.type&&"loading-raw-content"!==g.type||(e="min(20, 360px)"),"input-new-page-path"===g.type&&(e="min(40, 520px)"),{content:{backgroundColor:"dark"===O?"black":"white",width:e,maxHeight:"calc(100% - 100px)",margin:"80px auto 10px",inset:"auto",overscrollBehavior:"contain"},overlay:{background:"rgba(0, 0, 0, .5)","overflow-y":"auto",display:"flex",alignItems:"flex-start",justifyContent:"center",zIndex:10}}}),[O,g.type]),B=null!==(i=null==C?void 0:C.timestamp)&&void 0!==i?i:null;return o.default.createElement(d.default,{ariaHideApp:!1,isOpen:t,shouldCloseOnOverlayClick:!1,shouldCloseOnEsc:!1,style:N},"restore-session-prompt"===g.type&&o.default.createElement(_,{onDecision:I,lastEditTimestamp:B}),"loading-raw-content"===g.type&&o.default.createElement("div",null,"Loading raw page content..."),"input-new-page-path"===g.type&&o.default.createElement(S,{repoRootToWebsiteRoot:x,onSubmit:e=>{w({timestamp:Date.now().toString(),pageRawContent:"",newFilePath:`${x}/${e}`}),f({type:"editing"})}}),"editing"===g.type&&o.default.createElement(p.SDocEditor,{pageRawContent:null!==(s=null==C?void 0:C.pageRawContent)&&void 0!==s?s:"",diffKind:a,newFilePath:null!==(u=null==C?void 0:C.newFilePath)&&void 0!==u?u:"",setPageRawContentVersion:F,onEditorSubmit:L,handleCloseEditor:n,isSubmitting:!1}),"submitting"===g.type&&o.default.createElement(T,{onClose:n},"Submitting changes..."),"success"===g.type&&o.default.createElement(T,{onClose:n},"Diff has been submitted"," ",o.default.createElement(l.default,{to:g.url},g.diffId)),"failed"===g.type&&o.default.createElement(T,{onClose:n},"Error: ",g.reason))}function T(e){let{children:t,onClose:n}=e;return o.default.createElement("div",null,o.default.createElement(g.Button,{onClick:n,style:{position:"absolute",padding:"2px 2px 1px",top:0,right:0}},o.default.createElement("img",{src:x.default,style:{height:"17px"}})),t)}t.EditorTrigger=function(e){let{position:t}=e;var n;const a=null===(n=(0,f.useDocMeta)())||void 0===n?void 0:n.metadata,[r,i]=(0,o.useState)({isOpen:!1,kind:R.DiffKind.modify}),s=k(),d=(0,o.useMemo)((()=>(null==a?void 0:a.editUrl)?(0,b.getFilePathRelativeToDocsFolder)(a.editUrl,s.docsDir):null),[a,s.docsDir]);if(null==a)return null;const{editUrl:l}=a;if("before-post"===t&&"top"!==s.opts.enableEditor)return null;if("after-post"===t&&![!0,"bottom"].includes(s.opts.enableEditor))return null;if(!(l||a.lastUpdatedAt||a.lastUpdatedBy))return null;s.repoRootToWebsiteRoot;const c="undefined"!=typeof window&&"1"===new URLSearchParams(window.location.search).get("enableEditor");return l&&d&&(c||(0,y.isInternal)()&&true)?o.default.createElement("div",{className:"margin-vert--"+("after-post"===t?"xl":"xs"),id:"editor-trigger"},o.default.createElement(g.Button,{onClick:()=>i({isOpen:!0,kind:R.DiffKind.modify}),style:{marginRight:8}},"Edit this page"),o.default.createElement(g.Button,{onClick:()=>i({isOpen:!0,kind:R.DiffKind.add})},"Add new page"),r.isOpen?o.default.createElement(A,{isOpen:!0,kind:r.kind,onClose:()=>{i({isOpen:!1,kind:R.DiffKind.modify})},editUrl:l}):null):null},t.ClosableDiv=T},47181:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKdJREFUeNrslQEKgDAIRefooO0GO0o3WFfqRNZAotbcNLAIGkjUPr7U6TwiOkvzznh9HzCUHwAgPyK9TkI/uz7n/bTKopAYyZLAeTroo7bIYweSSMOvSgTlX3GRVDUXfwygB2H3NADOUTM6LaAGaabuDoCDJElNzRvt9RSZFtn0mJo2WpScFgainkXzZqGxH0gjH9fFiJaM6wxZOD00muu/Mp8BrAIMAE/aslxTtku5AAAAAElFTkSuQmCC"},6434:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var r=Object.getOwnPropertyDescriptor(t,n);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,r)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return r(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.SDocEditor=void 0;const o=i(n(67294)),d=s(n(39960)),l=s(n(95999)),c=s(n(44996)),u=s(n(74866)),h=s(n(85162)),g=n(2497),p=n(3905),f=s(n(75854)),m=n(19445),R=n(60555),y=n(77437),b=s(n(1925)),x=e=>({...f.default,MDXProvider:p.MDXProvider,Link:d.default,Translate:l.default,Tabs:u.default,TabItem:h.default,__unknownComponent:t=>function(n){const a=t in e,r=o.default.useMemo((()=>Object.keys(n).reduce(((e,t)=>("children"!==t&&(e[t]=n[t]),e)),{})),[n]);return o.default.createElement("div",{className:b.default.unknown_component},a&&o.default.createElement("p",null,"Live preview does not support imported components"),o.default.createElement("p",{style:{marginBottom:4}},a?"Imported":"Unknown"," component"," ",o.default.createElement("b",null,o.default.createElement("code",null,t))," ","with props ",o.default.createElement("code",null,(e=>{try{return JSON.stringify(e)}catch(t){return console.warn("Could not stringify props for UnknownComponent",e),"Could not stringify"}})(r))),!a&&o.default.createElement("details",null,o.default.createElement("summary",null,"Why did it not render?"),"Editor cannot render it due to the component being custom or nondefined"),n.children?o.default.createElement("div",{className:b.default.unknown_component_children},n.children):null)}});function v(e){let{onCancel:t,isSubmitDisabled:n,diffKind:a,filename:r}=e;return o.default.createElement("div",{className:b.default.editor_header},o.default.createElement("span",null,o.default.createElement("h2",{style:{margin:0}},"Staticdocs editor"),a===m.DiffKind.add?`Add content for a new file ${r}`:`Edit existing ${r}`),o.default.createElement("div",{className:b.default.cta_wrapper},o.default.createElement(R.Button,{onClick:t},"Cancel"),o.default.createElement(R.Button,{type:"submit",disabled:n},"Publish Diff")))}function _(){return o.default.createElement("div",{className:b.default.show_info},o.default.createElement("h3",null,"Note"),o.default.createElement("p",null,"The Live preview fails to render. ",o.default.createElement("br",null),"This might be because we currently do not have support for the operation being performed on the page e.g code-snippets. Please ignore this"," ",o.default.createElement("b",null,"if you are sure")," it is the case and continue with the editor."," ",o.default.createElement("b",null,"Happy Editing!")))}t.SDocEditor=function(e){let{onEditorSubmit:t,handleCloseEditor:n,pageRawContent:a,setPageRawContentVersion:r,isSubmitting:i,diffKind:s,newFilePath:d}=e;const[l,u]=(0,o.useState)(!1),[h,f]=(0,o.useState)({}),m=o.default.useMemo((()=>x(h)),[h]),R=(0,o.useCallback)((e=>{e.preventDefault(),t()}),[t]),k=(0,o.useCallback)((e=>{const t=(0,y.mdxToReactString)(e);if(null===t.code)return u(!0),"";u(!1);return Object.keys(h).join(",")!==Object.keys(t.importedComponents).join(",")&&f(t.importedComponents),`\n ${t.code}\n render(\n \n \n \n )\n `}),[u,h]),C=(0,o.useCallback)((e=>{r({pageRawContent:e,timestamp:Date.now().toString(),diffKind:s,newFilePath:d})}),[r,s,d]);if(null===a)return null;const w=d.split("/").pop();if(void 0===w)throw new Error(`Could not extract filename from "${d}"`);return o.default.createElement(g.LiveProvider,{code:a,noInline:!0,scope:{components:m,MDXProvider:p.MDXProvider,mdx:p.mdx,useBaseUrl:c.default},transformCode:k},o.default.createElement("form",{onSubmit:R,className:b.default.editor},o.default.createElement(v,{isSubmitDisabled:i,onCancel:n,diffKind:s,filename:w}),o.default.createElement("div",{className:b.default.editor_input},o.default.createElement(g.LiveEditor,{className:b.default.live_editor,onChange:C})),o.default.createElement("div",{className:b.default.editor_preview},l?o.default.createElement(_,null):o.default.createElement(g.LivePreview,{className:b.default.live_preview}),o.default.createElement(g.LiveError,{className:b.default.live_error}))))}},62466:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=a(n(67294)),i=a(n(93454)),s=n(32471);t.default=function(e){return r.default.createElement(s.DocMetaProvider,{value:{frontMatter:e.content.frontMatter,metadata:e.content.metadata}},r.default.createElement(i.default,{...e}))}},78641:(e,t)=>{"use strict";function n(e){const t=new URL(e).pathname;let n;if(t.startsWith("/intern/diffusion/"))n=6;else{if(!t.startsWith("/code/"))return console.warn(`Unexpected editUrl format for in-page editor: ${e}`),null;n=3}const a=t.split("/");if(a.length<=n||""==a[a.length-1])return null;return t.split("/").slice(n).join("/")}Object.defineProperty(t,"__esModule",{value:!0}),t.generateHash=t.getFilePathRelativeToDocsFolder=t.getFilePathRelativeToRepoRoot=void 0,t.getFilePathRelativeToRepoRoot=n,t.getFilePathRelativeToDocsFolder=function(e,t){const a=n(e);if(!a)return null;const r=t.split("/");for(let n=0;n{e.children=e.children.reduce(((e,t)=>{if("text"!==t.type)return e.push(t),e;const n=/((D|T|P|S|L|EX)\d+)(.)?/;if(!("value"in t))throw new Error('remark text node is missing "value" field');let a=t.value;if("string"!=typeof a)throw new Error('remark text node is missing "value" field');let r=a.match(n);for(r||e.push(t);r;){const[d,c,u,h]=r,g=r.index;if(null==g)break;"number"==typeof g&&g>0&&e.push(l(a.slice(0,r.index),t.position));h&&h.match(/\w/)?e.push(l(c,t.position)):e.push((i=c,s=`https://internalfb.com/${c}`,o=t.pos,{type:"link",url:s,children:[l(i,o)],position:{start:o,end:o}})),a=a.slice(g+r[1].length),r=a.match(n),a&&!r&&e.push(l(a,t.position))}var i,s,o;return e}),[])}))}}},77437:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.mdxToReactString=void 0;const r=a(n(84707)),i=n(9382),s=n(80865),o=n(24284),d=n(84946),l=new Map,c=()=>e=>(0,i.remove)(e,(e=>{var t,n,a;return"mdxjsEsm"===e.type&&(null===(a=null===(n=null===(t=e.data)||void 0===t?void 0:t.estree)||void 0===n?void 0:n.body)||void 0===a||a.forEach((e=>{"ImportDeclaration"===e.type&&e.specifiers.forEach((t=>{l.set(t.local.name,e.source.value)}))})),!0)})),u=new Set(["/*@jsxRuntime classic @jsx React.createElement @jsxFrag React.Fragment*/",'import React from "react";',"export default MDXContent;"]);t.mdxToReactString=function(e){const t=/^---(.|\n)*?---/;try{return{code:(0,s.compileSync)(e.replace(t,"").split("\n").map((e=>{const t=e.trim().match(/^$/);return t?`{/*${t[1]}*/}`:e})).join("\n"),{remarkPlugins:[[o.remarkMermaid,{version:"v2"}],[d.internLinks,{}],r.default,c],format:"mdx",jsxRuntime:"classic",outputFormat:"program"}).value.toString().replace("const _components =","let _components =").split("\n").filter((e=>!u.has(e))).map((e=>{const t=e.match(/if \(!(.+)\) _missingMdxReference/);if(null===t)return e;const n=t[1];return` if (!${n}) ${n} = _components.__unknownComponent("${n}");`})).join("\n"),importedComponents:Object.fromEntries([...l])}}catch(n){return console.warn("Transpiler error",n),{code:null,importedComponents:{}}}finally{l.clear()}}},24284:(e,t)=>{"use strict";function n(e){return"code"===e.type&&"mermaid"===e.lang}function a(e){e.children=e.children.map((e=>{if(n(e)){return{type:"jsx",value:[""].join("\n"),position:{...e.position,indent:[1,1,1]}}}return e}))}function r(e){e.children=e.children.map((e=>{if(n(e)){const t={start:{line:e.position.start.line,column:e.position.start.column},end:{line:e.position.end.line,column:e.position.end.column}},n=e.position.start.offset,a=e.position.end.offset,r=[n,a];return{type:"mdxJsxFlowElement",name:"Mermaid",data:{_xdmExplicitJsx:!0},children:[],meta:null,attributes:[{type:"mdxJsxAttribute",name:"chart",value:{type:"mdxJsxAttributeValueExpression",value:["`\n",e.value,"`"].join("\n"),data:{estree:{body:[{type:"ExpressionStatement",start:n,range:r,loc:t,expression:{loc:t,range:r,start:n,end:a,type:"Literal",value:e.value,raw:["`\n",e.value,"`"].join("\n")}}],comments:[],end:a,loc:t,range:r,sourceType:"module",start:n,type:"Program"}}},position:e.position}]}}return e}))}Object.defineProperty(t,"__esModule",{value:!0}),t.remarkMermaid=void 0,t.remarkMermaid=function(e){return"v1"===(null==e?void 0:e.version)?a:r}},32471:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var r=Object.getOwnPropertyDescriptor(t,n);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,r)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return r(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.useDocMeta=t.DocMetaProvider=void 0;const s=i(n(67294)),o=s.default.createContext(null);t.DocMetaProvider=o.Provider;t.useDocMeta=()=>(0,s.useContext)(o)},86121:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=a(n(67294)),i=a(n(46215)),s=n(81173),o=a(n(56262)),d=n(86341),l=e=>{let{url:t}=e;return r.default.createElement("a",{href:t,target:"_blank",rel:"noreferrer noopener",className:s.ThemeClassNames.common.editThisPage},r.default.createElement(o.default,null),"View in CodeHub")};t.default=function(e){return(0,d.isInternal)()?r.default.createElement(l,{url:e.editUrl}):r.default.createElement(i.default,{...e})}},5307:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAPFJREFUOBGtkD8OAVEQxpcQR+ACSolTKGyh0KtQECdwBFdwA+fQoBGlzhVI/CnwG7vz8t6zj5X4km9n5vtmZmc3iv6ImF0reIWPAMWTHul1IEJoKKQ7S9beghP1ENZSDohHaC+TSwz8syc4JdhPWSaOob1AZgxsQ/I67ELVW+QNq1YdKYEKfrxjT2ERylW+j5TAN7Sepf6IeIGqa4wKaYMIWVggnmEvy0TT+ehGoVvt2EaPA97rJ8q3CXZJ+Om5tbs7FPLD7Ld/y+UyB7JkAz8Nytlr+DaMZmAvOKA2jZMz0QVL+qs5Z5y2PdUcVhw1UDwBK0d9heZjHrYAAAAASUVORK5CYII="},93930:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var r=Object.getOwnPropertyDescriptor(t,n);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,r)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return r(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.FeedbackButton=void 0;const o=i(n(67294)),d=n(86341),l=s(n(84373)),c=s(n(5307)),u=s(n(91296));t.FeedbackButton=()=>{const[e,t]=(0,o.useState)(!1),[n,a]=(0,o.useState)(""),[r,i]=(0,o.useState)(!1),[s,h]=(0,o.useState)(0),[g,p]=(0,o.useState)(0);(0,o.useEffect)((()=>(document.addEventListener("mouseup",f),function(){document.removeEventListener("mouseup",f)}))),(0,o.useEffect)((()=>{let e=!0;return d.checkGKs.gk("sdocs_inline_feedback").then((t=>{e&&i(t)})),()=>{e=!1}}),[]);const f=(0,u.default)((0,o.useCallback)((e=>{var i;if(""!==(null===(i=document.getSelection())||void 0===i?void 0:i.toString())&&r){const r=document.getSelection();if(r&&r.toString()!=n){e&&e.preventDefault();const n=r.getRangeAt(0).getBoundingClientRect(),i=void 0!==window.pageYOffset?window.pageYOffset:(document.documentElement||document.body.parentNode||document.body).scrollTop;h(n.top-40+i),p(n.left+n.width/2-40),a(r.toString()),t(!0)}}else t(!1),p(0),h(0)}),[r,n]),200);return o.default.createElement(o.default.Fragment,null,e&&o.default.createElement("button",{onClick:()=>{var e;null!==n&&""!==n&&(null===(e=window.getSelection())||void 0===e||e.removeAllRanges(),d.feedback.reportContentSelected({textContent:n}))},className:l.default.FeedbackButton,style:{position:"absolute",top:s,left:g}},o.default.createElement("img",{src:c.default,className:l.default.FeedbackIcon}),"Feedback"))}},75854:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=a(n(42752)),i=n(86341),s=a(n(92969)),o={...r.default,FbInternalOnly:i.FbInternalOnly,FBInternalOnly:i.FbInternalOnly,OssOnly:i.OssOnly,OSSOnly:i.OssOnly,Mermaid:s.default};t.default=o},51788:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=a(n(67294)),i=a(n(45042)),s=n(92705),o=n(93930);t.default=function(e){return r.default.createElement(r.default.Fragment,null,r.default.createElement(s.EditorTrigger,{position:"before-post"}),r.default.createElement(i.default,{...e}),r.default.createElement(o.FeedbackButton,null),r.default.createElement(s.EditorTrigger,{position:"after-post"}))}},92969:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var r=Object.getOwnPropertyDescriptor(t,n);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,r)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return r(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(n(67294)),d=s(n(33231));d.default.initialize({startOnLoad:!0});t.default=e=>{let{chart:t}=e;return(0,o.useEffect)((()=>d.default.contentLoaded()),[]),o.default.createElement("div",{className:"mermaid"},t)}},76907:(e,t,n)=>{var a=n(4977);e.exports=a},9116:(e,t,n)=>{n(19601);var a=n(40857);e.exports=a.Object.assign},77671:(e,t,n)=>{e.exports=n(47537)},47537:(e,t,n)=>{var a=n(76907);e.exports=a},19662:(e,t,n)=>{var a=n(60614),r=n(66330),i=TypeError;e.exports=function(e){if(a(e))return e;throw i(r(e)+" is not a function")}},19670:(e,t,n)=>{var a=n(70111),r=String,i=TypeError;e.exports=function(e){if(a(e))return e;throw i(r(e)+" is not an object")}},41318:(e,t,n)=>{var a=n(45656),r=n(51400),i=n(26244),s=function(e){return function(t,n,s){var o,d=a(t),l=i(d),c=r(s,l);if(e&&n!=n){for(;l>c;)if((o=d[c++])!=o)return!0}else for(;l>c;c++)if((e||c in d)&&d[c]===n)return e||c||0;return!e&&-1}};e.exports={includes:s(!0),indexOf:s(!1)}},84326:(e,t,n)=>{var a=n(1702),r=a({}.toString),i=a("".slice);e.exports=function(e){return i(r(e),8,-1)}},99920:(e,t,n)=>{var a=n(92597),r=n(53887),i=n(31236),s=n(3070);e.exports=function(e,t,n){for(var o=r(t),d=s.f,l=i.f,c=0;c{var a=n(19781),r=n(3070),i=n(79114);e.exports=a?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},79114:e=>{e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},98052:(e,t,n)=>{var a=n(60614),r=n(3070),i=n(56339),s=n(13072);e.exports=function(e,t,n,o){o||(o={});var d=o.enumerable,l=void 0!==o.name?o.name:t;if(a(n)&&i(n,l,o),o.global)d?e[t]=n:s(t,n);else{try{o.unsafe?e[t]&&(d=!0):delete e[t]}catch(c){}d?e[t]=n:r.f(e,t,{value:n,enumerable:!1,configurable:!o.nonConfigurable,writable:!o.nonWritable})}return e}},13072:(e,t,n)=>{var a=n(17854),r=Object.defineProperty;e.exports=function(e,t){try{r(a,e,{value:t,configurable:!0,writable:!0})}catch(n){a[e]=t}return t}},19781:(e,t,n)=>{var a=n(47293);e.exports=!a((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},4154:e=>{var t="object"==typeof document&&document.all,n=void 0===t&&void 0!==t;e.exports={all:t,IS_HTMLDDA:n}},80317:(e,t,n)=>{var a=n(17854),r=n(70111),i=a.document,s=r(i)&&r(i.createElement);e.exports=function(e){return s?i.createElement(e):{}}},88113:(e,t,n)=>{var a=n(35005);e.exports=a("navigator","userAgent")||""},7392:(e,t,n)=>{var a,r,i=n(17854),s=n(88113),o=i.process,d=i.Deno,l=o&&o.versions||d&&d.version,c=l&&l.v8;c&&(r=(a=c.split("."))[0]>0&&a[0]<4?1:+(a[0]+a[1])),!r&&s&&(!(a=s.match(/Edge\/(\d+)/))||a[1]>=74)&&(a=s.match(/Chrome\/(\d+)/))&&(r=+a[1]),e.exports=r},80748:e=>{e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},82109:(e,t,n)=>{var a=n(17854),r=n(31236).f,i=n(68880),s=n(98052),o=n(13072),d=n(99920),l=n(54705);e.exports=function(e,t){var n,c,u,h,g,p=e.target,f=e.global,m=e.stat;if(n=f?a:m?a[p]||o(p,{}):(a[p]||{}).prototype)for(c in t){if(h=t[c],u=e.dontCallGetSet?(g=r(n,c))&&g.value:n[c],!l(f?c:p+(m?".":"#")+c,e.forced)&&void 0!==u){if(typeof h==typeof u)continue;d(h,u)}(e.sham||u&&u.sham)&&i(h,"sham",!0),s(n,c,h,e)}}},47293:e=>{e.exports=function(e){try{return!!e()}catch(t){return!0}}},34374:(e,t,n)=>{var a=n(47293);e.exports=!a((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},46916:(e,t,n)=>{var a=n(34374),r=Function.prototype.call;e.exports=a?r.bind(r):function(){return r.apply(r,arguments)}},76530:(e,t,n)=>{var a=n(19781),r=n(92597),i=Function.prototype,s=a&&Object.getOwnPropertyDescriptor,o=r(i,"name"),d=o&&"something"===function(){}.name,l=o&&(!a||a&&s(i,"name").configurable);e.exports={EXISTS:o,PROPER:d,CONFIGURABLE:l}},1702:(e,t,n)=>{var a=n(34374),r=Function.prototype,i=r.call,s=a&&r.bind.bind(i,i);e.exports=a?s:function(e){return function(){return i.apply(e,arguments)}}},35005:(e,t,n)=>{var a=n(17854),r=n(60614),i=function(e){return r(e)?e:void 0};e.exports=function(e,t){return arguments.length<2?i(a[e]):a[e]&&a[e][t]}},58173:(e,t,n)=>{var a=n(19662),r=n(68554);e.exports=function(e,t){var n=e[t];return r(n)?void 0:a(n)}},17854:(e,t,n)=>{var a=function(e){return e&&e.Math==Math&&e};e.exports=a("object"==typeof globalThis&&globalThis)||a("object"==typeof window&&window)||a("object"==typeof self&&self)||a("object"==typeof n.g&&n.g)||function(){return this}()||Function("return this")()},92597:(e,t,n)=>{var a=n(1702),r=n(47908),i=a({}.hasOwnProperty);e.exports=Object.hasOwn||function(e,t){return i(r(e),t)}},3501:e=>{e.exports={}},64664:(e,t,n)=>{var a=n(19781),r=n(47293),i=n(80317);e.exports=!a&&!r((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},68361:(e,t,n)=>{var a=n(1702),r=n(47293),i=n(84326),s=Object,o=a("".split);e.exports=r((function(){return!s("z").propertyIsEnumerable(0)}))?function(e){return"String"==i(e)?o(e,""):s(e)}:s},42788:(e,t,n)=>{var a=n(1702),r=n(60614),i=n(5465),s=a(Function.toString);r(i.inspectSource)||(i.inspectSource=function(e){return s(e)}),e.exports=i.inspectSource},29909:(e,t,n)=>{var a,r,i,s=n(94811),o=n(17854),d=n(70111),l=n(68880),c=n(92597),u=n(5465),h=n(6200),g=n(3501),p="Object already initialized",f=o.TypeError,m=o.WeakMap;if(s||u.state){var R=u.state||(u.state=new m);R.get=R.get,R.has=R.has,R.set=R.set,a=function(e,t){if(R.has(e))throw f(p);return t.facade=e,R.set(e,t),t},r=function(e){return R.get(e)||{}},i=function(e){return R.has(e)}}else{var y=h("state");g[y]=!0,a=function(e,t){if(c(e,y))throw f(p);return t.facade=e,l(e,y,t),t},r=function(e){return c(e,y)?e[y]:{}},i=function(e){return c(e,y)}}e.exports={set:a,get:r,has:i,enforce:function(e){return i(e)?r(e):a(e,{})},getterFor:function(e){return function(t){var n;if(!d(t)||(n=r(t)).type!==e)throw f("Incompatible receiver, "+e+" required");return n}}}},60614:(e,t,n)=>{var a=n(4154),r=a.all;e.exports=a.IS_HTMLDDA?function(e){return"function"==typeof e||e===r}:function(e){return"function"==typeof e}},54705:(e,t,n)=>{var a=n(47293),r=n(60614),i=/#|\.prototype\./,s=function(e,t){var n=d[o(e)];return n==c||n!=l&&(r(t)?a(t):!!t)},o=s.normalize=function(e){return String(e).replace(i,".").toLowerCase()},d=s.data={},l=s.NATIVE="N",c=s.POLYFILL="P";e.exports=s},68554:e=>{e.exports=function(e){return null==e}},70111:(e,t,n)=>{var a=n(60614),r=n(4154),i=r.all;e.exports=r.IS_HTMLDDA?function(e){return"object"==typeof e?null!==e:a(e)||e===i}:function(e){return"object"==typeof e?null!==e:a(e)}},31913:e=>{e.exports=!1},52190:(e,t,n)=>{var a=n(35005),r=n(60614),i=n(47976),s=n(43307),o=Object;e.exports=s?function(e){return"symbol"==typeof e}:function(e){var t=a("Symbol");return r(t)&&i(t.prototype,o(e))}},26244:(e,t,n)=>{var a=n(17466);e.exports=function(e){return a(e.length)}},56339:(e,t,n)=>{var a=n(47293),r=n(60614),i=n(92597),s=n(19781),o=n(76530).CONFIGURABLE,d=n(42788),l=n(29909),c=l.enforce,u=l.get,h=Object.defineProperty,g=s&&!a((function(){return 8!==h((function(){}),"length",{value:8}).length})),p=String(String).split("String"),f=e.exports=function(e,t,n){"Symbol("===String(t).slice(0,7)&&(t="["+String(t).replace(/^Symbol\(([^)]*)\)/,"$1")+"]"),n&&n.getter&&(t="get "+t),n&&n.setter&&(t="set "+t),(!i(e,"name")||o&&e.name!==t)&&(s?h(e,"name",{value:t,configurable:!0}):e.name=t),g&&n&&i(n,"arity")&&e.length!==n.arity&&h(e,"length",{value:n.arity});try{n&&i(n,"constructor")&&n.constructor?s&&h(e,"prototype",{writable:!1}):e.prototype&&(e.prototype=void 0)}catch(r){}var a=c(e);return i(a,"source")||(a.source=p.join("string"==typeof t?t:"")),e};Function.prototype.toString=f((function(){return r(this)&&u(this).source||d(this)}),"toString")},74758:e=>{var t=Math.ceil,n=Math.floor;e.exports=Math.trunc||function(e){var a=+e;return(a>0?n:t)(a)}},21574:(e,t,n)=>{"use strict";var a=n(19781),r=n(1702),i=n(46916),s=n(47293),o=n(81956),d=n(25181),l=n(55296),c=n(47908),u=n(68361),h=Object.assign,g=Object.defineProperty,p=r([].concat);e.exports=!h||s((function(){if(a&&1!==h({b:1},h(g({},"a",{enumerable:!0,get:function(){g(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},n=Symbol(),r="abcdefghijklmnopqrst";return e[n]=7,r.split("").forEach((function(e){t[e]=e})),7!=h({},e)[n]||o(h({},t)).join("")!=r}))?function(e,t){for(var n=c(e),r=arguments.length,s=1,h=d.f,g=l.f;r>s;)for(var f,m=u(arguments[s++]),R=h?p(o(m),h(m)):o(m),y=R.length,b=0;y>b;)f=R[b++],a&&!i(g,m,f)||(n[f]=m[f]);return n}:h},3070:(e,t,n)=>{var a=n(19781),r=n(64664),i=n(3353),s=n(19670),o=n(34948),d=TypeError,l=Object.defineProperty,c=Object.getOwnPropertyDescriptor,u="enumerable",h="configurable",g="writable";t.f=a?i?function(e,t,n){if(s(e),t=o(t),s(n),"function"==typeof e&&"prototype"===t&&"value"in n&&g in n&&!n[g]){var a=c(e,t);a&&a[g]&&(e[t]=n.value,n={configurable:h in n?n[h]:a[h],enumerable:u in n?n[u]:a[u],writable:!1})}return l(e,t,n)}:l:function(e,t,n){if(s(e),t=o(t),s(n),r)try{return l(e,t,n)}catch(a){}if("get"in n||"set"in n)throw d("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},31236:(e,t,n)=>{var a=n(19781),r=n(46916),i=n(55296),s=n(79114),o=n(45656),d=n(34948),l=n(92597),c=n(64664),u=Object.getOwnPropertyDescriptor;t.f=a?u:function(e,t){if(e=o(e),t=d(t),c)try{return u(e,t)}catch(n){}if(l(e,t))return s(!r(i.f,e,t),e[t])}},8006:(e,t,n)=>{var a=n(16324),r=n(80748).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return a(e,r)}},25181:(e,t)=>{t.f=Object.getOwnPropertySymbols},47976:(e,t,n)=>{var a=n(1702);e.exports=a({}.isPrototypeOf)},16324:(e,t,n)=>{var a=n(1702),r=n(92597),i=n(45656),s=n(41318).indexOf,o=n(3501),d=a([].push);e.exports=function(e,t){var n,a=i(e),l=0,c=[];for(n in a)!r(o,n)&&r(a,n)&&d(c,n);for(;t.length>l;)r(a,n=t[l++])&&(~s(c,n)||d(c,n));return c}},81956:(e,t,n)=>{var a=n(16324),r=n(80748);e.exports=Object.keys||function(e){return a(e,r)}},55296:(e,t)=>{"use strict";var n={}.propertyIsEnumerable,a=Object.getOwnPropertyDescriptor,r=a&&!n.call({1:2},1);t.f=r?function(e){var t=a(this,e);return!!t&&t.enumerable}:n},92140:(e,t,n)=>{var a=n(46916),r=n(60614),i=n(70111),s=TypeError;e.exports=function(e,t){var n,o;if("string"===t&&r(n=e.toString)&&!i(o=a(n,e)))return o;if(r(n=e.valueOf)&&!i(o=a(n,e)))return o;if("string"!==t&&r(n=e.toString)&&!i(o=a(n,e)))return o;throw s("Can't convert object to primitive value")}},53887:(e,t,n)=>{var a=n(35005),r=n(1702),i=n(8006),s=n(25181),o=n(19670),d=r([].concat);e.exports=a("Reflect","ownKeys")||function(e){var t=i.f(o(e)),n=s.f;return n?d(t,n(e)):t}},40857:(e,t,n)=>{var a=n(17854);e.exports=a},84488:(e,t,n)=>{var a=n(68554),r=TypeError;e.exports=function(e){if(a(e))throw r("Can't call method on "+e);return e}},6200:(e,t,n)=>{var a=n(72309),r=n(69711),i=a("keys");e.exports=function(e){return i[e]||(i[e]=r(e))}},5465:(e,t,n)=>{var a=n(17854),r=n(13072),i="__core-js_shared__",s=a[i]||r(i,{});e.exports=s},72309:(e,t,n)=>{var a=n(31913),r=n(5465);(e.exports=function(e,t){return r[e]||(r[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.27.1",mode:a?"pure":"global",copyright:"\xa9 2014-2022 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.27.1/LICENSE",source:"https://github.com/zloirock/core-js"})},36293:(e,t,n)=>{var a=n(7392),r=n(47293);e.exports=!!Object.getOwnPropertySymbols&&!r((function(){var e=Symbol();return!String(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&a&&a<41}))},51400:(e,t,n)=>{var a=n(19303),r=Math.max,i=Math.min;e.exports=function(e,t){var n=a(e);return n<0?r(n+t,0):i(n,t)}},45656:(e,t,n)=>{var a=n(68361),r=n(84488);e.exports=function(e){return a(r(e))}},19303:(e,t,n)=>{var a=n(74758);e.exports=function(e){var t=+e;return t!=t||0===t?0:a(t)}},17466:(e,t,n)=>{var a=n(19303),r=Math.min;e.exports=function(e){return e>0?r(a(e),9007199254740991):0}},47908:(e,t,n)=>{var a=n(84488),r=Object;e.exports=function(e){return r(a(e))}},57593:(e,t,n)=>{var a=n(46916),r=n(70111),i=n(52190),s=n(58173),o=n(92140),d=n(5112),l=TypeError,c=d("toPrimitive");e.exports=function(e,t){if(!r(e)||i(e))return e;var n,d=s(e,c);if(d){if(void 0===t&&(t="default"),n=a(d,e,t),!r(n)||i(n))return n;throw l("Can't convert object to primitive value")}return void 0===t&&(t="number"),o(e,t)}},34948:(e,t,n)=>{var a=n(57593),r=n(52190);e.exports=function(e){var t=a(e,"string");return r(t)?t:t+""}},66330:e=>{var t=String;e.exports=function(e){try{return t(e)}catch(n){return"Object"}}},69711:(e,t,n)=>{var a=n(1702),r=0,i=Math.random(),s=a(1..toString);e.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+s(++r+i,36)}},43307:(e,t,n)=>{var a=n(36293);e.exports=a&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},3353:(e,t,n)=>{var a=n(19781),r=n(47293);e.exports=a&&r((function(){return 42!=Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},94811:(e,t,n)=>{var a=n(17854),r=n(60614),i=a.WeakMap;e.exports=r(i)&&/native code/.test(String(i))},5112:(e,t,n)=>{var a=n(17854),r=n(72309),i=n(92597),s=n(69711),o=n(36293),d=n(43307),l=r("wks"),c=a.Symbol,u=c&&c.for,h=d?c:c&&c.withoutSetter||s;e.exports=function(e){if(!i(l,e)||!o&&"string"!=typeof l[e]){var t="Symbol."+e;o&&i(c,e)?l[e]=c[e]:l[e]=d&&u?u(t):h(t)}return l[e]}},19601:(e,t,n)=>{var a=n(82109),r=n(21574);a({target:"Object",stat:!0,arity:2,forced:Object.assign!==r},{assign:r})},4977:(e,t,n)=>{var a=n(9116);e.exports=a},58875:(e,t,n)=>{var a;!function(){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),i={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen};void 0===(a=function(){return i}.call(t,n,t,e))||(e.exports=a)}()},94470:e=>{"use strict";var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString,a=Object.defineProperty,r=Object.getOwnPropertyDescriptor,i=function(e){return"function"==typeof Array.isArray?Array.isArray(e):"[object Array]"===n.call(e)},s=function(e){if(!e||"[object Object]"!==n.call(e))return!1;var a,r=t.call(e,"constructor"),i=e.constructor&&e.constructor.prototype&&t.call(e.constructor.prototype,"isPrototypeOf");if(e.constructor&&!r&&!i)return!1;for(a in e);return void 0===a||t.call(e,a)},o=function(e,t){a&&"__proto__"===t.name?a(e,t.name,{enumerable:!0,configurable:!0,value:t.newValue,writable:!0}):e[t.name]=t.newValue},d=function(e,n){if("__proto__"===n){if(!t.call(e,n))return;if(r)return r(e,n).value}return e[n]};e.exports=function e(){var t,n,a,r,l,c,u=arguments[0],h=1,g=arguments.length,p=!1;for("boolean"==typeof u&&(p=u,u=arguments[1]||{},h=2),(null==u||"object"!=typeof u&&"function"!=typeof u)&&(u={});h{var t=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,n=/\n/g,a=/^\s*/,r=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,i=/^:\s*/,s=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,o=/^[;\s]*/,d=/^\s+|\s+$/g,l="";function c(e){return e?e.replace(d,l):l}e.exports=function(e,d){if("string"!=typeof e)throw new TypeError("First argument must be a string");if(!e)return[];d=d||{};var u=1,h=1;function g(e){var t=e.match(n);t&&(u+=t.length);var a=e.lastIndexOf("\n");h=~a?e.length-a:h+e.length}function p(){var e={line:u,column:h};return function(t){return t.position=new f(e),b(),t}}function f(e){this.start=e,this.end={line:u,column:h},this.source=d.source}f.prototype.content=e;var m=[];function R(t){var n=new Error(d.source+":"+u+":"+h+": "+t);if(n.reason=t,n.filename=d.source,n.line=u,n.column=h,n.source=e,!d.silent)throw n;m.push(n)}function y(t){var n=t.exec(e);if(n){var a=n[0];return g(a),e=e.slice(a.length),n}}function b(){y(a)}function x(e){var t;for(e=e||[];t=v();)!1!==t&&e.push(t);return e}function v(){var t=p();if("/"==e.charAt(0)&&"*"==e.charAt(1)){for(var n=2;l!=e.charAt(n)&&("*"!=e.charAt(n)||"/"!=e.charAt(n+1));)++n;if(n+=2,l===e.charAt(n-1))return R("End of comment missing");var a=e.slice(2,n-2);return h+=2,g(a),e=e.slice(n),h+=2,t({type:"comment",comment:a})}}function _(){var e=p(),n=y(r);if(n){if(v(),!y(i))return R("property missing ':'");var a=y(s),d=e({type:"declaration",property:c(n[0].replace(t,l)),value:a?c(a[0].replace(t,l)):l});return y(o),d}}return b(),function(){var e,t=[];for(x(t);e=_();)!1!==e&&(t.push(e),x(t));return t}()}},48738:e=>{e.exports=function(e){return null!=e&&null!=e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}},91296:(e,t,n)=>{var a=/^\s+|\s+$/g,r=/^[-+]0x[0-9a-f]+$/i,i=/^0b[01]+$/i,s=/^0o[0-7]+$/i,o=parseInt,d="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,l="object"==typeof self&&self&&self.Object===Object&&self,c=d||l||Function("return this")(),u=Object.prototype.toString,h=Math.max,g=Math.min,p=function(){return c.Date.now()};function f(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function m(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==u.call(e)}(e))return NaN;if(f(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=f(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(a,"");var n=i.test(e);return n||s.test(e)?o(e.slice(2),n?2:8):r.test(e)?NaN:+e}e.exports=function(e,t,n){var a,r,i,s,o,d,l=0,c=!1,u=!1,R=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function y(t){var n=a,i=r;return a=r=void 0,l=t,s=e.apply(i,n)}function b(e){return l=e,o=setTimeout(v,t),c?y(e):s}function x(e){var n=e-d;return void 0===d||n>=t||n<0||u&&e-l>=i}function v(){var e=p();if(x(e))return _(e);o=setTimeout(v,function(e){var n=t-(e-d);return u?g(n,i-(e-l)):n}(e))}function _(e){return o=void 0,R&&a?y(e):(a=r=void 0,s)}function k(){var e=p(),n=x(e);if(a=arguments,r=this,d=e,n){if(void 0===o)return b(d);if(u)return o=setTimeout(v,t),y(d)}return void 0===o&&(o=setTimeout(v,t)),s}return t=m(t)||0,f(n)&&(c=!!n.leading,i=(u="maxWait"in n)?h(m(n.maxWait)||0,t):i,R="trailing"in n?!!n.trailing:R),k.cancel=function(){void 0!==o&&clearTimeout(o),l=0,a=d=r=o=void 0},k.flush=function(){return void 0===o?s:_(p())},k}},26024:(e,t,n)=>{"use strict";e.exports=n(68914)},33231:function(e,t,n){(e=n.nmd(e)).exports=function(){"use strict";var a=Object.defineProperty,r=(e,t,n)=>t in e?a(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,i=(e,t,n)=>(r(e,"symbol"!=typeof t?t+"":t,n),n);function s(e){throw new Error('Could not dynamically require "'+e+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof n.g<"u"?n.g:typeof self<"u"&&self;var o,d,l={exports:{}};d=function(){var e;function t(){return e.apply(null,arguments)}function n(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function a(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function i(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(r(e,t))return;return 1}function d(e){return void 0===e}function l(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function c(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function u(e,t){for(var n=[],a=e.length,r=0;r>>0,a=0;aje(e)?(i=e+1,t-je(e)):(i=e,t),{year:i,dayOfYear:n}}function Ye(e,t,n){var a,r,i=ze(e.year(),t,n);return(i=Math.floor((e.dayOfYear()-i-1)/7)+1)<1?a=i+We(r=e.year()-1,t,n):i>We(e.year(),t,n)?(a=i-We(e.year(),t,n),r=e.year()+1):(r=e.year(),a=i),{week:a,year:r}}function We(e,t,n){var a=ze(e,t,n);return t=ze(e+1,t,n),(je(e)-a+t)/7}function qe(e,t){return e.slice(t,7).concat(e.slice(0,t))}B("w",["ww",2],"wo","week"),B("W",["WW",2],"Wo","isoWeek"),V("week","w"),V("isoWeek","W"),H("week",5),H("isoWeek",5),ge("w",ne),ge("ww",ne,Z),ge("W",ne),ge("WW",ne,Z),be(["w","ww","W","WW"],(function(e,t,n,a){t[a.substr(0,1)]=q(e)})),B("d",0,"do","day"),B("dd",0,0,(function(e){return this.localeData().weekdaysMin(this,e)})),B("ddd",0,0,(function(e){return this.localeData().weekdaysShort(this,e)})),B("dddd",0,0,(function(e){return this.localeData().weekdays(this,e)})),B("e",0,0,"weekday"),B("E",0,0,"isoWeekday"),V("day","d"),V("weekday","e"),V("isoWeekday","E"),H("day",11),H("weekday",11),H("isoWeekday",11),ge("d",ne),ge("e",ne),ge("E",ne),ge("dd",(function(e,t){return t.weekdaysMinRegex(e)})),ge("ddd",(function(e,t){return t.weekdaysShortRegex(e)})),ge("dddd",(function(e,t){return t.weekdaysRegex(e)})),be(["dd","ddd","dddd"],(function(e,t,n,a){null!=(a=n._locale.weekdaysParse(e,a,n._strict))?t.d=a:p(n).invalidWeekday=e})),be(["d","e","E"],(function(e,t,n,a){t[a]=q(e)}));var Ge="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Xe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Je="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Ke=he,Ze=he,Qe=he;function et(){function e(e,t){return t.length-e.length}for(var t,n,a,r=[],i=[],s=[],o=[],d=0;d<7;d++)a=g([2e3,1]).day(d),t=fe(this.weekdaysMin(a,"")),n=fe(this.weekdaysShort(a,"")),a=fe(this.weekdays(a,"")),r.push(t),i.push(n),s.push(a),o.push(t),o.push(n),o.push(a);r.sort(e),i.sort(e),s.sort(e),o.sort(e),this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function tt(){return this.hours()%12||12}function nt(e,t){B(e,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)}))}function at(e,t){return t._meridiemParse}B("H",["HH",2],0,"hour"),B("h",["hh",2],0,tt),B("k",["kk",2],0,(function(){return this.hours()||24})),B("hmm",0,0,(function(){return""+tt.apply(this)+L(this.minutes(),2)})),B("hmmss",0,0,(function(){return""+tt.apply(this)+L(this.minutes(),2)+L(this.seconds(),2)})),B("Hmm",0,0,(function(){return""+this.hours()+L(this.minutes(),2)})),B("Hmmss",0,0,(function(){return""+this.hours()+L(this.minutes(),2)+L(this.seconds(),2)})),nt("a",!0),nt("A",!1),V("hour","h"),H("hour",13),ge("a",at),ge("A",at),ge("H",ne),ge("h",ne),ge("k",ne),ge("HH",ne,Z),ge("hh",ne,Z),ge("kk",ne,Z),ge("hmm",ae),ge("hmmss",re),ge("Hmm",ae),ge("Hmmss",re),ye(["H","HH"],Ce),ye(["k","kk"],(function(e,t,n){e=q(e),t[Ce]=24===e?0:e})),ye(["a","A"],(function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e})),ye(["h","hh"],(function(e,t,n){t[Ce]=q(e),p(n).bigHour=!0})),ye("hmm",(function(e,t,n){var a=e.length-2;t[Ce]=q(e.substr(0,a)),t[we]=q(e.substr(a)),p(n).bigHour=!0})),ye("hmmss",(function(e,t,n){var a=e.length-4,r=e.length-2;t[Ce]=q(e.substr(0,a)),t[we]=q(e.substr(a,2)),t[Ee]=q(e.substr(r)),p(n).bigHour=!0})),ye("Hmm",(function(e,t,n){var a=e.length-2;t[Ce]=q(e.substr(0,a)),t[we]=q(e.substr(a))})),ye("Hmmss",(function(e,t,n){var a=e.length-4,r=e.length-2;t[Ce]=q(e.substr(0,a)),t[we]=q(e.substr(a,2)),t[Ee]=q(e.substr(r))})),he=G("Hours",!0);var rt,it={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Le,monthsShort:Ie,week:{dow:0,doy:6},weekdays:Ge,weekdaysMin:Je,weekdaysShort:Xe,meridiemParse:/[ap]\.?m?\.?/i},st={},ot={};function dt(e){return e&&e.toLowerCase().replace("_","-")}function lt(e){for(var t,n,a,r,i=0;i=t&&function(e,t){for(var n=Math.min(e.length,t.length),a=0;a=t-1)break;t--}i++}return rt}function ct(e){var t;if(void 0===st[e]&&o&&o.exports&&null!=e.match("^[^/\\\\]*$"))try{t=rt._abbr,s("./locale/"+e),ut(t)}catch{st[e]=null}return st[e]}function ut(e,t){return e&&((t=d(t)?gt(e):ht(e,t))?rt=t:typeof console<"u"&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),rt._abbr}function ht(e,t){if(null===t)return delete st[e],null;var n,a=it;if(t.abbr=e,null!=st[e])E("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),a=st[e]._config;else if(null!=t.parentLocale)if(null!=st[t.parentLocale])a=st[t.parentLocale]._config;else{if(null==(n=ct(t.parentLocale)))return ot[t.parentLocale]||(ot[t.parentLocale]=[]),ot[t.parentLocale].push({name:e,config:t}),null;a=n._config}return st[e]=new T(A(a,t)),ot[e]&&ot[e].forEach((function(e){ht(e.name,e.config)})),ut(e),st[e]}function gt(e){var t;if(!(e=e&&e._locale&&e._locale._abbr?e._locale._abbr:e))return rt;if(!n(e)){if(t=ct(e))return t;e=[e]}return lt(e)}function pt(e){var t=e._a;return t&&-2===p(e).overflow&&(t=t[_e]<0||11De(t[ve],t[_e])?ke:t[Ce]<0||24We(s,l,c)?p(r)._overflowWeeks=!0:null!=u?p(r)._overflowWeekday=!0:(h=He(s,o,d,l,c),r._a[ve]=h.year,r._dayOfYear=h.dayOfYear)),null!=e._dayOfYear&&(i=Et(e._a[ve],a[ve]),(e._dayOfYear>je(i)||0===e._dayOfYear)&&(p(e)._overflowDayOfYear=!0),u=Ue(i,0,e._dayOfYear),e._a[_e]=u.getUTCMonth(),e._a[ke]=u.getUTCDate()),n=0;n<3&&null==e._a[n];++n)e._a[n]=g[n]=a[n];for(;n<7;n++)e._a[n]=g[n]=null==e._a[n]?2===n?1:0:e._a[n];24===e._a[Ce]&&0===e._a[we]&&0===e._a[Ee]&&0===e._a[Se]&&(e._nextDay=!0,e._a[Ce]=0),e._d=(e._useUTC?Ue:$e).apply(null,g),s=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[Ce]=24),e._w&&void 0!==e._w.d&&e._w.d!==s&&(p(e).weekdayMismatch=!0)}}function At(e){if(e._f===t.ISO_8601)kt(e);else if(e._f===t.RFC_2822)wt(e);else{e._a=[],p(e).empty=!0;for(var n,a,i,s,o,d=""+e._i,l=d.length,c=0,u=P(e._f,e._locale).match(I)||[],h=u.length,g=0;ge.valueOf():e.valueOf()"}),K.toJSON=function(){return this.isValid()?this.toISOString():null},K.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},K.unix=function(){return Math.floor(this.valueOf()/1e3)},K.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},K.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},K.eraName=function(){for(var e,t=this.localeData().eras(),n=0,a=t.length;nthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},K.isLocal=function(){return!!this.isValid()&&!this._isUTC},K.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},K.isUtc=Ut,K.isUTC=Ut,K.zoneAbbr=function(){return this._isUTC?"UTC":""},K.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},K.dates=C("dates accessor is deprecated. Use date instead.",se),K.months=C("months accessor is deprecated. Use month instead",Me),K.years=C("years accessor is deprecated. Use year instead",Ve),K.zone=C("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(e,t){return null!=e?(this.utcOffset(e="string"!=typeof e?-e:e,t),this):-this.utcOffset()})),K.isDSTShifted=C("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!d(this._isDSTShifted))return this._isDSTShifted;var e,t={};return x(t,this),(t=Tt(t))._a?(e=(t._isUTC?g:Lt)(t._a),this._isDSTShifted=this.isValid()&&0{},debug:(...e)=>{},info:(...e)=>{},warn:(...e)=>{},error:(...e)=>{},fatal:(...e)=>{}},p=function(e="fatal"){let t=h.fatal;"string"==typeof e?(e=e.toLowerCase())in h&&(t=h[e]):"number"==typeof e&&(t=e),g.trace=()=>{},g.debug=()=>{},g.info=()=>{},g.warn=()=>{},g.error=()=>{},g.fatal=()=>{},t<=h.fatal&&(g.fatal=console.error?console.error.bind(console,f("FATAL"),"color: orange"):console.log.bind(console,"\x1b[35m",f("FATAL"))),t<=h.error&&(g.error=console.error?console.error.bind(console,f("ERROR"),"color: orange"):console.log.bind(console,"\x1b[31m",f("ERROR"))),t<=h.warn&&(g.warn=console.warn?console.warn.bind(console,f("WARN"),"color: orange"):console.log.bind(console,"\x1b[33m",f("WARN"))),t<=h.info&&(g.info=console.info?console.info.bind(console,f("INFO"),"color: lightblue"):console.log.bind(console,"\x1b[34m",f("INFO"))),t<=h.debug&&(g.debug=console.debug?console.debug.bind(console,f("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",f("DEBUG"))),t<=h.trace&&(g.trace=console.debug?console.debug.bind(console,f("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",f("TRACE")))},f=e=>`%c${u().format("ss.SSS")} : ${e} : `;var m={};Object.defineProperty(m,"__esModule",{value:!0});var R=m.sanitizeUrl=void 0,y=/^([^\w]*)(javascript|data|vbscript)/im,b=/&#(\w+)(^\w|;)?/g,x=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,v=/^([^:]+):/gm,_=[".","/"];function k(e){return _.indexOf(e[0])>-1}function C(e){return e.replace(b,(function(e,t){return String.fromCharCode(t)}))}function w(e){var t=C(e||"").replace(x,"").trim();if(!t)return"about:blank";if(k(t))return t;var n=t.match(v);if(!n)return t;var a=n[0];return y.test(a)?"about:blank":t}function E(e,t){return null==e||null==t?NaN:et?1:e>=t?0:NaN}function S(e,t){return null==e||null==t?NaN:te?1:t>=e?0:NaN}function A(e){let t,n,a;function r(e,a,r=0,i=e.length){if(r>>1;n(e[t],a)<0?r=t+1:i=t}while(r>>1;n(e[t],a)<=0?r=t+1:i=t}while(rn&&a(e[s-1],t)>-a(e[s],t)?s-1:s}return 2!==e.length?(t=E,n=(t,n)=>E(e(t),n),a=(t,n)=>e(t)-n):(t=e===E||e===S?e:T,n=e,a=e),{left:r,center:s,right:i}}function T(){return 0}function D(e){return null===e?NaN:+e}R=m.sanitizeUrl=w;const L=A(E).right;A(D).center;const I=L;class F extends Map{constructor(e,t=M){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:t}}),null!=e)for(const[n,a]of e)this.set(n,a)}get(e){return super.get(O(this,e))}has(e){return super.has(O(this,e))}set(e,t){return super.set(N(this,e),t)}delete(e){return super.delete(B(this,e))}}function O({_intern:e,_key:t},n){const a=t(n);return e.has(a)?e.get(a):n}function N({_intern:e,_key:t},n){const a=t(n);return e.has(a)?e.get(a):(e.set(a,n),n)}function B({_intern:e,_key:t},n){const a=t(n);return e.has(a)&&(n=e.get(a),e.delete(a)),n}function M(e){return null!==e&&"object"==typeof e?e.valueOf():e}var P=Math.sqrt(50),j=Math.sqrt(10),V=Math.sqrt(2);function $(e,t,n){var a,r,i,s,o=-1;if(n=+n,(e=+e)==(t=+t)&&n>0)return[e];if((a=t0){let n=Math.round(e/s),a=Math.round(t/s);for(n*st&&--a,i=new Array(r=a-n+1);++ot&&--a,i=new Array(r=a-n+1);++o=0?(i>=P?10:i>=j?5:i>=V?2:1)*Math.pow(10,r):-Math.pow(10,-r)/(i>=P?10:i>=j?5:i>=V?2:1)}function z(e,t,n){var a=Math.abs(t-e)/Math.max(0,n),r=Math.pow(10,Math.floor(Math.log(a)/Math.LN10)),i=a/r;return i>=P?r*=10:i>=j?r*=5:i>=V&&(r*=2),t=a)&&(n=a);else{let a=-1;for(let r of e)null!=(r=t(r,++a,e))&&(n=r)&&(n=r)}return n}function Y(e,t){let n;if(void 0===t)for(const a of e)null!=a&&(n>a||void 0===n&&a>=a)&&(n=a);else{let a=-1;for(let r of e)null!=(r=t(r,++a,e))&&(n>r||void 0===n&&r>=r)&&(n=r)}return n}function W(e){return e}var q=1,G=2,X=3,J=4,K=1e-6;function Z(e){return"translate("+e+",0)"}function Q(e){return"translate(0,"+e+")"}function ee(e){return t=>+e(t)}function te(e,t){return t=Math.max(0,e.bandwidth()-2*t)/2,e.round()&&(t=Math.round(t)),n=>+e(n)+t}function ne(){return!this.__axis}function ae(e,t){var n=[],a=null,r=null,i=6,s=6,o=3,d=typeof window<"u"&&window.devicePixelRatio>1?0:.5,l=e===q||e===J?-1:1,c=e===J||e===G?"x":"y",u=e===q||e===X?Z:Q;function h(h){var g=null==a?t.ticks?t.ticks.apply(t,n):t.domain():a,p=null==r?t.tickFormat?t.tickFormat.apply(t,n):W:r,f=Math.max(i,0)+o,m=t.range(),R=+m[0]+d,y=+m[m.length-1]+d,b=(t.bandwidth?te:ee)(t.copy(),d),x=h.selection?h.selection():h,v=x.selectAll(".domain").data([null]),_=x.selectAll(".tick").data(g,t).order(),k=_.exit(),C=_.enter().append("g").attr("class","tick"),w=_.select("line"),E=_.select("text");v=v.merge(v.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),_=_.merge(C),w=w.merge(C.append("line").attr("stroke","currentColor").attr(c+"2",l*i)),E=E.merge(C.append("text").attr("fill","currentColor").attr(c,l*f).attr("dy",e===q?"0em":e===X?"0.71em":"0.32em")),h!==x&&(v=v.transition(h),_=_.transition(h),w=w.transition(h),E=E.transition(h),k=k.transition(h).attr("opacity",K).attr("transform",(function(e){return isFinite(e=b(e))?u(e+d):this.getAttribute("transform")})),C.attr("opacity",K).attr("transform",(function(e){var t=this.parentNode.__axis;return u((t&&isFinite(t=t(e))?t:b(e))+d)}))),k.remove(),v.attr("d",e===J||e===G?s?"M"+l*s+","+R+"H"+d+"V"+y+"H"+l*s:"M"+d+","+R+"V"+y:s?"M"+R+","+l*s+"V"+d+"H"+y+"V"+l*s:"M"+R+","+d+"H"+y),_.attr("opacity",1).attr("transform",(function(e){return u(b(e)+d)})),w.attr(c+"2",l*i),E.attr(c,l*f).text(p),x.filter(ne).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",e===G?"start":e===J?"end":"middle"),x.each((function(){this.__axis=b}))}return h.scale=function(e){return arguments.length?(t=e,h):t},h.ticks=function(){return n=Array.from(arguments),h},h.tickArguments=function(e){return arguments.length?(n=null==e?[]:Array.from(e),h):n.slice()},h.tickValues=function(e){return arguments.length?(a=null==e?null:Array.from(e),h):a&&a.slice()},h.tickFormat=function(e){return arguments.length?(r=e,h):r},h.tickSize=function(e){return arguments.length?(i=s=+e,h):i},h.tickSizeInner=function(e){return arguments.length?(i=+e,h):i},h.tickSizeOuter=function(e){return arguments.length?(s=+e,h):s},h.tickPadding=function(e){return arguments.length?(o=+e,h):o},h.offset=function(e){return arguments.length?(d=+e,h):d},h}function re(e){return ae(q,e)}function ie(e){return ae(X,e)}var se={value:()=>{}};function oe(){for(var e,t=0,n=arguments.length,a={};t=0&&(n=e.slice(a+1),e=e.slice(0,a)),e&&!t.hasOwnProperty(e))throw new Error("unknown type: "+e);return{type:e,name:n}}))}function ce(e,t){for(var n,a=0,r=e.length;a0)for(var n,a,r=new Array(n),i=0;i=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),ge.hasOwnProperty(t)?{space:ge[t],local:e}:e}function fe(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===he&&t.documentElement.namespaceURI===he?t.createElement(e):t.createElementNS(n,e)}}function me(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function Re(e){var t=pe(e);return(t.local?me:fe)(t)}function ye(){}function be(e){return null==e?ye:function(){return this.querySelector(e)}}function xe(e){"function"!=typeof e&&(e=be(e));for(var t=this._groups,n=t.length,a=new Array(n),r=0;r=x&&(x=b+1);!(y=m[x])&&++x=0;)(a=r[i])&&(s&&4^a.compareDocumentPosition(s)&&s.parentNode.insertBefore(a,s),s=a);return this}function Je(e){function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}e||(e=Ke);for(var n=this._groups,a=n.length,r=new Array(a),i=0;it?1:e>=t?0:NaN}function Ze(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function Qe(){return Array.from(this)}function et(){for(var e=this._groups,t=0,n=e.length;t1?this.each((null==t?ht:"function"==typeof t?pt:gt)(e,t,null==n?"":n)):mt(this.node(),e)}function mt(e,t){return e.style.getPropertyValue(t)||ut(e).getComputedStyle(e,null).getPropertyValue(t)}function Rt(e){return function(){delete this[e]}}function yt(e,t){return function(){this[e]=t}}function bt(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function xt(e,t){return arguments.length>1?this.each((null==t?Rt:"function"==typeof t?bt:yt)(e,t)):this.node()[e]}function vt(e){return e.trim().split(/^|\s+/)}function _t(e){return e.classList||new kt(e)}function kt(e){this._node=e,this._names=vt(e.getAttribute("class")||"")}function Ct(e,t){for(var n=_t(e),a=-1,r=t.length;++a=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}}))}function Qt(e){return function(){var t=this.__on;if(t){for(var n,a=0,r=-1,i=t.length;a=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var dn=[null];function ln(e,t){this._groups=e,this._parents=t}function cn(){return new ln([[document.documentElement]],dn)}function un(){return this}function hn(e){return"string"==typeof e?new ln([[document.querySelector(e)]],[document.documentElement]):new ln([[e]],dn)}function gn(e){return"string"==typeof e?new ln([document.querySelectorAll(e)],[document.documentElement]):new ln([ve(e)],dn)}function pn(e,t,n){e.prototype=t.prototype=n,n.constructor=e}function fn(e,t){var n=Object.create(e.prototype);for(var a in t)n[a]=t[a];return n}function mn(){}ln.prototype=cn.prototype={constructor:ln,select:xe,selectAll:we,selectChild:Le,selectChildren:Ne,filter:Be,data:He,enter:Pe,exit:We,join:qe,merge:Ge,selection:un,order:Xe,sort:Je,call:Ze,nodes:Qe,node:et,size:tt,empty:nt,each:at,attr:ct,style:ft,property:xt,classed:Tt,text:Ft,html:Mt,raise:jt,lower:$t,append:Ut,insert:Ht,remove:Wt,clone:Xt,datum:Jt,on:tn,dispatch:sn,[Symbol.iterator]:on};var Rn=.7,yn=1/Rn,bn="\\s*([+-]?\\d+)\\s*",xn="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",vn="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",_n=/^#([0-9a-f]{3,8})$/,kn=new RegExp(`^rgb\\(${bn},${bn},${bn}\\)$`),Cn=new RegExp(`^rgb\\(${vn},${vn},${vn}\\)$`),wn=new RegExp(`^rgba\\(${bn},${bn},${bn},${xn}\\)$`),En=new RegExp(`^rgba\\(${vn},${vn},${vn},${xn}\\)$`),Sn=new RegExp(`^hsl\\(${xn},${vn},${vn}\\)$`),An=new RegExp(`^hsla\\(${xn},${vn},${vn},${xn}\\)$`),Tn={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};function Dn(){return this.rgb().formatHex()}function Ln(){return this.rgb().formatHex8()}function In(){return qn(this).formatHsl()}function Fn(){return this.rgb().formatRgb()}function On(e){var t,n;return e=(e+"").trim().toLowerCase(),(t=_n.exec(e))?(n=t[1].length,t=parseInt(t[1],16),6===n?Nn(t):3===n?new jn(t>>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t,1):8===n?Bn(t>>24&255,t>>16&255,t>>8&255,(255&t)/255):4===n?Bn(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|240&t,((15&t)<<4|15&t)/255):null):(t=kn.exec(e))?new jn(t[1],t[2],t[3],1):(t=Cn.exec(e))?new jn(255*t[1]/100,255*t[2]/100,255*t[3]/100,1):(t=wn.exec(e))?Bn(t[1],t[2],t[3],t[4]):(t=En.exec(e))?Bn(255*t[1]/100,255*t[2]/100,255*t[3]/100,t[4]):(t=Sn.exec(e))?Wn(t[1],t[2]/100,t[3]/100,1):(t=An.exec(e))?Wn(t[1],t[2]/100,t[3]/100,t[4]):Tn.hasOwnProperty(e)?Nn(Tn[e]):"transparent"===e?new jn(NaN,NaN,NaN,0):null}function Nn(e){return new jn(e>>16&255,e>>8&255,255&e,1)}function Bn(e,t,n,a){return a<=0&&(e=t=n=NaN),new jn(e,t,n,a)}function Mn(e){return e instanceof mn||(e=On(e)),e?new jn((e=e.rgb()).r,e.g,e.b,e.opacity):new jn}function Pn(e,t,n,a){return 1===arguments.length?Mn(e):new jn(e,t,n,null==a?1:a)}function jn(e,t,n,a){this.r=+e,this.g=+t,this.b=+n,this.opacity=+a}function Vn(){return`#${Yn(this.r)}${Yn(this.g)}${Yn(this.b)}`}function $n(){return`#${Yn(this.r)}${Yn(this.g)}${Yn(this.b)}${Yn(255*(isNaN(this.opacity)?1:this.opacity))}`}function Un(){const e=zn(this.opacity);return`${1===e?"rgb(":"rgba("}${Hn(this.r)}, ${Hn(this.g)}, ${Hn(this.b)}${1===e?")":`, ${e})`}`}function zn(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Hn(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Yn(e){return((e=Hn(e))<16?"0":"")+e.toString(16)}function Wn(e,t,n,a){return a<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Xn(e,t,n,a)}function qn(e){if(e instanceof Xn)return new Xn(e.h,e.s,e.l,e.opacity);if(e instanceof mn||(e=On(e)),!e)return new Xn;if(e instanceof Xn)return e;var t=(e=e.rgb()).r/255,n=e.g/255,a=e.b/255,r=Math.min(t,n,a),i=Math.max(t,n,a),s=NaN,o=i-r,d=(i+r)/2;return o?(s=t===i?(n-a)/o+6*(n0&&d<1?0:s,new Xn(s,o,d,e.opacity)}function Gn(e,t,n,a){return 1===arguments.length?qn(e):new Xn(e,t,n,null==a?1:a)}function Xn(e,t,n,a){this.h=+e,this.s=+t,this.l=+n,this.opacity=+a}function Jn(e){return(e=(e||0)%360)<0?e+360:e}function Kn(e){return Math.max(0,Math.min(1,e||0))}function Zn(e,t,n){return 255*(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)}pn(mn,On,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:Dn,formatHex:Dn,formatHex8:Ln,formatHsl:In,formatRgb:Fn,toString:Fn}),pn(jn,Pn,fn(mn,{brighter(e){return e=null==e?yn:Math.pow(yn,e),new jn(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=null==e?Rn:Math.pow(Rn,e),new jn(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new jn(Hn(this.r),Hn(this.g),Hn(this.b),zn(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Vn,formatHex:Vn,formatHex8:$n,formatRgb:Un,toString:Un})),pn(Xn,Gn,fn(mn,{brighter(e){return e=null==e?yn:Math.pow(yn,e),new Xn(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=null==e?Rn:Math.pow(Rn,e),new Xn(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,a=n+(n<.5?n:1-n)*t,r=2*n-a;return new jn(Zn(e>=240?e-240:e+120,r,a),Zn(e,r,a),Zn(e<120?e+240:e-120,r,a),this.opacity)},clamp(){return new Xn(Jn(this.h),Kn(this.s),Kn(this.l),zn(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=zn(this.opacity);return`${1===e?"hsl(":"hsla("}${Jn(this.h)}, ${100*Kn(this.s)}%, ${100*Kn(this.l)}%${1===e?")":`, ${e})`}`}}));const Qn=Math.PI/180,ea=180/Math.PI,ta=18,na=.96422,aa=1,ra=.82521,ia=4/29,sa=6/29,oa=3*sa*sa,da=sa*sa*sa;function la(e){if(e instanceof ua)return new ua(e.l,e.a,e.b,e.opacity);if(e instanceof ya)return ba(e);e instanceof jn||(e=Mn(e));var t,n,a=fa(e.r),r=fa(e.g),i=fa(e.b),s=ha((.2225045*a+.7168786*r+.0606169*i)/aa);return a===r&&r===i?t=n=s:(t=ha((.4360747*a+.3850649*r+.1430804*i)/na),n=ha((.0139322*a+.0971045*r+.7141733*i)/ra)),new ua(116*s-16,500*(t-s),200*(s-n),e.opacity)}function ca(e,t,n,a){return 1===arguments.length?la(e):new ua(e,t,n,null==a?1:a)}function ua(e,t,n,a){this.l=+e,this.a=+t,this.b=+n,this.opacity=+a}function ha(e){return e>da?Math.pow(e,1/3):e/oa+ia}function ga(e){return e>sa?e*e*e:oa*(e-ia)}function pa(e){return 255*(e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055)}function fa(e){return(e/=255)<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function ma(e){if(e instanceof ya)return new ya(e.h,e.c,e.l,e.opacity);if(e instanceof ua||(e=la(e)),0===e.a&&0===e.b)return new ya(NaN,0()=>e;function va(e,t){return function(n){return e+n*t}}function _a(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(a){return Math.pow(e+a*t,n)}}function ka(e,t){var n=t-e;return n?va(e,n>180||n<-180?n-360*Math.round(n/360):n):xa(isNaN(e)?t:e)}function Ca(e){return 1==(e=+e)?wa:function(t,n){return n-t?_a(t,n,e):xa(isNaN(t)?n:t)}}function wa(e,t){var n=t-e;return n?va(e,n):xa(isNaN(e)?t:e)}const Ea=function e(t){var n=Ca(t);function a(e,t){var a=n((e=Pn(e)).r,(t=Pn(t)).r),r=n(e.g,t.g),i=n(e.b,t.b),s=wa(e.opacity,t.opacity);return function(t){return e.r=a(t),e.g=r(t),e.b=i(t),e.opacity=s(t),e+""}}return a.gamma=e,a}(1);function Sa(e,t){t||(t=[]);var n,a=e?Math.min(t.length,e.length):0,r=t.slice();return function(i){for(n=0;ni&&(r=t.slice(i,r),o[s]?o[s]+=r:o[++s]=r),(n=n[0])===(a=a[0])?o[s]?o[s]+=a:o[++s]=a:(o[++s]=null,d.push({i:s,x:La(n,a)})),i=Oa.lastIndex;return i180?t+=360:t-e>180&&(e+=360),i.push({i:n.push(r(n)+"rotate(",null,a)-2,x:La(e,t)})):t&&n.push(r(n)+"rotate("+t+a)}function o(e,t,n,i){e!==t?i.push({i:n.push(r(n)+"skewX(",null,a)-2,x:La(e,t)}):t&&n.push(r(n)+"skewX("+t+a)}function d(e,t,n,a,i,s){if(e!==n||t!==a){var o=i.push(r(i)+"scale(",null,",",null,")");s.push({i:o-4,x:La(e,n)},{i:o-2,x:La(t,a)})}else(1!==n||1!==a)&&i.push(r(i)+"scale("+n+","+a+")")}return function(t,n){var a=[],r=[];return t=e(t),n=e(n),i(t.translateX,t.translateY,n.translateX,n.translateY,a,r),s(t.rotate,n.rotate,a,r),o(t.skewX,n.skewX,a,r),d(t.scaleX,t.scaleY,n.scaleX,n.scaleY,a,r),t=n=null,function(e){for(var t,n=-1,i=r.length;++n=0&&t._call.call(void 0,e),t=t._next;--Qa}function gr(){rr=(ar=sr.now())+ir,Qa=er=0;try{hr()}finally{Qa=0,fr(),rr=0}}function pr(){var e=sr.now(),t=e-ar;t>nr&&(ir-=t,ar=e)}function fr(){for(var e,t,n=Ka,a=1/0;n;)n._call?(a>n._time&&(a=n._time),e=n,n=n._next):(t=n._next,n._next=null,n=e?e._next=t:Ka=t);Za=e,mr(a)}function mr(e){Qa||(er&&(er=clearTimeout(er)),e-rr>24?(e<1/0&&(er=setTimeout(gr,e-sr.now()-ir)),tr&&(tr=clearInterval(tr))):(tr||(ar=sr.now(),tr=setInterval(pr,nr)),Qa=1,or(gr)))}function Rr(e,t,n){var a=new cr;return t=null==t?0:+t,a.restart((n=>{a.stop(),e(n+t)}),t,n),a}cr.prototype=ur.prototype={constructor:cr,restart:function(e,t,n){if("function"!=typeof e)throw new TypeError("callback is not a function");n=(null==n?dr():+n)+(null==t?0:+t),!this._next&&Za!==this&&(Za?Za._next=this:Ka=this,Za=this),this._call=e,this._time=n,mr()},stop:function(){this._call&&(this._call=null,this._time=1/0,mr())}};var yr=oe("start","end","cancel","interrupt"),br=[],xr=0,vr=1,_r=2,kr=3,Cr=4,wr=5,Er=6;function Sr(e,t,n,a,r,i){var s=e.__transition;if(s){if(n in s)return}else e.__transition={};Lr(e,n,{name:t,index:a,group:r,on:yr,tween:br,time:i.time,delay:i.delay,duration:i.duration,ease:i.ease,timer:null,state:xr})}function Ar(e,t){var n=Dr(e,t);if(n.state>xr)throw new Error("too late; already scheduled");return n}function Tr(e,t){var n=Dr(e,t);if(n.state>kr)throw new Error("too late; already running");return n}function Dr(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function Lr(e,t,n){var a,r=e.__transition;function i(e){n.state=vr,n.timer.restart(s,n.delay,n.time),n.delay<=e&&s(e-n.delay)}function s(i){var l,c,u,h;if(n.state!==vr)return d();for(l in r)if((h=r[l]).name===n.name){if(h.state===kr)return Rr(s);h.state===Cr?(h.state=Er,h.timer.stop(),h.on.call("interrupt",e,e.__data__,h.index,h.group),delete r[l]):+l_r&&n.state=0&&(e=e.slice(0,t)),!e||"start"===e}))}function ci(e,t,n){var a,r,i=li(t)?Ar:Tr;return function(){var s=i(this,e),o=s.on;o!==a&&(r=(a=o).copy()).on(t,n),s.on=r}}function ui(e,t){var n=this._id;return arguments.length<2?Dr(this.node(),n).on.on(e):this.each(ci(n,e,t))}function hi(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function gi(){return this.on("end.remove",hi(this._id))}function pi(e){var t=this._name,n=this._id;"function"!=typeof e&&(e=be(e));for(var a=this._groups,r=a.length,i=new Array(r),s=0;sJi(t,n).then((t=>(new DOMParser).parseFromString(t,e)))}qi.prototype=Gi.prototype={constructor:qi,moveTo:function(e,t){this._+="M"+(this._x0=this._x1=+e)+","+(this._y0=this._y1=+t)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(e,t){this._+="L"+(this._x1=+e)+","+(this._y1=+t)},quadraticCurveTo:function(e,t,n,a){this._+="Q"+ +e+","+ +t+","+(this._x1=+n)+","+(this._y1=+a)},bezierCurveTo:function(e,t,n,a,r,i){this._+="C"+ +e+","+ +t+","+ +n+","+ +a+","+(this._x1=+r)+","+(this._y1=+i)},arcTo:function(e,t,n,a,r){e=+e,t=+t,n=+n,a=+a,r=+r;var i=this._x1,s=this._y1,o=n-e,d=a-t,l=i-e,c=s-t,u=l*l+c*c;if(r<0)throw new Error("negative radius: "+r);if(null===this._x1)this._+="M"+(this._x1=e)+","+(this._y1=t);else if(u>Yi)if(Math.abs(c*o-d*l)>Yi&&r){var h=n-i,g=a-s,p=o*o+d*d,f=h*h+g*g,m=Math.sqrt(p),R=Math.sqrt(u),y=r*Math.tan((zi-Math.acos((p+u-f)/(2*m*R)))/2),b=y/R,x=y/m;Math.abs(b-1)>Yi&&(this._+="L"+(e+b*l)+","+(t+b*c)),this._+="A"+r+","+r+",0,0,"+ +(c*h>l*g)+","+(this._x1=e+x*o)+","+(this._y1=t+x*d)}else this._+="L"+(this._x1=e)+","+(this._y1=t)},arc:function(e,t,n,a,r,i){e=+e,t=+t,i=!!i;var s=(n=+n)*Math.cos(a),o=n*Math.sin(a),d=e+s,l=t+o,c=1^i,u=i?a-r:r-a;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+d+","+l:(Math.abs(this._x1-d)>Yi||Math.abs(this._y1-l)>Yi)&&(this._+="L"+d+","+l),n&&(u<0&&(u=u%Hi+Hi),u>Wi?this._+="A"+n+","+n+",0,1,"+c+","+(e-s)+","+(t-o)+"A"+n+","+n+",0,1,"+c+","+(this._x1=d)+","+(this._y1=l):u>Yi&&(this._+="A"+n+","+n+",0,"+ +(u>=zi)+","+c+","+(this._x1=e+n*Math.cos(r))+","+(this._y1=t+n*Math.sin(r))))},rect:function(e,t,n,a){this._+="M"+(this._x0=this._x1=+e)+","+(this._y0=this._y1=+t)+"h"+ +n+"v"+ +a+"h"+-n+"Z"},toString:function(){return this._}};var Zi=Ki("image/svg+xml");function Qi(e){return Math.abs(e=Math.round(e))>=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function es(e,t){if((n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"))<0)return null;var n,a=e.slice(0,n);return[a.length>1?a[0]+a.slice(2):a,+e.slice(n+1)]}function ts(e){return(e=es(Math.abs(e)))?e[1]:NaN}function ns(e,t){return function(n,a){for(var r=n.length,i=[],s=0,o=e[0],d=0;r>0&&o>0&&(d+o+1>a&&(o=Math.max(1,a-d)),i.push(n.substring(r-=o,r+o)),!((d+=o+1)>a));)o=e[s=(s+1)%e.length];return i.reverse().join(t)}}function as(e){return function(t){return t.replace(/[0-9]/g,(function(t){return e[+t]}))}}var rs,is=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function ss(e){if(!(t=is.exec(e)))throw new Error("invalid format: "+e);var t;return new os({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}function os(e){this.fill=void 0===e.fill?" ":e.fill+"",this.align=void 0===e.align?">":e.align+"",this.sign=void 0===e.sign?"-":e.sign+"",this.symbol=void 0===e.symbol?"":e.symbol+"",this.zero=!!e.zero,this.width=void 0===e.width?void 0:+e.width,this.comma=!!e.comma,this.precision=void 0===e.precision?void 0:+e.precision,this.trim=!!e.trim,this.type=void 0===e.type?"":e.type+""}function ds(e){e:for(var t,n=e.length,a=1,r=-1;a0&&(r=0)}return r>0?e.slice(0,r)+e.slice(t+1):e}function ls(e,t){var n=es(e,t);if(!n)return e+"";var a=n[0],r=n[1],i=r-(rs=3*Math.max(-8,Math.min(8,Math.floor(r/3))))+1,s=a.length;return i===s?a:i>s?a+new Array(i-s+1).join("0"):i>0?a.slice(0,i)+"."+a.slice(i):"0."+new Array(1-i).join("0")+es(e,Math.max(0,t+i-1))[0]}function cs(e,t){var n=es(e,t);if(!n)return e+"";var a=n[0],r=n[1];return r<0?"0."+new Array(-r).join("0")+a:a.length>r+1?a.slice(0,r+1)+"."+a.slice(r+1):a+new Array(r-a.length+2).join("0")}ss.prototype=os.prototype,os.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const us={"%":(e,t)=>(100*e).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:Qi,e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>cs(100*e,t),r:cs,s:ls,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function hs(e){return e}var gs,ps,fs,ms=Array.prototype.map,Rs=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function ys(e){var t=void 0===e.grouping||void 0===e.thousands?hs:ns(ms.call(e.grouping,Number),e.thousands+""),n=void 0===e.currency?"":e.currency[0]+"",a=void 0===e.currency?"":e.currency[1]+"",r=void 0===e.decimal?".":e.decimal+"",i=void 0===e.numerals?hs:as(ms.call(e.numerals,String)),s=void 0===e.percent?"%":e.percent+"",o=void 0===e.minus?"\u2212":e.minus+"",d=void 0===e.nan?"NaN":e.nan+"";function l(e){var l=(e=ss(e)).fill,c=e.align,u=e.sign,h=e.symbol,g=e.zero,p=e.width,f=e.comma,m=e.precision,R=e.trim,y=e.type;"n"===y?(f=!0,y="g"):us[y]||(void 0===m&&(m=12),R=!0,y="g"),(g||"0"===l&&"="===c)&&(g=!0,l="0",c="=");var b="$"===h?n:"#"===h&&/[boxX]/.test(y)?"0"+y.toLowerCase():"",x="$"===h?a:/[%p]/.test(y)?s:"",v=us[y],_=/[defgprs%]/.test(y);function k(e){var n,a,s,h=b,k=x;if("c"===y)k=v(e)+k,e="";else{var C=(e=+e)<0||1/e<0;if(e=isNaN(e)?d:v(Math.abs(e),m),R&&(e=ds(e)),C&&0==+e&&"+"!==u&&(C=!1),h=(C?"("===u?u:o:"-"===u||"("===u?"":u)+h,k=("s"===y?Rs[8+rs/3]:"")+k+(C&&"("===u?")":""),_)for(n=-1,a=e.length;++n(s=e.charCodeAt(n))||s>57){k=(46===s?r+e.slice(n+1):e.slice(n))+k,e=e.slice(0,n);break}}f&&!g&&(e=t(e,1/0));var w=h.length+e.length+k.length,E=w>1)+h+e+k+E.slice(w);break;default:e=E+h+e+k}return i(e)}return m=void 0===m?6:/[gprs]/.test(y)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),k.toString=function(){return e+""},k}function c(e,t){var n=l(((e=ss(e)).type="f",e)),a=3*Math.max(-8,Math.min(8,Math.floor(ts(t)/3))),r=Math.pow(10,-a),i=Rs[8+a/3];return function(e){return n(r*e)+i}}return{format:l,formatPrefix:c}}function bs(e){return gs=ys(e),ps=gs.format,fs=gs.formatPrefix,gs}function xs(e){return Math.max(0,-ts(Math.abs(e)))}function vs(e,t){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(ts(t)/3)))-ts(Math.abs(e)))}function _s(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,ts(t)-ts(e))+1}function ks(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e)}return this}bs({thousands:",",grouping:[3],currency:["$",""]});const Cs=Symbol("implicit");function ws(){var e=new F,t=[],n=[],a=Cs;function r(r){let i=e.get(r);if(void 0===i){if(a!==Cs)return a;e.set(r,i=t.push(r)-1)}return n[i%n.length]}return r.domain=function(n){if(!arguments.length)return t.slice();t=[],e=new F;for(const a of n)e.has(a)||e.set(a,t.push(a)-1);return r},r.range=function(e){return arguments.length?(n=Array.from(e),r):n.slice()},r.unknown=function(e){return arguments.length?(a=e,r):a},r.copy=function(){return ws(t,n).unknown(a)},ks.apply(r,arguments),r}function Es(e){return function(){return e}}function Ss(e){return+e}var As=[0,1];function Ts(e){return e}function Ds(e,t){return(t-=e=+e)?function(n){return(n-e)/t}:Es(isNaN(t)?NaN:.5)}function Ls(e,t){var n;return e>t&&(n=e,e=t,t=n),function(n){return Math.max(e,Math.min(t,n))}}function Is(e,t,n){var a=e[0],r=e[1],i=t[0],s=t[1];return r2?Fs:Is,r=i=null,u}function u(t){return null==t||isNaN(t=+t)?n:(r||(r=a(s.map(e),o,d)))(e(l(t)))}return u.invert=function(n){return l(t((i||(i=a(o,s.map(e),La)))(n)))},u.domain=function(e){return arguments.length?(s=Array.from(e,Ss),c()):s.slice()},u.range=function(e){return arguments.length?(o=Array.from(e),c()):o.slice()},u.rangeRound=function(e){return o=Array.from(e),d=ja,c()},u.clamp=function(e){return arguments.length?(l=!!e||Ts,c()):l!==Ts},u.interpolate=function(e){return arguments.length?(d=e,c()):d},u.unknown=function(e){return arguments.length?(n=e,u):n},function(n,a){return e=n,t=a,c()}}function Bs(){return Ns()(Ts,Ts)}function Ms(e,t,n,a){var r,i=z(e,t,n);switch((a=ss(null==a?",f":a)).type){case"s":var s=Math.max(Math.abs(e),Math.abs(t));return null==a.precision&&!isNaN(r=vs(i,s))&&(a.precision=r),fs(a,s);case"":case"e":case"g":case"p":case"r":null==a.precision&&!isNaN(r=_s(i,Math.max(Math.abs(e),Math.abs(t))))&&(a.precision=r-("e"===a.type));break;case"f":case"%":null==a.precision&&!isNaN(r=xs(i))&&(a.precision=r-2*("%"===a.type))}return ps(a)}function Ps(e){var t=e.domain;return e.ticks=function(e){var n=t();return $(n[0],n[n.length-1],null==e?10:e)},e.tickFormat=function(e,n){var a=t();return Ms(a[0],a[a.length-1],null==e?10:e,n)},e.nice=function(n){null==n&&(n=10);var a,r,i=t(),s=0,o=i.length-1,d=i[s],l=i[o],c=10;for(l0;){if((r=U(d,l,n))===a)return i[s]=d,i[o]=l,t(i);if(r>0)d=Math.floor(d/r)*r,l=Math.ceil(l/r)*r;else{if(!(r<0))break;d=Math.ceil(d*r)/r,l=Math.floor(l*r)/r}a=r}return e},e}function js(){var e=Bs();return e.copy=function(){return Os(e,js())},ks.apply(e,arguments),Ps(e)}function Vs(e,t){var n,a=0,r=(e=e.slice()).length-1,i=e[a],s=e[r];return s0))return o;do{o.push(s=new Date(+n)),t(n,i),e(n)}while(s=t)for(;e(t),!n(t);)t.setTime(t-1)}),(function(e,a){if(e>=e)if(a<0)for(;++a<=0;)for(;t(e,-1),!n(e););else for(;--a>=0;)for(;t(e,1),!n(e););}))},n&&(r.count=function(t,a){return $s.setTime(+t),Us.setTime(+a),e($s),e(Us),Math.floor(n($s,Us))},r.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?r.filter(a?function(t){return a(t)%e==0}:function(t){return r.count(0,t)%e==0}):r:null}),r}var Hs=zs((function(){}),(function(e,t){e.setTime(+e+t)}),(function(e,t){return t-e}));Hs.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?zs((function(t){t.setTime(Math.floor(t/e)*e)}),(function(t,n){t.setTime(+t+n*e)}),(function(t,n){return(n-t)/e})):Hs:null};const Ys=Hs;Hs.range;const Ws=1e3,qs=60*Ws,Gs=60*qs,Xs=24*Gs,Js=7*Xs,Ks=30*Xs,Zs=365*Xs;var Qs=zs((function(e){e.setTime(e-e.getMilliseconds())}),(function(e,t){e.setTime(+e+t*Ws)}),(function(e,t){return(t-e)/Ws}),(function(e){return e.getUTCSeconds()}));const eo=Qs;Qs.range;var to=zs((function(e){e.setTime(e-e.getMilliseconds()-e.getSeconds()*Ws)}),(function(e,t){e.setTime(+e+t*qs)}),(function(e,t){return(t-e)/qs}),(function(e){return e.getMinutes()}));const no=to;to.range;var ao=zs((function(e){e.setTime(e-e.getMilliseconds()-e.getSeconds()*Ws-e.getMinutes()*qs)}),(function(e,t){e.setTime(+e+t*Gs)}),(function(e,t){return(t-e)/Gs}),(function(e){return e.getHours()}));const ro=ao;ao.range;var io=zs((e=>e.setHours(0,0,0,0)),((e,t)=>e.setDate(e.getDate()+t)),((e,t)=>(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*qs)/Xs),(e=>e.getDate()-1));const so=io;function oo(e){return zs((function(t){t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)}),(function(e,t){e.setDate(e.getDate()+7*t)}),(function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*qs)/Js}))}io.range;var lo=oo(0),co=oo(1),uo=oo(2),ho=oo(3),go=oo(4),po=oo(5),fo=oo(6);lo.range,co.range,uo.range,ho.range,go.range,po.range,fo.range;var mo=zs((function(e){e.setDate(1),e.setHours(0,0,0,0)}),(function(e,t){e.setMonth(e.getMonth()+t)}),(function(e,t){return t.getMonth()-e.getMonth()+12*(t.getFullYear()-e.getFullYear())}),(function(e){return e.getMonth()}));const Ro=mo;mo.range;var yo=zs((function(e){e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,t){e.setFullYear(e.getFullYear()+t)}),(function(e,t){return t.getFullYear()-e.getFullYear()}),(function(e){return e.getFullYear()}));yo.every=function(e){return isFinite(e=Math.floor(e))&&e>0?zs((function(t){t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,n){t.setFullYear(t.getFullYear()+n*e)})):null};const bo=yo;yo.range;var xo=zs((function(e){e.setUTCSeconds(0,0)}),(function(e,t){e.setTime(+e+t*qs)}),(function(e,t){return(t-e)/qs}),(function(e){return e.getUTCMinutes()}));const vo=xo;xo.range;var _o=zs((function(e){e.setUTCMinutes(0,0,0)}),(function(e,t){e.setTime(+e+t*Gs)}),(function(e,t){return(t-e)/Gs}),(function(e){return e.getUTCHours()}));const ko=_o;_o.range;var Co=zs((function(e){e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCDate(e.getUTCDate()+t)}),(function(e,t){return(t-e)/Xs}),(function(e){return e.getUTCDate()-1}));const wo=Co;function Eo(e){return zs((function(t){t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCDate(e.getUTCDate()+7*t)}),(function(e,t){return(t-e)/Js}))}Co.range;var So=Eo(0),Ao=Eo(1),To=Eo(2),Do=Eo(3),Lo=Eo(4),Io=Eo(5),Fo=Eo(6);So.range,Ao.range,To.range,Do.range,Lo.range,Io.range,Fo.range;var Oo=zs((function(e){e.setUTCDate(1),e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCMonth(e.getUTCMonth()+t)}),(function(e,t){return t.getUTCMonth()-e.getUTCMonth()+12*(t.getUTCFullYear()-e.getUTCFullYear())}),(function(e){return e.getUTCMonth()}));const No=Oo;Oo.range;var Bo=zs((function(e){e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCFullYear(e.getUTCFullYear()+t)}),(function(e,t){return t.getUTCFullYear()-e.getUTCFullYear()}),(function(e){return e.getUTCFullYear()}));Bo.every=function(e){return isFinite(e=Math.floor(e))&&e>0?zs((function(t){t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n*e)})):null};const Mo=Bo;function Po(e,t,n,a,r,i){const s=[[eo,1,Ws],[eo,5,5*Ws],[eo,15,15*Ws],[eo,30,30*Ws],[i,1,qs],[i,5,5*qs],[i,15,15*qs],[i,30,30*qs],[r,1,Gs],[r,3,3*Gs],[r,6,6*Gs],[r,12,12*Gs],[a,1,Xs],[a,2,2*Xs],[n,1,Js],[t,1,Ks],[t,3,3*Ks],[e,1,Zs]];function o(e,t,n){const a=te)).right(s,r);if(i===s.length)return e.every(z(t/Zs,n/Zs,a));if(0===i)return Ys.every(Math.max(z(t,n,a),1));const[o,d]=s[r/s[i-1][2]53)return null;"w"in i||(i.w=1),"Z"in i?(r=(a=Uo(zo(i.y,0,1))).getUTCDay(),a=r>4||0===r?Ao.ceil(a):Ao(a),a=wo.offset(a,7*(i.V-1)),i.y=a.getUTCFullYear(),i.m=a.getUTCMonth(),i.d=a.getUTCDate()+(i.w+6)%7):(r=(a=$o(zo(i.y,0,1))).getDay(),a=r>4||0===r?co.ceil(a):co(a),a=so.offset(a,7*(i.V-1)),i.y=a.getFullYear(),i.m=a.getMonth(),i.d=a.getDate()+(i.w+6)%7)}else("W"in i||"U"in i)&&("w"in i||(i.w="u"in i?i.u%7:"W"in i?1:0),r="Z"in i?Uo(zo(i.y,0,1)).getUTCDay():$o(zo(i.y,0,1)).getDay(),i.m=0,i.d="W"in i?(i.w+6)%7+7*i.W-(r+5)%7:i.w+7*i.U-(r+6)%7);return"Z"in i?(i.H+=i.Z/100|0,i.M+=i.Z%100,Uo(i)):$o(i)}}function C(e,t,n,a){for(var r,i,s=0,o=t.length,d=n.length;s=d)return-1;if(37===(r=t.charCodeAt(s++))){if(r=t.charAt(s++),!(i=v[r in qo?t.charAt(s++):r])||(a=i(e,n,a))<0)return-1}else if(r!=n.charCodeAt(a++))return-1}return a}function w(e,t,n){var a=l.exec(t.slice(n));return a?(e.p=c.get(a[0].toLowerCase()),n+a[0].length):-1}function E(e,t,n){var a=g.exec(t.slice(n));return a?(e.w=p.get(a[0].toLowerCase()),n+a[0].length):-1}function S(e,t,n){var a=u.exec(t.slice(n));return a?(e.w=h.get(a[0].toLowerCase()),n+a[0].length):-1}function A(e,t,n){var a=R.exec(t.slice(n));return a?(e.m=y.get(a[0].toLowerCase()),n+a[0].length):-1}function T(e,t,n){var a=f.exec(t.slice(n));return a?(e.m=m.get(a[0].toLowerCase()),n+a[0].length):-1}function D(e,n,a){return C(e,t,n,a)}function L(e,t,a){return C(e,n,t,a)}function I(e,t,n){return C(e,a,t,n)}function F(e){return s[e.getDay()]}function O(e){return i[e.getDay()]}function N(e){return d[e.getMonth()]}function B(e){return o[e.getMonth()]}function M(e){return r[+(e.getHours()>=12)]}function P(e){return 1+~~(e.getMonth()/3)}function j(e){return s[e.getUTCDay()]}function V(e){return i[e.getUTCDay()]}function $(e){return d[e.getUTCMonth()]}function U(e){return o[e.getUTCMonth()]}function z(e){return r[+(e.getUTCHours()>=12)]}function H(e){return 1+~~(e.getUTCMonth()/3)}return b.x=_(n,b),b.X=_(a,b),b.c=_(t,b),x.x=_(n,x),x.X=_(a,x),x.c=_(t,x),{format:function(e){var t=_(e+="",b);return t.toString=function(){return e},t},parse:function(e){var t=k(e+="",!1);return t.toString=function(){return e},t},utcFormat:function(e){var t=_(e+="",x);return t.toString=function(){return e},t},utcParse:function(e){var t=k(e+="",!0);return t.toString=function(){return e},t}}}var Yo,Wo,qo={"-":"",_:" ",0:"0"},Go=/^\s*\d+/,Xo=/^%/,Jo=/[\\^$*+?|[\]().{}]/g;function Ko(e,t,n){var a=e<0?"-":"",r=(a?-e:e)+"",i=r.length;return a+(i[e.toLowerCase(),t])))}function td(e,t,n){var a=Go.exec(t.slice(n,n+1));return a?(e.w=+a[0],n+a[0].length):-1}function nd(e,t,n){var a=Go.exec(t.slice(n,n+1));return a?(e.u=+a[0],n+a[0].length):-1}function ad(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.U=+a[0],n+a[0].length):-1}function rd(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.V=+a[0],n+a[0].length):-1}function id(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.W=+a[0],n+a[0].length):-1}function sd(e,t,n){var a=Go.exec(t.slice(n,n+4));return a?(e.y=+a[0],n+a[0].length):-1}function od(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.y=+a[0]+(+a[0]>68?1900:2e3),n+a[0].length):-1}function dd(e,t,n){var a=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(t.slice(n,n+6));return a?(e.Z=a[1]?0:-(a[2]+(a[3]||"00")),n+a[0].length):-1}function ld(e,t,n){var a=Go.exec(t.slice(n,n+1));return a?(e.q=3*a[0]-3,n+a[0].length):-1}function cd(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.m=a[0]-1,n+a[0].length):-1}function ud(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.d=+a[0],n+a[0].length):-1}function hd(e,t,n){var a=Go.exec(t.slice(n,n+3));return a?(e.m=0,e.d=+a[0],n+a[0].length):-1}function gd(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.H=+a[0],n+a[0].length):-1}function pd(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.M=+a[0],n+a[0].length):-1}function fd(e,t,n){var a=Go.exec(t.slice(n,n+2));return a?(e.S=+a[0],n+a[0].length):-1}function md(e,t,n){var a=Go.exec(t.slice(n,n+3));return a?(e.L=+a[0],n+a[0].length):-1}function Rd(e,t,n){var a=Go.exec(t.slice(n,n+6));return a?(e.L=Math.floor(a[0]/1e3),n+a[0].length):-1}function yd(e,t,n){var a=Xo.exec(t.slice(n,n+1));return a?n+a[0].length:-1}function bd(e,t,n){var a=Go.exec(t.slice(n));return a?(e.Q=+a[0],n+a[0].length):-1}function xd(e,t,n){var a=Go.exec(t.slice(n));return a?(e.s=+a[0],n+a[0].length):-1}function vd(e,t){return Ko(e.getDate(),t,2)}function _d(e,t){return Ko(e.getHours(),t,2)}function kd(e,t){return Ko(e.getHours()%12||12,t,2)}function Cd(e,t){return Ko(1+so.count(bo(e),e),t,3)}function wd(e,t){return Ko(e.getMilliseconds(),t,3)}function Ed(e,t){return wd(e,t)+"000"}function Sd(e,t){return Ko(e.getMonth()+1,t,2)}function Ad(e,t){return Ko(e.getMinutes(),t,2)}function Td(e,t){return Ko(e.getSeconds(),t,2)}function Dd(e){var t=e.getDay();return 0===t?7:t}function Ld(e,t){return Ko(lo.count(bo(e)-1,e),t,2)}function Id(e){var t=e.getDay();return t>=4||0===t?go(e):go.ceil(e)}function Fd(e,t){return e=Id(e),Ko(go.count(bo(e),e)+(4===bo(e).getDay()),t,2)}function Od(e){return e.getDay()}function Nd(e,t){return Ko(co.count(bo(e)-1,e),t,2)}function Bd(e,t){return Ko(e.getFullYear()%100,t,2)}function Md(e,t){return Ko((e=Id(e)).getFullYear()%100,t,2)}function Pd(e,t){return Ko(e.getFullYear()%1e4,t,4)}function jd(e,t){var n=e.getDay();return Ko((e=n>=4||0===n?go(e):go.ceil(e)).getFullYear()%1e4,t,4)}function Vd(e){var t=e.getTimezoneOffset();return(t>0?"-":(t*=-1,"+"))+Ko(t/60|0,"0",2)+Ko(t%60,"0",2)}function $d(e,t){return Ko(e.getUTCDate(),t,2)}function Ud(e,t){return Ko(e.getUTCHours(),t,2)}function zd(e,t){return Ko(e.getUTCHours()%12||12,t,2)}function Hd(e,t){return Ko(1+wo.count(Mo(e),e),t,3)}function Yd(e,t){return Ko(e.getUTCMilliseconds(),t,3)}function Wd(e,t){return Yd(e,t)+"000"}function qd(e,t){return Ko(e.getUTCMonth()+1,t,2)}function Gd(e,t){return Ko(e.getUTCMinutes(),t,2)}function Xd(e,t){return Ko(e.getUTCSeconds(),t,2)}function Jd(e){var t=e.getUTCDay();return 0===t?7:t}function Kd(e,t){return Ko(So.count(Mo(e)-1,e),t,2)}function Zd(e){var t=e.getUTCDay();return t>=4||0===t?Lo(e):Lo.ceil(e)}function Qd(e,t){return e=Zd(e),Ko(Lo.count(Mo(e),e)+(4===Mo(e).getUTCDay()),t,2)}function el(e){return e.getUTCDay()}function tl(e,t){return Ko(Ao.count(Mo(e)-1,e),t,2)}function nl(e,t){return Ko(e.getUTCFullYear()%100,t,2)}function al(e,t){return Ko((e=Zd(e)).getUTCFullYear()%100,t,2)}function rl(e,t){return Ko(e.getUTCFullYear()%1e4,t,4)}function il(e,t){var n=e.getUTCDay();return Ko((e=n>=4||0===n?Lo(e):Lo.ceil(e)).getUTCFullYear()%1e4,t,4)}function sl(){return"+0000"}function ol(){return"%"}function dl(e){return+e}function ll(e){return Math.floor(+e/1e3)}function cl(e){return Yo=Ho(e),Wo=Yo.format,Yo.parse,Yo.utcFormat,Yo.utcParse,Yo}function ul(e){return new Date(e)}function hl(e){return e instanceof Date?+e:+new Date(+e)}function gl(e,t,n,a,r,i,s,o,d,l){var c=Bs(),u=c.invert,h=c.domain,g=l(".%L"),p=l(":%S"),f=l("%I:%M"),m=l("%I %p"),R=l("%a %d"),y=l("%b %d"),b=l("%B"),x=l("%Y");function v(e){return(d(e)1?0:e<-1?Cl:Math.acos(e)}function Al(e){return e>=1?wl:e<=-1?-wl:Math.asin(e)}function Tl(e){return e.innerRadius}function Dl(e){return e.outerRadius}function Ll(e){return e.startAngle}function Il(e){return e.endAngle}function Fl(e){return e&&e.padAngle}function Ol(e,t,n,a,r,i,s,o){var d=n-e,l=a-t,c=s-r,u=o-i,h=u*d-c*l;if(!(h*hD*D+L*L&&(C=E,w=S),{cx:C,cy:w,x01:-c,y01:-u,x11:C*(r/v-1),y11:w*(r/v-1)}}function Bl(){var e=Tl,t=Dl,n=fl(0),a=null,r=Ll,i=Il,s=Fl,o=null;function d(){var d,l,c=+e.apply(this,arguments),u=+t.apply(this,arguments),h=r.apply(this,arguments)-wl,g=i.apply(this,arguments)-wl,p=ml(g-h),f=g>h;if(o||(o=d=Gi()),ukl)if(p>El-kl)o.moveTo(u*yl(h),u*vl(h)),o.arc(0,0,u,h,g,!f),c>kl&&(o.moveTo(c*yl(g),c*vl(g)),o.arc(0,0,c,g,h,f));else{var m,R,y=h,b=g,x=h,v=g,_=p,k=p,C=s.apply(this,arguments)/2,w=C>kl&&(a?+a.apply(this,arguments):_l(c*c+u*u)),E=xl(ml(u-c)/2,+n.apply(this,arguments)),S=E,A=E;if(w>kl){var T=Al(w/c*vl(C)),D=Al(w/u*vl(C));(_-=2*T)>kl?(x+=T*=f?1:-1,v-=T):(_=0,x=v=(h+g)/2),(k-=2*D)>kl?(y+=D*=f?1:-1,b-=D):(k=0,y=b=(h+g)/2)}var L=u*yl(y),I=u*vl(y),F=c*yl(v),O=c*vl(v);if(E>kl){var N,B=u*yl(b),M=u*vl(b),P=c*yl(x),j=c*vl(x);if(pkl?A>kl?(m=Nl(P,j,L,I,u,A,f),R=Nl(B,M,F,O,u,A,f),o.moveTo(m.cx+m.x01,m.cy+m.y01),Akl&&_>kl?S>kl?(m=Nl(F,O,B,M,c,-S,f),R=Nl(L,I,P,j,c,-S,f),o.lineTo(m.cx+m.x01,m.cy+m.y01),Se?1:t>=e?0:NaN}function Hl(e){return e}function Yl(){var e=Hl,t=zl,n=null,a=fl(0),r=fl(El),i=fl(0);function s(s){var o,d,l,c,u,h=(s=Ml(s)).length,g=0,p=new Array(h),f=new Array(h),m=+a.apply(this,arguments),R=Math.min(El,Math.max(-El,r.apply(this,arguments)-m)),y=Math.min(Math.abs(R)/h,i.apply(this,arguments)),b=y*(R<0?-1:1);for(o=0;o0&&(g+=u);for(null!=t?p.sort((function(e,n){return t(f[e],f[n])})):null!=n&&p.sort((function(e,t){return n(s[e],s[t])})),o=0,l=g?(R-h*b)/g:0;o0?u*l:0)+b,f[d]={data:s[d],index:o,value:u,startAngle:m,endAngle:c,padAngle:y};return f}return s.value=function(t){return arguments.length?(e="function"==typeof t?t:fl(+t),s):e},s.sortValues=function(e){return arguments.length?(t=e,n=null,s):t},s.sort=function(e){return arguments.length?(n=e,t=null,s):n},s.startAngle=function(e){return arguments.length?(a="function"==typeof e?e:fl(+e),s):a},s.endAngle=function(e){return arguments.length?(r="function"==typeof e?e:fl(+e),s):r},s.padAngle=function(e){return arguments.length?(i="function"==typeof e?e:fl(+e),s):i},s}function Wl(){}function ql(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function Gl(e){this._context=e}function Xl(e){return new Gl(e)}function Jl(e){this._context=e}function Kl(e){return new Jl(e)}function Zl(e){this._context=e}function Ql(e){return new Zl(e)}function ec(e){this._context=e}function tc(e){return new ec(e)}function nc(e){return e<0?-1:1}function ac(e,t,n){var a=e._x1-e._x0,r=t-e._x1,i=(e._y1-e._y0)/(a||r<0&&-0),s=(n-e._y1)/(r||a<0&&-0),o=(i*r+s*a)/(a+r);return(nc(i)+nc(s))*Math.min(Math.abs(i),Math.abs(s),.5*Math.abs(o))||0}function rc(e,t){var n=e._x1-e._x0;return n?(3*(e._y1-e._y0)/n-t)/2:t}function ic(e,t,n){var a=e._x0,r=e._y0,i=e._x1,s=e._y1,o=(i-a)/3;e._context.bezierCurveTo(a+o,r+o*t,i-o,s-o*n,i,s)}function sc(e){this._context=e}function oc(e){this._context=new dc(e)}function dc(e){this._context=e}function lc(e){return new sc(e)}function cc(e){return new oc(e)}function uc(e){this._context=e}function hc(e){var t,n,a=e.length-1,r=new Array(a),i=new Array(a),s=new Array(a);for(r[0]=0,i[0]=2,s[0]=e[0]+2*e[1],t=1;t=0;--t)r[t]=(s[t]-r[t+1])/i[t];for(i[a-1]=(e[a]+r[a-1])/2,t=0;t"u"||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch{return!1}}function _c(e,t,n){return(_c=vc()?Reflect.construct:function(e,t,n){var a=[null];a.push.apply(a,t);var r=new(Function.bind.apply(e,a));return n&&xc(r,n.prototype),r}).apply(null,arguments)}function kc(e){return Cc(e)||wc(e)||Ec(e)||Ac()}function Cc(e){if(Array.isArray(e))return Sc(e)}function wc(e){if(typeof Symbol<"u"&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function Ec(e,t){if(e){if("string"==typeof e)return Sc(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Sc(e,t)}}function Sc(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=new Array(t);n=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var n=this._x*(1-this._t)+e*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,t)}}this._x=e,this._y=t}},yc.prototype={constructor:yc,scale:function(e){return 1===e?this:new yc(this.k*e,this.x,this.y)},translate:function(e,t){return 0===e&0===t?this:new yc(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new yc(1,0,0),yc.prototype;var Tc=Object.hasOwnProperty,Dc=Object.setPrototypeOf,Lc=Object.isFrozen,Ic=Object.getPrototypeOf,Fc=Object.getOwnPropertyDescriptor,Oc=Object.freeze,Nc=Object.seal,Bc=Object.create,Mc=typeof Reflect<"u"&&Reflect,Pc=Mc.apply,jc=Mc.construct;Pc||(Pc=function(e,t,n){return e.apply(t,n)}),Oc||(Oc=function(e){return e}),Nc||(Nc=function(e){return e}),jc||(jc=function(e,t){return _c(e,kc(t))});var Vc=Kc(Array.prototype.forEach),$c=Kc(Array.prototype.pop),Uc=Kc(Array.prototype.push),zc=Kc(String.prototype.toLowerCase),Hc=Kc(String.prototype.toString),Yc=Kc(String.prototype.match),Wc=Kc(String.prototype.replace),qc=Kc(String.prototype.indexOf),Gc=Kc(String.prototype.trim),Xc=Kc(RegExp.prototype.test),Jc=Zc(TypeError);function Kc(e){return function(t){for(var n=arguments.length,a=new Array(n>1?n-1:0),r=1;r/gm),fu=Nc(/\${[\w\W]*}/gm),mu=Nc(/^data-[\-\w.\u00B7-\uFFFF]/),Ru=Nc(/^aria-[\-\w]+$/),yu=Nc(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),bu=Nc(/^(?:\w+script|data):/i),xu=Nc(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),vu=Nc(/^html$/i),_u=function(){return typeof window>"u"?null:window},ku=function(e,t){if("object"!==bc(e)||"function"!=typeof e.createPolicy)return null;var n=null,a="data-tt-policy-suffix";t.currentScript&&t.currentScript.hasAttribute(a)&&(n=t.currentScript.getAttribute(a));var r="dompurify"+(n?"#"+n:"");try{return e.createPolicy(r,{createHTML:function(e){return e},createScriptURL:function(e){return e}})}catch{return console.warn("TrustedTypes policy "+r+" could not be created."),null}};function Cu(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:_u(),t=function(e){return Cu(e)};if(t.version="2.4.1",t.removed=[],!e||!e.document||9!==e.document.nodeType)return t.isSupported=!1,t;var n=e.document,a=e.document,r=e.DocumentFragment,i=e.HTMLTemplateElement,s=e.Node,o=e.Element,d=e.NodeFilter,l=e.NamedNodeMap,c=void 0===l?e.NamedNodeMap||e.MozNamedAttrMap:l,u=e.HTMLFormElement,h=e.DOMParser,g=e.trustedTypes,p=o.prototype,f=tu(p,"cloneNode"),m=tu(p,"nextSibling"),R=tu(p,"childNodes"),y=tu(p,"parentNode");if("function"==typeof i){var b=a.createElement("template");b.content&&b.content.ownerDocument&&(a=b.content.ownerDocument)}var x=ku(g,n),v=x?x.createHTML(""):"",_=a,k=_.implementation,C=_.createNodeIterator,w=_.createDocumentFragment,E=_.getElementsByTagName,S=n.importNode,A={};try{A=eu(a).documentMode?a.documentMode:{}}catch{}var T={};t.isSupported="function"==typeof y&&k&&typeof k.createHTMLDocument<"u"&&9!==A;var D,L,I=gu,F=pu,O=fu,N=mu,B=Ru,M=bu,P=xu,j=yu,V=null,$=Qc({},[].concat(kc(nu),kc(au),kc(ru),kc(su),kc(du))),U=null,z=Qc({},[].concat(kc(lu),kc(cu),kc(uu),kc(hu))),H=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Y=null,W=null,q=!0,G=!0,X=!1,J=!1,K=!1,Z=!1,Q=!1,ee=!1,te=!1,ne=!1,ae=!0,re=!1,ie="user-content-",se=!0,oe=!1,de={},le=null,ce=Qc({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),ue=null,he=Qc({},["audio","video","img","source","image","track"]),ge=null,pe=Qc({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),fe="http://www.w3.org/1998/Math/MathML",me="http://www.w3.org/2000/svg",Re="http://www.w3.org/1999/xhtml",ye=Re,be=!1,xe=null,ve=Qc({},[fe,me,Re],Hc),_e=["application/xhtml+xml","text/html"],ke="text/html",Ce=null,we=a.createElement("form"),Ee=function(e){return e instanceof RegExp||e instanceof Function},Se=function(e){Ce&&Ce===e||((!e||"object"!==bc(e))&&(e={}),e=eu(e),D=D=-1===_e.indexOf(e.PARSER_MEDIA_TYPE)?ke:e.PARSER_MEDIA_TYPE,L="application/xhtml+xml"===D?Hc:zc,V="ALLOWED_TAGS"in e?Qc({},e.ALLOWED_TAGS,L):$,U="ALLOWED_ATTR"in e?Qc({},e.ALLOWED_ATTR,L):z,xe="ALLOWED_NAMESPACES"in e?Qc({},e.ALLOWED_NAMESPACES,Hc):ve,ge="ADD_URI_SAFE_ATTR"in e?Qc(eu(pe),e.ADD_URI_SAFE_ATTR,L):pe,ue="ADD_DATA_URI_TAGS"in e?Qc(eu(he),e.ADD_DATA_URI_TAGS,L):he,le="FORBID_CONTENTS"in e?Qc({},e.FORBID_CONTENTS,L):ce,Y="FORBID_TAGS"in e?Qc({},e.FORBID_TAGS,L):{},W="FORBID_ATTR"in e?Qc({},e.FORBID_ATTR,L):{},de="USE_PROFILES"in e&&e.USE_PROFILES,q=!1!==e.ALLOW_ARIA_ATTR,G=!1!==e.ALLOW_DATA_ATTR,X=e.ALLOW_UNKNOWN_PROTOCOLS||!1,J=e.SAFE_FOR_TEMPLATES||!1,K=e.WHOLE_DOCUMENT||!1,ee=e.RETURN_DOM||!1,te=e.RETURN_DOM_FRAGMENT||!1,ne=e.RETURN_TRUSTED_TYPE||!1,Q=e.FORCE_BODY||!1,ae=!1!==e.SANITIZE_DOM,re=e.SANITIZE_NAMED_PROPS||!1,se=!1!==e.KEEP_CONTENT,oe=e.IN_PLACE||!1,j=e.ALLOWED_URI_REGEXP||j,ye=e.NAMESPACE||Re,e.CUSTOM_ELEMENT_HANDLING&&Ee(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(H.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&Ee(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(H.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(H.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),J&&(G=!1),te&&(ee=!0),de&&(V=Qc({},kc(du)),U=[],!0===de.html&&(Qc(V,nu),Qc(U,lu)),!0===de.svg&&(Qc(V,au),Qc(U,cu),Qc(U,hu)),!0===de.svgFilters&&(Qc(V,ru),Qc(U,cu),Qc(U,hu)),!0===de.mathMl&&(Qc(V,su),Qc(U,uu),Qc(U,hu))),e.ADD_TAGS&&(V===$&&(V=eu(V)),Qc(V,e.ADD_TAGS,L)),e.ADD_ATTR&&(U===z&&(U=eu(U)),Qc(U,e.ADD_ATTR,L)),e.ADD_URI_SAFE_ATTR&&Qc(ge,e.ADD_URI_SAFE_ATTR,L),e.FORBID_CONTENTS&&(le===ce&&(le=eu(le)),Qc(le,e.FORBID_CONTENTS,L)),se&&(V["#text"]=!0),K&&Qc(V,["html","head","body"]),V.table&&(Qc(V,["tbody"]),delete Y.tbody),Oc&&Oc(e),Ce=e)},Ae=Qc({},["mi","mo","mn","ms","mtext"]),Te=Qc({},["foreignobject","desc","title","annotation-xml"]),De=Qc({},["title","style","font","a","script"]),Le=Qc({},au);Qc(Le,ru),Qc(Le,iu);var Ie=Qc({},su);Qc(Ie,ou);var Fe=function(e){var t=y(e);(!t||!t.tagName)&&(t={namespaceURI:ye,tagName:"template"});var n=zc(e.tagName),a=zc(t.tagName);return!!xe[e.namespaceURI]&&(e.namespaceURI===me?t.namespaceURI===Re?"svg"===n:t.namespaceURI===fe?"svg"===n&&("annotation-xml"===a||Ae[a]):Boolean(Le[n]):e.namespaceURI===fe?t.namespaceURI===Re?"math"===n:t.namespaceURI===me?"math"===n&&Te[a]:Boolean(Ie[n]):e.namespaceURI===Re?!(t.namespaceURI===me&&!Te[a]||t.namespaceURI===fe&&!Ae[a])&&!Ie[n]&&(De[n]||!Le[n]):!("application/xhtml+xml"!==D||!xe[e.namespaceURI]))},Oe=function(e){Uc(t.removed,{element:e});try{e.parentNode.removeChild(e)}catch{try{e.outerHTML=v}catch{e.remove()}}},Ne=function(e,n){try{Uc(t.removed,{attribute:n.getAttributeNode(e),from:n})}catch{Uc(t.removed,{attribute:null,from:n})}if(n.removeAttribute(e),"is"===e&&!U[e])if(ee||te)try{Oe(n)}catch{}else try{n.setAttribute(e,"")}catch{}},Be=function(e){var t,n;if(Q)e=""+e;else{var r=Yc(e,/^[\r\n\t ]+/);n=r&&r[0]}"application/xhtml+xml"===D&&ye===Re&&(e=''+e+"");var i=x?x.createHTML(e):e;if(ye===Re)try{t=(new h).parseFromString(i,D)}catch{}if(!t||!t.documentElement){t=k.createDocument(ye,"template",null);try{t.documentElement.innerHTML=be?"":i}catch{}}var s=t.body||t.documentElement;return e&&n&&s.insertBefore(a.createTextNode(n),s.childNodes[0]||null),ye===Re?E.call(t,K?"html":"body")[0]:K?t.documentElement:s},Me=function(e){return C.call(e.ownerDocument||e,e,d.SHOW_ELEMENT|d.SHOW_COMMENT|d.SHOW_TEXT,null,!1)},Pe=function(e){return e instanceof u&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof c)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},je=function(e){return"object"===bc(s)?e instanceof s:e&&"object"===bc(e)&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},Ve=function(e,n,a){!T[e]||Vc(T[e],(function(e){e.call(t,n,a,Ce)}))},$e=function(e){var n;if(Ve("beforeSanitizeElements",e,null),Pe(e)||Xc(/[\u0080-\uFFFF]/,e.nodeName))return Oe(e),!0;var a=L(e.nodeName);if(Ve("uponSanitizeElement",e,{tagName:a,allowedTags:V}),e.hasChildNodes()&&!je(e.firstElementChild)&&(!je(e.content)||!je(e.content.firstElementChild))&&Xc(/<[/\w]/g,e.innerHTML)&&Xc(/<[/\w]/g,e.textContent)||"select"===a&&Xc(/