diff --git a/docs/concepts/modifiers.md b/docs/concepts/modifiers.md new file mode 100644 index 0000000000000..55802a45cce42 --- /dev/null +++ b/docs/concepts/modifiers.md @@ -0,0 +1,51 @@ +--- +id: modifiers +title: Configuration modifiers +--- + +Configuration modifiers (or just "modifiers" for short) are a feature +that lets users add ad-hoc [configuration +constraints](../rule_authors/configurations) to individual +directories, target definitions and individual `buck2` invocations. + +## Adding modifiers to a project + +To add support for modifiers in your project, simply call `set_cfg_constructor` in your root `PACKAGE` file. + +See the [dedicated how-to](../users/how_tos/modifiers_setup) for more +information. + +## Modifiers in `PACKAGE` files + +Modifiers can be specified per-directory. In that case, they are used as +the default build configurations defined in that directory. + +See the [dedicated how-to](../users/how_tos/modifiers_package) for more +information. + +## Modifiers on targets + +Modifiers can be added to individual targets. This can be used as an +alternative to the missing [per-target +transitions](../rule_authors/configurations#per-target-transition). + +See the [dedicated how-to](../users/how_tos/modifiers_target) for more +information. + +## Modifiers on the CLI + +Custom modifiers can be specified on the CLI to build a target with a +specific build configuration. For example, this can be used to build a +target with a non-default compiler, or to run a test using a specific +sanitizer. + +See the [dedicated how-to](../users/how_tos/modifiers_cli) for more +information. + +## More information + +Official documentation on modifiers is sparse at the moment, so you +might be interested in the following documents: + +- [The original RFC](../rfcs/cfg-modifiers/modifiers.pdf) +- [The @ configuration CLI RFC](../rfcs/drafts/configuration-at-syntax) diff --git a/docs/users/how_tos/compilation_database.md b/docs/users/how_tos/compilation_database.md index 073ae91a72501..f75b5bd85204a 100644 --- a/docs/users/how_tos/compilation_database.md +++ b/docs/users/how_tos/compilation_database.md @@ -1,10 +1,8 @@ --- id: compilation_database -title: Compilation databases +title: Generate C++ compilation databases --- -# Generating compilation databases - You can generate compilation databases for consumption by tools such as clangd and clang-tidy by running the following BXL script: diff --git a/docs/users/how_tos/modifiers_cli.md b/docs/users/how_tos/modifiers_cli.md new file mode 100644 index 0000000000000..54d1aba11d2f2 --- /dev/null +++ b/docs/users/how_tos/modifiers_cli.md @@ -0,0 +1,29 @@ +--- +id: modifiers_cli +title: Specify configuration modifiers from the CLI +--- + +Modifiers can be specified on the command line to override the values +set in `PACKAGE` files or on targets directly. To do so, pass constraint +targets via the `-m`/`--modifiers` flag: + +```sh +# Assuming that `//constraints:BUCK` contains the appropriate constraint +# definitions. +buck build :my_target -m //constraints:debug +buck build :my_target -m //constraints:release +``` + +Aliases can be used as shorthands (see the [setup how-to](./modifiers_setup) for more +information): + +```sh +buck build :my_target -m debug +``` + +The following shorthand syntax is planned, but is currently +unimplemented: + +```sh +buck2 build :my_target?debug +``` diff --git a/docs/users/how_tos/modifiers_package.md b/docs/users/how_tos/modifiers_package.md new file mode 100644 index 0000000000000..23846eb7e8f02 --- /dev/null +++ b/docs/users/how_tos/modifiers_package.md @@ -0,0 +1,27 @@ +--- +id: package_modifiers +title: Add configuration modifiers to entire directories +--- + +Modifiers can be set in [`PACKAGE` files](../../rule_authors/package) +using the prelude's `set_cfg_modifiers`. In this case they will be +applied to all targets affected by that `PACKAGE` file. + +For example, assuming that `root//build:debug` is an existing constraint +value and [modifiers have been setup](./modifiers_setup), the following +will apply it by default to all targets defined in that `PACKAGE`'s +directory: + +```python +load("@prelude//cfg/modifier/set_cfg_modifiers.bzl", "set_cfg_modifiers") + +set_cfg_modifiers([ + "root//build:debug", +]) +``` + +`set_cfg_modifiers` takes 2 arguments: + +- `cfg_modifiers`, a list of modifiers to set. +- `extra_cfg_modifiers_per_rule`, a dictionary mapping rule names to + lists of modifiers that should be applied only for that rule. diff --git a/docs/users/how_tos/modifiers_setup.md b/docs/users/how_tos/modifiers_setup.md new file mode 100644 index 0000000000000..33f3418449bb3 --- /dev/null +++ b/docs/users/how_tos/modifiers_setup.md @@ -0,0 +1,93 @@ +--- +id: modifiers_setup +title: Setup configuration modifiers +--- + +To start using configuration modifiers, all you need to do is call +`set_cfg_constructor` from a `PACKAGE` file. + +Start by adding the following to your root `PACKAGE` file: + +```python +load("@prelude//cfg/modifier:cfg_constructor.bzl", "cfg_constructor_post_constraint_analysis", "cfg_constructor_pre_constraint_analysis") +load("@prelude//cfg/modifier:common.bzl", "MODIFIER_METADATA_KEY") + +native.set_cfg_constructor( + stage0 = cfg_constructor_pre_constraint_analysis, + stage1 = cfg_constructor_post_constraint_analysis, + key = MODIFIER_METADATA_KEY, + aliases = struct(), + extra_data = struct(), +) +``` + +`set_cfg_constructor` is a Buck2 builtin used to setup configuration +modifiers. It supports a few configuration points: + +- `stage0` and `stage1` are used to resolve modifiers from the [target + platform](../../rule_authors/configurations) (which is now considered + deprecated) and the modifiers set in the nearest `PACKAGE` file, on + the target, and on the CLI. You _can_ override those, but the + functions provided by the prelude basically do what you would expect. +- `key` is used to fetch modifiers defined on `metadata` attributes. It + is only supported for legacy reasons, so you should not have to worry + about it. +- `aliases` contains modifier aliases to modifier modifiers. Populate it + to make aliases available from the CLI. +- `extra_data` is used for logging/validation by Meta's internal + modifier implementation. + +As you can see, `aliases` is the the only value that one would commonly +want to configure, and it might make sense to call `set_cfg_constructor` +with different `aliases` values in different `PACKAGE` files, if some +aliases only make sense in specific projects (e.g. because they have +custom configuration constraints). + +The following is an example of exposing custom aliases for build +constraints. We create a `build_mode` constraint with 2 values (`debug` +and `release`), which would most likely be `select`ed in a toolchain +definition. + +`BUCK`: + +```python +constraint_setting(name = "build_mode") + +constraint_value( + name = "debug", + constraint_setting = ":build_mode", +) + +constraint_value( + name = "release", + constraint_setting = ":build_mode", +) +``` + +`PACKAGE`: + +```python + +load("@prelude//cfg/modifier:cfg_constructor.bzl", "cfg_constructor_post_constraint_analysis", "cfg_constructor_pre_constraint_analysis") +load("@prelude//cfg/modifier:common.bzl", "MODIFIER_METADATA_KEY") + +native.set_cfg_constructor( + stage0 = cfg_constructor_pre_constraint_analysis, + stage1 = cfg_constructor_post_constraint_analysis, + key = MODIFIER_METADATA_KEY, + aliases = struct( + debug = "//build:debug", + release = "//build:release", + ), + extra_data = struct(), +) +``` + +Now, assuming that `:my_target` exists and is affected by the +`build_mode` constraint, we can build it in debug and release mode +from the command line using the `-m`/`--modifier` flag: + +```sh +buck2 build :my_target -m debug +buck2 build :my_target -m release +``` diff --git a/docs/users/how_tos/modifiers_target.md b/docs/users/how_tos/modifiers_target.md new file mode 100644 index 0000000000000..aea076d568b47 --- /dev/null +++ b/docs/users/how_tos/modifiers_target.md @@ -0,0 +1,55 @@ +--- +id: modifiers_target +title: Add configuration modifiers to a specific target +--- + +Modifiers can be added to individual targets via the `modifiers` +attribute which is exposed by all rules (this is handled by Buck2 +itself, so rule authors do not have to add it themselves). + +For example, lets assume that we have a `release_package` rule that +references various `dep`s and packages them, and that our [`PACKAGE` +file defaults our build mode to debug](./modifiers_package). We could +add the `release` modifier to our artifact target to build all +dependencies in release mode rather than debug: + +```python +release_package( + name = "my_package", + binaries = [ + ":my_cxx_bin", + ":my_rust_bin", + ], + modifiers = [ + "//constraints:debug", + ], +) +``` + +As another example, imagine that we have a constraint that controls +whether we use real or simulated IO: + +```python +constraint_setting(name = "io_mode") + +constraint_value( + name = "real_io", + constraint_setting = ":io_mode", +) + +constraint_value( + name = "simulated_io", + constraint_setting = ":io_mode", +) +``` + +The default IO mode would be `real_io`, but we would like to override it +for a specific test: + +```python +go_test( + name = "simulated_io_test", + srcs = ["test.go"], + modifiers = ["//constraints:simulated_io"], +) +``` diff --git a/website/sidebars.ts b/website/sidebars.ts index 8549e2fd40f3c..31591cf102315 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -67,6 +67,7 @@ export const sidebars: SidebarsConfig = { 'concepts/isolation_dir', 'concepts/buckconfig', 'concepts/configurations', + 'concepts/modifiers', 'concepts/glossary', ], }, @@ -82,6 +83,17 @@ export const sidebars: SidebarsConfig = { { type: 'autogenerated' as const, dirName: 'users/commands' }, ], }, + { + type: 'category' as const, + label: 'How-tos', + items: [ + 'users/how_tos/modifiers_setup', + 'users/how_tos/modifiers_package', + 'users/how_tos/modifiers_target', + 'users/how_tos/modifiers_cli', + 'users/how_tos/compilation_database', + ], + }, 'users/cheat_sheet', { type: 'category' as const,