diff options
-rw-r--r-- | aconfig/codegen/Android.bp | 2 | ||||
-rw-r--r-- | aconfig/codegen/aconfig_declarations_group.go | 129 | ||||
-rw-r--r-- | aconfig/codegen/aconfig_declarations_group_test.go | 79 | ||||
-rw-r--r-- | aconfig/codegen/init.go | 1 | ||||
-rw-r--r-- | aconfig/codegen/java_aconfig_library.go | 7 | ||||
-rw-r--r-- | aconfig/init.go | 14 | ||||
-rw-r--r-- | android/all_teams.go | 4 | ||||
-rw-r--r-- | android/apex_contributions.go | 4 | ||||
-rw-r--r-- | android/config.go | 4 | ||||
-rw-r--r-- | android/variable.go | 2 | ||||
-rw-r--r-- | java/aar.go | 15 | ||||
-rw-r--r-- | java/base.go | 135 | ||||
-rw-r--r-- | java/device_host_converter.go | 1 | ||||
-rw-r--r-- | java/droiddoc.go | 8 | ||||
-rw-r--r-- | java/java.go | 37 | ||||
-rw-r--r-- | java/sdk_library.go | 6 | ||||
-rw-r--r-- | rust/builder.go | 30 |
17 files changed, 441 insertions, 37 deletions
diff --git a/aconfig/codegen/Android.bp b/aconfig/codegen/Android.bp index 494f7e693..0c78b946b 100644 --- a/aconfig/codegen/Android.bp +++ b/aconfig/codegen/Android.bp @@ -17,6 +17,7 @@ bootstrap_go_package { "soong-rust", ], srcs: [ + "aconfig_declarations_group.go", "cc_aconfig_library.go", "init.go", "java_aconfig_library.go", @@ -24,6 +25,7 @@ bootstrap_go_package { "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 000000000..203b6be6f --- /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 000000000..ec7cea383 --- /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 0bff9d2af..73a89514d 100644 --- a/aconfig/codegen/init.go +++ b/aconfig/codegen/init.go @@ -77,6 +77,7 @@ func init() { } 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 d4c6da574..7d7296e6a 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -17,6 +17,7 @@ package codegen import ( "fmt" + "android/soong/aconfig" "android/soong/android" "android/soong/java" @@ -118,6 +119,12 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild 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 77f5ed363..16fb0cd9b 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -20,6 +20,20 @@ import ( "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 dd7d2db33..b177e20e7 100644 --- a/android/all_teams.go +++ b/android/all_teams.go @@ -68,10 +68,6 @@ func (this *allTeamsSingleton) GenerateBuildActions(ctx SingletonContext) { 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 236abf663..89e27b97b 100644 --- a/android/apex_contributions.go +++ b/android/apex_contributions.go @@ -98,6 +98,10 @@ func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) { 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 e57bc2cbd..afcebf5e9 100644 --- a/android/config.go +++ b/android/config.go @@ -2044,3 +2044,7 @@ func (c *config) AllApexContributions() []string { } return ret } + +func (c *config) BuildIgnoreApexContributionContents() []string { + return c.productVariables.BuildIgnoreApexContributionContents +} diff --git a/android/variable.go b/android/variable.go index 758967e23..252002037 100644 --- a/android/variable.go +++ b/android/variable.go @@ -494,6 +494,8 @@ type ProductVariables struct { 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 f61fc8374..146b17319 100644 --- a/java/aar.go +++ b/java/aar.go @@ -23,6 +23,7 @@ import ( "android/soong/android" "android/soong/dexpreopt" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -414,17 +415,11 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio 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 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { "--static-lib", "--merge-only", "--auto-add-overlay", + "--no-static-lib-packages", } linkFlags = append(linkFlags, "--manifest "+a.manifest.String()) @@ -1250,6 +1246,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 4e2366f7d..e2c4d327b 100644 --- a/java/base.go +++ b/java/base.go @@ -205,6 +205,13 @@ type CommonProperties struct { // 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 @@ type Module struct { // 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 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath ExportedPlugins: j.exportedPluginJars, ExportedPluginClasses: j.exportedPluginClasses, ExportedPluginDisableTurbine: j.exportedDisableTurbine, + StubsLinkType: j.stubsLinkType, }) j.outputFile = j.headerJarFile @@ -1729,6 +1739,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath 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 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { // 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 (module *Module) addJarJarRenameRule(original string, renamed string) { 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 { + 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 result == nil { - result = &JarJarProviderData{ - Rename: make(map[string]string), - } - } 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 efd13b8d3..3f8735c0c 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -137,6 +137,7 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont 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 cfbf2b49c..6a66f45ec 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -21,6 +21,7 @@ import ( "github.com/google/blueprint/proptools" + "android/soong/aconfig" "android/soong/android" "android/soong/java/config" ) @@ -413,9 +414,12 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { 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 d7d271cca..1a266b859 100644 --- a/java/java.go +++ b/java/java.go @@ -87,6 +87,14 @@ func RegisterJavaSdkMemberTypes() { 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 @@ type JavaInfo struct { // 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 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 @@ type ImportProperties struct { // 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 @@ type Import struct { sdkVersion android.SdkSpec minSdkVersion android.ApiLevel + + stubsLinkType StubsLinkType } var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) @@ -2226,6 +2256,12 @@ func (j *Import) commonBuildActions(ctx android.ModuleContext) { 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 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 fbde04276..2e4f2e349 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1572,6 +1572,8 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) // 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 @@ type libraryProperties struct { Dir *string Tag *string } + Is_stubs_module *bool } func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties { @@ -1821,6 +1824,7 @@ func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, // 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 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl Libs []string Jars []string Compile_dex *bool + Is_stubs_module *bool android.UserSuppliedPrebuiltProperties }{} @@ -2730,6 +2735,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl 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 c855cfbd2..65995ed2a 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -122,8 +122,6 @@ func init() { 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 TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, 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 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl 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 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl // 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")) { |