1# Soong-Bazel equivalents 2 3This doc aims to describe *internal*-facing implementation concepts. For 4external-facing, see 5https://android.googlesource.com/platform/build/bazel/+/refs/heads/master/docs/concepts.md. 6 7[TOC] 8 9## Overview 10 11Soong/Ninja | Bazel | Remarks 12--------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ------- 13make phony goal, e.g. "dist", "sdk", "apps_only", "droidcore" | Top level `filegroup` rule target | [Details](#phony-goal) 14Ninja build target (phony) | (readable) alias to a file target | 15Ninja build target (non-phony) | File target | 16`ModuleFactory` | `RuleConfiguredTargetFactory` | 17`Module type` (e.g. `cc_library`) | Rule class (e.g. `cc_library`) | 18Module object instance | Target (instance of a rule) | [Details](#instance) 19Module properties | [Rule attributes](https://docs.bazel.build/versions/main/skylark/rules.html#attributes) | [Details](#props) 20Module name | Target label | 21Module variant | (Split) configured target | 22[LoadHooks](#loadhooks) | [macros (ish)](https://docs.bazel.build/versions/main/skylark/macros.html) | 23Top-down mutators on modules | Split configuration on targets | Allows building multiple "variants" of the same build artifact in the same build. 24Bottom-up mutators on modules | [Aspects](https://docs.bazel.build/versions/main/skylark/aspects.html) on targets | 25[Build statement (Ninja)](#ninja-build-statement) | Action (result of ctx.actions.run) | 26[Rule statement (Ninja)](#ninja-rules) | [ctx.actions.run() API](https://docs.bazel.build/versions/main/skylark/lib/actions.html) | 27`out/soong/build.ninja` and `out/build-<target>.ninja` | Action graph (serialized) | 28Pool (ninja) | Thread pools / `ExecutorService` | 29Blueprint's Registration and Parse, `ResolveDependencies` phase | Loading phase | 30Blueprint's [Generate and Write phases](#blueprint-analysis) | Analysis Phase | 31Ninja execution | Execution phase | 32Blueprints/`Android.bp` files | `BUILD`/`BUILD.bazel` files | 33[Namespaces](#namespaces) | [Packages](#pkgs) | Most Soong modules are within the global namespace 34[Mutators](#mutators) | Configuration keys (ish) | 35[Variation](#variation) | Configuration value | 36[Singleton](#singleton) | Aspect-ish | 37Target (system + vendor + product) | [Platform](https://docs.bazel.build/versions/main/platforms.html) | 38Bash scripts e.g. envsetup functions, `soong_ui.bash`) | Repository rule | 39Product and board configuration makefile and env variables | Configuration in Bazel (ish) | [Details](#config) 40[Dependency Tags](#deptags) | Provider names | 41 42## Remarks 43 44### Phony goals {#phony-goal} 45 46Soong maintains the make terminology of 47[goals](https://www.gnu.org/software/make/manual/html_node/Goals.html) to denote 48what should be built. All modules can be specified by name as a goal, in 49addition, phony goals are supported. 50 51A Phony goal creates a Make-style phony rule, a rule with no commands that can 52depend on other phony rules or real files. Phony can be called on the same name 53multiple times to add additional dependencies. These are often used to build 54many targets at once. The default goal for Android's build system is `droid`. 55Some other common phony goals include: `nothing` (perform loading/analysis), 56`docs`, `checkbuild`, `apps_only`. 57 58Some common phony goals are defined in 59[`build/make/core/main.mk`](http://cs.android.com/android/platform/superproject/+/master:build/make/core/main.mk) 60The purpose is to help `soong_ui` to determine what top level files to build. 61 62### Module/Target {#instance} 63 64When a Module is instantiated by Blueprint (which calls the appropriate 65`ModuleFactory`), the [property structs](#props) are populated by Blueprint. 66 67Blueprint performs no additional operations on these properties, such that 68dependencies on other modules and references to source files are unresolved 69initially. [`Mutators`](#mutators) then introspect the values of properties to 70[specify dependencies](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/module_ctx.go;l=871-886,918-960;drc=030150d8f9d164783ea661f07793c45198739cca) 71between modules, which 72[Blueprint resolves](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/context.go;l=1630,1667;drc=5c4abb15e3b84ab0bcedfa119e2feb397d1fb106). 73Source files (including globs) and output paths for references to other modules 74are resolved during [blueprint analysis](#blueprint-analysis) via the various 75`Path[s]ForModuleSrc[Excludes]` functions within 76[build/soong/android/paths.go](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/paths.go). 77 78For a Bazel target instance, the dependencies and source file references within 79[`attrs`](#attributes) have been resolved by Bazel. 80 81Bazel 82[implementation](https://github.com/bazelbuild/bazel/blob/a20b32690a71caf712d1d241f01fef16649562ba/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveBaseTraversalFunction.java#L113-L140) 83to collect deps. 84 85### Properties/Attributes {#props} 86 87#### Properties 88 89Within Soong/Blueprint, properties are represented as Go structs, which can be 90nested, with no depth limit. Properties can be primitive or pointer types, but 91they must be one of these types: `int64`, `string`, `bool`, `list`. 92 93These properties can be defined from various structs within the module type 94factory itself (via 95[AddProperties](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=1276;drc=8631cc7327919845c9d9037188cbd483d22ba077)) 96or from common helper functions such as: 97 98* `InitAndroidModule`: 99 [specifies](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=1042-1045;drc=8631cc7327919845c9d9037188cbd483d22ba077) 100 name-related, common, and dist properties. 101* `InitAndroidArchModule`: adds 102 [host/device properies](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=1077;drc=8631cc7327919845c9d9037188cbd483d22ba077) 103 104Go comments for a property will be treated as documentation to describe the 105property. In some cases, these comments describe a default value for the 106property. However, the default value is not based on the comment or field 107definition but resolved somewhere within the module's mutators or build. These 108defaults are often determined using Blueprint 109[`proptools`](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/proptools/proptools.go) 110`*Default` functions. For example, `cc` modules have a property 111[`include_build_directory`](https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/compiler.go;l=265;drc=135bf55281d79576f33469ce4f9abc517a614af5), 112which is described in the comments. The default value is 113[resolved](https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/compiler.go;l=265;drc=135bf55281d79576f33469ce4f9abc517a614af5) 114when compiler flags are being determined. 115 116In general, these can be set in an Android.bp file. However, if the property is 117tagged with `` `blueprint:"mutated"` ``, it can only be set programmatically 118within Blueprint/Soong. Additionally, `mutated` tagged properties also support 119`map` and `int` types in addition to those mentioned above. These `mutated` 120properties are used to propagate data that gets set during mutations, which 121ensures that the information is copied successfully to module variants during 122mutation. 123 124Soong supports additional property tags to provide additional 125functionality/information about a property: 126 127* `` `android:arch_variant` ``: This specifies that a property can be 128 configured for different architectures, operating systems, targets, etc. The 129 [arch mutator](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=597;drc=135bf55281d79576f33469ce4f9abc517a614af5), 130 will merge target-specific properties into the correct variant for 131 properties with this tag. 132 133 Note: if a nested property is arch-variant, all recursively nesting structs 134 that can be specified in an Android.bp file must also be tagged as 135 arch-variant. 136 137* `` `android:variant_prepend` ``: When merging properties for the arch 138 variant, the arch-specific values should be *prepended* rather than appended 139 to existing property values. 140 141* `` `android:path` ``: This specifies that this property will contain some 142 combination of: 143 144 * module-relative paths 145 * references to other modules in the form: 146 * `":<name>{.<tag>}"`, where `{.<tag>}` is optional to specify a 147 non-default output file, specific to the module type 148 * `"<namespace>:<name>{.<tag>}""` 149 150 Note: Dependencies to other modules for these properties will be 151 automatically added by the 152 [pathdeps mutator](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/path_properties.go;l=40;drc=40131a3f9e5ac974a44d3bd1293d31d585dc3a07). 153 154#### Attributes 155 156Similar to properties, 157[attributes](https://docs.bazel.build/versions/main/skylark/lib/attr.html) only 158support a few types. The difference is that Bazel attributes cannot be nested . 159 160Some attributes are 161[common](https://docs.bazel.build/versions/2.1.0/be/common-definitions.html#common-attributes) 162across many/all rule classes, including (but not limited to) `name`, `tag`, 163`visibility`. 164 165The definition of an attribute can contain settings, such as: its default value, 166whether it is mandatory ot have a value, and its documentation. 167 168To specify a source file or reference to another module, use `label` or 169`label_list` attribute types (rather than regular `string` or `string_list` 170types). These support additional restrictions (as compared to `string*` types), 171such as: 172 173* whether files are supported 174* the providers that must be given by a dependency 175* whether the dependency should be executable 176* the configuration (host, target) 177* aspects 178 179Unlike Soong, when accessing this attribute within the rule's implementation (at 180anlysis time), the label(s) will be resolved to the file or target they refer 181to. 182 183Attributes do not need to specify whether they accept 184[configurable attribute](https://docs.bazel.build/versions/main/configurable-attributes.html). 185However, the rule definition can specify the configuration or specify a 186[configuration transition](https://docs.bazel.build/versions/main/skylark/lib/transition.html). 187 188However, not all target definitions within a `BUILD` file are invoking a rule. 189Instead, they may invoke a Starlark macro, which is a load-time wrapper around 190rules. Arguments for a macro are not typed. If macros are used, their arguments 191would have to be wrangled into an attribute-compatible type. 192 193### LoadHooks 194 195[LoadHooks](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/hooks.go;l=24-36;drc=07656410df1836a70bea3054e50bb410ecbf8e07) 196provide access to : 197 198* append/prepend additional properties to the module 199 (`AppendProperties`/`PrependProperties`) 200* create a new module `CreateModule` 201 202`LoadHooks` make it easier to extend existing module factories to always specify 203certain properties or to split a single `Android.bp` definition into multiple 204Module instances . 205 206### Build Statement (ninja) {#ninja-build-statement} 207 208[Ninja build statements](https://ninja-build.org/manual.html#_build_statements) can be 209expanded from [Ninja rules](https://ninja-build.org/manual.html#_rules), which are like 210templates. 211 212``` 213# rule 214rule cattool 215 depfile = out/test/depfile.d 216 command = ${in} ${out} 217 218# build statement 219build out/test/output.txt: cattool test/cattool.sh test/one test/two 220 221# build statement 222build out/test/other_output.txt: cattool test/cattool.sh test/three test/four 223``` 224 225Rules for `Android.mk` modules (`out/build-<target>.ninja`) and build statements 226are 1:1. That is every rule is only used once by a single build statement. 227 228Soong (`out/soong/build.ninja`) rules are reused extensively in build statements 229(1:many). For example the `Cp` rule is a commonly used rule for creating build 230statements which copy files. 231 232### Ninja Rules in Soong {#ninja-rules} 233 234In Soong, Ninja rules can be defined in two ways: 235 236* [rule_builder](http://cs.android.com/android/platform/superproject/+/master:build/soong/android/rule_builder.go) 237* [package_ctx](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/package_ctx.go;l=102-293;drc=77cdcfdeafd383ef1f1214226c47eb20c902a28f) 238 239### Blueprint Generate & Write phase {#blueprint-analysis} 240 2411. [`ResolveDependencies`](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/context.go;l=1547;drc=5c4abb15e3b84ab0bcedfa119e2feb397d1fb106) 242 Running a series of Mutators, to add dependencies, split modules with 243 variations, etc 2441. [`PrepareBuildActions`](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/context.go;l=2367;drc=5c4abb15e3b84ab0bcedfa119e2feb397d1fb106): 245 246 1. Running Modules’ `GenerateBuildActions` to generate Ninja statements, 247 which in turn calls each module's 248 [`GenerateAndroidBuildActions`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=445-448;drc=8631cc7327919845c9d9037188cbd483d22ba077). 249 1. Running Singletons to generate Ninja statements that generate docs, 250 android.mk statements, etc 251 252### Soong namespaces {#namespace} 253 254Module 255[Namespaces](https://android.googlesource.com/platform/build/soong/+/master/README.md#namespaces) 256can import other namespaces, and there’s a module name lookup algorithm which 257terminates in the global namespace. 258 259Note: this is not widely used and most Soong modules are in the global 260namespace. 261 262### Bazel packages {#pkgs} 263 264[Packages](https://docs.bazel.build/versions/main/build-ref.html#packages) can 265nest subpackages recursively, but they are independent containers of Bazel 266targets. This means that Bazel target names only need to be unique within a 267package. 268 269### Mutators 270 271blueprint invokes mutators are invoking in the order they are registered (e.g. 272top-down and bottom-up can be interleaved). Each mutator applys a single 273visitation to every module in the graph. 274 275Mutators visiting module can parallelized, while maintaining their ordering, by 276calling `.Parallel()`. 277 278While top-down and bottom-up mutators differ in their purposes, the interface 279available to each contains many similarities. Both have access to: 280[`BaseModuleContext`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=139;drc=8631cc7327919845c9d9037188cbd483d22ba077) 281and 282[`BaseMutatorContext`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/mutator.go;l=246;drc=2ada09a5463a0108d713773679c5ba2c35450fa4). 283 284In addition to the registration order, Soong supports phase-based ordering of 285mutators: 286 2871. Pre-Arch: mutators that need to run before arch-variation. For example, 288 defaults are handled at this stage such properties from defaults are 289 correctly propagated to arch-variants later. 290 2911. (Hard-coded) 292 [`archMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=597;drc=135bf55281d79576f33469ce4f9abc517a614af5) 293 splits a module into the appropriate target(s). Next, the arch- and 294 OS-specific properties are merged into the appropriate variant. 295 2961. Pre-Deps: mutators that can/need to run before deps have been resolved, for 297 instance, creating variations that have an impact on dependency resolution. 298 2991. (Hard-coded) 300 [`depsMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/mutator.go;l=502;drc=2ada09a5463a0108d713773679c5ba2c35450fa4), 301 which calls the `DepsMutator` function that *must* be part of a Soong 302 `Module`'s interface. 303 3041. Post-Deps: mutators that need to run after deps have been resolved 305 3061. Final-Deps like post-deps but variations cannot be created 307 308#### Top-down Mutator 309 310A top-down mutator is invoked on a module before its dependencies. 311 312The general purpose is to propagate dependency info from a module to its 313dependencies. 314 315#### Bottom-up Mutator 316 317A bottom-up mutator is invoked on a module only after the mutator has been 318invoked on all its dependencies. 319 320The general purpose of a bottom-up mutator is to split modules into variants. 321 322### Soong/Blueprint Variation {#variation} 323 324A tuple (name of mutator, variation / config value) passed to 325`CreateVariations`. 326 327### Configuration {#config} 328 329Soong's config process encompasses both *what* should build and *how* it should 330build. This section focuses on the *how* aspect. 331 332We do not cover how Soong's configuration will be implemented in Bazel, but the 333general capabilities of Bazel to configure builds. 334 335#### Soong 336 337Android users can configure their builds based on: 338 339* Specifying a target (via lunch, banchan, tapas, or Soong’s command line 340 options) 341* Environment variables 342 343Some environment variables or command line options are used directly to alter 344the build. However, specification of target product encompasses many aspects of 345both *what* and *how* things are built. This configuration is currently handled 346within Make but is in the process of being migrated to Starlark. 347 348Soong 349[invokes Kati](https://cs.android.com/android/platform/superproject/+/master:build/soong/ui/build/dumpvars.go;drc=7ae80a704494bbb934dced97ed97eb55a21a9a00) 350to run in a "config" mode, also commonly known as "product config". This mode 351limits the scope of what `.mk` files are parsed. The product-specific handlers 352are largely in: 353 354* [`product_config.mk`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/product_config.mk;drc=d189ab71f3505ea28324ebfaced2466af5eb0af7): 355 this subset of functionality is also commonly referred to as "product 356 config" 357* [`board_config.mk`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/board_config.mk) 358 359However, these cover only a subset of 360[`config.mk`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/config.mk). 361This ensures that all values have appropriate defaults and specify details 362necessary to the build. Some examples: 363 364* [handling of version defaults](https://cs.android.com/android/platform/superproject/+/master:build/make/core/version_defaults.mk) 365* [rbe setup](https://cs.android.com/android/platform/superproject/+/master:build/make/core/rbe.mk) 366* [user-defined config](https://cs.android.com/android/platform/superproject/+/master:build/make/core/config.mk;l=300-308;drc=ee20ae1a8dcdfe7b843d65099000708800d9b93a): 367 [buildspec.mk](http://cs.android.com/android/platform/superproject/+/master:build/make/buildspec.mk.default) 368 is similar to 369 [`.bazelrc`](https://docs.bazel.build/versions/main/guide.html#bazelrc-the-bazel-configuration-file) 370 file. 371* ensuring 372 [`PRODUCT_SHIPPING_API_LEVEL`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/config.mk;l=729-745;drc=ee20ae1a8dcdfe7b843d65099000708800d9b93a) 373 is defaulted if not specified by the target. 374 375Finally, Kati dumps variables to be consumed by Soong: 376 377* environment variables specifically requested by Soong 378* writes 379 [`soong.variables`](http://cs.android.com/android/platform/superproject/+/master:build/make/core/soong_config.mk), 380 a JSON file 381 382Throughout Soong, environment variables can be accessed to alter the build via 383the `Config`: 384 385* [`GetEnv`](http://cs.android.com/search?q=f:soong%20%5C.GetEnv%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) 386* [`GetEnvWithDefault`](http://cs.android.com/search?q=f:soong%20%5C.GetEnvWithDefault%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) 387* [`IsEnvTrue`](http://cs.android.com/search?q=f:soong%20%5C.IsEnvTrue%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) 388* [`IsEnvFalse`](http://cs.android.com/search?q=f:soong%20%5C.IsEnvFalse%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) 389 390Soong 391[loads the `soong.variables`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/config.go;l=174;drc=b078ade28d94c85cec78e9776eb31948a5647070) 392config file, stored as 393[`productVariables`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/variable.go;l=163;drc=16e77a9b303a71018eb6630f12f1414cd6ad615c). 394These variables are used in three ways: 395 396* Direct access from `Config`, for example: paths can be 397 [opted out](https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/sanitize.go;l=364,371,393;drc=582fc2d1dde6c70687e6a0bea192f2a2ef67bbd5) 398 of specific sanitizers 399* In limited cases, users can use these within their `Android.bp` file to 400 control what is built or perform variable replacement. 401 [`variableProperties`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/variable.go;l=38;drc=16e77a9b303a71018eb6630f12f1414cd6ad615c) 402 limits which configuration variables can be specified within an `Android.bp` 403 file and which properties they can apply to. The values specified within an 404 `Android.bp` file, are merged/replaced by the 405 [`VariableMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/variable.go;l=539;drc=16e77a9b303a71018eb6630f12f1414cd6ad615c), 406 which appends performs string replacement if requested and merges the 407 properties into the modules. 408* Through 409 [Soong Config Variables](https://android.googlesource.com/platform/build/soong/+/refs/heads/master/README.md#soong-config-variables): 410 which allow users to specify additional configuration variables that can be 411 used within an `Android.bp` file for the module type and properties they 412 request. Soong config variable structs are 413 [dynamically generated](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/soongconfig/modules.go;l=257;drc=997f27aa0353dabf76d063d78ee5d4495da85651) 414 via reflection. In the 415 [factory](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/soong_config_modules.go;l=423;drc=18fd09998223d004a926b02938e4cb588e4cc934), 416 the properties to merge into the module instance are 417 [identified](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/soongconfig/modules.go;l=416;drc=997f27aa0353dabf76d063d78ee5d4495da85651) 418 based on the config variable's type. 419 420The product configuration also provides information about architecture and 421operating system, both for target(s) and host. This is used within the 422[`archMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=569-597;drc=135bf55281d79576f33469ce4f9abc517a614af5) 423to split a module into the required variants and merge target-specific 424properties into the appropriate variant. Only properties which have been tagged 425with `android:"arch_variant"` can be specified within an `Android.bp` as 426arch/os/target-specific. For example: 427 428```go 429type properties struct { 430 // this property will be arch-variant 431 Arch_variant_not_nested *string `android:"arch_variant"` 432 433 Nested_with_arch_variant struct { 434 // this property is arch-variant 435 Arch_variant_nested *string `android:"arch_variant"` 436 437 // this property is **not** arch-variant 438 Not_arch_variant_nested *string 439 } `android:"arch_variant"` 440 441 Nested_no_arch_variant struct { 442 // this property is **NOT** arch-variant 443 No_arch_variant_nested_not_arch_variant *string `android:"arch_variant"` 444 445 // this property is **not** arch-variant 446 No_arch_variant_nested *string 447 } 448} 449``` 450 451The arch/os/target-specific structs are 452[dynamically generated](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=780-787;drc=135bf55281d79576f33469ce4f9abc517a614af5) 453based on the tags using reflection. 454 455#### Bazel 456 457Bazel documentation covers configurable builds fairly extensively, so this is a 458short overview that primarily links to existing Bazel documentation rather than 459repeating it here. 460 461[Configurable attributes](https://docs.bazel.build/versions/main/configurable-attributes.html), 462(aka `select()`) allows users to toggle values of build rule attributes on the 463command line. 464 465Within a `rule`, the value of a `select` will have been resolved based on the 466configuration at analysis phase. However, within a macro (at loading phase, 467before analysis phase), a `select()` is an opaque type that cannot be inspected. 468This restricts what operations are possible on the arguments passed to a macro. 469 470The conditions within a `select` statement are one of: 471 472* [`config_setting`](https://docs.bazel.build/versions/main/be/general.html#config_setting) 473* [`constraint_value`](https://docs.bazel.build/versions/main/be/platform.html#constraint_value) 474 475A `config_setting` is a collection of build settings, whether defined by Bazel, 476or user-defined. 477 478User-defined 479[build settings](https://docs.bazel.build/versions/main/skylark/config.html#defining-build-settings) 480allow users to specify additional configuration, which *optionally* can be 481specified as a flag. In addition to specifying build settings within a 482`config_setting`, rules can depend directly on them. 483 484In addition, Bazel supports 485[`platform`s](https://docs.bazel.build/versions/main/be/platform.html#platform), 486which is a named collection of constraints. Both a target and host platform can 487be specified on the command line. 488[More about platforms](https://docs.bazel.build/versions/main/platforms.html). 489 490## Communicating between modules/targets 491 492### Soong communication 493 494There are many mechanisms to communicate between Soong modules. Because of this, 495it can be difficult to trace the information communicated between modules. 496 497#### Dependency Tags {#deptags} 498 499Dependency tags are the primary way to filter module dependencies by what 500purpose the dependency serves. For example, to filter for annotation processor 501plugins in the deps of a Java library module, use `ctx.VisitDirectDeps` and 502check the tags: 503 504``` 505ctx.VisitDirectDeps(func(module android.Module) { 506 tag := ctx.OtherModuleDependencyTag(module) 507 if tag == pluginTag { patchPaths += ":" + strings.Split(ctx.OtherModuleDir(module), "/")[0] } 508 } 509) 510``` 511 512At this point the module managing the dependency, may have enough information to 513cast it to a specific type or interface and perform more specific operations. 514 515For instance, shared libraries and executables have 516[special handling](http://cs.android.com/android/platform/superproject/+/master:build/soong/cc/cc.go;l=2771-2776;drc=5df7bd33f7b64e2b880856e3193419697a8fb693) 517for static library dependencies: where the coverage files and source based ABI 518dump files are needed explicitly. Based on the dependency tag, the module is 519cast to a concrete type, like `cc.Module`, where internal fields are accessed 520and used to obtain the desired data. 521 522Usage of dependency tags can be more evident when used between module types 523representing different langauges, as the functions must be exported in Go due to 524Soong's language-based package layout. For example, rust uses `cc` module's 525[`HasStubVariants`](http://cs.android.com/android/platform/superproject/+/master:build/soong/rust/rust.go;l=1457-1458;drc=9f59e8db270f58a3f2e4fe5bc041f84363a5877e). 526 527#### Interfaces 528 529A common mechanism for a module to communicate information about itself is to 530define or implement a Go interface. 531 532Some interfaces are common throughout Soong: 533 534* [`SourceFileProducer`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=2967;drc=8707cd74bf083fe4a31e5f5aa5e74bd2a47e9e58), 535 by implementing `Srcs() Paths` 536* [`OutputFileProducer`](http://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=2974;drc=8707cd74bf083fe4a31e5f5aa5e74bd2a47e9e58) 537 by implementing `OutputFiles(string) (Paths, error)` 538* [`HostToolProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=3032;drc=8707cd74bf083fe4a31e5f5aa5e74bd2a47e9e58) 539 by implementing `HostToolPath() OptionalPath` 540 541`SourceFileProducer` and `OutputFileProducer` are used to resolve references to 542other modules via `android:"path"` references. 543 544Modules may define additional interfaces. For example, `genrule` defines a 545[`SourceFileGenerator` interface](http://cs.android.com/android/platform/superproject/+/master:build/soong/genrule/genrule.go;l=98-102;drc=2ada09a5463a0108d713773679c5ba2c35450fa4). 546 547#### Providers 548 549Soong has Bazel-inspired providers, but providers are not used in all cases yet. 550 551Usages of providers are the easiest, simplest, and cleanest communication 552approach in Soong. 553 554In the module providing information, these are specified via 555[`SetProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=212;drc=5a34ffb350fb295780e5c373fd1c78430fa4e3ed) 556and 557[`SetVariationProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/mutator.go;l=719;drc=5a34ffb350fb295780e5c373fd1c78430fa4e3ed). 558 559In the module retrieving information, 560[`HasProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=205-206;drc=8631cc7327919845c9d9037188cbd483d22ba077) 561and 562[`Provider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=198-203;drc=8631cc7327919845c9d9037188cbd483d22ba077) 563or 564[`OtherModuleHasProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=195-196;drc=8631cc7327919845c9d9037188cbd483d22ba077) 565and 566[`OtherModuleProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=189-193;drc=8631cc7327919845c9d9037188cbd483d22ba077) 567are used to test existence and retrieve a provider. 568 569### Bazel communication 570 571Targets primarily communicate with each other via providers in Bazel rule 572implementations. All rules have access to any of the providers but rules will 573pick and choose which ones to access based on their needs. For example, all 574rules can access `JavaInfo` provider, which provides information about compile 575and rolled-up runtime jars for javac and java invocations downstream. However, 576the `JavaInfo` provider is only useful to `java_*` rules or rules that need jvm 577information. 578 579#### Starlark rules 580 581[Providers](https://docs.bazel.build/versions/main/skylark/rules.html#providers) 582are pieces of information exposed to other modules. 583 584One such provider is `DefaultInfo`, which contains the default output files and 585[`runfiles`](https://docs.bazel.build/versions/main/skylark/rules.html#runfiles). 586 587Rule authors can also create 588[custom providers](https://docs.bazel.build/versions/main/skylark/lib/Provider.html#modules.Provider) 589or implement existing providers to communicate information specific to their 590rule logic. For instance, in Android Starlark 591[`cc_object`](http://cs/android/build/bazel/rules/cc_object.bzl?l=86-87&rcl=42607e831f8ff73c82825b663609cafb777c18e1) 592rule implementation, we return a 593[`CcInfo`](https://docs.bazel.build/versions/main/skylark/lib/CcInfo.html) 594provider and a custom 595[`CcObjectInfo`](http://cs/android/build/bazel/rules/cc_object.bzl?l=17-21&rcl=42607e831f8ff73c82825b663609cafb777c18e1) 596provider. 597 598#### Native rules 599 600For implementation of native rules in Java, 601[`ruleContext.getPrerequisite`](https://github.com/bazelbuild/bazel/blob/a20b32690a71caf712d1d241f01fef16649562ba/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java#L911-L983) 602is used to extract providers from dependencies. 603 604#### `depset` construction 605 606[`depset`](https://docs.bazel.build/versions/main/glossary.html#depset) are used 607in conjunction with providers to accumulate data efficiently from transitive 608dependencies. used to accumulate data from transitive dependencies. 609 610#### `exports` 611 612Some target have an `exports` attribute by convention, like 613[`java_library.exports`](https://docs.bazel.build/versions/main/be/java.html#java_import.exports). 614This attribute is commonly used to propagate transitive dependencies to the 615dependent as though the dependent has a direct edge to the transitive 616dependencies. 617