Merge "Revert "Remove non-generic provider APIs"" into main
diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go
index 80d36af..b55d7bf 100644
--- a/aconfig/aconfig_declarations.go
+++ b/aconfig/aconfig_declarations.go
@@ -112,24 +112,6 @@
return sb.String()
}
-// Provider published by aconfig_value_set
-type DeclarationsProviderData struct {
- Package string
- Container string
- IntermediateCacheOutputPath android.WritablePath
- IntermediateDumpOutputPath android.WritablePath
-}
-
-var DeclarationsProviderKey = blueprint.NewProvider[DeclarationsProviderData]()
-
-// This is used to collect the aconfig declarations info on the transitive closure,
-// the data is keyed on the container.
-type TransitiveDeclarationsInfo struct {
- AconfigFiles map[string]android.Paths
-}
-
-var TransitiveDeclarationsInfoProvider = blueprint.NewProvider[TransitiveDeclarationsInfo]()
-
func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
valuesFiles := make([]android.Path, 0)
@@ -174,7 +156,7 @@
Description: "aconfig_text",
})
- android.SetProvider(ctx, DeclarationsProviderKey, DeclarationsProviderData{
+ android.SetProvider(ctx, android.AconfigDeclarationsProviderKey, android.AconfigDeclarationsProviderData{
Package: module.properties.Package,
Container: module.properties.Container,
IntermediateCacheOutputPath: intermediateCacheFilePath,
@@ -182,57 +164,18 @@
})
}
-func CollectDependencyAconfigFiles(ctx android.ModuleContext, mergedAconfigFiles *map[string]android.Paths) {
- if *mergedAconfigFiles == nil {
- *mergedAconfigFiles = make(map[string]android.Paths)
- }
- ctx.VisitDirectDeps(func(module android.Module) {
- if dep, _ := android.OtherModuleProvider(ctx, module, DeclarationsProviderKey); dep.IntermediateCacheOutputPath != nil {
- (*mergedAconfigFiles)[dep.Container] = append((*mergedAconfigFiles)[dep.Container], dep.IntermediateCacheOutputPath)
- return
- }
- if dep, _ := android.OtherModuleProvider(ctx, module, TransitiveDeclarationsInfoProvider); len(dep.AconfigFiles) > 0 {
- for container, v := range dep.AconfigFiles {
- (*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...)
- }
- }
- })
-
- for container, aconfigFiles := range *mergedAconfigFiles {
- (*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, aconfigFiles)
- }
-
- android.SetProvider(ctx, TransitiveDeclarationsInfoProvider, TransitiveDeclarationsInfo{
- AconfigFiles: *mergedAconfigFiles,
- })
-}
-
-func mergeAconfigFiles(ctx android.ModuleContext, inputs android.Paths) android.Paths {
- inputs = android.LastUniquePaths(inputs)
- if len(inputs) == 1 {
- return android.Paths{inputs[0]}
- }
-
- output := android.PathForModuleOut(ctx, "aconfig_merged.pb")
-
- ctx.Build(pctx, android.BuildParams{
- Rule: mergeAconfigFilesRule,
- Description: "merge aconfig files",
- Inputs: inputs,
- Output: output,
- Args: map[string]string{
- "flags": android.JoinWithPrefix(inputs.Strings(), "--cache "),
- },
- })
-
- return android.Paths{output}
-}
func SetAconfigFileMkEntries(m *android.ModuleBase, entries *android.AndroidMkEntries, aconfigFiles map[string]android.Paths) {
- if m.InstallInVendor() {
- entries.SetPaths("LOCAL_ACONFIG_FILES", aconfigFiles["vendor"])
- } else {
- // TODO(b/311155208): The container here should be system.
- entries.SetPaths("LOCAL_ACONFIG_FILES", aconfigFiles[""])
+ // TODO(b/311155208): The default container here should be system.
+ container := ""
+
+ if m.SocSpecific() {
+ container = "vendor"
+ } else if m.ProductSpecific() {
+ container = "product"
+ } else if m.SystemExtSpecific() {
+ container = "system_ext"
}
+
+ entries.SetPaths("LOCAL_ACONFIG_FILES", aconfigFiles[container])
}
diff --git a/aconfig/aconfig_declarations_test.go b/aconfig/aconfig_declarations_test.go
index 1b4acab..d508af7 100644
--- a/aconfig/aconfig_declarations_test.go
+++ b/aconfig/aconfig_declarations_test.go
@@ -38,7 +38,7 @@
module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule)
// Check that the provider has the right contents
- depData, _ := android.SingletonModuleProvider(result, module, DeclarationsProviderKey)
+ depData, _ := android.SingletonModuleProvider(result, module, android.AconfigDeclarationsProviderKey)
android.AssertStringEquals(t, "package", depData.Package, "com.example.package")
android.AssertStringEquals(t, "container", depData.Container, "com.android.foo")
if !strings.HasSuffix(depData.IntermediateCacheOutputPath.String(), "/intermediate.pb") {
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index d860498..36bea0e 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -37,7 +37,7 @@
// Find all of the aconfig_declarations modules
var cacheFiles android.Paths
ctx.VisitAllModules(func(module android.Module) {
- decl, ok := android.SingletonModuleProvider(ctx, module, DeclarationsProviderKey)
+ decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey)
if !ok {
return
}
diff --git a/aconfig/codegen/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
index 2c8369b..12c2dea 100644
--- a/aconfig/codegen/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -15,7 +15,6 @@
package codegen
import (
- "android/soong/aconfig"
"android/soong/android"
"android/soong/cc"
@@ -92,7 +91,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], aconfig.DeclarationsProviderKey)
+ declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], android.AconfigDeclarationsProviderKey)
// Figure out the generated file paths. This has to match aconfig's codegen_cpp.rs.
this.generatedDir = android.PathForModuleGen(ctx)
@@ -122,7 +121,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], aconfig.DeclarationsProviderKey)
+ declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], android.AconfigDeclarationsProviderKey)
mode := proptools.StringDefault(this.properties.Mode, "production")
if !isModeSupported(mode) {
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index b33481b..c027815 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -17,7 +17,6 @@
import (
"fmt"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/java"
@@ -62,10 +61,18 @@
ctx.AddDependency(ctx.Module(), declarationsTag, declarations)
}
- // Add aconfig-annotations-lib as a dependency for the optimization / code stripping annotations
- module.AddSharedLibrary("aconfig-annotations-lib")
- // TODO(b/303773055): Remove the annotation after access issue is resolved.
- module.AddSharedLibrary("unsupportedappusage")
+ // "libcore_aconfig_flags_lib" module has a circular dependency because the shared libraries
+ // are built on core_current and the module is used to flag the APIs in the core_current.
+ // http://b/316554963#comment2 has the details of the circular dependency chain.
+ // If a java_aconfig_library uses "none" sdk_version, it should include and build these
+ // annotation files as the shared library themselves.
+ var addLibraries bool = module.Library.Module.SdkVersion(ctx).Kind != android.SdkNone
+ if addLibraries {
+ // Add aconfig-annotations-lib as a dependency for the optimization / code stripping annotations
+ module.AddSharedLibrary("aconfig-annotations-lib")
+ // TODO(b/303773055): Remove the annotation after access issue is resolved.
+ module.AddSharedLibrary("unsupportedappusage")
+ }
}
func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
@@ -74,7 +81,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], aconfig.DeclarationsProviderKey)
+ declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], android.AconfigDeclarationsProviderKey)
// Generate the action to build the srcjar
srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
diff --git a/aconfig/codegen/rust_aconfig_library.go b/aconfig/codegen/rust_aconfig_library.go
index 88f5b45..73b6fec 100644
--- a/aconfig/codegen/rust_aconfig_library.go
+++ b/aconfig/codegen/rust_aconfig_library.go
@@ -3,7 +3,6 @@
import (
"fmt"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/rust"
@@ -65,7 +64,7 @@
if len(declarationsModules) != 1 {
panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
}
- declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], aconfig.DeclarationsProviderKey)
+ declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], android.AconfigDeclarationsProviderKey)
mode := proptools.StringDefault(a.Properties.Mode, "production")
if !isModeSupported(mode) {
diff --git a/aconfig/exported_java_aconfig_library.go b/aconfig/exported_java_aconfig_library.go
index 8644810..291938f 100644
--- a/aconfig/exported_java_aconfig_library.go
+++ b/aconfig/exported_java_aconfig_library.go
@@ -30,7 +30,7 @@
// Find all of the aconfig_declarations modules
var cacheFiles android.Paths
ctx.VisitAllModules(func(module android.Module) {
- decl, ok := android.SingletonModuleProvider(ctx, module, DeclarationsProviderKey)
+ decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey)
if !ok {
return
}
diff --git a/aconfig/init.go b/aconfig/init.go
index 05fab4c..04176ec 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -62,18 +62,21 @@
},
}, "cache_files")
- mergeAconfigFilesRule = pctx.AndroidStaticRule("mergeAconfigFilesRule",
- blueprint.RuleParams{
- Command: `${aconfig} dump --dedup --format protobuf --out $out $flags`,
- CommandDeps: []string{"${aconfig}"},
- }, "flags")
// For exported_java_aconfig_library: Generate a JAR from all
// java_aconfig_libraries to be consumed by apps built outside the
// platform
exportedJavaRule = pctx.AndroidStaticRule("exported_java_aconfig_library",
+ // For each aconfig cache file, if the cache contains any
+ // exported flags, generate Java flag lookup code for the
+ // exported flags (only). Finally collect all generated code
+ // into the ${out} JAR file.
blueprint.RuleParams{
Command: `rm -rf ${out}.tmp` +
- `&& for cache in ${cache_files}; do ${aconfig} create-java-lib --cache $$cache --out ${out}.tmp; done` +
+ `&& for cache in ${cache_files}; do ` +
+ ` if [ -n "$$(${aconfig} dump --cache $$cache --filter=is_exported:true --format='{fully_qualified_name}')" ]; then ` +
+ ` ${aconfig} create-java-lib --cache $$cache --mode=exported --out ${out}.tmp; ` +
+ ` fi ` +
+ `done` +
`&& $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
`&& rm -rf ${out}.tmp`,
CommandDeps: []string{
diff --git a/android/Android.bp b/android/Android.bp
index 26317b8..b359df9 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -27,6 +27,7 @@
"androidmk-parser",
],
srcs: [
+ "aconfig_providers.go",
"androidmk.go",
"apex.go",
"apex_contributions.go",
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
new file mode 100644
index 0000000..ddebec3
--- /dev/null
+++ b/android/aconfig_providers.go
@@ -0,0 +1,92 @@
+// Copyright 2023 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "github.com/google/blueprint"
+)
+
+var (
+ mergeAconfigFilesRule = pctx.AndroidStaticRule("mergeAconfigFilesRule",
+ blueprint.RuleParams{
+ Command: `${aconfig} dump --dedup --format protobuf --out $out $flags`,
+ CommandDeps: []string{"${aconfig}"},
+ }, "flags")
+ _ = pctx.HostBinToolVariable("aconfig", "aconfig")
+)
+
+// Provider published by aconfig_value_set
+type AconfigDeclarationsProviderData struct {
+ Package string
+ Container string
+ IntermediateCacheOutputPath WritablePath
+ IntermediateDumpOutputPath WritablePath
+}
+
+var AconfigDeclarationsProviderKey = blueprint.NewProvider[AconfigDeclarationsProviderData]()
+
+// This is used to collect the aconfig declarations info on the transitive closure,
+// the data is keyed on the container.
+type AconfigTransitiveDeclarationsInfo struct {
+ AconfigFiles map[string]Paths
+}
+
+var AconfigTransitiveDeclarationsInfoProvider = blueprint.NewProvider[AconfigTransitiveDeclarationsInfo]()
+
+func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[string]Paths) {
+ if *mergedAconfigFiles == nil {
+ *mergedAconfigFiles = make(map[string]Paths)
+ }
+ ctx.VisitDirectDeps(func(module Module) {
+ if dep, _ := OtherModuleProvider(ctx, module, AconfigDeclarationsProviderKey); dep.IntermediateCacheOutputPath != nil {
+ (*mergedAconfigFiles)[dep.Container] = append((*mergedAconfigFiles)[dep.Container], dep.IntermediateCacheOutputPath)
+ return
+ }
+ if dep, _ := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); len(dep.AconfigFiles) > 0 {
+ for container, v := range dep.AconfigFiles {
+ (*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...)
+ }
+ }
+ })
+
+ for container, aconfigFiles := range *mergedAconfigFiles {
+ (*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, aconfigFiles)
+ }
+
+ SetProvider(ctx, AconfigTransitiveDeclarationsInfoProvider, AconfigTransitiveDeclarationsInfo{
+ AconfigFiles: *mergedAconfigFiles,
+ })
+}
+
+func mergeAconfigFiles(ctx ModuleContext, inputs Paths) Paths {
+ inputs = LastUniquePaths(inputs)
+ if len(inputs) == 1 {
+ return Paths{inputs[0]}
+ }
+
+ output := PathForModuleOut(ctx, "aconfig_merged.pb")
+
+ ctx.Build(pctx, BuildParams{
+ Rule: mergeAconfigFilesRule,
+ Description: "merge aconfig files",
+ Inputs: inputs,
+ Output: output,
+ Args: map[string]string{
+ "flags": JoinWithPrefix(inputs.Strings(), "--cache "),
+ },
+ })
+
+ return Paths{output}
+}
diff --git a/android/apex.go b/android/apex.go
index c0907a7..b4bb67c 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -954,3 +954,15 @@
// Return true if the apex bundle is an apex_test
IsTestApex() bool
}
+
+var ApexExportsInfoProvider = blueprint.NewProvider[ApexExportsInfo]()
+
+// ApexExportsInfo contains information about the artifacts provided by apexes to dexpreopt and hiddenapi
+type ApexExportsInfo struct {
+ // Canonical name of this APEX. Used to determine the path to the activated APEX on
+ // device (/apex/<apex_name>)
+ ApexName string
+
+ // Path to the image profile file on host (or empty, if profile is not generated).
+ ProfilePathOnHost Path
+}
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index 34941c0..a309640 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -164,6 +164,18 @@
}
}
+// Return the list of soong modules selected for this api domain
+// In the case of apexes, it is the canonical name of the apex on device (/apex/<apex_name>)
+func (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain string) []string {
+ selected := []string{}
+ for _, entry := range *p {
+ if entry.apiDomain == apiDomain {
+ selected = append(selected, entry.selectedModuleName)
+ }
+ }
+ return selected
+}
+
// This module type does not have any build actions.
func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
}
diff --git a/android/deapexer.go b/android/deapexer.go
index de933d1..fb2073d 100644
--- a/android/deapexer.go
+++ b/android/deapexer.go
@@ -15,6 +15,7 @@
package android
import (
+ "fmt"
"strings"
"github.com/google/blueprint"
@@ -146,10 +147,16 @@
// FindDeapexerProviderForModule searches through the direct dependencies of the current context
// module for a DeapexerTag dependency and returns its DeapexerInfo. If a single nonambiguous
-// deapexer module isn't found then errors are reported with ctx.ModuleErrorf and nil is returned.
-func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo {
+// deapexer module isn't found then it returns it an error
+// clients should check the value of error and call ctx.ModuleErrof if a non nil error is received
+func FindDeapexerProviderForModule(ctx ModuleContext) (*DeapexerInfo, error) {
var di *DeapexerInfo
+ var err error
ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) {
+ if err != nil {
+ // An err has been found. Do not visit further.
+ return
+ }
c, _ := OtherModuleProvider(ctx, m, DeapexerProvider)
p := &c
if di != nil {
@@ -159,17 +166,18 @@
di = selected
return
}
- ctx.ModuleErrorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s",
- di.ApexModuleName(), p.ApexModuleName())
+ err = fmt.Errorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s", di.ApexModuleName(), p.ApexModuleName())
}
di = p
})
+ if err != nil {
+ return nil, err
+ }
if di != nil {
- return di
+ return di, nil
}
ai, _ := ModuleProvider(ctx, ApexInfoProvider)
- ctx.ModuleErrorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
- return nil
+ return nil, fmt.Errorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
}
// removeCompressedApexSuffix removes the _compressed suffix from the name if present.
diff --git a/android/module.go b/android/module.go
index 7e88797..1100fee 100644
--- a/android/module.go
+++ b/android/module.go
@@ -77,6 +77,8 @@
InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
+ InstallInOdm() bool
+ InstallInProduct() bool
InstallInVendor() bool
InstallForceOS() (*OsType, *ArchType)
PartitionTag(DeviceConfig) string
@@ -1399,6 +1401,14 @@
return Bool(m.commonProperties.Recovery)
}
+func (m *ModuleBase) InstallInOdm() bool {
+ return false
+}
+
+func (m *ModuleBase) InstallInProduct() bool {
+ return false
+}
+
func (m *ModuleBase) InstallInVendor() bool {
return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
}
diff --git a/android/module_context.go b/android/module_context.go
index 39986df..81692d5 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -181,6 +181,8 @@
InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
+ InstallInOdm() bool
+ InstallInProduct() bool
InstallInVendor() bool
InstallForceOS() (*OsType, *ArchType)
@@ -438,6 +440,14 @@
return m.module.InstallForceOS()
}
+func (m *moduleContext) InstallInOdm() bool {
+ return m.module.InstallInOdm()
+}
+
+func (m *moduleContext) InstallInProduct() bool {
+ return m.module.InstallInProduct()
+}
+
func (m *moduleContext) InstallInVendor() bool {
return m.module.InstallInVendor()
}
diff --git a/android/paths.go b/android/paths.go
index 3f35449..6aabe4f 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -111,6 +111,9 @@
InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
+ InstallInOdm() bool
+ InstallInProduct() bool
+ InstallInVendor() bool
InstallForceOS() (*OsType, *ArchType)
}
@@ -152,6 +155,18 @@
return ctx.Module().InstallInRoot()
}
+func (ctx *baseModuleContextToModuleInstallPathContext) InstallInOdm() bool {
+ return ctx.Module().InstallInOdm()
+}
+
+func (ctx *baseModuleContextToModuleInstallPathContext) InstallInProduct() bool {
+ return ctx.Module().InstallInProduct()
+}
+
+func (ctx *baseModuleContextToModuleInstallPathContext) InstallInVendor() bool {
+ return ctx.Module().InstallInVendor()
+}
+
func (ctx *baseModuleContextToModuleInstallPathContext) InstallForceOS() (*OsType, *ArchType) {
return ctx.Module().InstallForceOS()
}
@@ -1866,11 +1881,11 @@
// the layout of recovery partion is the same as that of system partition
partition = "recovery/root/system"
}
- } else if ctx.SocSpecific() {
+ } else if ctx.SocSpecific() || ctx.InstallInVendor() {
partition = ctx.DeviceConfig().VendorPath()
- } else if ctx.DeviceSpecific() {
+ } else if ctx.DeviceSpecific() || ctx.InstallInOdm() {
partition = ctx.DeviceConfig().OdmPath()
- } else if ctx.ProductSpecific() {
+ } else if ctx.ProductSpecific() || ctx.InstallInProduct() {
partition = ctx.DeviceConfig().ProductPath()
} else if ctx.SystemExtSpecific() {
partition = ctx.DeviceConfig().SystemExtPath()
@@ -2066,6 +2081,9 @@
inDebugRamdisk bool
inRecovery bool
inRoot bool
+ inOdm bool
+ inProduct bool
+ inVendor bool
forceOS *OsType
forceArch *ArchType
}
@@ -2108,6 +2126,18 @@
return m.inRoot
}
+func (m testModuleInstallPathContext) InstallInOdm() bool {
+ return m.inOdm
+}
+
+func (m testModuleInstallPathContext) InstallInProduct() bool {
+ return m.inProduct
+}
+
+func (m testModuleInstallPathContext) InstallInVendor() bool {
+ return m.inVendor
+}
+
func (m testModuleInstallPathContext) InstallForceOS() (*OsType, *ArchType) {
return m.forceOS, m.forceArch
}
diff --git a/apex/apex.go b/apex/apex.go
index 56559b1..35a8782 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -24,7 +24,6 @@
"sort"
"strings"
- "android/soong/aconfig"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -2272,7 +2271,7 @@
}
func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
- dep, _ := android.OtherModuleProvider(ctx, module, aconfig.TransitiveDeclarationsInfoProvider)
+ dep, _ := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider)
if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
}
@@ -2371,6 +2370,24 @@
a.buildApex(ctx)
a.buildApexDependencyInfo(ctx)
a.buildLintReports(ctx)
+
+ // Set a provider for dexpreopt of bootjars
+ a.provideApexExportsInfo(ctx)
+}
+
+// Set a provider containing information about the jars and .prof provided by the apex
+// Apexes built from source retrieve this information by visiting `bootclasspath_fragments`
+// Used by dex_bootjars to generate the boot image
+func (a *apexBundle) provideApexExportsInfo(ctx android.ModuleContext) {
+ ctx.VisitDirectDepsWithTag(bcpfTag, func(child android.Module) {
+ if info, ok := android.OtherModuleProvider(ctx, child, java.BootclasspathFragmentApexContentInfoProvider); ok {
+ exports := android.ApexExportsInfo{
+ ApexName: a.ApexVariationName(),
+ ProfilePathOnHost: info.ProfilePathOnHost(),
+ }
+ ctx.SetProvider(android.ApexExportsInfoProvider, exports)
+ }
+ })
}
// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
diff --git a/apex/apex_test.go b/apex/apex_test.go
index abf6b15..6c7dabc 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3725,7 +3725,7 @@
}
func ensureExactDeapexedContents(t *testing.T, ctx *android.TestContext, moduleName string, variant string, files []string) {
- deapexer := ctx.ModuleForTests(moduleName+".deapexer", variant).Rule("deapexer")
+ deapexer := ctx.ModuleForTests(moduleName+".deapexer", variant).Description("deapex")
outputs := make([]string, 0, len(deapexer.ImplicitOutputs)+1)
if deapexer.Output != nil {
outputs = append(outputs, deapexer.Output.String())
@@ -8432,6 +8432,13 @@
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
apex_available: ["com.android.myapex"],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
%s
}
`
@@ -8453,6 +8460,7 @@
public: {
jars: ["libbar.jar"],
},
+ shared_library: false,
apex_available: ["com.android.myapex"],
}
`)
@@ -8468,6 +8476,7 @@
public: {
jars: ["libbar.jar"],
},
+ shared_library: false,
apex_available: ["com.android.myapex"],
}
`)
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 42f5cd4..159e9e1 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -530,6 +530,8 @@
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
`com.android.art.apex.selector`,
+ `com.android.art.deapexer`,
+ `dex2oatd`,
`prebuilt_art-bootclasspath-fragment`,
})
diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go
index 2e828ca..9d74519 100644
--- a/apex/dexpreopt_bootjars_test.go
+++ b/apex/dexpreopt_bootjars_test.go
@@ -252,3 +252,153 @@
testDexpreoptBoot(t, ruleFile, expectedInputs, expectedOutputs, false)
}
+
+// Multiple ART apexes might exist in the tree.
+// The profile should correspond to the apex selected using release build flags
+func TestDexpreoptProfileWithMultiplePrebuiltArtApexes(t *testing.T) {
+ ruleFile := "out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art"
+ bp := `
+ // Platform.
+
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+
+ // Source ART APEX.
+
+ java_library {
+ name: "core-oj",
+ srcs: ["core-oj.java"],
+ installable: true,
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ contents: ["core-oj"],
+ apex_available: [
+ "com.android.art",
+ ],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ updatable: false,
+ }
+
+ // Prebuilt ART APEX.
+
+ prebuilt_bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ prebuilt_apex {
+ name: "com.android.art",
+ apex_name: "com.android.art",
+ src: "com.android.art-arm.apex",
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ }
+
+ // Another Prebuilt ART APEX
+ prebuilt_apex {
+ name: "com.android.art.v2",
+ apex_name: "com.android.art", // Used to determine the API domain
+ src: "com.android.art-arm.apex",
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ }
+
+ // APEX contribution modules
+
+ apex_contributions {
+ name: "art.source.contributions",
+ api_domain: "com.android.art",
+ contents: ["com.android.art"],
+ }
+
+ apex_contributions {
+ name: "art.prebuilt.contributions",
+ api_domain: "com.android.art",
+ contents: ["prebuilt_com.android.art"],
+ }
+
+ apex_contributions {
+ name: "art.prebuilt.v2.contributions",
+ api_domain: "com.android.art",
+ contents: ["com.android.art.v2"], // prebuilt_ prefix is missing because of prebuilt_rename mutator
+ }
+
+ `
+
+ testCases := []struct {
+ desc string
+ selectedArtApexContributions string
+ expectedProfile string
+ }{
+ {
+ desc: "Source apex com.android.art is selected, profile should come from source java library",
+ selectedArtApexContributions: "art.source.contributions",
+ expectedProfile: "out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/art-bootclasspath-fragment/boot.prof",
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.art is selected, profile should come from .prof deapexed from the prebuilt",
+ selectedArtApexContributions: "art.prebuilt.contributions",
+ expectedProfile: "out/soong/.intermediates/com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof",
+ },
+ {
+ desc: "Prebuilt apex prebuilt_com.android.art.v2 is selected, profile should come from .prof deapexed from the prebuilt",
+ selectedArtApexContributions: "art.prebuilt.v2.contributions",
+ expectedProfile: "out/soong/.intermediates/com.android.art.v2.deapexer/android_common/deapexer/etc/boot-image.prof",
+ },
+ }
+ for _, tc := range testCases {
+ result := android.GroupFixturePreparers(
+ java.PrepareForTestWithDexpreopt,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureConfigureBootJars("com.android.art:core-oj"),
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithArtApex,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ART": tc.selectedArtApexContributions,
+ }
+ }),
+ ).RunTestWithBp(t, bp)
+
+ dexBootJars := result.ModuleForTests("dex_bootjars", "android_common")
+ rule := dexBootJars.Output(ruleFile)
+
+ inputs := rule.Implicits.Strings()
+ android.AssertStringListContains(t, tc.desc, inputs, tc.expectedProfile)
+ }
+}
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 179d90b..37a9ff5 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -22,6 +22,7 @@
"strings"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/java"
"android/soong/provenance"
@@ -50,6 +51,7 @@
type prebuiltCommon struct {
android.ModuleBase
+ java.Dexpreopter
prebuilt android.Prebuilt
// Properties common to both prebuilt_apex and apex_set.
@@ -170,50 +172,42 @@
return proptools.BoolDefault(p.prebuiltCommonProperties.Installable, true)
}
-// initApexFilesForAndroidMk initializes the prebuiltCommon.apexFilesForAndroidMk field from the
-// modules that this depends upon.
+// To satisfy java.DexpreopterInterface
+func (p *prebuiltCommon) IsInstallable() bool {
+ return p.installable()
+}
+
+// initApexFilesForAndroidMk initializes the prebuiltCommon.requiredModuleNames field with the install only deps of the prebuilt apex
func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
- // Walk the dependencies of this module looking for the java modules that it exports.
- ctx.WalkDeps(func(child, parent android.Module) bool {
- tag := ctx.OtherModuleDependencyTag(child)
+ // If this apex contains a system server jar, then the dexpreopt artifacts should be added as required
+ for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
+ p.requiredModuleNames = append(p.requiredModuleNames, install.FullModuleName())
+ }
+}
- name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
- if java.IsBootclasspathFragmentContentDepTag(tag) ||
- java.IsSystemServerClasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
- // If the exported java module provides a dex jar path then add it to the list of apexFiles.
- path := child.(interface {
- DexJarBuildPath() java.OptionalDexJarPath
- }).DexJarBuildPath()
- if path.IsSet() {
- af := apexFile{
- module: child,
- moduleDir: ctx.OtherModuleDir(child),
- androidMkModuleName: name,
- builtFile: path.Path(),
- class: javaSharedLib,
- }
- if module, ok := child.(java.DexpreopterInterface); ok {
- for _, install := range module.DexpreoptBuiltInstalledForApex() {
- af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
- }
- }
- p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
- }
- } else if tag == exportedBootclasspathFragmentTag {
- _, ok := child.(*java.PrebuiltBootclasspathFragmentModule)
- if !ok {
- ctx.PropertyErrorf("exported_bootclasspath_fragments", "%q is not a prebuilt_bootclasspath_fragment module", name)
- return false
- }
- // Visit the children of the bootclasspath_fragment.
- return true
- } else if tag == exportedSystemserverclasspathFragmentTag {
- // Visit the children of the systemserver_fragment.
- return true
+// If this prebuilt has system server jar, create the rules to dexpreopt it and install it alongside the prebuilt apex
+func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) {
+ // If this apex does not export anything, return
+ if !p.hasExportedDeps() {
+ return
+ }
+ // Use apex_name to determine the api domain of this prebuilt apex
+ apexName := p.ApexVariationName()
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ ctx.ModuleErrorf(err.Error())
+ }
+ dc := dexpreopt.GetGlobalConfig(ctx)
+ systemServerJarList := dc.AllApexSystemServerJars(ctx)
+
+ for i := 0; i < systemServerJarList.Len(); i++ {
+ sscpApex := systemServerJarList.Apex(i)
+ sscpJar := systemServerJarList.Jar(i)
+ if apexName != sscpApex {
+ continue
}
-
- return false
- })
+ p.Dexpreopter.DexpreoptPrebuiltApexSystemServerJars(ctx, sscpJar, di)
+ }
}
func (p *prebuiltCommon) addRequiredModules(entries *android.AndroidMkEntries) {
@@ -248,6 +242,11 @@
},
}
+ // Add the dexpreopt artifacts to androidmk
+ for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
+ entriesList = append(entriesList, install.ToMakeEntries())
+ }
+
// Iterate over the apexFilesForAndroidMk list and create an AndroidMkEntries struct for each
// file. This provides similar behavior to that provided in apexBundle.AndroidMk() as it makes the
// apex specific variants of the exported java modules available for use from within make.
@@ -756,12 +755,39 @@
p.prebuiltApexContentsDeps(ctx)
}
+func (p *prebuiltCommon) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if p.hasExportedDeps() {
+ // Create a dependency from the prebuilt apex (prebuilt_apex/apex_set) to the internal deapexer module
+ // The deapexer will return a provider that will be bubbled up to the rdeps of apexes (e.g. dex_bootjars)
+ ctx.AddDependency(ctx.Module(), android.DeapexerTag, deapexerModuleName(p.BaseModuleName()))
+ }
+}
+
var _ ApexInfoMutator = (*Prebuilt)(nil)
func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) {
p.apexInfoMutator(mctx)
}
+// Set a provider containing information about the jars and .prof provided by the apex
+// Apexes built from prebuilts retrieve this information by visiting its internal deapexer module
+// Used by dex_bootjars to generate the boot image
+func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext) {
+ if !p.hasExportedDeps() {
+ // nothing to do
+ return
+ }
+ if di, err := android.FindDeapexerProviderForModule(ctx); err == nil {
+ exports := android.ApexExportsInfo{
+ ApexName: p.ApexVariationName(),
+ ProfilePathOnHost: di.PrebuiltExportPath(java.ProfileInstallPathInApex),
+ }
+ ctx.SetProvider(android.ApexExportsInfoProvider, exports)
+ } else {
+ ctx.ModuleErrorf(err.Error())
+ }
+}
+
func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.apexKeysPath = writeApexKeys(ctx, p)
// TODO(jungjw): Check the key validity.
@@ -783,6 +809,12 @@
return
}
+ // dexpreopt any system server jars if present
+ p.dexpreoptSystemServerJars(ctx)
+
+ // provide info used for generating the boot image
+ p.provideApexExportsInfo(ctx)
+
// Save the files that need to be made available to Make.
p.initApexFilesForAndroidMk(ctx)
@@ -999,6 +1031,12 @@
return
}
+ // dexpreopt any system server jars if present
+ a.dexpreoptSystemServerJars(ctx)
+
+ // provide info used for generating the boot image
+ a.provideApexExportsInfo(ctx)
+
// Save the files that need to be made available to Make.
a.initApexFilesForAndroidMk(ctx)
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 40d0581..90fd2ca 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -272,7 +272,9 @@
ctx := result.TestContext
java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
+ `dex2oatd`,
`myapex.apex.selector`,
+ `myapex.deapexer`,
`prebuilt_mysystemserverclasspathfragment`,
})
diff --git a/cc/cc.go b/cc/cc.go
index e6b9d8b..9f32c44 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -28,7 +28,6 @@
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/aidl_library"
"android/soong/android"
"android/soong/cc/config"
@@ -2137,7 +2136,7 @@
}
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: deps.GeneratedSources.Strings()})
- aconfig.CollectDependencyAconfigFiles(ctx, &c.mergedAconfigFiles)
+ android.CollectDependencyAconfigFiles(ctx, &c.mergedAconfigFiles)
c.maybeInstall(ctx, apexInfo)
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index cebf129..5c5275e 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -194,13 +194,13 @@
}
}
socSpecific := func(m *Module) bool {
- return m.SocSpecific() || m.socSpecificModuleContext()
+ return m.SocSpecific() || m.InstallInVendor()
}
deviceSpecific := func(m *Module) bool {
- return m.DeviceSpecific() || m.deviceSpecificModuleContext()
+ return m.DeviceSpecific() || m.InstallInOdm()
}
productSpecific := func(m *Module) bool {
- return m.ProductSpecific() || m.productSpecificModuleContext()
+ return m.ProductSpecific() || m.InstallInProduct()
}
systemExtSpecific := func(m *Module) bool {
return m.SystemExtSpecific()
diff --git a/cc/image.go b/cc/image.go
index 4f36111..4c0c722 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -51,18 +51,6 @@
ProductVariationPrefix = "product."
)
-func (ctx *moduleContext) ProductSpecific() bool {
- return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext()
-}
-
-func (ctx *moduleContext) SocSpecific() bool {
- return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext()
-}
-
-func (ctx *moduleContext) DeviceSpecific() bool {
- return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext()
-}
-
func (ctx *moduleContextImpl) inProduct() bool {
return ctx.mod.InProduct()
}
@@ -83,20 +71,20 @@
return ctx.mod.InRecovery()
}
-func (c *Module) productSpecificModuleContext() bool {
+func (c *Module) InstallInProduct() bool {
// Additionally check if this module is inProduct() that means it is a "product" variant of a
// module. As well as product specific modules, product variants must be installed to /product.
return c.InProduct()
}
-func (c *Module) socSpecificModuleContext() bool {
+func (c *Module) InstallInVendor() bool {
// Additionally check if this module is inVendor() that means it is a "vendor" variant of a
// module. As well as SoC specific modules, vendor variants must be installed to /vendor
// unless they have "odm_available: true".
return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm()
}
-func (c *Module) deviceSpecificModuleContext() bool {
+func (c *Module) InstallInOdm() bool {
// Some vendor variants want to be installed to /odm by setting "odm_available: true".
return c.InVendor() && c.VendorVariantToOdm()
}
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index 3364f50..e69a930 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -22,6 +22,7 @@
"flag"
"fmt"
"io"
+ "io/fs"
"io/ioutil"
"os"
"os/exec"
@@ -478,7 +479,8 @@
// copyOneFile copies a file and its permissions. If forceExecutable is true it adds u+x to the
// permissions. If exists is allowFromNotExists it returns nil if the from path doesn't exist.
// If write is onlyWriteIfChanged then the output file is compared to the input file and not written to
-// if it is the same, avoiding updating the timestamp.
+// if it is the same, avoiding updating the timestamp. If from is a symlink, the symlink itself
+// will be copied, instead of what it points to.
func copyOneFile(from string, to string, forceExecutable bool, exists existsType,
write writeType) error {
err := os.MkdirAll(filepath.Dir(to), 0777)
@@ -486,7 +488,7 @@
return err
}
- stat, err := os.Stat(from)
+ stat, err := os.Lstat(from)
if err != nil {
if os.IsNotExist(err) && exists == allowFromNotExists {
return nil
@@ -494,6 +496,25 @@
return err
}
+ if stat.Mode()&fs.ModeSymlink != 0 {
+ linkTarget, err := os.Readlink(from)
+ if err != nil {
+ return err
+ }
+ if write == onlyWriteIfChanged {
+ toLinkTarget, err := os.Readlink(to)
+ if err == nil && toLinkTarget == linkTarget {
+ return nil
+ }
+ }
+ err = os.Remove(to)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ return os.Symlink(linkTarget, to)
+ }
+
perm := stat.Mode()
if forceExecutable {
perm = perm | 0100 // u+x
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index 8abf73e..dc2d9e6 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -25,7 +25,6 @@
// go/keep-sorted start
"CtsApkVerityTestDebugFiles",
"aidl_camera_build_version",
- "camera-its",
"chre_atoms_log.h",
// go/keep-sorted end
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 809f9b5..cbf9abb 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -207,11 +207,7 @@
func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
if prebuilt.hideApexVariantFromMake {
- // For a library imported from a prebuilt APEX, we don't need a Make module for itself, as we
- // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it
- // is preopted.
- dexpreoptEntries := prebuilt.dexpreopter.AndroidMkEntriesForApex()
- return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true})
+ return []android.AndroidMkEntries{}
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
diff --git a/java/app.go b/java/app.go
index 7f0303a..8b28dac 100755
--- a/java/app.go
+++ b/java/app.go
@@ -22,7 +22,6 @@
"path/filepath"
"strings"
- "android/soong/aconfig"
"android/soong/testing"
"github.com/google/blueprint"
@@ -509,7 +508,7 @@
var aconfigTextFilePaths android.Paths
ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
- if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.DeclarationsProviderKey); ok {
+ if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
} else {
ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 8f29bb3..ef4626e 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -40,8 +40,8 @@
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
t.Errorf("can't find dexpreopt outputs")
}
@@ -74,8 +74,8 @@
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs. They shouldn't exist.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule != nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule != nil {
t.Errorf("dexpreopt shouldn't have run.")
}
@@ -101,8 +101,8 @@
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
t.Errorf("can't find dexpreopt outputs")
}
// Make sure signing was skipped and aligning was done.
@@ -210,8 +210,8 @@
variant := ctx.ModuleForTests("foo", "android_common")
// Check dexpreopt outputs.
- if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
- variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
t.Errorf("can't find dexpreopt outputs")
}
diff --git a/java/app_test.go b/java/app_test.go
index 0936b28..861c047 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3357,7 +3357,7 @@
cmd := app.Rule("dexpreopt").RuleParams.Command
android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=")
android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd,
- "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/product_packages.txt")
+ "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt")
}
func TestDexpreoptBcp(t *testing.T) {
diff --git a/java/base.go b/java/base.go
index 41f2fcc..0d3e4db 100644
--- a/java/base.go
+++ b/java/base.go
@@ -24,7 +24,6 @@
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/dexpreopt"
"android/soong/java/config"
@@ -1694,7 +1693,7 @@
ctx.CheckbuildFile(outputFile)
- aconfig.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles)
+ android.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles)
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index d2bb523..010dbec 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -240,7 +240,8 @@
sourceOnlyProperties SourceOnlyBootclasspathProperties
// Path to the boot image profile.
- profilePath android.WritablePath
+ profilePath android.WritablePath
+ profilePathErr error
}
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
@@ -533,7 +534,7 @@
if profile != nil {
info.profilePathOnHost = profile
- info.profileInstallPathInApex = profileInstallPathInApex
+ info.profileInstallPathInApex = ProfileInstallPathInApex
}
// Make the apex content info available for other modules.
@@ -1065,15 +1066,21 @@
return nil
}
- di := android.FindDeapexerProviderForModule(ctx)
- if di == nil {
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ // An error was found, possibly due to multiple apexes in the tree that export this library
+ // Defer the error till a client tries to call getProfilePath
+ module.profilePathErr = err
return nil // An error has been reported by FindDeapexerProviderForModule.
}
- return di.PrebuiltExportPath(profileInstallPathInApex)
+ return di.PrebuiltExportPath(ProfileInstallPathInApex)
}
func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path {
+ if b.profilePathErr != nil {
+ panic(b.profilePathErr.Error())
+ }
return b.profilePath
}
@@ -1087,7 +1094,7 @@
func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
for _, apex := range module.ApexProperties.Apex_available {
if isProfileProviderApex(ctx, apex) {
- return []string{profileInstallPathInApex}
+ return []string{ProfileInstallPathInApex}
}
}
return nil
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0f69dc3..1e289c5 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -79,18 +79,25 @@
func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries {
return android.AndroidMkEntries{
Class: "ETC",
- SubName: install.SubModuleName(),
OutputFile: android.OptionalPathForPath(install.outputPathOnHost),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE", install.FullModuleName())
entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
+ // Unset LOCAL_SOONG_INSTALLED_MODULE so that this does not default to the primary .apex file
+ // Without this, installation of the dexpreopt artifacts get skipped
+ entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", "")
},
},
}
}
+type Dexpreopter struct {
+ dexpreopter
+}
+
type dexpreopter struct {
dexpreoptProperties DexpreoptProperties
importDexpreoptProperties ImportDexpreoptProperties
@@ -258,6 +265,17 @@
return defaultInstallPath
}
+// DexpreoptPrebuiltApexSystemServerJars generates the dexpreopt artifacts from a jar file that has been deapexed from a prebuilt apex
+func (d *Dexpreopter) DexpreoptPrebuiltApexSystemServerJars(ctx android.ModuleContext, libraryName string, di *android.DeapexerInfo) {
+ // A single prebuilt apex can have multiple apex system jars
+ // initialize the output path for this dex jar
+ dc := dexpreopt.GetGlobalConfig(ctx)
+ d.installPath = android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexpreopt.GetSystemServerDexLocation(ctx, dc, libraryName), "/"))
+ // generate the rules for creating the .odex and .vdex files for this system server jar
+ dexJarFile := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(libraryName))
+ d.dexpreopt(ctx, dexJarFile)
+}
+
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) {
global := dexpreopt.GetGlobalConfig(ctx)
@@ -346,11 +364,15 @@
d.dexpreoptProperties.Dex_preopt_result.Profile_guided = profileClassListing.Valid()
+ // A single apex can have multiple system server jars
+ // Use the dexJar to create a unique scope for each
+ dexJarStem := strings.TrimSuffix(dexJarFile.Base(), dexJarFile.Ext())
+
// Full dexpreopt config, used to create dexpreopt build rules.
dexpreoptConfig := &dexpreopt.ModuleConfig{
Name: moduleName(ctx),
DexLocation: dexLocation,
- BuildPath: android.PathForModuleOut(ctx, "dexpreopt", moduleName(ctx)+".jar").OutputPath,
+ BuildPath: android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, moduleName(ctx)+".jar").OutputPath,
DexPath: dexJarFile,
ManifestPath: android.OptionalPathForPath(d.manifestFile),
UncompressedDex: d.uncompressedDex,
@@ -380,7 +402,7 @@
PresignedPrebuilt: d.isPresignedPrebuilt,
}
- d.configPath = android.PathForModuleOut(ctx, "dexpreopt", "dexpreopt.config")
+ d.configPath = android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "dexpreopt.config")
dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath)
if d.dexpreoptDisabled(ctx) {
@@ -394,7 +416,7 @@
// dependencies to create a per-app list, and use `rsync --checksum` to prevent the file's mtime
// from being changed if the contents don't change. This avoids unnecessary dexpreopt reruns.
productPackages := android.PathForModuleInPartitionInstall(ctx, "", "product_packages.txt")
- appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", "product_packages.txt")
+ appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "product_packages.txt")
appProductPackagesStaging := appProductPackages.ReplaceExtension(ctx, "txt.tmp")
clcNames, _ := dexpreopt.ComputeClassLoaderContextDependencies(dexpreoptConfig.ClassLoaderContexts)
sort.Strings(clcNames) // The order needs to be deterministic.
@@ -416,7 +438,7 @@
Text("rsync --checksum").
Input(appProductPackagesStaging).
Output(appProductPackages)
- productPackagesRule.Restat().Build("product_packages", "dexpreopt product_packages")
+ productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages")
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
@@ -425,9 +447,11 @@
return
}
- dexpreoptRule.Build("dexpreopt", "dexpreopt")
+ dexpreoptRule.Build("dexpreopt"+"."+dexJarStem, "dexpreopt")
- isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
+ // The current ctx might be of a deapexer module created by a prebuilt apex
+ // Use the path of the dex file to determine the library name
+ isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(dexJarStem)
for _, install := range dexpreoptRule.Installs() {
// Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT.
@@ -452,7 +476,7 @@
// The installs will be handled by Make as sub-modules of the java library.
d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{
name: arch + "-" + installBase,
- moduleName: moduleName(ctx),
+ moduleName: dexJarStem,
outputPathOnHost: install.From,
installDirOnDevice: installPath,
installFileOnDevice: installBase,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 5a19945..e158ed3 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -21,6 +21,7 @@
"android/soong/android"
"android/soong/dexpreopt"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -224,8 +225,9 @@
}
var (
- dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
- dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
+ dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
+ dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
+ apexContributionsMetadataDepTag = dependencyTag{name: "all_apex_contributions"}
)
func init() {
@@ -502,6 +504,11 @@
dexpreoptConfigForMake android.WritablePath
}
+func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) {
+ // Create a dependency on all_apex_contributions to determine the selected mainline module
+ ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions")
+}
+
func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
if _, ok := ctx.Module().(*dexpreoptBootJars); !ok {
return
@@ -520,6 +527,14 @@
}
// For accessing the boot jars.
addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag)
+ // Create a dependency on the apex selected using RELEASE_APEX_CONTRIBUTIONS_*
+ // TODO: b/308174306 - Remove the direct depedendency edge to the java_library (source/prebuilt) once all mainline modules
+ // have been flagged using RELEASE_APEX_CONTRIBUTIONS_*
+ apexes := []string{}
+ for i := 0; i < config.modules.Len(); i++ {
+ apexes = append(apexes, config.modules.Apex(i))
+ }
+ addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...)
}
if ctx.OtherModuleExists("platform-bootclasspath") {
@@ -532,6 +547,28 @@
}
}
+// Create a dependency from dex_bootjars to the specific apexes selected using all_apex_contributions
+// This dependency will be used to get the path to the deapexed dex boot jars and profile (via a provider)
+func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorContext, apexes ...string) {
+ psi := android.PrebuiltSelectionInfoMap{}
+ ctx.VisitDirectDepsWithTag(apexContributionsMetadataDepTag, func(am android.Module) {
+ if ctx.OtherModuleHasProvider(am, android.PrebuiltSelectionInfoProvider) {
+ psi = ctx.OtherModuleProvider(am, android.PrebuiltSelectionInfoProvider).(android.PrebuiltSelectionInfoMap)
+ }
+ })
+ for _, apex := range apexes {
+ for _, selected := range psi.GetSelectedModulesForApiDomain(apex) {
+ // We need to add a dep on only the apex listed in `contents` of the selected apex_contributions module
+ // This is not available in a structured format in `apex_contributions`, so this hack adds a dep on all `contents`
+ // (some modules like art.module.public.api do not have an apex variation since it is a pure stub module that does not get installed)
+ apexVariationOfSelected := append(ctx.Target().Variations(), blueprint.Variation{Mutator: "apex", Variation: apex})
+ if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, selected) {
+ ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, selected)
+ }
+ }
+ }
+}
+
func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module {
return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
fragments := make(map[string]android.Module)
@@ -823,6 +860,27 @@
config *bootImageVariant
}
+// Returns the profile file for an apex
+// This information can come from two mechanisms
+// 1. New: Direct deps to _selected_ apexes. The apexes return a BootclasspathFragmentApexContentInfo
+// 2. Legacy: An edge to bootclasspath_fragment module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
+// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
+func getProfilePathForApex(ctx android.ModuleContext, apexName string, apexNameToBcpInfoMap map[string]android.ApexExportsInfo) android.Path {
+ if info, exists := apexNameToBcpInfoMap[apexName]; exists {
+ return info.ProfilePathOnHost
+ }
+ // TODO: b/308174306 - Remove the legacy mechanism
+ fragment := getBootclasspathFragmentByApex(ctx, apexName)
+ if fragment == nil {
+ ctx.ModuleErrorf("Boot image config imports profile from '%[2]s', but a "+
+ "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+
+ "dependency of dex_bootjars",
+ apexName)
+ return nil
+ }
+ return fragment.(commonBootclasspathFragment).getProfilePath()
+}
+
// Generate boot image build rules for a specific target.
func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs {
@@ -865,6 +923,13 @@
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
+ apexNameToBcpInfoMap := map[string]android.ApexExportsInfo{}
+ ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(am android.Module) {
+ if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists {
+ apexNameToBcpInfoMap[info.ApexName] = info
+ }
+ })
+
cmd.Tool(globalSoong.Dex2oat).
Flag("--avoid-storing-invocation").
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
@@ -877,16 +942,7 @@
}
for _, apex := range image.profileImports {
- fragment := getBootclasspathFragmentByApex(ctx, apex)
- if fragment == nil {
- ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+
- "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+
- "dependency of dex_bootjars",
- image.name,
- apex)
- return bootImageVariantOutputs{}
- }
- importedProfile := fragment.(commonBootclasspathFragment).getProfilePath()
+ importedProfile := getProfilePathForApex(ctx, apex, apexNameToBcpInfoMap)
if importedProfile == nil {
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
"doesn't provide a profile",
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 2bd696c..254b2c1 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -45,7 +45,7 @@
frameworkBootImageName = "boot"
mainlineBootImageName = "mainline"
bootImageStem = "boot"
- profileInstallPathInApex = "etc/boot-image.prof"
+ ProfileInstallPathInApex = "etc/boot-image.prof"
)
// getImageNames returns an ordered list of image names. The order doesn't matter but needs to be
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index fedd564..73e33f4 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -410,7 +410,7 @@
verifyEntries(t,
"entriesList[0]",
"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- "/dexpreopt/oat/arm64/javalib.odex",
+ "/dexpreopt/service-foo/oat/arm64/javalib.odex",
"/system/framework/oat/arm64",
"apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
entriesList[0])
@@ -418,7 +418,7 @@
verifyEntries(t,
"entriesList[1]",
"service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- "/dexpreopt/oat/arm64/javalib.vdex",
+ "/dexpreopt/service-foo/oat/arm64/javalib.vdex",
"/system/framework/oat/arm64",
"apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
entriesList[1])
@@ -459,7 +459,7 @@
ctx := result.TestContext
dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt")
- expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/profile.prof"}
+ expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/foo/profile.prof"}
android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs())
}
diff --git a/java/java.go b/java/java.go
index 630318e..51e8c34 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2100,6 +2100,7 @@
// output file containing classes.dex and resources
dexJarFile OptionalDexJarPath
+ dexJarFileErr error
dexJarInstallFile android.Path
combinedClasspathFile android.Path
@@ -2250,9 +2251,12 @@
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
if ai.ForPrebuiltApex {
// Get the path of the dex implementation jar from the `deapexer` module.
- di := android.FindDeapexerProviderForModule(ctx)
- if di == nil {
- return // An error has been reported by FindDeapexerProviderForModule.
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ // An error was found, possibly due to multiple apexes in the tree that export this library
+ // Defer the error till a client tries to call DexJarBuildPath
+ j.dexJarFileErr = err
+ return
}
dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName())
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
@@ -2375,6 +2379,9 @@
}
func (j *Import) DexJarBuildPath() OptionalDexJarPath {
+ if j.dexJarFileErr != nil {
+ panic(j.dexJarFileErr.Error())
+ }
return j.dexJarFile
}
diff --git a/java/java_test.go b/java/java_test.go
index e21018c..2368b6c 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -618,8 +618,6 @@
android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0]
android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
- entries = android.AndroidMkEntriesForTest(t, ctx, ctx.ModuleForTests("sdklib", "android_common").Module())[0]
- android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_sdk_library_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 0584281..38bd301 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -2378,7 +2378,8 @@
xmlPermissionsFileModule *sdkLibraryXml
// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
- dexJarFile OptionalDexJarPath
+ dexJarFile OptionalDexJarPath
+ dexJarFileErr error
// Expected install file path of the source module(sdk_library)
// or dex implementation jar obtained from the prebuilt_apex, if any.
@@ -2591,14 +2592,6 @@
}
}
-func (module *SdkLibraryImport) AndroidMkEntries() []android.AndroidMkEntries {
- // For an SDK library imported from a prebuilt APEX, we don't need a Make module for itself, as we
- // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it
- // is preopted.
- dexpreoptEntries := module.dexpreopter.AndroidMkEntriesForApex()
- return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true})
-}
-
var _ android.ApexModule = (*SdkLibraryImport)(nil)
// Implements android.ApexModule
@@ -2695,9 +2688,12 @@
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
if ai.ForPrebuiltApex {
// Get the path of the dex implementation jar from the `deapexer` module.
- di := android.FindDeapexerProviderForModule(ctx)
- if di == nil {
- return // An error has been reported by FindDeapexerProviderForModule.
+ di, err := android.FindDeapexerProviderForModule(ctx)
+ if err != nil {
+ // An error was found, possibly due to multiple apexes in the tree that export this library
+ // Defer the error till a client tries to call DexJarBuildPath
+ module.dexJarFileErr = err
+ return
}
dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(module.BaseModuleName())
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
@@ -2759,6 +2755,9 @@
func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath {
// The dex implementation jar extracted from the .apex file should be used in preference to the
// source.
+ if module.dexJarFileErr != nil {
+ panic(module.dexJarFileErr.Error())
+ }
if module.dexJarFile.IsSet() {
return module.dexJarFile
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 0965fc2..63419d6 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -950,6 +950,7 @@
})
CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{
+ `all_apex_contributions`,
`prebuilt_sdklib.stubs`,
`sdklib.impl`,
// This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the
@@ -1022,6 +1023,7 @@
})
CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{
+ `all_apex_contributions`,
`dex2oatd`,
`prebuilt_sdklib.stubs`,
`prebuilt_sdklib.stubs.source`,
@@ -1085,9 +1087,6 @@
"prebuilt_sdklib.source_preferred_using_legacy_flags",
],
}
- all_apex_contributions {
- name: "all_apex_contributions",
- }
java_sdk_library {
name: "sdklib.prebuilt_preferred_using_legacy_flags",
srcs: ["a.java"],
@@ -1169,9 +1168,6 @@
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("sdklib.source_preferred_using_legacy_flags", "sdklib.prebuilt_preferred_using_legacy_flags"),
- android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
- android.RegisterApexContributionsBuildComponents(ctx)
- }),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.BuildFlags = map[string]string{
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions",
diff --git a/java/testing.go b/java/testing.go
index d55cffc..5959c49 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -383,6 +383,7 @@
RegisterSystemModulesBuildComponents(ctx)
registerSystemserverClasspathBuildComponents(ctx)
registerLintBuildComponents(ctx)
+ android.RegisterApexContributionsBuildComponents(ctx)
}
// gatherRequiredDepsForTest gathers the module definitions used by
@@ -570,6 +571,11 @@
}
`
+ bp += `
+ all_apex_contributions {
+ name: "all_apex_contributions",
+ }
+`
return bp
}
diff --git a/rust/image.go b/rust/image.go
index c2e250c..d0218f0 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -117,20 +117,16 @@
return false
}
-func (ctx *moduleContext) SocSpecific() bool {
+func (mod *Module) InstallInVendor() bool {
// Additionally check if this module is inVendor() that means it is a "vendor" variant of a
// module. As well as SoC specific modules, vendor variants must be installed to /vendor
// unless they have "odm_available: true".
- return ctx.ModuleContext.SocSpecific() || (ctx.RustModule().InVendor() && !ctx.RustModule().VendorVariantToOdm())
+ return mod.InVendor() && !mod.VendorVariantToOdm()
}
-func (ctx *moduleContext) DeviceSpecific() bool {
+func (mod *Module) InstallInOdm() bool {
// Some vendor variants want to be installed to /odm by setting "odm_available: true".
- return ctx.ModuleContext.DeviceSpecific() || (ctx.RustModule().InVendor() && ctx.RustModule().VendorVariantToOdm())
-}
-
-func (ctx *moduleContext) SystemExtSpecific() bool {
- return ctx.ModuleContext.SystemExtSpecific()
+ return mod.InVendor() && mod.VendorVariantToOdm()
}
// Returns true when this module creates a vendor variant and wants to install the vendor variant
diff --git a/rust/protobuf.go b/rust/protobuf.go
index b95d8cb..d021076 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -56,6 +56,7 @@
// Use protobuf version 3.x. This will be deleted once we migrate all current users
// of protobuf off of 2.x.
+ // ludovicb@: DEPRECATED, to be removed
Use_protobuf3 *bool
// List of exported include paths containing proto files for dependent rust_protobuf modules.
@@ -74,10 +75,6 @@
protoFlags android.ProtoFlags
}
-func (proto *protobufDecorator) useProtobuf3() bool {
- return Bool(proto.Properties.Use_protobuf3)
-}
-
func (proto *protobufDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path {
var protoFlags android.ProtoFlags
var grpcProtoFlags android.ProtoFlags
@@ -87,12 +84,7 @@
protoFiles := android.PathsForModuleSrc(ctx, proto.Properties.Protos)
grpcFiles := android.PathsForModuleSrc(ctx, proto.Properties.Grpc_protos)
- // For now protobuf2 (the deprecated version) remains the default. This will change in the
- // future as we update the various users.
- protoPluginPath := ctx.Config().HostToolPath(ctx, "protoc-gen-rust-deprecated")
- if proto.useProtobuf3() == true {
- protoPluginPath = ctx.Config().HostToolPath(ctx, "protoc-gen-rust")
- }
+ protoPluginPath := ctx.Config().HostToolPath(ctx, "protoc-gen-rust")
commonProtoFlags = append(commonProtoFlags, defaultProtobufFlags...)
commonProtoFlags = append(commonProtoFlags, proto.Properties.Proto_flags...)
@@ -216,13 +208,7 @@
lines = append(
lines,
"pub mod empty {",
- " pub use protobuf::well_known_types::Empty;",
- "}",
- "pub mod wrappers {",
- " pub use protobuf::well_known_types::{",
- " DoubleValue, FloatValue, Int64Value, UInt64Value, Int32Value, UInt32Value,",
- " BoolValue, StringValue, BytesValue",
- " };",
+ " pub use protobuf::well_known_types::empty::Empty;",
"}")
}
@@ -235,20 +221,10 @@
func (proto *protobufDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps {
deps = proto.BaseSourceProvider.SourceProviderDeps(ctx, deps)
- useProtobuf3 := proto.useProtobuf3()
- if useProtobuf3 == true {
- deps.Rustlibs = append(deps.Rustlibs, "libprotobuf")
- } else {
- deps.Rustlibs = append(deps.Rustlibs, "libprotobuf_deprecated")
- }
+ deps.Rustlibs = append(deps.Rustlibs, "libprotobuf")
deps.HeaderLibs = append(deps.SharedLibs, proto.Properties.Header_libs...)
if len(proto.Properties.Grpc_protos) > 0 {
- if useProtobuf3 == true {
- ctx.PropertyErrorf("protos", "rust_protobuf with grpc_protos defined must currently use "+
- "`use_protobuf3: false,` in the Android.bp file. This is temporary until the "+
- "grpcio crate is updated to use the current version of the protobuf crate.")
- }
deps.Rustlibs = append(deps.Rustlibs, "libgrpcio", "libfutures")
deps.HeaderLibs = append(deps.HeaderLibs, "libprotobuf-cpp-full")
}
diff --git a/rust/protobuf_test.go b/rust/protobuf_test.go
index 9dca029..b375a64 100644
--- a/rust/protobuf_test.go
+++ b/rust/protobuf_test.go
@@ -21,54 +21,6 @@
"android/soong/android"
)
-func TestRustProtobuf(t *testing.T) {
- ctx := testRust(t, `
- rust_protobuf {
- name: "librust_proto",
- protos: ["buf.proto", "proto.proto"],
- crate_name: "rust_proto",
- source_stem: "buf",
- shared_libs: ["libfoo_shared"],
- static_libs: ["libfoo_static"],
- }
- cc_library_shared {
- name: "libfoo_shared",
- export_include_dirs: ["shared_include"],
- }
- cc_library_static {
- name: "libfoo_static",
- export_include_dirs: ["static_include"],
- }
- `)
- // Check that libprotobuf is added as a dependency.
- librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_dylib").Module().(*Module)
- if !android.InList("libprotobuf_deprecated", librust_proto.Properties.AndroidMkDylibs) {
- t.Errorf("libprotobuf_deprecated dependency missing for rust_protobuf (dependency missing from AndroidMkDylibs)")
- }
-
- // Make sure the correct plugin is being used.
- librust_proto_out := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("buf.rs")
- cmd := librust_proto_out.RuleParams.Command
- if w := "protoc-gen-rust-deprecated"; !strings.Contains(cmd, w) {
- t.Errorf("expected %q in %q", w, cmd)
- }
-
- // Check exported include directories
- if w := "-Ishared_include"; !strings.Contains(cmd, w) {
- t.Errorf("expected %q in %q", w, cmd)
- }
- if w := "-Istatic_include"; !strings.Contains(cmd, w) {
- t.Errorf("expected %q in %q", w, cmd)
- }
-
- // Check proto.rs, the second protobuf, is listed as an output
- librust_proto_outputs := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").AllOutputs()
- if android.InList("proto.rs", librust_proto_outputs) {
- t.Errorf("rust_protobuf is not producing multiple outputs; expected 'proto.rs' in list, got: %#v ",
- librust_proto_outputs)
- }
-}
-
func TestRustProtobuf3(t *testing.T) {
ctx := testRust(t, `
rust_protobuf {
diff --git a/rust/rust.go b/rust/rust.go
index 521f624..6f4631d 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -23,7 +23,6 @@
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/cc"
cc_config "android/soong/cc/config"
@@ -1007,7 +1006,7 @@
android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
}
- aconfig.CollectDependencyAconfigFiles(ctx, &mod.mergedAconfigFiles)
+ android.CollectDependencyAconfigFiles(ctx, &mod.mergedAconfigFiles)
}
func (mod *Module) deps(ctx DepsContext) Deps {
diff --git a/rust/testing.go b/rust/testing.go
index 3fe751e..0b34c97 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -133,12 +133,6 @@
host_supported: true,
}
rust_library {
- name: "libprotobuf_deprecated",
- crate_name: "protobuf",
- srcs: ["foo.rs"],
- host_supported: true,
- }
- rust_library {
name: "libgrpcio",
crate_name: "grpcio",
srcs: ["foo.rs"],
diff --git a/ui/terminal/format.go b/ui/terminal/format.go
index 5391023..241a1dd 100644
--- a/ui/terminal/format.go
+++ b/ui/terminal/format.go
@@ -25,7 +25,6 @@
type formatter struct {
format string
quiet bool
- smart bool
start time.Time
}
@@ -33,11 +32,10 @@
// the terminal in a format similar to Ninja.
// format takes nearly all the same options as NINJA_STATUS.
// %c is currently unsupported.
-func newFormatter(format string, quiet bool, smart bool) formatter {
+func newFormatter(format string, quiet bool) formatter {
return formatter{
format: format,
quiet: quiet,
- smart: smart,
start: time.Now(),
}
}
@@ -63,9 +61,8 @@
func (s formatter) progress(counts status.Counts) string {
if s.format == "" {
output := fmt.Sprintf("[%3d%% %d/%d", 100*counts.FinishedActions/counts.TotalActions, counts.FinishedActions, counts.TotalActions)
- // Not to break parsing logic in the build bot
- // TODO(b/313981966): make buildbot more flexible for output format
- if s.smart && !counts.EstimatedTime.IsZero() {
+
+ if !counts.EstimatedTime.IsZero() {
output += fmt.Sprintf(" %s remaining", remainingTimeString(counts.EstimatedTime))
}
output += "] "
diff --git a/ui/terminal/status.go b/ui/terminal/status.go
index 810e3c9..2ad174f 100644
--- a/ui/terminal/status.go
+++ b/ui/terminal/status.go
@@ -27,10 +27,9 @@
// statusFormat takes nearly all the same options as NINJA_STATUS.
// %c is currently unsupported.
func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild, forceKeepANSI bool) status.StatusOutput {
- useSmartStatus := !forceSimpleOutput && isSmartTerminal(w)
- formatter := newFormatter(statusFormat, quietBuild, useSmartStatus)
+ formatter := newFormatter(statusFormat, quietBuild)
- if useSmartStatus {
+ if !forceSimpleOutput && isSmartTerminal(w) {
return NewSmartStatusOutput(w, formatter)
} else {
return NewSimpleStatusOutput(w, formatter, forceKeepANSI)