Always specify version to use aidl_interface except it is unstable
As-is, the rule for versions of generated modules from aidl_interface is
implicit and messy. For example, the version that <aidl_interface>-cpp
stands for can be different depending on the context(it can be the
latest stable version n or unstable version). And the version
<aidl_interface>-unstable-* or <aidl_interface>-* refers to can be
changed in accordance with freezing the interface. And also, for native
modules, version name and generated library file name is sometimes
mismatched.
So, I make it more explicit. There are only two rules
1. If an interface is unstable, the generated module name is
<aidl_interface>-<backend>
2. If not, the generated module name is always
<aidl_interface>-V<version>-<backend> (the version for ToT version is
the latest version + 1)
And the library name(so, jar, and so on) is the same as the generated
module name.
In terms of implemenation, the logic around version is getting simpler.
And Java, C++, NDK module creation logic is moved to PreArchMutator
because the other aidl_interface's version infomation is unknown
in the LoadHook phase, so we cannot find proper imported library name
which includes the version
Note that AIDL still generates <aidl_interface>-<backend> and
<aidl_interface>-unstable-<backend> to prevent unexpected breakage in
downstream branch and apply the change gradually, but it will be done
before release.
Bug: 150578172
Bug: 178138244
Test: m nothing
Change-Id: I7d5ed804843360a4e5e94ce9bb391cee5904402f
Merged-In: I7d5ed804843360a4e5e94ce9bb391cee5904402f
(cherry picked from commit cbda12e517c0c39b82992b5584c5f130c87477a3)
diff --git a/build/aidl_interface_backends.go b/build/aidl_interface_backends.go
index 53b4b73..f21431d 100644
--- a/build/aidl_interface_backends.go
+++ b/build/aidl_interface_backends.go
@@ -21,17 +21,24 @@
"android/soong/rust"
"path/filepath"
- "strconv"
"strings"
"github.com/google/blueprint/proptools"
)
-func addCppLibrary(mctx android.LoadHookContext, i *aidlInterface, versionForModuleName string, lang string) string {
- cppSourceGen := i.versionedName(versionForModuleName) + "-" + lang + "-source"
- cppModuleGen := i.versionedName(versionForModuleName) + "-" + lang
- cppOutputGen := i.cppOutputName(versionForModuleName) + "-" + lang
- version := i.normalizeVersion(versionForModuleName)
+func addLibrary(mctx android.LoadHookContext, i *aidlInterface, version string, lang string) string {
+ if lang == langJava {
+ return addJavaLibrary(mctx, i, version)
+ } else if lang == langRust {
+ return addRustLibrary(mctx, i, version)
+ }
+ return addCppLibrary(mctx, i, version, lang)
+}
+
+func addCppLibrary(mctx android.LoadHookContext, i *aidlInterface, version string, lang string) string {
+ cppSourceGen := i.versionedName(version) + "-" + lang + "-source"
+ cppModuleGen := i.versionedName(version) + "-" + lang
+
srcs, aidlRoot := i.srcsForVersion(mctx, version)
if len(srcs) == 0 {
// This can happen when the version is about to be frozen; the version
@@ -42,7 +49,7 @@
var overrideVndkProperties cc.VndkProperties
- if i.moduleVersionForVndk() != versionForModuleName {
+ if !i.isModuleForVndk(version) {
// We only want the VNDK to include the latest interface. For interfaces in
// development, they will be frozen, so we put their latest version in the
// VNDK. For interfaces which are already frozen, we put their latest version
@@ -73,15 +80,14 @@
Lang: lang,
BaseName: i.ModuleBase.Name(),
GenLog: genLog,
- Version: version,
+ Version: i.versionForAidlGenRule(version),
GenTrace: genTrace,
Unstable: i.properties.Unstable,
Visibility: srcsVisibility(mctx, lang),
Flags: i.properties.Flags,
})
- importPostfix := i.getImportPostfix(mctx, version, lang)
- importExportDependencies := wrap("", i.properties.Imports, importPostfix)
+ importExportDependencies := []string{}
var sharedLibDependency []string
var headerLibs []string
var sdkVersion *string
@@ -149,41 +155,61 @@
overrideVndkProperties.Vndk.Support_system_process = proptools.BoolPtr(false)
}
- mctx.CreateModule(cc.LibraryFactory, &ccProperties{
- Name: proptools.StringPtr(cppModuleGen),
- Vendor_available: vendorAvailable,
- Product_available: productAvailable,
- Host_supported: hostSupported,
- Defaults: []string{"aidl-cpp-module-defaults"},
- Double_loadable: i.properties.Double_loadable,
- Generated_sources: []string{cppSourceGen},
- Generated_headers: []string{cppSourceGen},
- Export_generated_headers: []string{cppSourceGen},
- Shared_libs: append(importExportDependencies, sharedLibDependency...),
- Header_libs: headerLibs,
- Export_shared_lib_headers: importExportDependencies,
- Sdk_version: sdkVersion,
- Stl: stl,
- Cpp_std: cpp_std,
- Cflags: append(addCflags, "-Wextra", "-Wall", "-Werror"),
- Stem: proptools.StringPtr(cppOutputGen),
- Apex_available: commonProperties.Apex_available,
- Min_sdk_version: minSdkVersion,
- UseApexNameMacro: true,
- Target: targetProperties{Darwin: perTargetProperties{Enabled: proptools.BoolPtr(false)}},
- Tidy: proptools.BoolPtr(true),
- // Do the tidy check only for the generated headers
- Tidy_flags: []string{"--header-filter=" + android.PathForOutput(mctx).String() + ".*"},
- Tidy_checks_as_errors: []string{"*"},
- }, &i.properties.VndkProperties, &commonProperties.VndkProperties, &overrideVndkProperties)
+ mctx.CreateModule(aidlImplementationGeneratorFactory, &nameProperties{
+ Name: proptools.StringPtr(cppModuleGen + "-generator"),
+ }, &aidlImplementationGeneratorProperties{
+ Lang: lang,
+ AidlInterfaceName: i.ModuleBase.Name(),
+ Version: version,
+ ModuleProperties: []interface{}{
+ &ccProperties{
+ Name: proptools.StringPtr(cppModuleGen),
+ Vendor_available: vendorAvailable,
+ Product_available: productAvailable,
+ Host_supported: hostSupported,
+ Defaults: []string{"aidl-cpp-module-defaults"},
+ Double_loadable: i.properties.Double_loadable,
+ Generated_sources: []string{cppSourceGen},
+ Generated_headers: []string{cppSourceGen},
+ Export_generated_headers: []string{cppSourceGen},
+ Shared_libs: append(importExportDependencies, sharedLibDependency...),
+ Header_libs: headerLibs,
+ Export_shared_lib_headers: importExportDependencies,
+ Sdk_version: sdkVersion,
+ Stl: stl,
+ Cpp_std: cpp_std,
+ Cflags: append(addCflags, "-Wextra", "-Wall", "-Werror", "-Wextra-semi"),
+ Apex_available: commonProperties.Apex_available,
+ Min_sdk_version: minSdkVersion,
+ UseApexNameMacro: true,
+ Target: ccTargetProperties{
+ // Currently necessary for host builds
+ // TODO(b/31559095): bionic on host should define this
+ // TODO(b/146436251): default isn't applied because the module is created
+ // in PreArchMutators, when import behavior becomes explicit, the logic can
+ // be moved back to LoadHook
+ Host: hostProperties{Cflags: []string{
+ "-D__INTRODUCED_IN(n)=",
+ "-D__assert(a,b,c)=",
+ // We want all the APIs to be available on the host.
+ "-D__ANDROID_API__=10000"}},
+ Darwin: perTargetProperties{Enabled: proptools.BoolPtr(false)}},
+ Tidy: proptools.BoolPtr(true),
+ // Do the tidy check only for the generated headers
+ Tidy_flags: []string{"--header-filter=" + android.PathForOutput(mctx).String() + ".*"},
+ Tidy_checks_as_errors: []string{"*"},
+ }, &i.properties.VndkProperties,
+ &commonProperties.VndkProperties,
+ &overrideVndkProperties,
+ },
+ })
return cppModuleGen
}
-func addJavaLibrary(mctx android.LoadHookContext, i *aidlInterface, versionForModuleName string) string {
- javaSourceGen := i.versionedName(versionForModuleName) + "-java-source"
- javaModuleGen := i.versionedName(versionForModuleName) + "-java"
- version := i.normalizeVersion(versionForModuleName)
+func addJavaLibrary(mctx android.LoadHookContext, i *aidlInterface, version string) string {
+ javaSourceGen := i.versionedName(version) + "-java-source"
+ javaModuleGen := i.versionedName(version) + "-java"
srcs, aidlRoot := i.srcsForVersion(mctx, version)
if len(srcs) == 0 {
// This can happen when the version is about to be frozen; the version
@@ -207,33 +233,37 @@
Stability: i.properties.Stability,
Lang: langJava,
BaseName: i.ModuleBase.Name(),
- Version: version,
+ Version: i.versionForAidlGenRule(version),
GenTrace: proptools.Bool(i.properties.Gen_trace),
Unstable: i.properties.Unstable,
Visibility: srcsVisibility(mctx, langJava),
Flags: i.properties.Flags,
})
- importPostfix := i.getImportPostfix(mctx, version, langJava)
- mctx.CreateModule(java.LibraryFactory, &javaProperties{
- Name: proptools.StringPtr(javaModuleGen),
- Installable: proptools.BoolPtr(true),
- Defaults: []string{"aidl-java-module-defaults"},
- Sdk_version: sdkVersion,
- Platform_apis: i.properties.Backend.Java.Platform_apis,
- Static_libs: wrap("", i.properties.Imports, importPostfix),
- Srcs: []string{":" + javaSourceGen},
- Apex_available: i.properties.Backend.Java.Apex_available,
- Min_sdk_version: i.properties.Backend.Java.Min_sdk_version,
+ mctx.CreateModule(aidlImplementationGeneratorFactory, &nameProperties{
+ Name: proptools.StringPtr(javaModuleGen + "-generator"),
+ }, &aidlImplementationGeneratorProperties{
+ Lang: langJava,
+ AidlInterfaceName: i.ModuleBase.Name(),
+ Version: version,
+ ModuleProperties: []interface{}{&javaProperties{
+ Name: proptools.StringPtr(javaModuleGen),
+ Installable: proptools.BoolPtr(true),
+ Defaults: []string{"aidl-java-module-defaults"},
+ Sdk_version: sdkVersion,
+ Platform_apis: i.properties.Backend.Java.Platform_apis,
+ Srcs: []string{":" + javaSourceGen},
+ Apex_available: i.properties.Backend.Java.Apex_available,
+ Min_sdk_version: i.properties.Backend.Java.Min_sdk_version,
+ }},
})
return javaModuleGen
}
-func addRustLibrary(mctx android.LoadHookContext, i *aidlInterface, versionForModuleName string) string {
- rustSourceGen := i.versionedName(versionForModuleName) + "-rust-source"
- rustModuleGen := i.versionedName(versionForModuleName) + "-rust"
- version := i.normalizeVersion(versionForModuleName)
+func addRustLibrary(mctx android.LoadHookContext, i *aidlInterface, version string) string {
+ rustSourceGen := i.versionedName(version) + "-rust-source"
+ rustModuleGen := i.versionedName(version) + "-rust"
srcs, aidlRoot := i.srcsForVersion(mctx, version)
if len(srcs) == 0 {
// This can happen when the version is about to be frozen; the version
@@ -251,26 +281,29 @@
Stability: i.properties.Stability,
Lang: langRust,
BaseName: i.ModuleBase.Name(),
- Version: version,
+ Version: i.versionForAidlGenRule(version),
Unstable: i.properties.Unstable,
Visibility: srcsVisibility(mctx, langRust),
Flags: i.properties.Flags,
})
- versionedRustName := fixRustName(i.versionedName(versionForModuleName))
+ versionedRustName := fixRustName(i.versionedName(version))
+ rustCrateName := fixRustName(i.ModuleBase.Name())
mctx.CreateModule(aidlRustLibraryFactory, &rustProperties{
Name: proptools.StringPtr(rustModuleGen),
- Crate_name: versionedRustName,
+ Crate_name: rustCrateName,
Stem: proptools.StringPtr("lib" + versionedRustName),
Defaults: []string{"aidl-rust-module-defaults"},
Host_supported: i.properties.Host_supported,
- Target: targetProperties{Darwin: perTargetProperties{Enabled: proptools.BoolPtr(false)}},
+ Target: rustTargetProperties{Darwin: perTargetProperties{Enabled: proptools.BoolPtr(false)}},
}, &rust.SourceProviderProperties{
Source_stem: proptools.StringPtr(versionedRustName),
}, &aidlRustSourceProviderProperties{
- SourceGen: rustSourceGen,
- Imports: i.properties.Imports,
+ SourceGen: rustSourceGen,
+ Imports: i.properties.Imports,
+ Version: version,
+ AidlInterfaceName: i.ModuleBase.Name(),
})
return rustModuleGen
@@ -280,55 +313,24 @@
// Version -> Module name
// "1"->foo-V1
// "2"->foo-V2
-// "3"(unfrozen)->foo-unstable
-// ""-> foo
-// "unstable" -> foo-unstable
+// "3"->foo-V3
+// And assume that there is 'bar' which is an 'unstable' interface.
+// ""->bar
func (i *aidlInterface) versionedName(version string) string {
name := i.ModuleBase.Name()
+ // TODO(b/150578172) remove exception when every module specify its version.
if version == "" {
return name
- }
- if version == i.currentVersion() || version == unstableVersion {
+ } else if version == unstableVersion {
return name + "-" + unstableVersion
}
return name + "-V" + version
}
-// This function returns C++ artifact's name. Mostly, it returns same as versionedName(),
-// But, it returns different value only if it is the case below.
-// Assume that there is foo of which latest version is 2
-// foo-unstable -> foo-V3
-// foo -> foo-V2 (latest frozen version)
-// Assume that there is bar of which version hasn't been defined yet.
-// bar -> bar
-// bar-unstable -> bar-V1
-func (i *aidlInterface) cppOutputName(version string) string {
- name := i.ModuleBase.Name()
- if i.hasVersion() && version == unstableVersion {
- panic("A versioned module's output name in C++ must not contain 'unstable'")
- }
- // If the module doesn't have version, it returns with version(-V1) only if 'version' is unstable,
- // otherwise, it returns the name without version.
- if !i.hasVersion() {
- // TODO(b/150578172): Use "-V1" as 'unstable' when the build system supports it, or remove it altogether later.
- if version == "" {
- return name
- }
- // latestVersion() always returns "0"
- i, err := strconv.Atoi(i.latestVersion())
- if err != nil {
- panic(err)
- }
- return name + "-V" + strconv.Itoa(i+1)
- }
- if version == "" {
- version = i.latestVersion()
- }
- return name + "-V" + version
-}
-
func (i *aidlInterface) srcsForVersion(mctx android.LoadHookContext, version string) (srcs []string, aidlRoot string) {
- if version == i.currentVersion() {
+ // TODO(b/150578172) remove exception when every module specify its version.
+ version = i.normalizeVersion(version)
+ if version == i.nextVersion() {
return i.properties.Srcs, i.properties.Local_include_dir
} else {
aidlRoot = filepath.Join(aidlApiDir, i.ModuleBase.Name(), version)
@@ -343,3 +345,122 @@
return srcs, aidlRoot
}
}
+
+func (i *aidlInterface) versionForAidlGenRule(version string) string {
+ if !i.hasVersion() {
+ return ""
+ }
+ // TODO(b/150578172) remove exception when every module specify its version.
+ if version == "" {
+ return i.latestVersion()
+ }
+ if version == unstableVersion {
+ return i.nextVersion()
+ }
+ return version
+}
+
+func (i *aidlInterface) isModuleForVndk(version string) bool {
+ // TODO(b/150578172) remove exception when every module specify its version.
+ version = i.normalizeVersion(version)
+
+ if i.properties.Vndk_use_version != nil {
+ if !i.hasVersion() {
+ panic("does not make sense, vndk_use_version specififed")
+ }
+ // Will be exactly one of the version numbers
+ return version == *i.properties.Vndk_use_version
+ }
+
+ // For an interface with no versions, this is the ToT interface.
+ if !i.hasVersion() {
+ return version == i.nextVersion()
+ }
+
+ return version == i.latestVersion()
+}
+
+// importing aidl_interface's version | imported aidl_interface | imported aidl_interface's version
+// --------------------------------------------------------------------------------------------------
+// whatever | unstable | unstable version
+// ToT version(including unstable) | whatever | ToT version(unstable if unstable)
+// otherwise | whatever | the latest stable version
+// TODO(b/146436251) Make import field specify the explicit version which it wants to import.
+func (i *aidlInterface) getImportWithVersion(version string, anImport string, config android.Config) string {
+ // TODO(b/150578172) remove exception when every module specify its version.
+ version = i.normalizeVersion(version)
+
+ other := lookupInterface(anImport, config)
+ if proptools.Bool(other.properties.Unstable) {
+ return anImport
+ }
+ if version == i.nextVersion() || !other.hasVersion() {
+ return other.versionedName(other.nextVersion())
+ }
+ return other.versionedName(other.latestVersion())
+}
+
+// TODO(b/150578172) remove exception when every module specify its version.
+func (i *aidlInterface) normalizeVersion(version string) string {
+ if version == "" {
+ if i.hasVersion() {
+ return i.latestVersion()
+ } else if !proptools.Bool(i.properties.Unstable) {
+ return i.nextVersion()
+ }
+ } else if version == unstableVersion {
+ return i.nextVersion()
+ }
+ return version
+}
+
+func aidlImplementationGeneratorFactory() android.Module {
+ g := &aidlImplementationGenerator{}
+ g.AddProperties(&g.properties)
+ android.InitAndroidModule(g)
+ return g
+}
+
+type aidlImplementationGenerator struct {
+ android.ModuleBase
+ properties aidlImplementationGeneratorProperties
+}
+
+type aidlImplementationGeneratorProperties struct {
+ Lang string
+ AidlInterfaceName string
+ Version string
+ ModuleProperties []interface{}
+}
+
+func (g *aidlImplementationGenerator) DepsMutator(ctx android.BottomUpMutatorContext) {
+}
+
+func (g *aidlImplementationGenerator) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+}
+
+func (g *aidlImplementationGenerator) GenerateImplementation(ctx android.TopDownMutatorContext) {
+ i := lookupInterface(g.properties.AidlInterfaceName, ctx.Config())
+ version := g.properties.Version
+ lang := g.properties.Lang
+ if g.properties.Lang == langJava {
+ imports := make([]string, len(i.properties.Imports))
+ for idx, anImport := range i.properties.Imports {
+ imports[idx] = i.getImportWithVersion(version, anImport, ctx.Config()) + "-" + langJava
+ }
+ if p, ok := g.properties.ModuleProperties[0].(*javaProperties); ok {
+ p.Static_libs = imports
+ }
+ ctx.CreateModule(java.LibraryFactory, g.properties.ModuleProperties...)
+ } else {
+ imports := make([]string, len(i.properties.Imports))
+ for idx, anImport := range i.properties.Imports {
+ imports[idx] = i.getImportWithVersion(version, anImport, ctx.Config()) + "-" + lang
+ }
+ if p, ok := g.properties.ModuleProperties[0].(*ccProperties); ok {
+ p.Shared_libs = append(p.Shared_libs, imports...)
+ p.Export_shared_lib_headers = append(p.Export_shared_lib_headers, imports...)
+ }
+ ctx.CreateModule(cc.LibraryFactory, g.properties.ModuleProperties...)
+ }
+}