Loading README.md +103 −26 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ cc_binary { ``` Variables are scoped to the remainder of the file they are declared in, as well as any child blueprint files. Variables are immutable with one exception - they as any child Android.bp files. Variables are immutable with one exception - they can be appended to with a += assignment, but only before they have been referenced. Loading Loading @@ -168,37 +168,114 @@ package { } ``` ### Name resolution ### Referencing Modules Soong provides the ability for modules in different directories to specify the same name, as long as each module is declared within a separate namespace. A namespace can be declared like this: A module `libfoo` can be referenced by its name ``` cc_binary { name: "app", shared_libs: ["libfoo"], } ``` Obviously, this works only if there is only one `libfoo` module in the source tree. Ensuring such name uniqueness for larger trees may become problematic. We might also want to use the same name in multiple mutually exclusive subtrees (for example, implementing different devices) deliberately in order to describe a functionally equivalent module. Enter Soong namespaces. #### Namespaces A presense of the `soong_namespace {..}` in an Android.bp file defines a **namespace**. For instance, having ``` soong_namespace { imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"], ... } ... ``` Each Soong module is assigned a namespace based on its location in the tree. Each Soong module is considered to be in the namespace defined by the soong_namespace found in an Android.bp in the current directory or closest ancestor directory, unless no such soong_namespace module is found, in which case the module is considered to be in the implicit root namespace. When Soong attempts to resolve dependency D declared my module M in namespace N which imports namespaces I1, I2, I3..., then if D is a fully-qualified name of the form "//namespace:module", only the specified namespace will be searched for the specified module name. Otherwise, Soong will first look for a module named D declared in namespace N. If that module does not exist, Soong will look for a module named D in namespaces I1, I2, I3... Lastly, Soong will look in the root namespace. Until we have fully converted from Make to Soong, it will be necessary for the Make product config to specify a value of PRODUCT_SOONG_NAMESPACES. Its value should be a space-separated list of namespaces that Soong export to Make to be built by the `m` command. After we have fully converted from Make to Soong, the details of enabling namespaces could potentially change. in `device/google/bonito/Android.bp` informs Soong that within the `device/google/bonito` package the module names are unique, that is, all the modules defined in the Android.bp files in the `device/google/bonito/` tree have unique names. However, there may be modules with the same names outside `device/google/bonito` tree. Indeed, there is a module `"pixelstats-vendor"` both in `device/google/bonito/pixelstats` and in `device/google/coral/pixelstats`. The name of a namespace is the path of its directory. The name of the namespace in the example above is thus `device/google/bonito`. An implicit **global namespace** corresponds to the source tree as a whole. It has empty name. A module name's **scope** is the smallest namespace containing it. Suppose a source tree has `device/my` and `device/my/display` namespaces. If `libfoo` module is defined in `device/co/display/lib/Android.bp`, its namespace is `device/co/display`. The name uniqueness thus means that module's name is unique within its scope. In other words, "//_scope_:_name_" is globally unique module reference, e.g, `"//device/google/bonito:pixelstats-vendor"`. _Note_ that the name of the namespace for a module may be different from module's package name: `libfoo` belongs to `device/my/display` namespace but is contained in `device/my/display/lib` package. #### Name Resolution The form of a module reference determines how Soong locates the module. For a **global reference** of the "//_scope_:_name_" form, Soong verifies there is a namespace called "_scope_", then verifies it contains a "_name_" module and uses it. Soong verifies there is only one "_name_" in "_scope_" at the beginning when it parses Android.bp files. A **local reference** has "_name_" form, and resolving it involves looking for a module "_name_" in one or more namespaces. By default only the global namespace is searched for "_name_" (in other words, only the modules not belonging to an explicitly defined scope are considered). The `imports` attribute of the `soong_namespaces` allows to specify where to look for modules . For instance, with `device/google/bonito/Android.bp` containing ``` soong_namespace { imports: [ "hardware/google/interfaces", "hardware/google/pixel", "hardware/qcom/bootctrl", ], } ``` a reference to `"libpixelstats"` will resolve to the module defined in `hardware/google/pixel/pixelstats/Android.bp` because this module is in `hardware/google/pixel` namespace. **TODO**: Conventionally, languages with similar concepts provide separate constructs for namespace definition and name resolution (`namespace` and `using` in C++, for instance). Should Soong do that, too? #### Referencing modules in makefiles While we are gradually converting makefiles to Android.bp files, Android build is described by a mixture of Android.bp and Android.mk files, and a module defined in an Android.mk file can reference a module defined in Android.bp file. For instance, a binary still defined in an Android.mk file may have a library defined in already converted Android.bp as a dependency. A module defined in an Android.bp file and belonging to the global namespace can be referenced from a makefile without additional effort. If a module belongs to an explicit namespace, it can be referenced from a makefile only after after the name of the namespace has been added to the value of PRODUCT_SOONG_NAMESPACES variable. Note that makefiles have no notion of namespaces and exposing namespaces with the same modules via PRODUCT_SOONG_NAMESPACES may cause Make failure. For instance, exposing both `device/google/bonito` and `device/google/coral` namespaces will cause Make failure because it will see two targets for the `pixelstats-vendor` module. ### Visibility Loading Loading @@ -266,7 +343,7 @@ owner's responsibility to replace that with a more appropriate visibility. ### Formatter Soong includes a canonical formatter for blueprint files, similar to Soong includes a canonical formatter for Android.bp files, similar to [gofmt](https://golang.org/cmd/gofmt/). To recursively reformat all Android.bp files in the current directory: ``` Loading docs/best_practices.md +2 −2 Original line number Diff line number Diff line Loading @@ -240,8 +240,8 @@ PRODUCT_PROPERTY_OVERRIDES += ro.hardware.gralloc=soc_a In cases where the names cannot be made unique a `soong_namespace` should be used to partition a set of modules so that they are built only when the namespace is listed in `PRODUCT_SOONG_NAMESPACES`. See the [Name resolution](../README.md#name-resolution) section of the Soong README.md for more on namespaces. [Referencing Modules](../README.md#referencing-modules) section of the Soong README.md for more on namespaces. ### Module with name based on variable Loading Loading
README.md +103 −26 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ cc_binary { ``` Variables are scoped to the remainder of the file they are declared in, as well as any child blueprint files. Variables are immutable with one exception - they as any child Android.bp files. Variables are immutable with one exception - they can be appended to with a += assignment, but only before they have been referenced. Loading Loading @@ -168,37 +168,114 @@ package { } ``` ### Name resolution ### Referencing Modules Soong provides the ability for modules in different directories to specify the same name, as long as each module is declared within a separate namespace. A namespace can be declared like this: A module `libfoo` can be referenced by its name ``` cc_binary { name: "app", shared_libs: ["libfoo"], } ``` Obviously, this works only if there is only one `libfoo` module in the source tree. Ensuring such name uniqueness for larger trees may become problematic. We might also want to use the same name in multiple mutually exclusive subtrees (for example, implementing different devices) deliberately in order to describe a functionally equivalent module. Enter Soong namespaces. #### Namespaces A presense of the `soong_namespace {..}` in an Android.bp file defines a **namespace**. For instance, having ``` soong_namespace { imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"], ... } ... ``` Each Soong module is assigned a namespace based on its location in the tree. Each Soong module is considered to be in the namespace defined by the soong_namespace found in an Android.bp in the current directory or closest ancestor directory, unless no such soong_namespace module is found, in which case the module is considered to be in the implicit root namespace. When Soong attempts to resolve dependency D declared my module M in namespace N which imports namespaces I1, I2, I3..., then if D is a fully-qualified name of the form "//namespace:module", only the specified namespace will be searched for the specified module name. Otherwise, Soong will first look for a module named D declared in namespace N. If that module does not exist, Soong will look for a module named D in namespaces I1, I2, I3... Lastly, Soong will look in the root namespace. Until we have fully converted from Make to Soong, it will be necessary for the Make product config to specify a value of PRODUCT_SOONG_NAMESPACES. Its value should be a space-separated list of namespaces that Soong export to Make to be built by the `m` command. After we have fully converted from Make to Soong, the details of enabling namespaces could potentially change. in `device/google/bonito/Android.bp` informs Soong that within the `device/google/bonito` package the module names are unique, that is, all the modules defined in the Android.bp files in the `device/google/bonito/` tree have unique names. However, there may be modules with the same names outside `device/google/bonito` tree. Indeed, there is a module `"pixelstats-vendor"` both in `device/google/bonito/pixelstats` and in `device/google/coral/pixelstats`. The name of a namespace is the path of its directory. The name of the namespace in the example above is thus `device/google/bonito`. An implicit **global namespace** corresponds to the source tree as a whole. It has empty name. A module name's **scope** is the smallest namespace containing it. Suppose a source tree has `device/my` and `device/my/display` namespaces. If `libfoo` module is defined in `device/co/display/lib/Android.bp`, its namespace is `device/co/display`. The name uniqueness thus means that module's name is unique within its scope. In other words, "//_scope_:_name_" is globally unique module reference, e.g, `"//device/google/bonito:pixelstats-vendor"`. _Note_ that the name of the namespace for a module may be different from module's package name: `libfoo` belongs to `device/my/display` namespace but is contained in `device/my/display/lib` package. #### Name Resolution The form of a module reference determines how Soong locates the module. For a **global reference** of the "//_scope_:_name_" form, Soong verifies there is a namespace called "_scope_", then verifies it contains a "_name_" module and uses it. Soong verifies there is only one "_name_" in "_scope_" at the beginning when it parses Android.bp files. A **local reference** has "_name_" form, and resolving it involves looking for a module "_name_" in one or more namespaces. By default only the global namespace is searched for "_name_" (in other words, only the modules not belonging to an explicitly defined scope are considered). The `imports` attribute of the `soong_namespaces` allows to specify where to look for modules . For instance, with `device/google/bonito/Android.bp` containing ``` soong_namespace { imports: [ "hardware/google/interfaces", "hardware/google/pixel", "hardware/qcom/bootctrl", ], } ``` a reference to `"libpixelstats"` will resolve to the module defined in `hardware/google/pixel/pixelstats/Android.bp` because this module is in `hardware/google/pixel` namespace. **TODO**: Conventionally, languages with similar concepts provide separate constructs for namespace definition and name resolution (`namespace` and `using` in C++, for instance). Should Soong do that, too? #### Referencing modules in makefiles While we are gradually converting makefiles to Android.bp files, Android build is described by a mixture of Android.bp and Android.mk files, and a module defined in an Android.mk file can reference a module defined in Android.bp file. For instance, a binary still defined in an Android.mk file may have a library defined in already converted Android.bp as a dependency. A module defined in an Android.bp file and belonging to the global namespace can be referenced from a makefile without additional effort. If a module belongs to an explicit namespace, it can be referenced from a makefile only after after the name of the namespace has been added to the value of PRODUCT_SOONG_NAMESPACES variable. Note that makefiles have no notion of namespaces and exposing namespaces with the same modules via PRODUCT_SOONG_NAMESPACES may cause Make failure. For instance, exposing both `device/google/bonito` and `device/google/coral` namespaces will cause Make failure because it will see two targets for the `pixelstats-vendor` module. ### Visibility Loading Loading @@ -266,7 +343,7 @@ owner's responsibility to replace that with a more appropriate visibility. ### Formatter Soong includes a canonical formatter for blueprint files, similar to Soong includes a canonical formatter for Android.bp files, similar to [gofmt](https://golang.org/cmd/gofmt/). To recursively reformat all Android.bp files in the current directory: ``` Loading
docs/best_practices.md +2 −2 Original line number Diff line number Diff line Loading @@ -240,8 +240,8 @@ PRODUCT_PROPERTY_OVERRIDES += ro.hardware.gralloc=soc_a In cases where the names cannot be made unique a `soong_namespace` should be used to partition a set of modules so that they are built only when the namespace is listed in `PRODUCT_SOONG_NAMESPACES`. See the [Name resolution](../README.md#name-resolution) section of the Soong README.md for more on namespaces. [Referencing Modules](../README.md#referencing-modules) section of the Soong README.md for more on namespaces. ### Module with name based on variable Loading