Merge "Fix characteristic rro for overridden packages" into main
diff --git a/aconfig/codegen/Android.bp b/aconfig/codegen/Android.bp
index 494f7e6..0c78b94 100644
--- a/aconfig/codegen/Android.bp
+++ b/aconfig/codegen/Android.bp
@@ -17,6 +17,7 @@
"soong-rust",
],
srcs: [
+ "aconfig_declarations_group.go",
"cc_aconfig_library.go",
"init.go",
"java_aconfig_library.go",
@@ -24,6 +25,7 @@
"testing.go",
],
testSrcs: [
+ "aconfig_declarations_group_test.go",
"java_aconfig_library_test.go",
"cc_aconfig_library_test.go",
"rust_aconfig_library_test.go",
diff --git a/aconfig/codegen/aconfig_declarations_group.go b/aconfig/codegen/aconfig_declarations_group.go
new file mode 100644
index 0000000..203b6be
--- /dev/null
+++ b/aconfig/codegen/aconfig_declarations_group.go
@@ -0,0 +1,129 @@
+// Copyright 2024 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 codegen
+
+import (
+ "android/soong/aconfig"
+ "android/soong/android"
+ "fmt"
+
+ "github.com/google/blueprint"
+)
+
+type dependencyTag struct {
+ blueprint.BaseDependencyTag
+ name string
+}
+
+var (
+ aconfigDeclarationsGroupTag = dependencyTag{name: "aconfigDeclarationsGroup"}
+ javaAconfigLibraryTag = dependencyTag{name: "javaAconfigLibrary"}
+ ccAconfigLibraryTag = dependencyTag{name: "ccAconfigLibrary"}
+ rustAconfigLibraryTag = dependencyTag{name: "rustAconfigLibrary"}
+)
+
+type AconfigDeclarationsGroup struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ properties AconfigDeclarationsGroupProperties
+
+ aconfigDeclarationNames []string
+ intermediateCacheOutputPaths android.Paths
+ javaSrcjars android.Paths
+}
+
+type AconfigDeclarationsGroupProperties struct {
+
+ // Name of the aconfig_declarations_group modules
+ Aconfig_declarations_groups []string
+
+ // Name of the java_aconfig_library modules
+ Java_aconfig_libraries []string
+
+ // Name of the cc_aconfig_library modules
+ Cc_aconfig_libraries []string
+
+ // Name of the rust_aconfig_library modules
+ Rust_aconfig_libraries []string
+}
+
+func AconfigDeclarationsGroupFactory() android.Module {
+ module := &AconfigDeclarationsGroup{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidModule(module)
+ android.InitDefaultableModule(module)
+ return module
+}
+
+func (adg *AconfigDeclarationsGroup) DepsMutator(ctx android.BottomUpMutatorContext) {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationsGroupTag, adg.properties.Aconfig_declarations_groups...)
+ ctx.AddDependency(ctx.Module(), javaAconfigLibraryTag, adg.properties.Java_aconfig_libraries...)
+ ctx.AddDependency(ctx.Module(), ccAconfigLibraryTag, adg.properties.Cc_aconfig_libraries...)
+ ctx.AddDependency(ctx.Module(), rustAconfigLibraryTag, adg.properties.Rust_aconfig_libraries...)
+}
+
+func (adg *AconfigDeclarationsGroup) VisitDeps(ctx android.ModuleContext) {
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ tag := ctx.OtherModuleDependencyTag(dep)
+ if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+
+ // aconfig declaration names and cache files are collected for all aconfig library dependencies
+ adg.aconfigDeclarationNames = append(adg.aconfigDeclarationNames, provider.AconfigDeclarations...)
+ adg.intermediateCacheOutputPaths = append(adg.intermediateCacheOutputPaths, provider.IntermediateCacheOutputPaths...)
+
+ switch tag {
+ case aconfigDeclarationsGroupTag:
+ // Will retrieve outputs from another language codegen modules when support is added
+ adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+ case javaAconfigLibraryTag:
+ adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+ }
+ }
+ })
+}
+
+func (adg *AconfigDeclarationsGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ adg.VisitDeps(ctx)
+ adg.aconfigDeclarationNames = android.FirstUniqueStrings(adg.aconfigDeclarationNames)
+ adg.intermediateCacheOutputPaths = android.FirstUniquePaths(adg.intermediateCacheOutputPaths)
+
+ android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+ AconfigDeclarations: adg.aconfigDeclarationNames,
+ IntermediateCacheOutputPaths: adg.intermediateCacheOutputPaths,
+ Srcjars: adg.javaSrcjars,
+ })
+}
+
+var _ android.OutputFileProducer = (*AconfigDeclarationsGroup)(nil)
+
+func (adg *AconfigDeclarationsGroup) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return adg.intermediateCacheOutputPaths, nil
+ case ".srcjars":
+ return adg.javaSrcjars, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %s", tag)
+ }
+}
+
+func (adg *AconfigDeclarationsGroup) Srcjars() android.Paths {
+ return adg.javaSrcjars
+}
+
+func (adg *AconfigDeclarationsGroup) AconfigDeclarations() []string {
+ return adg.aconfigDeclarationNames
+}
diff --git a/aconfig/codegen/aconfig_declarations_group_test.go b/aconfig/codegen/aconfig_declarations_group_test.go
new file mode 100644
index 0000000..ec7cea3
--- /dev/null
+++ b/aconfig/codegen/aconfig_declarations_group_test.go
@@ -0,0 +1,79 @@
+// Copyright 2024 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 codegen
+
+import (
+ "android/soong/android"
+ "android/soong/java"
+ "testing"
+)
+
+func TestAconfigDeclarationsGroup(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ aconfig_declarations {
+ name: "foo-aconfig",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "foo-java",
+ aconfig_declarations: "foo-aconfig",
+ }
+
+ aconfig_declarations {
+ name: "bar-aconfig",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "bar-java",
+ aconfig_declarations: "bar-aconfig",
+ }
+
+ aconfig_declarations_group {
+ name: "my_group",
+ java_aconfig_libraries: [
+ "foo-java",
+ "bar-java",
+ ],
+ }
+
+ java_library {
+ name: "baz",
+ srcs: [
+ ":my_group{.srcjars}",
+ ],
+ }
+ `)
+
+ // Check if aconfig_declarations_group module depends on the aconfig_library modules
+ java.CheckModuleDependencies(t, result.TestContext, "my_group", "", []string{
+ `bar-java`,
+ `foo-java`,
+ })
+
+ // Check if srcjar files are correctly passed to the reverse dependency of
+ // aconfig_declarations_group module
+ bazModule := result.ModuleForTests("baz", "android_common")
+ bazJavacSrcjars := bazModule.Rule("javac").Args["srcJars"]
+ errorMessage := "baz javac argument expected to contain srcjar provided by aconfig_declrations_group"
+ android.AssertStringDoesContain(t, errorMessage, bazJavacSrcjars, "foo-java.srcjar")
+ android.AssertStringDoesContain(t, errorMessage, bazJavacSrcjars, "bar-java.srcjar")
+}
diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go
index 0bff9d2..73a8951 100644
--- a/aconfig/codegen/init.go
+++ b/aconfig/codegen/init.go
@@ -77,6 +77,7 @@
}
func RegisterBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("aconfig_declarations_group", AconfigDeclarationsGroupFactory)
ctx.RegisterModuleType("cc_aconfig_library", CcAconfigLibraryFactory)
ctx.RegisterModuleType("java_aconfig_library", JavaDeclarationsLibraryFactory)
ctx.RegisterModuleType("rust_aconfig_library", RustAconfigLibraryFactory)
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index d4c6da5..7d7296e 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -17,6 +17,7 @@
import (
"fmt"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/java"
@@ -118,6 +119,12 @@
module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "")
}
+ android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+ AconfigDeclarations: []string{declarationsModules[0].Name()},
+ IntermediateCacheOutputPaths: android.Paths{declarations.IntermediateCacheOutputPath},
+ Srcjars: android.Paths{srcJarPath},
+ })
+
return srcJarPath
}
diff --git a/aconfig/init.go b/aconfig/init.go
index 77f5ed3..16fb0cd 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -20,6 +20,20 @@
"github.com/google/blueprint"
)
+type CodegenInfo struct {
+ // AconfigDeclarations is the name of the aconfig_declarations modules that
+ // the codegen module is associated with
+ AconfigDeclarations []string
+
+ // Paths to the cache files of the associated aconfig_declaration modules
+ IntermediateCacheOutputPaths android.Paths
+
+ // Paths to the srcjar files generated from the java_aconfig_library modules
+ Srcjars android.Paths
+}
+
+var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]()
+
var (
pctx = android.NewPackageContext("android/soong/aconfig")
diff --git a/android/all_teams.go b/android/all_teams.go
index dd7d2db..b177e20 100644
--- a/android/all_teams.go
+++ b/android/all_teams.go
@@ -68,10 +68,6 @@
this.teams_for_mods = make(map[string]moduleTeamInfo)
ctx.VisitAllModules(func(module Module) {
- if !module.Enabled() {
- return
- }
-
bpFile := ctx.BlueprintFile(module)
// Package Modules and Team Modules are stored in a map so we can look them up by name for
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index 236abf6..89e27b9 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -98,6 +98,10 @@
func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
for _, content := range m.Contents() {
+ // Skip any apexes that have been added to the product specific ignore list
+ if InList(content, ctx.Config().BuildIgnoreApexContributionContents()) {
+ continue
+ }
if !ctx.OtherModuleExists(content) && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
}
diff --git a/android/config.go b/android/config.go
index e57bc2c..afcebf5 100644
--- a/android/config.go
+++ b/android/config.go
@@ -2044,3 +2044,7 @@
}
return ret
}
+
+func (c *config) BuildIgnoreApexContributionContents() []string {
+ return c.productVariables.BuildIgnoreApexContributionContents
+}
diff --git a/android/variable.go b/android/variable.go
index 758967e..2520020 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -494,6 +494,8 @@
BuildFlags map[string]string `json:",omitempty"`
BuildFromSourceStub *bool `json:",omitempty"`
+
+ BuildIgnoreApexContributionContents []string `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
diff --git a/java/aar.go b/java/aar.go
index f61fc83..146b173 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -23,6 +23,7 @@
"android/soong/android"
"android/soong/dexpreopt"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -414,17 +415,11 @@
linkFlags = append(linkFlags, "--static-lib")
}
+ linkFlags = append(linkFlags, "--no-static-lib-packages")
if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
- // When building an android_library using ResourceProcessorBusyBox the resources are merged into
- // package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
- // contains resources from this library.
+ // When building an android_library using ResourceProcessorBusyBox pass --merge-only to skip resource
+ // references validation until the final app link step when all static libraries are present.
linkFlags = append(linkFlags, "--merge-only")
- } else {
- // When building and app or when building an android_library without ResourceProcessorBusyBox
- // --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
- // is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
- // sort resources into the right packages in R.class.
- linkFlags = append(linkFlags, "--no-static-lib-packages")
}
packageRes := android.PathForModuleOut(ctx, "package-res.apk")
@@ -1177,6 +1172,7 @@
"--static-lib",
"--merge-only",
"--auto-add-overlay",
+ "--no-static-lib-packages",
}
linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
@@ -1250,6 +1246,7 @@
TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
ImplementationJars: android.PathsIfNonNil(a.classpathFile),
+ StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
diff --git a/java/base.go b/java/base.go
index 4e2366f..e2c4d32 100644
--- a/java/base.go
+++ b/java/base.go
@@ -205,6 +205,13 @@
// Note that currently not all actions implemented by android_apps are sandboxed, so you
// may only see this being necessary in lint builds.
Compile_data []string `android:"path"`
+
+ // Property signifying whether the module compiles stubs or not.
+ // Should be set to true when srcs of this module are stub files.
+ // This property does not need to be set to true when the module depends on
+ // the stubs via libs, but should be set to true when the module depends on
+ // the stubs via static libs.
+ Is_stubs_module *bool
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -532,6 +539,8 @@
// Values that will be set in the JarJarProvider data for jarjar repackaging,
// and merged with our dependencies' rules.
jarjarRenameRules map[string]string
+
+ stubsLinkType StubsLinkType
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -1212,6 +1221,7 @@
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ StubsLinkType: j.stubsLinkType,
})
j.outputFile = j.headerJarFile
@@ -1729,6 +1739,7 @@
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
JacocoReportClassesFile: j.jacocoReportClassesFile,
+ StubsLinkType: j.stubsLinkType,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -2372,11 +2383,26 @@
// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
// be renamed from that module.
// TODO: Add another property to suppress the forwarding of
+type DependencyUse int
+
+const (
+ RenameUseInvalid DependencyUse = iota
+ RenameUseInclude
+ RenameUseExclude
+)
+
+type RenameUseElement struct {
+ DepName string
+ RenameUse DependencyUse
+ Why string // token for determining where in the logic the decision was made.
+}
+
type JarJarProviderData struct {
// Mapping of class names: original --> renamed. If the value is "", the class will be
// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
// attribute). Rdeps of that module will inherit the renaming.
- Rename map[string]string
+ Rename map[string]string
+ RenameUse []RenameUseElement
}
func (this JarJarProviderData) GetDebugString() string {
@@ -2440,17 +2466,112 @@
func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
// Gather repackage information from deps
// If the dep jas a JarJarProvider, it is used. Otherwise, any BaseJarJarProvider is used.
+
+ module := ctx.Module()
+ moduleName := module.Name()
+
ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
- if ctx.OtherModuleDependencyTag(m) == proguardRaiseTag {
- return
- }
- merge := func(theirs *JarJarProviderData) {
- for orig, renamed := range theirs.Rename {
- if result == nil {
- result = &JarJarProviderData{
- Rename: make(map[string]string),
+ tag := ctx.OtherModuleDependencyTag(m)
+ // This logic mirrors that in (*Module).collectDeps above. There are several places
+ // where we explicitly return RenameUseExclude, even though it is the default, to
+ // indicate that it has been verified to be the case.
+ //
+ // Note well: there are probably cases that are getting to the unconditional return
+ // and are therefore wrong.
+ shouldIncludeRenames := func() (DependencyUse, string) {
+ if moduleName == m.Name() {
+ return RenameUseInclude, "name" // If we have the same module name, include the renames.
+ }
+ if sc, ok := module.(android.SdkContext); ok {
+ if ctx.Device() {
+ sdkDep := decodeSdkDep(ctx, sc)
+ if !sdkDep.invalidVersion && sdkDep.useFiles {
+ return RenameUseExclude, "useFiles"
}
}
+ }
+ if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
+ return RenameUseExclude, "tags"
+ }
+ if _, ok := m.(SdkLibraryDependency); ok {
+ switch tag {
+ case sdkLibTag, libTag:
+ return RenameUseExclude, "sdklibdep" // matches collectDeps()
+ }
+ return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
+ } else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ switch ji.StubsLinkType {
+ case Stubs:
+ return RenameUseExclude, "info"
+ case Implementation:
+ return RenameUseInclude, "info"
+ default:
+ //fmt.Printf("LJ: %v -> %v StubsLinkType unknown\n", module, m)
+ // Fall through to the heuristic logic.
+ }
+ switch reflect.TypeOf(m).String() {
+ case "*java.GeneratedJavaLibraryModule":
+ // Probably a java_aconfig_library module.
+ // TODO: make this check better.
+ return RenameUseInclude, "reflect"
+ }
+ switch tag {
+ case bootClasspathTag:
+ return RenameUseExclude, "tagswitch"
+ case sdkLibTag, libTag, instrumentationForTag:
+ return RenameUseInclude, "tagswitch"
+ case java9LibTag:
+ return RenameUseExclude, "tagswitch"
+ case staticLibTag:
+ return RenameUseInclude, "tagswitch"
+ case pluginTag:
+ return RenameUseInclude, "tagswitch"
+ case errorpronePluginTag:
+ return RenameUseInclude, "tagswitch"
+ case exportedPluginTag:
+ return RenameUseInclude, "tagswitch"
+ case kotlinStdlibTag, kotlinAnnotationsTag:
+ return RenameUseExclude, "tagswitch"
+ case kotlinPluginTag:
+ return RenameUseInclude, "tagswitch"
+ default:
+ return RenameUseExclude, "tagswitch"
+ }
+ } else if _, ok := m.(android.SourceFileProducer); ok {
+ switch tag {
+ case sdkLibTag, libTag, staticLibTag:
+ return RenameUseInclude, "srcfile"
+ default:
+ return RenameUseExclude, "srcfile"
+ }
+ } else {
+ switch tag {
+ case bootClasspathTag:
+ return RenameUseExclude, "else"
+ case systemModulesTag:
+ return RenameUseInclude, "else"
+ }
+ }
+ // If we got here, choose the safer option, which may lead to a build failure, rather
+ // than runtime failures on the device.
+ return RenameUseExclude, "end"
+ }
+
+ if result == nil {
+ result = &JarJarProviderData{
+ Rename: make(map[string]string),
+ RenameUse: make([]RenameUseElement, 0),
+ }
+ }
+ how, why := shouldIncludeRenames()
+ result.RenameUse = append(result.RenameUse, RenameUseElement{DepName: m.Name(), RenameUse: how, Why: why})
+ if how != RenameUseInclude {
+ // Nothing to merge.
+ return
+ }
+
+ merge := func(theirs *JarJarProviderData) {
+ for orig, renamed := range theirs.Rename {
if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
result.Rename[orig] = renamed
} else if preexisting != "" && renamed != "" && preexisting != renamed {
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index efd13b8..3f8735c 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -137,6 +137,7 @@
ResourceJars: d.resourceJars,
SrcJarArgs: d.srcJarArgs,
SrcJarDeps: d.srcJarDeps,
+ StubsLinkType: Implementation,
// TODO: Not sure if aconfig flags that have been moved between device and host variants
// make sense.
})
diff --git a/java/droiddoc.go b/java/droiddoc.go
index cfbf2b4..6a66f45 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -21,6 +21,7 @@
"github.com/google/blueprint/proptools"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/java/config"
)
@@ -413,9 +414,12 @@
case aconfigDeclarationTag:
if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, aconfig.CodegenInfoProvider); ok {
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
} else {
- ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
- "flags_packages property, but %s is not aconfig_declarations module type",
+ ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
+ "module type is allowed for flags_packages property, but %s is neither "+
+ "of these supported module types",
module.Name(),
)
}
diff --git a/java/java.go b/java/java.go
index d7d271c..1a266b8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -87,6 +87,14 @@
android.RegisterSdkMemberType(javaTestSdkMemberType)
}
+type StubsLinkType int
+
+const (
+ Unknown StubsLinkType = iota
+ Stubs
+ Implementation
+)
+
var (
// Supports adding java header libraries to module_exports and sdk.
javaHeaderLibsSdkMemberType = &librarySdkMemberType{
@@ -296,6 +304,11 @@
// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
// instrumented by jacoco.
JacocoReportClassesFile android.Path
+
+ // StubsLinkType provides information about whether the provided jars are stub jars or
+ // implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
+ // and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
+ StubsLinkType StubsLinkType
}
var JavaInfoProvider = blueprint.NewProvider[JavaInfo]()
@@ -694,6 +707,17 @@
j.minSdkVersion = j.MinSdkVersion(ctx)
j.maxSdkVersion = j.MaxSdkVersion(ctx)
+ // SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown.
+ // If the stubsLinkType has already been set to Unknown, the stubsLinkType should
+ // not be overridden.
+ if j.stubsLinkType != Unknown {
+ if proptools.Bool(j.properties.Is_stubs_module) {
+ j.stubsLinkType = Stubs
+ } else {
+ j.stubsLinkType = Implementation
+ }
+ }
+
j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
proguardSpecInfo := j.collectProguardSpecInfo(ctx)
@@ -2018,6 +2042,7 @@
ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar),
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
AidlIncludeDirs: android.Paths{},
+ StubsLinkType: Stubs,
// No aconfig libraries on api libraries
})
}
@@ -2102,6 +2127,9 @@
// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
// (without any prebuilt_ prefix)
Created_by_java_sdk_library_name *string `blueprint:"mutated"`
+
+ // Property signifying whether the module provides stubs jar or not.
+ Is_stubs_module *bool
}
type Import struct {
@@ -2132,6 +2160,8 @@
sdkVersion android.SdkSpec
minSdkVersion android.ApiLevel
+
+ stubsLinkType StubsLinkType
}
var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)
@@ -2226,6 +2256,12 @@
if ctx.Windows() {
j.HideFromMake()
}
+
+ if proptools.Bool(j.properties.Is_stubs_module) {
+ j.stubsLinkType = Stubs
+ } else {
+ j.stubsLinkType = Implementation
+ }
}
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -2359,6 +2395,7 @@
ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
+ StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index fbde042..2e4f2e3 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1572,6 +1572,8 @@
// Only build an implementation library if required.
if module.requiresRuntimeImplementationLibrary() {
+ // stubsLinkType must be set before calling Library.GenerateAndroidBuildActions
+ module.Library.stubsLinkType = Unknown
module.Library.GenerateAndroidBuildActions(ctx)
}
@@ -1797,6 +1799,7 @@
Dir *string
Tag *string
}
+ Is_stubs_module *bool
}
func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
@@ -1821,6 +1824,7 @@
// We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
// interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8")
+ props.Is_stubs_module = proptools.BoolPtr(true)
return props
}
@@ -2709,6 +2713,7 @@
Libs []string
Jars []string
Compile_dex *bool
+ Is_stubs_module *bool
android.UserSuppliedPrebuiltProperties
}{}
@@ -2730,6 +2735,7 @@
compileDex = proptools.BoolPtr(true)
}
props.Compile_dex = compileDex
+ props.Is_stubs_module = proptools.BoolPtr(true)
mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
diff --git a/rust/builder.go b/rust/builder.go
index c855cfb..65995ed 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -122,8 +122,6 @@
func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
-
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin")
}
@@ -134,20 +132,16 @@
func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
-
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "dylib")
}
func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib")
}
func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib")
}
@@ -263,6 +257,21 @@
inputs = append(inputs, main)
+ if ctx.Config().Eng() {
+ // Per https://doc.rust-lang.org/rustc/codegen-options/index.html#codegen-units
+ // incremental building implies codegen-units=256
+ incrementalPath := android.PathForModuleOut(ctx, "rustc-incremental").String()
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C incremental="+incrementalPath)
+
+ } else {
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C codegen-units=1")
+
+ if !(ctx.RustModule().Rlib() || ctx.RustModule().ProcMacro()) {
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-Z dylib-lto")
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ }
+ }
+
// Collect rustc flags
rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
rustcFlags = append(rustcFlags, flags.RustFlags...)
@@ -278,15 +287,6 @@
// Suppress an implicit sysroot
rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
- // Enable incremental compilation if requested by user
- if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
- incrementalPath := android.PathForOutput(ctx, "rustc").String()
-
- rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath)
- } else {
- rustcFlags = append(rustcFlags, "-C codegen-units=1")
- }
-
// Disallow experimental features
modulePath := ctx.ModuleDir()
if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {