# Soong-Bazel equivalents This doc aims to describe *internal*-facing implementation concepts. For external-facing, see https://android.googlesource.com/platform/build/bazel/+/refs/heads/master/docs/concepts.md. [TOC] ## Overview Soong/Ninja | Bazel | Remarks --------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ------- make phony goal, e.g. "dist", "sdk", "apps_only", "droidcore" | Top level `filegroup` rule target | [Details](#phony-goal) Ninja build target (phony) | (readable) alias to a file target | Ninja build target (non-phony) | File target | `ModuleFactory` | `RuleConfiguredTargetFactory` | `Module type` (e.g. `cc_library`) | Rule class (e.g. `cc_library`) | Module object instance | Target (instance of a rule) | [Details](#instance) Module properties | [Rule attributes](https://docs.bazel.build/versions/main/skylark/rules.html#attributes) | [Details](#props) Module name | Target label | Module variant | (Split) configured target | [LoadHooks](#loadhooks) | [macros (ish)](https://docs.bazel.build/versions/main/skylark/macros.html) | Top-down mutators on modules | Split configuration on targets | Allows building multiple "variants" of the same build artifact in the same build. Bottom-up mutators on modules | [Aspects](https://docs.bazel.build/versions/main/skylark/aspects.html) on targets | [Build statement (Ninja)](#ninja-build-statement) | Action (result of ctx.actions.run) | [Rule statement (Ninja)](#ninja-rules) | [ctx.actions.run() API](https://docs.bazel.build/versions/main/skylark/lib/actions.html) | `out/soong/build.ninja` and `out/build-.ninja` | Action graph (serialized) | Pool (ninja) | Thread pools / `ExecutorService` | Blueprint's Registration and Parse, `ResolveDependencies` phase | Loading phase | Blueprint's [Generate and Write phases](#blueprint-analysis) | Analysis Phase | Ninja execution | Execution phase | Blueprints/`Android.bp` files | `BUILD`/`BUILD.bazel` files | [Namespaces](#namespaces) | [Packages](#pkgs) | Most Soong modules are within the global namespace [Mutators](#mutators) | Configuration keys (ish) | [Variation](#variation) | Configuration value | [Singleton](#singleton) | Aspect-ish | Target (system + vendor + product) | [Platform](https://docs.bazel.build/versions/main/platforms.html) | Bash scripts e.g. envsetup functions, `soong_ui.bash`) | Repository rule | Product and board configuration makefile and env variables | Configuration in Bazel (ish) | [Details](#config) [Dependency Tags](#deptags) | Provider names | ## Remarks ### Phony goals {#phony-goal} Soong maintains the make terminology of [goals](https://www.gnu.org/software/make/manual/html_node/Goals.html) to denote what should be built. All modules can be specified by name as a goal, in addition, phony goals are supported. A Phony goal creates a Make-style phony rule, a rule with no commands that can depend on other phony rules or real files. Phony can be called on the same name multiple times to add additional dependencies. These are often used to build many targets at once. The default goal for Android's build system is `droid`. Some other common phony goals include: `nothing` (perform loading/analysis), `docs`, `checkbuild`, `apps_only`. Some common phony goals are defined in [`build/make/core/main.mk`](http://cs.android.com/android/platform/superproject/+/master:build/make/core/main.mk) The purpose is to help `soong_ui` to determine what top level files to build. ### Module/Target {#instance} When a Module is instantiated by Blueprint (which calls the appropriate `ModuleFactory`), the [property structs](#props) are populated by Blueprint. Blueprint performs no additional operations on these properties, such that dependencies on other modules and references to source files are unresolved initially. [`Mutators`](#mutators) then introspect the values of properties to [specify dependencies](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/module_ctx.go;l=871-886,918-960;drc=030150d8f9d164783ea661f07793c45198739cca) between modules, which [Blueprint resolves](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/context.go;l=1630,1667;drc=5c4abb15e3b84ab0bcedfa119e2feb397d1fb106). Source files (including globs) and output paths for references to other modules are resolved during [blueprint analysis](#blueprint-analysis) via the various `Path[s]ForModuleSrc[Excludes]` functions within [build/soong/android/paths.go](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/paths.go). For a Bazel target instance, the dependencies and source file references within [`attrs`](#attributes) have been resolved by Bazel. Bazel [implementation](https://github.com/bazelbuild/bazel/blob/a20b32690a71caf712d1d241f01fef16649562ba/src/main/java/com/google/devtools/build/lib/skyframe/TransitiveBaseTraversalFunction.java#L113-L140) to collect deps. ### Properties/Attributes {#props} #### Properties Within Soong/Blueprint, properties are represented as Go structs, which can be nested, with no depth limit. Properties can be primitive or pointer types, but they must be one of these types: `int64`, `string`, `bool`, `list`. These properties can be defined from various structs within the module type factory itself (via [AddProperties](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=1276;drc=8631cc7327919845c9d9037188cbd483d22ba077)) or from common helper functions such as: * `InitAndroidModule`: [specifies](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=1042-1045;drc=8631cc7327919845c9d9037188cbd483d22ba077) name-related, common, and dist properties. * `InitAndroidArchModule`: adds [host/device properies](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=1077;drc=8631cc7327919845c9d9037188cbd483d22ba077) Go comments for a property will be treated as documentation to describe the property. In some cases, these comments describe a default value for the property. However, the default value is not based on the comment or field definition but resolved somewhere within the module's mutators or build. These defaults are often determined using Blueprint [`proptools`](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/proptools/proptools.go) `*Default` functions. For example, `cc` modules have a property [`include_build_directory`](https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/compiler.go;l=265;drc=135bf55281d79576f33469ce4f9abc517a614af5), which is described in the comments. The default value is [resolved](https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/compiler.go;l=265;drc=135bf55281d79576f33469ce4f9abc517a614af5) when compiler flags are being determined. In general, these can be set in an Android.bp file. However, if the property is tagged with `` `blueprint:"mutated"` ``, it can only be set programmatically within Blueprint/Soong. Additionally, `mutated` tagged properties also support `map` and `int` types in addition to those mentioned above. These `mutated` properties are used to propagate data that gets set during mutations, which ensures that the information is copied successfully to module variants during mutation. Soong supports additional property tags to provide additional functionality/information about a property: * `` `android:arch_variant` ``: This specifies that a property can be configured for different architectures, operating systems, targets, etc. The [arch mutator](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=597;drc=135bf55281d79576f33469ce4f9abc517a614af5), will merge target-specific properties into the correct variant for properties with this tag. Note: if a nested property is arch-variant, all recursively nesting structs that can be specified in an Android.bp file must also be tagged as arch-variant. * `` `android:variant_prepend` ``: When merging properties for the arch variant, the arch-specific values should be *prepended* rather than appended to existing property values. * `` `android:path` ``: This specifies that this property will contain some combination of: * module-relative paths * references to other modules in the form: * `":{.}"`, where `{.}` is optional to specify a non-default output file, specific to the module type * `":{.}""` Note: Dependencies to other modules for these properties will be automatically added by the [pathdeps mutator](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/path_properties.go;l=40;drc=40131a3f9e5ac974a44d3bd1293d31d585dc3a07). #### Attributes Similar to properties, [attributes](https://docs.bazel.build/versions/main/skylark/lib/attr.html) only support a few types. The difference is that Bazel attributes cannot be nested . Some attributes are [common](https://docs.bazel.build/versions/2.1.0/be/common-definitions.html#common-attributes) across many/all rule classes, including (but not limited to) `name`, `tag`, `visibility`. The definition of an attribute can contain settings, such as: its default value, whether it is mandatory ot have a value, and its documentation. To specify a source file or reference to another module, use `label` or `label_list` attribute types (rather than regular `string` or `string_list` types). These support additional restrictions (as compared to `string*` types), such as: * whether files are supported * the providers that must be given by a dependency * whether the dependency should be executable * the configuration (host, target) * aspects Unlike Soong, when accessing this attribute within the rule's implementation (at anlysis time), the label(s) will be resolved to the file or target they refer to. Attributes do not need to specify whether they accept [configurable attribute](https://docs.bazel.build/versions/main/configurable-attributes.html). However, the rule definition can specify the configuration or specify a [configuration transition](https://docs.bazel.build/versions/main/skylark/lib/transition.html). However, not all target definitions within a `BUILD` file are invoking a rule. Instead, they may invoke a Starlark macro, which is a load-time wrapper around rules. Arguments for a macro are not typed. If macros are used, their arguments would have to be wrangled into an attribute-compatible type. ### LoadHooks [LoadHooks](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/hooks.go;l=24-36;drc=07656410df1836a70bea3054e50bb410ecbf8e07) provide access to : * append/prepend additional properties to the module (`AppendProperties`/`PrependProperties`) * create a new module `CreateModule` `LoadHooks` make it easier to extend existing module factories to always specify certain properties or to split a single `Android.bp` definition into multiple Module instances . ### Build Statement (ninja) {#ninja-build-statement} [Ninja build statements](https://ninja-build.org/manual.html#_build_statements) can be expanded from [Ninja rules](https://ninja-build.org/manual.html#_rules), which are like templates. ``` # rule rule cattool depfile = out/test/depfile.d command = ${in} ${out} # build statement build out/test/output.txt: cattool test/cattool.sh test/one test/two # build statement build out/test/other_output.txt: cattool test/cattool.sh test/three test/four ``` Rules for `Android.mk` modules (`out/build-.ninja`) and build statements are 1:1. That is every rule is only used once by a single build statement. Soong (`out/soong/build.ninja`) rules are reused extensively in build statements (1:many). For example the `Cp` rule is a commonly used rule for creating build statements which copy files. ### Ninja Rules in Soong {#ninja-rules} In Soong, Ninja rules can be defined in two ways: * [rule_builder](http://cs.android.com/android/platform/superproject/+/master:build/soong/android/rule_builder.go) * [package_ctx](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/package_ctx.go;l=102-293;drc=77cdcfdeafd383ef1f1214226c47eb20c902a28f) ### Blueprint Generate & Write phase {#blueprint-analysis} 1. [`ResolveDependencies`](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/context.go;l=1547;drc=5c4abb15e3b84ab0bcedfa119e2feb397d1fb106) Running a series of Mutators, to add dependencies, split modules with variations, etc 1. [`PrepareBuildActions`](https://cs.android.com/android/platform/superproject/+/master:build/blueprint/context.go;l=2367;drc=5c4abb15e3b84ab0bcedfa119e2feb397d1fb106): 1. Running Modules’ `GenerateBuildActions` to generate Ninja statements, which in turn calls each module's [`GenerateAndroidBuildActions`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=445-448;drc=8631cc7327919845c9d9037188cbd483d22ba077). 1. Running Singletons to generate Ninja statements that generate docs, android.mk statements, etc ### Soong namespaces {#namespace} Module [Namespaces](https://android.googlesource.com/platform/build/soong/+/master/README.md#namespaces) can import other namespaces, and there’s a module name lookup algorithm which terminates in the global namespace. Note: this is not widely used and most Soong modules are in the global namespace. ### Bazel packages {#pkgs} [Packages](https://docs.bazel.build/versions/main/build-ref.html#packages) can nest subpackages recursively, but they are independent containers of Bazel targets. This means that Bazel target names only need to be unique within a package. ### Mutators blueprint invokes mutators are invoking in the order they are registered (e.g. top-down and bottom-up can be interleaved). Each mutator applys a single visitation to every module in the graph. Mutators visiting module can parallelized, while maintaining their ordering, by calling `.Parallel()`. While top-down and bottom-up mutators differ in their purposes, the interface available to each contains many similarities. Both have access to: [`BaseModuleContext`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=139;drc=8631cc7327919845c9d9037188cbd483d22ba077) and [`BaseMutatorContext`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/mutator.go;l=246;drc=2ada09a5463a0108d713773679c5ba2c35450fa4). In addition to the registration order, Soong supports phase-based ordering of mutators: 1. Pre-Arch: mutators that need to run before arch-variation. For example, defaults are handled at this stage such properties from defaults are correctly propagated to arch-variants later. 1. (Hard-coded) [`archMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=597;drc=135bf55281d79576f33469ce4f9abc517a614af5) splits a module into the appropriate target(s). Next, the arch- and OS-specific properties are merged into the appropriate variant. 1. Pre-Deps: mutators that can/need to run before deps have been resolved, for instance, creating variations that have an impact on dependency resolution. 1. (Hard-coded) [`depsMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/mutator.go;l=502;drc=2ada09a5463a0108d713773679c5ba2c35450fa4), which calls the `DepsMutator` function that *must* be part of a Soong `Module`'s interface. 1. Post-Deps: mutators that need to run after deps have been resolved 1. Final-Deps like post-deps but variations cannot be created #### Top-down Mutator A top-down mutator is invoked on a module before its dependencies. The general purpose is to propagate dependency info from a module to its dependencies. #### Bottom-up Mutator A bottom-up mutator is invoked on a module only after the mutator has been invoked on all its dependencies. The general purpose of a bottom-up mutator is to split modules into variants. ### Soong/Blueprint Variation {#variation} A tuple (name of mutator, variation / config value) passed to `CreateVariations`. ### Configuration {#config} Soong's config process encompasses both *what* should build and *how* it should build. This section focuses on the *how* aspect. We do not cover how Soong's configuration will be implemented in Bazel, but the general capabilities of Bazel to configure builds. #### Soong Android users can configure their builds based on: * Specifying a target (via lunch, banchan, tapas, or Soong’s command line options) * Environment variables Some environment variables or command line options are used directly to alter the build. However, specification of target product encompasses many aspects of both *what* and *how* things are built. This configuration is currently handled within Make but is in the process of being migrated to Starlark. Soong [invokes Kati](https://cs.android.com/android/platform/superproject/+/master:build/soong/ui/build/dumpvars.go;drc=7ae80a704494bbb934dced97ed97eb55a21a9a00) to run in a "config" mode, also commonly known as "product config". This mode limits the scope of what `.mk` files are parsed. The product-specific handlers are largely in: * [`product_config.mk`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/product_config.mk;drc=d189ab71f3505ea28324ebfaced2466af5eb0af7): this subset of functionality is also commonly referred to as "product config" * [`board_config.mk`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/board_config.mk) However, these cover only a subset of [`config.mk`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/config.mk). This ensures that all values have appropriate defaults and specify details necessary to the build. Some examples: * [handling of version defaults](https://cs.android.com/android/platform/superproject/+/master:build/make/core/version_defaults.mk) * [rbe setup](https://cs.android.com/android/platform/superproject/+/master:build/make/core/rbe.mk) * [user-defined config](https://cs.android.com/android/platform/superproject/+/master:build/make/core/config.mk;l=300-308;drc=ee20ae1a8dcdfe7b843d65099000708800d9b93a): [buildspec.mk](http://cs.android.com/android/platform/superproject/+/master:build/make/buildspec.mk.default) is similar to [`.bazelrc`](https://docs.bazel.build/versions/main/guide.html#bazelrc-the-bazel-configuration-file) file. * ensuring [`PRODUCT_SHIPPING_API_LEVEL`](https://cs.android.com/android/platform/superproject/+/master:build/make/core/config.mk;l=729-745;drc=ee20ae1a8dcdfe7b843d65099000708800d9b93a) is defaulted if not specified by the target. Finally, Kati dumps variables to be consumed by Soong: * environment variables specifically requested by Soong * writes [`soong.variables`](http://cs.android.com/android/platform/superproject/+/master:build/make/core/soong_config.mk), a JSON file Throughout Soong, environment variables can be accessed to alter the build via the `Config`: * [`GetEnv`](http://cs.android.com/search?q=f:soong%20%5C.GetEnv%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) * [`GetEnvWithDefault`](http://cs.android.com/search?q=f:soong%20%5C.GetEnvWithDefault%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) * [`IsEnvTrue`](http://cs.android.com/search?q=f:soong%20%5C.IsEnvTrue%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) * [`IsEnvFalse`](http://cs.android.com/search?q=f:soong%20%5C.IsEnvFalse%5C%28%20-f:%2Fui%2F%20-f:%2Fcmd%2F&sq=) Soong [loads the `soong.variables`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/config.go;l=174;drc=b078ade28d94c85cec78e9776eb31948a5647070) config file, stored as [`productVariables`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/variable.go;l=163;drc=16e77a9b303a71018eb6630f12f1414cd6ad615c). These variables are used in three ways: * Direct access from `Config`, for example: paths can be [opted out](https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/sanitize.go;l=364,371,393;drc=582fc2d1dde6c70687e6a0bea192f2a2ef67bbd5) of specific sanitizers * In limited cases, users can use these within their `Android.bp` file to control what is built or perform variable replacement. [`variableProperties`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/variable.go;l=38;drc=16e77a9b303a71018eb6630f12f1414cd6ad615c) limits which configuration variables can be specified within an `Android.bp` file and which properties they can apply to. The values specified within an `Android.bp` file, are merged/replaced by the [`VariableMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/variable.go;l=539;drc=16e77a9b303a71018eb6630f12f1414cd6ad615c), which appends performs string replacement if requested and merges the properties into the modules. * Through [Soong Config Variables](https://android.googlesource.com/platform/build/soong/+/refs/heads/master/README.md#soong-config-variables): which allow users to specify additional configuration variables that can be used within an `Android.bp` file for the module type and properties they request. Soong config variable structs are [dynamically generated](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/soongconfig/modules.go;l=257;drc=997f27aa0353dabf76d063d78ee5d4495da85651) via reflection. In the [factory](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/soong_config_modules.go;l=423;drc=18fd09998223d004a926b02938e4cb588e4cc934), the properties to merge into the module instance are [identified](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/soongconfig/modules.go;l=416;drc=997f27aa0353dabf76d063d78ee5d4495da85651) based on the config variable's type. The product configuration also provides information about architecture and operating system, both for target(s) and host. This is used within the [`archMutator`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=569-597;drc=135bf55281d79576f33469ce4f9abc517a614af5) to split a module into the required variants and merge target-specific properties into the appropriate variant. Only properties which have been tagged with `android:"arch_variant"` can be specified within an `Android.bp` as arch/os/target-specific. For example: ```go type properties struct { // this property will be arch-variant Arch_variant_not_nested *string `android:"arch_variant"` Nested_with_arch_variant struct { // this property is arch-variant Arch_variant_nested *string `android:"arch_variant"` // this property is **not** arch-variant Not_arch_variant_nested *string } `android:"arch_variant"` Nested_no_arch_variant struct { // this property is **NOT** arch-variant No_arch_variant_nested_not_arch_variant *string `android:"arch_variant"` // this property is **not** arch-variant No_arch_variant_nested *string } } ``` The arch/os/target-specific structs are [dynamically generated](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=780-787;drc=135bf55281d79576f33469ce4f9abc517a614af5) based on the tags using reflection. #### Bazel Bazel documentation covers configurable builds fairly extensively, so this is a short overview that primarily links to existing Bazel documentation rather than repeating it here. [Configurable attributes](https://docs.bazel.build/versions/main/configurable-attributes.html), (aka `select()`) allows users to toggle values of build rule attributes on the command line. Within a `rule`, the value of a `select` will have been resolved based on the configuration at analysis phase. However, within a macro (at loading phase, before analysis phase), a `select()` is an opaque type that cannot be inspected. This restricts what operations are possible on the arguments passed to a macro. The conditions within a `select` statement are one of: * [`config_setting`](https://docs.bazel.build/versions/main/be/general.html#config_setting) * [`constraint_value`](https://docs.bazel.build/versions/main/be/platform.html#constraint_value) A `config_setting` is a collection of build settings, whether defined by Bazel, or user-defined. User-defined [build settings](https://docs.bazel.build/versions/main/skylark/config.html#defining-build-settings) allow users to specify additional configuration, which *optionally* can be specified as a flag. In addition to specifying build settings within a `config_setting`, rules can depend directly on them. In addition, Bazel supports [`platform`s](https://docs.bazel.build/versions/main/be/platform.html#platform), which is a named collection of constraints. Both a target and host platform can be specified on the command line. [More about platforms](https://docs.bazel.build/versions/main/platforms.html). ## Communicating between modules/targets ### Soong communication There are many mechanisms to communicate between Soong modules. Because of this, it can be difficult to trace the information communicated between modules. #### Dependency Tags {#deptags} Dependency tags are the primary way to filter module dependencies by what purpose the dependency serves. For example, to filter for annotation processor plugins in the deps of a Java library module, use `ctx.VisitDirectDeps` and check the tags: ``` ctx.VisitDirectDeps(func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) if tag == pluginTag { patchPaths += ":" + strings.Split(ctx.OtherModuleDir(module), "/")[0] } } ) ``` At this point the module managing the dependency, may have enough information to cast it to a specific type or interface and perform more specific operations. For instance, shared libraries and executables have [special handling](http://cs.android.com/android/platform/superproject/+/master:build/soong/cc/cc.go;l=2771-2776;drc=5df7bd33f7b64e2b880856e3193419697a8fb693) for static library dependencies: where the coverage files and source based ABI dump files are needed explicitly. Based on the dependency tag, the module is cast to a concrete type, like `cc.Module`, where internal fields are accessed and used to obtain the desired data. Usage of dependency tags can be more evident when used between module types representing different langauges, as the functions must be exported in Go due to Soong's language-based package layout. For example, rust uses `cc` module's [`HasStubVariants`](http://cs.android.com/android/platform/superproject/+/master:build/soong/rust/rust.go;l=1457-1458;drc=9f59e8db270f58a3f2e4fe5bc041f84363a5877e). #### Interfaces A common mechanism for a module to communicate information about itself is to define or implement a Go interface. Some interfaces are common throughout Soong: * [`SourceFileProducer`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=2967;drc=8707cd74bf083fe4a31e5f5aa5e74bd2a47e9e58), by implementing `Srcs() Paths` * [`OutputFileProducer`](http://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=2974;drc=8707cd74bf083fe4a31e5f5aa5e74bd2a47e9e58) by implementing `OutputFiles(string) (Paths, error)` * [`HostToolProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=3032;drc=8707cd74bf083fe4a31e5f5aa5e74bd2a47e9e58) by implementing `HostToolPath() OptionalPath` `SourceFileProducer` and `OutputFileProducer` are used to resolve references to other modules via `android:"path"` references. Modules may define additional interfaces. For example, `genrule` defines a [`SourceFileGenerator` interface](http://cs.android.com/android/platform/superproject/+/master:build/soong/genrule/genrule.go;l=98-102;drc=2ada09a5463a0108d713773679c5ba2c35450fa4). #### Providers Soong has Bazel-inspired providers, but providers are not used in all cases yet. Usages of providers are the easiest, simplest, and cleanest communication approach in Soong. In the module providing information, these are specified via [`SetProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=212;drc=5a34ffb350fb295780e5c373fd1c78430fa4e3ed) and [`SetVariationProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/mutator.go;l=719;drc=5a34ffb350fb295780e5c373fd1c78430fa4e3ed). In the module retrieving information, [`HasProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=205-206;drc=8631cc7327919845c9d9037188cbd483d22ba077) and [`Provider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=198-203;drc=8631cc7327919845c9d9037188cbd483d22ba077) or [`OtherModuleHasProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=195-196;drc=8631cc7327919845c9d9037188cbd483d22ba077) and [`OtherModuleProvider`](https://cs.android.com/android/platform/superproject/+/master:build/soong/android/module.go;l=189-193;drc=8631cc7327919845c9d9037188cbd483d22ba077) are used to test existence and retrieve a provider. ### Bazel communication Targets primarily communicate with each other via providers in Bazel rule implementations. All rules have access to any of the providers but rules will pick and choose which ones to access based on their needs. For example, all rules can access `JavaInfo` provider, which provides information about compile and rolled-up runtime jars for javac and java invocations downstream. However, the `JavaInfo` provider is only useful to `java_*` rules or rules that need jvm information. #### Starlark rules [Providers](https://docs.bazel.build/versions/main/skylark/rules.html#providers) are pieces of information exposed to other modules. One such provider is `DefaultInfo`, which contains the default output files and [`runfiles`](https://docs.bazel.build/versions/main/skylark/rules.html#runfiles). Rule authors can also create [custom providers](https://docs.bazel.build/versions/main/skylark/lib/Provider.html#modules.Provider) or implement existing providers to communicate information specific to their rule logic. For instance, in Android Starlark [`cc_object`](http://cs/android/build/bazel/rules/cc_object.bzl?l=86-87&rcl=42607e831f8ff73c82825b663609cafb777c18e1) rule implementation, we return a [`CcInfo`](https://docs.bazel.build/versions/main/skylark/lib/CcInfo.html) provider and a custom [`CcObjectInfo`](http://cs/android/build/bazel/rules/cc_object.bzl?l=17-21&rcl=42607e831f8ff73c82825b663609cafb777c18e1) provider. #### Native rules For implementation of native rules in Java, [`ruleContext.getPrerequisite`](https://github.com/bazelbuild/bazel/blob/a20b32690a71caf712d1d241f01fef16649562ba/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java#L911-L983) is used to extract providers from dependencies. #### `depset` construction [`depset`](https://docs.bazel.build/versions/main/glossary.html#depset) are used in conjunction with providers to accumulate data efficiently from transitive dependencies. used to accumulate data from transitive dependencies. #### `exports` Some target have an `exports` attribute by convention, like [`java_library.exports`](https://docs.bazel.build/versions/main/be/java.html#java_import.exports). This attribute is commonly used to propagate transitive dependencies to the dependent as though the dependent has a direct edge to the transitive dependencies.