diff options
| -rw-r--r-- | android/all_teams.go | 4 | ||||
| -rw-r--r-- | java/aar.go | 15 | ||||
| -rwxr-xr-x | java/app.go | 5 | ||||
| -rw-r--r-- | java/base.go | 135 | ||||
| -rw-r--r-- | java/device_host_converter.go | 1 | ||||
| -rw-r--r-- | java/java.go | 37 | ||||
| -rw-r--r-- | java/sdk_library.go | 6 |
7 files changed, 181 insertions, 22 deletions
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/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/app.go b/java/app.go index 9be3f6d50..05f042d7f 100755 --- a/java/app.go +++ b/java/app.go @@ -472,8 +472,9 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided. autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro) hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product") - if !autogenerateRRO && !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 { - aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics()) + characteristics := ctx.Config().ProductAAPTCharacteristics() + if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" { + aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics) } if !Bool(a.aaptProperties.Aapt_include_all_resources) { 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/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()) } |