Expand namespaces explanation.
Test: N/A Change-Id: Iec7d40e6886285046fbe00aea8e19073c6c1ba73
This commit is contained in:
127
README.md
127
README.md
@@ -74,7 +74,7 @@ cc_binary {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Variables are scoped to the remainder of the file they are declared in, as well
|
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
|
can be appended to with a += assignment, but only before they have been
|
||||||
referenced.
|
referenced.
|
||||||
|
|
||||||
@@ -168,37 +168,114 @@ package {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Name resolution
|
### Referencing Modules
|
||||||
|
|
||||||
Soong provides the ability for modules in different directories to specify
|
A module `libfoo` can be referenced by its name
|
||||||
the same name, as long as each module is declared within a separate namespace.
|
|
||||||
A namespace can be declared like this:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
soong_namespace {
|
cc_binary {
|
||||||
imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
|
name: "app",
|
||||||
|
shared_libs: ["libfoo"],
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Each Soong module is assigned a namespace based on its location in the tree.
|
Obviously, this works only if there is only one `libfoo` module in the source
|
||||||
Each Soong module is considered to be in the namespace defined by the
|
tree. Ensuring such name uniqueness for larger trees may become problematic. We
|
||||||
soong_namespace found in an Android.bp in the current directory or closest
|
might also want to use the same name in multiple mutually exclusive subtrees
|
||||||
ancestor directory, unless no such soong_namespace module is found, in which
|
(for example, implementing different devices) deliberately in order to describe
|
||||||
case the module is considered to be in the implicit root namespace.
|
a functionally equivalent module. Enter Soong namespaces.
|
||||||
|
|
||||||
When Soong attempts to resolve dependency D declared my module M in namespace
|
#### Namespaces
|
||||||
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
|
A presense of the `soong_namespace {..}` in an Android.bp file defines a
|
||||||
Make product config to specify a value of PRODUCT_SOONG_NAMESPACES. Its value
|
**namespace**. For instance, having
|
||||||
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.
|
soong_namespace {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
### Visibility
|
||||||
|
|
||||||
@@ -266,7 +343,7 @@ owner's responsibility to replace that with a more appropriate visibility.
|
|||||||
|
|
||||||
### Formatter
|
### 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
|
[gofmt](https://golang.org/cmd/gofmt/). To recursively reformat all Android.bp files
|
||||||
in the current directory:
|
in the current directory:
|
||||||
```
|
```
|
||||||
|
@@ -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
|
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
|
used to partition a set of modules so that they are built only when the
|
||||||
namespace is listed in `PRODUCT_SOONG_NAMESPACES`. See the
|
namespace is listed in `PRODUCT_SOONG_NAMESPACES`. See the
|
||||||
[Name resolution](../README.md#name-resolution) section of the Soong README.md
|
[Referencing Modules](../README.md#referencing-modules) section of the Soong
|
||||||
for more on namespaces.
|
README.md for more on namespaces.
|
||||||
|
|
||||||
### Module with name based on variable
|
### Module with name based on variable
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user