diff options
65 files changed, 1230 insertions, 1045 deletions
diff --git a/Android.bp b/Android.bp index 535246e65..ab8e4a086 100644 --- a/Android.bp +++ b/Android.bp @@ -3,6 +3,7 @@ package { default_visibility: [ "//build/soong:__subpackages__", ], + default_team: "trendy_team_build", } subdirs = [ @@ -116,6 +117,11 @@ dex_bootjars { visibility: ["//visibility:public"], } +art_boot_images { + name: "art_boot_images", + visibility: ["//art:__subpackages__"], +} + // Pseudo-test that's run on checkbuilds to ensure that get_clang_version can // parse cc/config/global.go. genrule { @@ -136,9 +142,13 @@ all_apex_contributions { visibility: ["//visibility:public"], } +// TODO(b/365670526): remove the cuttlefish visibility once it is fully removed product_config { name: "product_config", - visibility: ["//device/google/cuttlefish/system_image"], + visibility: [ + "//build/make/target/product/generic", + "//device/google/cuttlefish/system_image", + ], } build_prop { @@ -147,6 +157,7 @@ build_prop { product_config: ":product_config", // Currently, only microdroid and cf system image can refer to system-build.prop visibility: [ + "//build/make/target/product/generic", "//device/google/cuttlefish/system_image", "//packages/modules/Virtualization/build/microdroid", ], diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go index 98d288f0a..ed0b3ed7f 100644 --- a/aconfig/codegen/init.go +++ b/aconfig/codegen/init.go @@ -32,6 +32,7 @@ var ( ` --mode ${mode}` + ` --cache ${in}` + ` --out ${out}.tmp` + + ` --allow-instrumentation ${debug}` + ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` + ` && rm -rf ${out}.tmp`, CommandDeps: []string{ @@ -39,7 +40,7 @@ var ( "$soong_zip", }, Restat: true, - }, "mode") + }, "mode", "debug") // For cc_aconfig_library: Generate C++ library cppRule = pctx.AndroidStaticRule("cc_aconfig_library", diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index 673ac2afe..ebca4134c 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -20,6 +20,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/proptools" + "strconv" ) type declarationsTagType struct { @@ -71,6 +72,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) DepsMutator(module *ja module.AddSharedLibrary("aconfig-annotations-lib") // TODO(b/303773055): Remove the annotation after access issue is resolved. module.AddSharedLibrary("unsupportedappusage") + module.AddSharedLibrary("aconfig_storage_reader_java") } } @@ -102,7 +104,8 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild Output: srcJarPath, Description: "aconfig.srcjar", Args: map[string]string{ - "mode": mode, + "mode": mode, + "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()), }, }) diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index d2a9622e3..b902f8be5 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -107,7 +107,7 @@ func aconfigUpdateAndroidBuildActions(ctx ModuleContext) { mergedAconfigFiles := make(map[string]Paths) mergedModeInfos := make(map[string]ModeInfo) - ctx.VisitDirectDepsIgnoreBlueprint(func(module Module) { + ctx.VisitDirectDeps(func(module Module) { if aconfig_dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok && len(aconfig_dep.ModeInfos) > 0 { maps.Copy(mergedModeInfos, aconfig_dep.ModeInfos) } diff --git a/android/apex.go b/android/apex.go index 114fe2988..79ab13caf 100644 --- a/android/apex.go +++ b/android/apex.go @@ -989,8 +989,8 @@ func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, minSdkVersion // Function called while walking an APEX's payload dependencies. // // Return true if the `to` module should be visited, false otherwise. -type PayloadDepsCallback func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool -type WalkPayloadDepsFunc func(ctx ModuleContext, do PayloadDepsCallback) +type PayloadDepsCallback func(ctx BaseModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool +type WalkPayloadDepsFunc func(ctx BaseModuleContext, do PayloadDepsCallback) // ModuleWithMinSdkVersionCheck represents a module that implements min_sdk_version checks type ModuleWithMinSdkVersionCheck interface { @@ -1017,7 +1017,7 @@ func CheckMinSdkVersion(ctx ModuleContext, minSdkVersion ApiLevel, walk WalkPayl return } - walk(ctx, func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool { + walk(ctx, func(ctx BaseModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool { if externalDep { // external deps are outside the payload boundary, which is "stable" // interface. We don't have to check min_sdk_version for external diff --git a/android/arch.go b/android/arch.go index 942727ace..d9ecb508d 100644 --- a/android/arch.go +++ b/android/arch.go @@ -138,6 +138,13 @@ func (a ArchType) String() string { return a.Name } +func (a ArchType) Bitness() string { + if a.Multilib == "lib32" { + return "32" + } + return "64" +} + const COMMON_VARIANT = "common" var ( diff --git a/android/arch_list.go b/android/arch_list.go index 9501c877c..389f194e8 100644 --- a/android/arch_list.go +++ b/android/arch_list.go @@ -29,6 +29,7 @@ var archVariants = map[ArchType][]string{ "armv9-2a", }, X86: { + "alderlake", "amberlake", "atom", "broadwell", @@ -53,6 +54,7 @@ var archVariants = map[ArchType][]string{ "x86_64", }, X86_64: { + "alderlake", "amberlake", "broadwell", "goldmont", @@ -110,9 +112,6 @@ var cpuVariants = map[ArchType][]string{ } var archFeatures = map[ArchType][]string{ - Arm: { - "neon", - }, Arm64: { "dotprod", }, @@ -142,17 +141,6 @@ var archFeatures = map[ArchType][]string{ } var androidArchFeatureMap = map[ArchType]map[string][]string{ - Arm: { - "armv7-a-neon": { - "neon", - }, - "armv8-a": { - "neon", - }, - "armv8-2a": { - "neon", - }, - }, Arm64: { "armv8-2a-dotprod": { "dotprod", @@ -165,6 +153,16 @@ var androidArchFeatureMap = map[ArchType]map[string][]string{ }, }, X86: { + "alderlake": { + "ssse3", + "sse4", + "sse4_1", + "sse4_2", + "avx", + "avx2", + "aes_ni", + "popcnt", + }, "amberlake": { "ssse3", "sse4", @@ -341,6 +339,16 @@ var androidArchFeatureMap = map[ArchType]map[string][]string{ "sse4_2", "popcnt", }, + "alderlake": { + "ssse3", + "sse4", + "sse4_1", + "sse4_2", + "avx", + "avx2", + "aes_ni", + "popcnt", + }, "amberlake": { "ssse3", "sse4", diff --git a/android/base_module_context.go b/android/base_module_context.go index bb8137720..c7d7573f1 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -113,31 +113,22 @@ type BaseModuleContext interface { // the first DependencyTag. GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) - // VisitDirectDepsBlueprint calls visit for each direct dependency. If there are multiple - // direct dependencies on the same module visit will be called multiple times on that module - // and OtherModuleDependencyTag will return a different tag for each. - // - // The Module passed to the visit function should not be retained outside of the visit - // function, it may be invalidated by future mutators. - VisitDirectDepsBlueprint(visit func(blueprint.Module)) - - // VisitDirectDepsIgnoreBlueprint calls visit for each direct dependency. If there are multiple + // VisitDirectDeps calls visit for each direct dependency. If there are multiple // direct dependencies on the same module visit will be called multiple times on that module - // and OtherModuleDependencyTag will return a different tag for each. It silently ignores any - // dependencies that are not an android.Module. + // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the + // dependencies are disabled. // // The Module passed to the visit function should not be retained outside of the visit // function, it may be invalidated by future mutators. - VisitDirectDepsIgnoreBlueprint(visit func(Module)) + VisitDirectDeps(visit func(Module)) // VisitDirectDeps calls visit for each direct dependency. If there are multiple // direct dependencies on the same module visit will be called multiple times on that module - // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the - // dependencies are not an android.Module. + // and OtherModuleDependencyTag will return a different tag for each. // // The Module passed to the visit function should not be retained outside of the visit // function, it may be invalidated by future mutators. - VisitDirectDeps(visit func(Module)) + VisitDirectDepsAllowDisabled(visit func(Module)) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) @@ -164,17 +155,6 @@ type BaseModuleContext interface { // invalidated by future mutators. WalkDeps(visit func(child, parent Module) bool) - // WalkDepsBlueprint calls visit for each transitive dependency, traversing the dependency - // tree in top down order. visit may be called multiple times for the same (child, parent) - // pair if there are multiple direct dependencies between the child and parent with different - // tags. OtherModuleDependencyTag will return the tag for the currently visited - // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down - // to child. - // - // The Modules passed to the visit function should not be retained outside of the visit function, they may be - // invalidated by future mutators. - WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) - // GetWalkPath is supposed to be called in visit function passed in WalkDeps() // and returns a top-down dependency path from a start module to current child module. GetWalkPath() []Module @@ -220,10 +200,6 @@ type BaseModuleContext interface { // EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context // can be used to evaluate the final value of Configurable properties. EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue - - // HasMutatorFinished returns true if the given mutator has finished running. - // It will panic if given an invalid mutator name. - HasMutatorFinished(mutatorName string) bool } type baseModuleContext struct { @@ -274,10 +250,6 @@ func (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value b.bp.SetProvider(provider, value) } -func (b *baseModuleContext) HasMutatorFinished(mutatorName string) bool { - return b.bp.HasMutatorFinished(mutatorName) -} - func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { return b.bp.GetDirectDepWithTag(name, tag) } @@ -319,7 +291,7 @@ func (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependency(Mo return true } -func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool, ignoreBlueprint bool) Module { +func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool) Module { aModule, _ := module.(Module) if !strict { @@ -327,10 +299,7 @@ func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag b } if aModule == nil { - if !ignoreBlueprint { - b.ModuleErrorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag) - } - return nil + panic(fmt.Errorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag)) } if !aModule.Enabled(b) { @@ -353,15 +322,8 @@ type dep struct { func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep { var deps []dep - b.VisitDirectDepsBlueprint(func(module blueprint.Module) { - if aModule, _ := module.(Module); aModule != nil { - if aModule.base().BaseModuleName() == name { - returnedTag := b.bp.OtherModuleDependencyTag(aModule) - if tag == nil || returnedTag == tag { - deps = append(deps, dep{aModule, returnedTag}) - } - } - } else if b.bp.OtherModuleName(module) == name { + b.VisitDirectDeps(func(module Module) { + if module.base().BaseModuleName() == name { returnedTag := b.bp.OtherModuleDependencyTag(module) if tag == nil || returnedTag == tag { deps = append(deps, dep{module, returnedTag}) @@ -404,11 +366,9 @@ func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module { var deps []Module - b.VisitDirectDepsBlueprint(func(module blueprint.Module) { - if aModule, _ := module.(Module); aModule != nil { - if b.bp.OtherModuleDependencyTag(aModule) == tag { - deps = append(deps, aModule) - } + b.VisitDirectDeps(func(module Module) { + if b.bp.OtherModuleDependencyTag(module) == tag { + deps = append(deps, module) } }) return deps @@ -421,30 +381,24 @@ func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, bluepri return b.getDirectDepFirstTag(name) } -func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) { - b.bp.VisitDirectDeps(visit) -} - func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) { - b.visitDirectDeps(visit, false) -} - -func (b *baseModuleContext) VisitDirectDepsIgnoreBlueprint(visit func(Module)) { - b.visitDirectDeps(visit, true) -} - -func (b *baseModuleContext) visitDirectDeps(visit func(Module), ignoreBlueprint bool) { b.bp.VisitDirectDeps(func(module blueprint.Module) { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, ignoreBlueprint); aModule != nil { + if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { visit(aModule) } }) } +func (b *baseModuleContext) VisitDirectDepsAllowDisabled(visit func(Module)) { + b.bp.VisitDirectDeps(func(module blueprint.Module) { + visit(module.(Module)) + }) +} + func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { b.bp.VisitDirectDeps(func(module blueprint.Module) { if b.bp.OtherModuleDependencyTag(module) == tag { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil { + if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { visit(aModule) } } @@ -455,7 +409,7 @@ func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func b.bp.VisitDirectDepsIf( // pred func(module blueprint.Module) bool { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil { + if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { return pred(aModule) } else { return false @@ -469,7 +423,7 @@ func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) { b.bp.VisitDepsDepthFirst(func(module blueprint.Module) { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil { + if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { visit(aModule) } }) @@ -479,7 +433,7 @@ func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit b.bp.VisitDepsDepthFirstIf( // pred func(module blueprint.Module) bool { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil { + if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { return pred(aModule) } else { return false @@ -491,10 +445,6 @@ func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit }) } -func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) { - b.bp.WalkDeps(visit) -} - func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { b.walkPath = []Module{b.Module()} b.tagPath = []blueprint.DependencyTag{} diff --git a/android/config.go b/android/config.go index 00fc823a8..9f92fff0f 100644 --- a/android/config.go +++ b/android/config.go @@ -1252,7 +1252,7 @@ func (c *config) TidyChecks() string { } func (c *config) LibartImgHostBaseAddress() string { - return "0x60000000" + return "0x70000000" } func (c *config) LibartImgDeviceBaseAddress() string { @@ -1278,6 +1278,7 @@ func (c *config) EnforceRROForModule(name string) bool { } return false } + func (c *config) EnforceRROExcludedOverlay(path string) bool { excluded := c.productVariables.EnforceRROExcludedOverlays if len(excluded) > 0 { @@ -1286,6 +1287,11 @@ func (c *config) EnforceRROExcludedOverlay(path string) bool { return false } +func (c *config) EnforceRROGlobally() bool { + enforceList := c.productVariables.EnforceRROTargets + return InList("*", enforceList) +} + func (c *config) ExportedNamespaces() []string { return append([]string(nil), c.productVariables.NamespacesToExport...) } @@ -1691,14 +1697,6 @@ func (c *config) EnforceProductPartitionInterface() bool { return Bool(c.productVariables.EnforceProductPartitionInterface) } -func (c *config) EnforceInterPartitionJavaSdkLibrary() bool { - return Bool(c.productVariables.EnforceInterPartitionJavaSdkLibrary) -} - -func (c *config) InterPartitionJavaLibraryAllowList() []string { - return c.productVariables.InterPartitionJavaLibraryAllowList -} - func (c *config) ProductHiddenAPIStubs() []string { return c.productVariables.ProductHiddenAPIStubs } diff --git a/android/container.go b/android/container.go index c048d6c73..2a3777b30 100644 --- a/android/container.go +++ b/android/container.go @@ -479,7 +479,7 @@ func setContainerInfo(ctx ModuleContext) { func checkContainerViolations(ctx ModuleContext) { if _, ok := ctx.Module().(InstallableModule); ok { containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module()) - ctx.VisitDirectDepsIgnoreBlueprint(func(dep Module) { + ctx.VisitDirectDeps(func(dep Module) { if !dep.Enabled(ctx) { return } diff --git a/android/early_module_context.go b/android/early_module_context.go index 23f4c90a2..11de77146 100644 --- a/android/early_module_context.go +++ b/android/early_module_context.go @@ -93,6 +93,10 @@ type EarlyModuleContext interface { // Namespace returns the Namespace object provided by the NameInterface set by Context.SetNameInterface, or the // default SimpleNameInterface if Context.SetNameInterface was not called. Namespace() *Namespace + + // HasMutatorFinished returns true if the given mutator has finished running. + // It will panic if given an invalid mutator name. + HasMutatorFinished(mutatorName string) bool } // Deprecated: use EarlyModuleContext instead @@ -175,3 +179,7 @@ func (e *earlyModuleContext) Namespace() *Namespace { func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) { e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...) } + +func (e *earlyModuleContext) HasMutatorFinished(mutatorName string) bool { + return e.EarlyModuleContext.HasMutatorFinished(mutatorName) +} diff --git a/android/hooks.go b/android/hooks.go index 2ad3b5fa5..bd2fa5e75 100644 --- a/android/hooks.go +++ b/android/hooks.go @@ -95,10 +95,17 @@ func (l *loadHookContext) createModule(factory blueprint.ModuleFactory, name str type createModuleContext interface { Module() Module + HasMutatorFinished(mutatorName string) bool createModule(blueprint.ModuleFactory, string, ...interface{}) blueprint.Module } func createModule(ctx createModuleContext, factory ModuleFactory, ext string, props ...interface{}) Module { + if ctx.HasMutatorFinished("defaults") { + // Creating modules late is oftentimes problematic, because they don't have earlier + // mutators run on them. Prevent making modules after the defaults mutator has run. + panic("Cannot create a module after the defaults mutator has finished") + } + inherited := []interface{}{&ctx.Module().base().commonProperties} var typeName string diff --git a/android/license_metadata.go b/android/license_metadata.go index 0ac975fa2..f92563862 100644 --- a/android/license_metadata.go +++ b/android/license_metadata.go @@ -63,11 +63,7 @@ func buildLicenseMetadata(ctx *moduleContext, licenseMetadataFile WritablePath) var allDepOutputFiles Paths var allDepMetadataDepSets []*DepSet[Path] - ctx.VisitDirectDepsBlueprint(func(bpdep blueprint.Module) { - dep, _ := bpdep.(Module) - if dep == nil { - return - } + ctx.VisitDirectDeps(func(dep Module) { if !dep.Enabled(ctx) { return } diff --git a/android/module.go b/android/module.go index d6c129ac8..1866d7a9d 100644 --- a/android/module.go +++ b/android/module.go @@ -1861,10 +1861,8 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) if m.Enabled(ctx) { // ensure all direct android.Module deps are enabled - ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) { - if m, ok := bm.(Module); ok { - ctx.validateAndroidModule(bm, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps, false) - } + ctx.VisitDirectDeps(func(m Module) { + ctx.validateAndroidModule(m, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps) }) if m.Device() { diff --git a/android/mutator.go b/android/mutator.go index 940494506..434e3ba56 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -26,7 +26,7 @@ import ( // run Pre-deps mutators // run depsMutator // run PostDeps mutators -// run FinalDeps mutators (CreateVariations disallowed in this phase) +// run FinalDeps mutators (TransitionMutators disallowed in this phase) // continue on to GenerateAndroidBuildActions // collateGloballyRegisteredMutators constructs the list of mutators that have been registered @@ -231,36 +231,6 @@ type BottomUpMutatorContext interface { // module's dependency list. AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) - // CreateVariations splits a module into multiple variants, one for each name in the variationNames - // parameter. It returns a list of new modules in the same order as the variationNames - // list. - // - // If any of the dependencies of the module being operated on were already split - // by calling CreateVariations with the same name, the dependency will automatically - // be updated to point the matching variant. - // - // If a module is split, and then a module depending on the first module is not split - // when the Mutator is later called on it, the dependency of the depending module will - // automatically be updated to point to the first variant. - CreateVariations(...string) []Module - - // CreateLocationVariations splits a module into multiple variants, one for each name in the variantNames - // parameter. It returns a list of new modules in the same order as the variantNames - // list. - // - // Local variations do not affect automatic dependency resolution - dependencies added - // to the split module via deps or DynamicDependerModule must exactly match a variant - // that contains all the non-local variations. - CreateLocalVariations(...string) []Module - - // SetDependencyVariation sets all dangling dependencies on the current module to point to the variation - // with given name. This function ignores the default variation set by SetDefaultDependencyVariation. - SetDependencyVariation(string) - - // SetDefaultDependencyVariation sets the default variation when a dangling reference is detected - // during the subsequent calls on Create*Variations* functions. To reset, set it to nil. - SetDefaultDependencyVariation(*string) - // AddVariationDependencies adds deps as dependencies of the current module, but uses the variations // argument to select which variant of the dependency to use. It returns a slice of modules for // each dependency (some entries may be nil). A variant of the dependency must exist that matches @@ -287,12 +257,6 @@ type BottomUpMutatorContext interface { // be ordered correctly for all future mutator passes. AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module - // AddInterVariantDependency adds a dependency between two variants of the same module. Variants are always - // ordered in the same orderas they were listed in CreateVariations, and AddInterVariantDependency does not change - // that ordering, but it associates a DependencyTag with the dependency and makes it visible to VisitDirectDeps, - // WalkDeps, etc. - AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) - // ReplaceDependencies finds all the variants of the module with the specified name, then // replaces all dependencies onto those variants with the current variant of this module. // Replacements don't take effect until after the mutator pass is finished. @@ -303,30 +267,6 @@ type BottomUpMutatorContext interface { // as long as the supplied predicate returns true. // Replacements don't take effect until after the mutator pass is finished. ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate) - - // AliasVariation takes a variationName that was passed to CreateVariations for this module, - // and creates an alias from the current variant (before the mutator has run) to the new - // variant. The alias will be valid until the next time a mutator calls CreateVariations or - // CreateLocalVariations on this module without also calling AliasVariation. The alias can - // be used to add dependencies on the newly created variant using the variant map from - // before CreateVariations was run. - AliasVariation(variationName string) - - // CreateAliasVariation takes a toVariationName that was passed to CreateVariations for this - // module, and creates an alias from a new fromVariationName variant the toVariationName - // variant. The alias will be valid until the next time a mutator calls CreateVariations or - // CreateLocalVariations on this module without also calling AliasVariation. The alias can - // be used to add dependencies on the toVariationName variant using the fromVariationName - // variant. - CreateAliasVariation(fromVariationName, toVariationName string) - - // SetVariationProvider sets the value for a provider for the given newly created variant of - // the current module, i.e. one of the Modules returned by CreateVariations.. It panics if - // not called during the appropriate mutator or GenerateBuildActions pass for the provider, - // if the value is not of the appropriate type, or if the module is not a newly created - // variant of the current module. The value should not be modified after being passed to - // SetVariationProvider. - SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{}) } // An outgoingTransitionContextImpl and incomingTransitionContextImpl is created for every dependency of every module @@ -763,51 +703,6 @@ func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, t } b.bp.AddReverseDependency(module, tag, name) } - -func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module { - if b.finalPhase { - panic("CreateVariations not allowed in FinalDepsMutators") - } - - modules := b.bp.CreateVariations(variations...) - - aModules := make([]Module, len(modules)) - for i := range variations { - aModules[i] = modules[i].(Module) - base := aModules[i].base() - base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) - base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) - } - - return aModules -} - -func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module { - if b.finalPhase { - panic("CreateLocalVariations not allowed in FinalDepsMutators") - } - - modules := b.bp.CreateLocalVariations(variations...) - - aModules := make([]Module, len(modules)) - for i := range variations { - aModules[i] = modules[i].(Module) - base := aModules[i].base() - base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) - base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) - } - - return aModules -} - -func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) { - b.bp.SetDependencyVariation(variation) -} - -func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) { - b.bp.SetDefaultDependencyVariation(variation) -} - func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module { if b.baseModuleContext.checkedMissingDeps() { @@ -825,10 +720,6 @@ func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []bluepr return b.bp.AddFarVariationDependencies(variations, tag, names...) } -func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) { - b.bp.AddInterVariantDependency(tag, from, to) -} - func (b *bottomUpMutatorContext) ReplaceDependencies(name string) { if b.baseModuleContext.checkedMissingDeps() { panic("Adding deps not allowed after checking for missing deps") @@ -842,15 +733,3 @@ func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate bl } b.bp.ReplaceDependenciesIf(name, predicate) } - -func (b *bottomUpMutatorContext) AliasVariation(variationName string) { - b.bp.AliasVariation(variationName) -} - -func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVariationName string) { - b.bp.CreateAliasVariation(fromVariationName, toVariationName) -} - -func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{}) { - b.bp.SetVariationProvider(module, provider, value) -} diff --git a/android/mutator_test.go b/android/mutator_test.go index b3ef00f3d..5d4074a54 100644 --- a/android/mutator_test.go +++ b/android/mutator_test.go @@ -287,7 +287,7 @@ func TestFinalDepsPhase(t *testing.T) { AssertDeepEquals(t, "final", finalWant, finalGot) } -func TestNoCreateVariationsInFinalDeps(t *testing.T) { +func TestTransitionMutatorInFinalDeps(t *testing.T) { GroupFixturePreparers( FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) { diff --git a/android/paths.go b/android/paths.go index 0d94f03e6..1c8258ede 100644 --- a/android/paths.go +++ b/android/paths.go @@ -92,7 +92,7 @@ func GlobFiles(ctx EarlyModulePathContext, globPattern string, excludes []string type ModuleWithDepsPathContext interface { EarlyModulePathContext OtherModuleProviderContext - VisitDirectDepsBlueprint(visit func(blueprint.Module)) + VisitDirectDeps(visit func(Module)) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag HasMutatorFinished(mutatorName string) bool } @@ -598,7 +598,7 @@ func GetModuleFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) // create the tag here as was supplied to create the tag when the dependency was added so that // this finds the matching dependency module. expectedTag := sourceOrOutputDepTag(moduleName, tag) - ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) { + ctx.VisitDirectDeps(func(module Module) { depTag := ctx.OtherModuleDependencyTag(module) if depTag == expectedTag { found = module diff --git a/android/prebuilt.go b/android/prebuilt.go index fd5a6eaee..4f04d057b 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -359,8 +359,8 @@ func GetEmbeddedPrebuilt(module Module) *Prebuilt { // // This function is for use on dependencies after PrebuiltPostDepsMutator has // run - any dependency that is registered before that will already reference -// the right module. This function is only safe to call after all mutators that -// may call CreateVariations, e.g. in GenerateAndroidBuildActions. +// the right module. This function is only safe to call after all TransitionMutators +// have run, e.g. in GenerateAndroidBuildActions. func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { if !module.IsReplacedByPrebuilt() { return module diff --git a/android/rule_builder.go b/android/rule_builder.go index 18bbcab5c..56de9cd00 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -38,6 +38,9 @@ const sboxOutSubDir = "out" const sboxToolsSubDir = "tools" const sboxOutDir = sboxSandboxBaseDir + "/" + sboxOutSubDir +const nsjailToolsSubDir = "tools" +const nsjailOutDir = "out" + // RuleBuilder provides an alternative to ModuleContext.Rule and ModuleContext.Build to add a command line to the build // graph. type RuleBuilder struct { @@ -59,6 +62,9 @@ type RuleBuilder struct { sboxManifestPath WritablePath missingDeps []string args map[string]string + nsjail bool + nsjailBasePath WritablePath + nsjailImplicits Paths } // NewRuleBuilder returns a newly created RuleBuilder. @@ -165,12 +171,43 @@ func (r *RuleBuilder) Sbox(outputDir WritablePath, manifestPath WritablePath) *R if len(r.commands) > 0 { panic("Sbox() may not be called after Command()") } + if r.nsjail { + panic("Sbox() may not be called after Nsjail()") + } r.sbox = true r.outDir = outputDir r.sboxManifestPath = manifestPath return r } +// Nsjail marks the rule as needing to be wrapped by nsjail. The outputDir should point to the +// output directory that nsjail will mount to out/. It should not be written to by any other rule. +// baseDir should point to a location where nsjail will mount to /nsjail_build_sandbox, which will +// be the working directory of the command. +func (r *RuleBuilder) Nsjail(outputDir WritablePath, baseDir WritablePath) *RuleBuilder { + if len(r.commands) > 0 { + panic("Nsjail() may not be called after Command()") + } + if r.sbox { + panic("Nsjail() may not be called after Sbox()") + } + r.nsjail = true + r.outDir = outputDir + r.nsjailBasePath = baseDir + return r +} + +// NsjailImplicits adds implicit inputs that are not directly mounted. This is useful when +// the rule mounts directories, as files within those directories can be globbed and +// tracked as dependencies with NsjailImplicits(). +func (r *RuleBuilder) NsjailImplicits(inputs Paths) *RuleBuilder { + if !r.nsjail { + panic("NsjailImplicits() must be called after Nsjail()") + } + r.nsjailImplicits = append(r.nsjailImplicits, inputs...) + return r +} + // SandboxTools enables tool sandboxing for the rule by copying any referenced tools into the // sandbox. func (r *RuleBuilder) SandboxTools() *RuleBuilder { @@ -514,7 +551,73 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b commandString := strings.Join(commands, " && ") - if r.sbox { + if !r.sbox { + // If not using sbox the rule will run the command directly, put the hash of the + // list of input files in a comment at the end of the command line to ensure ninja + // reruns the rule when the list of input files changes. + commandString += " # hash of input list: " + hashSrcFiles(inputs) + } + + if r.nsjail { + var nsjailCmd strings.Builder + nsjailPath := r.ctx.Config().PrebuiltBuildTool(r.ctx, "nsjail") + nsjailCmd.WriteString("mkdir -p ") + nsjailCmd.WriteString(r.nsjailBasePath.String()) + nsjailCmd.WriteString(" && ") + nsjailCmd.WriteString(nsjailPath.String()) + nsjailCmd.WriteRune(' ') + nsjailCmd.WriteString("-B $PWD/") + nsjailCmd.WriteString(r.nsjailBasePath.String()) + nsjailCmd.WriteString(":nsjail_build_sandbox") + + // out is mounted to $(genDir). + nsjailCmd.WriteString(" -B $PWD/") + nsjailCmd.WriteString(r.outDir.String()) + nsjailCmd.WriteString(":nsjail_build_sandbox/out") + + for _, input := range inputs { + nsjailCmd.WriteString(" -R $PWD/") + nsjailCmd.WriteString(input.String()) + nsjailCmd.WriteString(":nsjail_build_sandbox/") + nsjailCmd.WriteString(r.nsjailPathForInputRel(input)) + } + for _, tool := range tools { + nsjailCmd.WriteString(" -R $PWD/") + nsjailCmd.WriteString(tool.String()) + nsjailCmd.WriteString(":nsjail_build_sandbox/") + nsjailCmd.WriteString(nsjailPathForToolRel(r.ctx, tool)) + } + inputs = append(inputs, tools...) + for _, c := range r.commands { + for _, tool := range c.packagedTools { + nsjailCmd.WriteString(" -R $PWD/") + nsjailCmd.WriteString(tool.srcPath.String()) + nsjailCmd.WriteString(":nsjail_build_sandbox/") + nsjailCmd.WriteString(nsjailPathForPackagedToolRel(tool)) + inputs = append(inputs, tool.srcPath) + } + } + + // These five directories are necessary to run native host tools like /bin/bash and py3-cmd. + nsjailCmd.WriteString(" -R /bin") + nsjailCmd.WriteString(" -R /lib") + nsjailCmd.WriteString(" -R /lib64") + nsjailCmd.WriteString(" -R /dev") + nsjailCmd.WriteString(" -R /usr") + + nsjailCmd.WriteString(" -m none:/tmp:tmpfs:size=1073741824") // 1GB, should be enough + nsjailCmd.WriteString(" -D nsjail_build_sandbox") + nsjailCmd.WriteString(" --disable_rlimits") + nsjailCmd.WriteString(" -q") + nsjailCmd.WriteString(" -- ") + nsjailCmd.WriteString("/bin/bash -c ") + nsjailCmd.WriteString(proptools.ShellEscape(commandString)) + + commandString = nsjailCmd.String() + + inputs = append(inputs, nsjailPath) + inputs = append(inputs, r.nsjailImplicits...) + } else if r.sbox { // If running the command inside sbox, write the rule data out to an sbox // manifest.textproto. manifest := sbox_proto.Manifest{} @@ -734,11 +837,6 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b rewrapperCommand := r.rbeParams.NoVarTemplate(r.ctx.Config().RBEWrapper()) commandString = rewrapperCommand + " bash -c '" + strings.ReplaceAll(commandString, `'`, `'\''`) + "'" } - } else { - // If not using sbox the rule will run the command directly, put the hash of the - // list of input files in a comment at the end of the command line to ensure ninja - // reruns the rule when the list of input files changes. - commandString += " # hash of input list: " + hashSrcFiles(inputs) } // Ninja doesn't like multiple outputs when depfiles are enabled, move all but the first output to @@ -869,6 +967,8 @@ func (c *RuleBuilderCommand) PathForInput(path Path) string { rel = filepath.Join(sboxSandboxBaseDir, rel) } return rel + } else if c.rule.nsjail { + return c.rule.nsjailPathForInputRel(path) } return path.String() } @@ -894,6 +994,10 @@ func (c *RuleBuilderCommand) PathForOutput(path WritablePath) string { // Errors will be handled in RuleBuilder.Build where we have a context to report them rel, _, _ := maybeRelErr(c.rule.outDir.String(), path.String()) return filepath.Join(sboxOutDir, rel) + } else if c.rule.nsjail { + // Errors will be handled in RuleBuilder.Build where we have a context to report them + rel, _, _ := maybeRelErr(c.rule.outDir.String(), path.String()) + return filepath.Join(nsjailOutDir, rel) } return path.String() } @@ -945,15 +1049,49 @@ func sboxPathForPackagedToolRel(spec PackagingSpec) string { return filepath.Join(sboxToolsSubDir, "out", spec.relPathInPackage) } +func nsjailPathForToolRel(ctx BuilderContext, path Path) string { + // Errors will be handled in RuleBuilder.Build where we have a context to report them + toolDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "") + relOutSoong, isRelOutSoong, _ := maybeRelErr(toolDir.String(), path.String()) + if isRelOutSoong { + // The tool is in the Soong output directory, it will be copied to __SBOX_OUT_DIR__/tools/out + return filepath.Join(nsjailToolsSubDir, "out", relOutSoong) + } + // The tool is in the source directory, it will be copied to __SBOX_OUT_DIR__/tools/src + return filepath.Join(nsjailToolsSubDir, "src", path.String()) +} + +func (r *RuleBuilder) nsjailPathForInputRel(path Path) string { + rel, isRelSboxOut, _ := maybeRelErr(r.outDir.String(), path.String()) + if isRelSboxOut { + return filepath.Join(nsjailOutDir, rel) + } + return path.String() +} + +func (r *RuleBuilder) nsjailPathsForInputsRel(paths Paths) []string { + ret := make([]string, len(paths)) + for i, path := range paths { + ret[i] = r.nsjailPathForInputRel(path) + } + return ret +} + +func nsjailPathForPackagedToolRel(spec PackagingSpec) string { + return filepath.Join(nsjailToolsSubDir, "out", spec.relPathInPackage) +} + // PathForPackagedTool takes a PackageSpec for a tool and returns the corresponding path for the // tool after copying it into the sandbox. This can be used on the RuleBuilder command line to // reference the tool. func (c *RuleBuilderCommand) PathForPackagedTool(spec PackagingSpec) string { - if !c.rule.sboxTools { - panic("PathForPackagedTool() requires SandboxTools()") + if c.rule.sboxTools { + return filepath.Join(sboxSandboxBaseDir, sboxPathForPackagedToolRel(spec)) + } else if c.rule.nsjail { + return nsjailPathForPackagedToolRel(spec) + } else { + panic("PathForPackagedTool() requires SandboxTools() or Nsjail()") } - - return filepath.Join(sboxSandboxBaseDir, sboxPathForPackagedToolRel(spec)) } // PathForTool takes a path to a tool, which may be an output file or a source file, and returns @@ -962,6 +1100,8 @@ func (c *RuleBuilderCommand) PathForPackagedTool(spec PackagingSpec) string { func (c *RuleBuilderCommand) PathForTool(path Path) string { if c.rule.sbox && c.rule.sboxTools { return filepath.Join(sboxSandboxBaseDir, sboxPathForToolRel(c.rule.ctx, path)) + } else if c.rule.nsjail { + return nsjailPathForToolRel(c.rule.ctx, path) } return path.String() } @@ -976,6 +1116,12 @@ func (c *RuleBuilderCommand) PathsForTools(paths Paths) []string { ret = append(ret, filepath.Join(sboxSandboxBaseDir, sboxPathForToolRel(c.rule.ctx, path))) } return ret + } else if c.rule.nsjail { + var ret []string + for _, path := range paths { + ret = append(ret, nsjailPathForToolRel(c.rule.ctx, path)) + } + return ret } return paths.Strings() } @@ -983,20 +1129,22 @@ func (c *RuleBuilderCommand) PathsForTools(paths Paths) []string { // PackagedTool adds the specified tool path to the command line. It can only be used with tool // sandboxing enabled by SandboxTools(), and will copy the tool into the sandbox. func (c *RuleBuilderCommand) PackagedTool(spec PackagingSpec) *RuleBuilderCommand { - if !c.rule.sboxTools { - panic("PackagedTool() requires SandboxTools()") - } - c.packagedTools = append(c.packagedTools, spec) - c.Text(sboxPathForPackagedToolRel(spec)) + if c.rule.sboxTools { + c.Text(sboxPathForPackagedToolRel(spec)) + } else if c.rule.nsjail { + c.Text(nsjailPathForPackagedToolRel(spec)) + } else { + panic("PackagedTool() requires SandboxTools() or Nsjail()") + } return c } // ImplicitPackagedTool copies the specified tool into the sandbox without modifying the command // line. It can only be used with tool sandboxing enabled by SandboxTools(). func (c *RuleBuilderCommand) ImplicitPackagedTool(spec PackagingSpec) *RuleBuilderCommand { - if !c.rule.sboxTools { - panic("ImplicitPackagedTool() requires SandboxTools()") + if !c.rule.sboxTools && !c.rule.nsjail { + panic("ImplicitPackagedTool() requires SandboxTools() or Nsjail()") } c.packagedTools = append(c.packagedTools, spec) @@ -1006,8 +1154,8 @@ func (c *RuleBuilderCommand) ImplicitPackagedTool(spec PackagingSpec) *RuleBuild // ImplicitPackagedTools copies the specified tools into the sandbox without modifying the command // line. It can only be used with tool sandboxing enabled by SandboxTools(). func (c *RuleBuilderCommand) ImplicitPackagedTools(specs []PackagingSpec) *RuleBuilderCommand { - if !c.rule.sboxTools { - panic("ImplicitPackagedTools() requires SandboxTools()") + if !c.rule.sboxTools && !c.rule.nsjail { + panic("ImplicitPackagedTools() requires SandboxTools() or Nsjail()") } c.packagedTools = append(c.packagedTools, specs...) diff --git a/android/variable.go b/android/variable.go index e0d512d3a..7041f4960 100644 --- a/android/variable.go +++ b/android/variable.go @@ -428,9 +428,6 @@ type ProductVariables struct { EnforceProductPartitionInterface *bool `json:",omitempty"` - EnforceInterPartitionJavaSdkLibrary *bool `json:",omitempty"` - InterPartitionJavaLibraryAllowList []string `json:",omitempty"` - BoardUsesRecoveryAsBoot *bool `json:",omitempty"` BoardKernelBinaries []string `json:",omitempty"` diff --git a/apex/apex.go b/apex/apex.go index 0caf37ccc..5f4d823ff 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -68,8 +68,6 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { ctx.Transition("apex", &apexTransitionMutator{}) ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel() ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel() - // Register after apex_info mutator so that it can use ApexVariationName - ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel() } type apexBundleProperties struct { @@ -583,7 +581,7 @@ type apexFile struct { dataPaths []android.DataPath // becomes LOCAL_TEST_DATA jacocoReportClassesFile android.Path // only for javalibs and apps - lintDepSets java.LintDepSets // only for javalibs and apps + lintInfo *java.LintInfo // only for javalibs and apps certificate java.Certificate // only for apps overriddenPackageName string // only for apps @@ -1115,34 +1113,6 @@ func apexInfoMutator(mctx android.TopDownMutatorContext) { enforceAppUpdatability(mctx) } -// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module -// This check is enforced for updatable modules -func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) { - if !mctx.Module().Enabled(mctx) { - return - } - if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting(mctx) { - mctx.WalkDeps(func(child, parent android.Module) bool { - // b/208656169 Do not propagate strict updatability linting to libcore/ - // These libs are available on the classpath during compilation - // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep - // Only skip libraries defined in libcore root, not subdirectories - if mctx.OtherModuleDir(child) == "libcore" { - // Do not traverse transitive deps of libcore/ libs - return false - } - if android.InList(child.Name(), skipLintJavalibAllowlist) { - return false - } - if lintable, ok := child.(java.LintDepSetsIntf); ok { - lintable.SetStrictUpdatabilityLinting(true) - } - // visit transitive deps - return true - }) - } -} - // enforceAppUpdatability propagates updatable=true to apps of updatable apexes func enforceAppUpdatability(mctx android.TopDownMutatorContext) { if !mctx.Module().Enabled(mctx) { @@ -1203,20 +1173,9 @@ var ( "test_jitzygote_com.android.art", // go/keep-sorted end } - - // TODO: b/215736885 Remove this list - skipLintJavalibAllowlist = []string{ - "conscrypt.module.platform.api.stubs", - "conscrypt.module.public.api.stubs", - "conscrypt.module.public.api.stubs.system", - "conscrypt.module.public.api.stubs.module_lib", - "framework-media.stubs", - "framework-media.stubs.system", - "framework-media.stubs.module_lib", - } ) -func (a *apexBundle) checkStrictUpdatabilityLinting(mctx android.TopDownMutatorContext) bool { +func (a *apexBundle) checkStrictUpdatabilityLinting(mctx android.ModuleContext) bool { // The allowlist contains the base apex name, so use that instead of the ApexVariationName return a.Updatable() && !android.InList(mctx.ModuleName(), skipStrictUpdatabilityLintAllowlist) } @@ -1662,7 +1621,6 @@ type javaModule interface { BaseModuleName() string DexJarBuildPath(ctx android.ModuleErrorfContext) java.OptionalDexJarPath JacocoReportClassesFile() android.Path - LintDepSets() java.LintDepSets Stem() string } @@ -1682,7 +1640,9 @@ func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module javaModule, dirInApex := "javalib" af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module) af.jacocoReportClassesFile = module.JacocoReportClassesFile() - af.lintDepSets = module.LintDepSets() + if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok { + af.lintInfo = lintInfo + } af.customStem = module.Stem() + ".jar" // TODO: b/338641779 - Remove special casing of sdkLibrary once bcpf and sscpf depends // on the implementation library @@ -1720,7 +1680,6 @@ type androidApp interface { JacocoReportClassesFile() android.Path Certificate() java.Certificate BaseModuleName() string - LintDepSets() java.LintDepSets PrivAppAllowlist() android.OptionalPath } @@ -1756,7 +1715,9 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []ap af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp) af.jacocoReportClassesFile = aapp.JacocoReportClassesFile() - af.lintDepSets = aapp.LintDepSets() + if lintInfo, ok := android.OtherModuleProvider(ctx, aapp, java.LintProvider); ok { + af.lintInfo = lintInfo + } af.certificate = aapp.Certificate() if app, ok := aapp.(interface { @@ -1807,7 +1768,7 @@ func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path // visited module, the `do` callback is executed. Returning true in the callback continues the visit // to the child modules. Returning false makes the visit to continue in the sibling or the parent // modules. This is used in check* functions below. -func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) { +func (a *apexBundle) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) { ctx.WalkDeps(func(child, parent android.Module) bool { am, ok := child.(android.ApexModule) if !ok || !am.CanHaveApexVariants() { @@ -1974,12 +1935,12 @@ func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) { }) } -func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool { +func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent android.Module) bool { depTag := ctx.OtherModuleDependencyTag(child) if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok { return false } - if mod, ok := child.(android.Module); ok && !mod.Enabled(ctx) { + if !child.Enabled(ctx) { return false } depName := ctx.OtherModuleName(child) @@ -2323,7 +2284,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { checkDuplicate: a.shouldCheckDuplicate(ctx), unwantedTransitiveDeps: a.properties.Unwanted_transitive_deps, } - ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) }) + ctx.WalkDeps(func(child, parent android.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) }) vctx.normalizeFileInfo(ctx) if a.privateKeyFile == nil { if ctx.Config().AllowMissingDependencies() { @@ -2653,7 +2614,7 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider) - a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { if ccm, ok := to.(*cc.Module); ok { apexName := ctx.ModuleName() fromName := ctx.OtherModuleName(from) @@ -2724,7 +2685,7 @@ func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) { func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) { // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs, // java's checkLinkType guarantees correct usage for transitive deps - ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) { + ctx.VisitDirectDeps(func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) switch tag { case javaLibTag, androidAppTag: @@ -2765,7 +2726,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { return } - a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { // As soon as the dependency graph crosses the APEX boundary, don't go further. if externalDep { return false @@ -2817,7 +2778,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { // checkStaticExecutable ensures that executables in an APEX are not static. func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) { - ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) { + ctx.VisitDirectDeps(func(module android.Module) { if ctx.OtherModuleDependencyTag(module) != executableTag { return } diff --git a/apex/apex_test.go b/apex/apex_test.go index ad0bb177d..7465f40eb 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -5429,11 +5429,11 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { apex_available: ["myapex"], shared_library: false, permitted_packages: ["bar"], + prefer: true, } java_sdk_library { name: "libbar", - enabled: false, srcs: ["foo/bar/MyClass.java"], unsafe_ignore_missing_latest_api: true, apex_available: ["myapex"], @@ -9693,120 +9693,84 @@ func TestApexStrictUpdtabilityLint(t *testing.T) { } testCases := []struct { - testCaseName string - apexUpdatable bool - javaStrictUpdtabilityLint bool - lintFileExists bool - disallowedFlagExpected bool + testCaseName string + apexUpdatable bool + javaStrictUpdtabilityLint bool + lintFileExists bool + disallowedFlagExpectedOnApex bool + disallowedFlagExpectedOnJavalib bool }{ { - testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd", - apexUpdatable: true, - javaStrictUpdtabilityLint: true, - lintFileExists: false, - disallowedFlagExpected: false, + testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd", + apexUpdatable: true, + javaStrictUpdtabilityLint: true, + lintFileExists: false, + disallowedFlagExpectedOnApex: false, + disallowedFlagExpectedOnJavalib: false, }, { - testCaseName: "non-updatable apex respects strict_updatability of javalib", - apexUpdatable: false, - javaStrictUpdtabilityLint: false, - lintFileExists: true, - disallowedFlagExpected: false, + testCaseName: "non-updatable apex respects strict_updatability of javalib", + apexUpdatable: false, + javaStrictUpdtabilityLint: false, + lintFileExists: true, + disallowedFlagExpectedOnApex: false, + disallowedFlagExpectedOnJavalib: false, }, { - testCaseName: "non-updatable apex respects strict updatability of javalib", - apexUpdatable: false, - javaStrictUpdtabilityLint: true, - lintFileExists: true, - disallowedFlagExpected: true, + testCaseName: "non-updatable apex respects strict updatability of javalib", + apexUpdatable: false, + javaStrictUpdtabilityLint: true, + lintFileExists: true, + disallowedFlagExpectedOnApex: false, + disallowedFlagExpectedOnJavalib: true, }, { - testCaseName: "updatable apex sets strict updatability of javalib to true", - apexUpdatable: true, - javaStrictUpdtabilityLint: false, // will be set to true by mutator - lintFileExists: true, - disallowedFlagExpected: true, + testCaseName: "updatable apex checks strict updatability of javalib", + apexUpdatable: true, + javaStrictUpdtabilityLint: false, + lintFileExists: true, + disallowedFlagExpectedOnApex: true, + disallowedFlagExpectedOnJavalib: false, }, } for _, testCase := range testCases { - fixtures := []android.FixturePreparer{} - baselineProperty := "" - if testCase.lintFileExists { - fixtures = append(fixtures, fs.AddToFixture()) - baselineProperty = "baseline_filename: \"lint-baseline.xml\"" - } - bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint, baselineProperty) - - result := testApex(t, bp, fixtures...) - myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto")) - disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi") + t.Run(testCase.testCaseName, func(t *testing.T) { + fixtures := []android.FixturePreparer{} + baselineProperty := "" + if testCase.lintFileExists { + fixtures = append(fixtures, fs.AddToFixture()) + baselineProperty = "baseline_filename: \"lint-baseline.xml\"" + } + bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint, baselineProperty) - if disallowedFlagActual != testCase.disallowedFlagExpected { - t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command) - } - } -} + result := testApex(t, bp, fixtures...) -func TestUpdatabilityLintSkipLibcore(t *testing.T) { - bp := ` - apex { - name: "myapex", - key: "myapex.key", - java_libs: ["myjavalib"], - updatable: true, - min_sdk_version: "29", - } - apex_key { - name: "myapex.key", - } - java_library { - name: "myjavalib", - srcs: ["MyClass.java"], - apex_available: [ "myapex" ], - sdk_version: "current", - min_sdk_version: "29", - lint: { - baseline_filename: "lint-baseline.xml", + checkModule := func(m android.TestingBuildParams, name string, expectStrictUpdatability bool) { + if expectStrictUpdatability { + if m.Rule == nil { + t.Errorf("expected strict updatability check rule on %s", name) + } else { + android.AssertStringDoesContain(t, fmt.Sprintf("strict updatability check rule for %s", name), + m.RuleParams.Command, "--disallowed_issues NewApi") + android.AssertStringListContains(t, fmt.Sprintf("strict updatability check baselines for %s", name), + m.Inputs.Strings(), "lint-baseline.xml") + } + } else { + if m.Rule != nil { + t.Errorf("expected no strict updatability check rule on %s", name) + } + } } - } - ` - testCases := []struct { - testCaseName string - moduleDirectory string - disallowedFlagExpected bool - }{ - { - testCaseName: "lintable module defined outside libcore", - moduleDirectory: "", - disallowedFlagExpected: true, - }, - { - testCaseName: "lintable module defined in libcore root directory", - moduleDirectory: "libcore/", - disallowedFlagExpected: false, - }, - { - testCaseName: "lintable module defined in libcore child directory", - moduleDirectory: "libcore/childdir/", - disallowedFlagExpected: true, - }, - } + myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") + apex := result.ModuleForTests("myapex", "android_common_myapex") + apexStrictUpdatabilityCheck := apex.MaybeOutput("lint_strict_updatability_check.stamp") + javalibStrictUpdatabilityCheck := myjavalib.MaybeOutput("lint_strict_updatability_check.stamp") - for _, testCase := range testCases { - lintFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"lint-baseline.xml", "") - bpFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"Android.bp", bp) - result := testApex(t, "", lintFileCreator, bpFileCreator) - myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto")) - cmdFlags := fmt.Sprintf("--baseline %vlint-baseline.xml --disallowed_issues NewApi", testCase.moduleDirectory) - disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, cmdFlags) - - if disallowedFlagActual != testCase.disallowedFlagExpected { - t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command) - } + checkModule(apexStrictUpdatabilityCheck, "myapex", testCase.disallowedFlagExpectedOnApex) + checkModule(javalibStrictUpdatabilityCheck, "myjavalib", testCase.disallowedFlagExpectedOnJavalib) + }) } } @@ -9848,11 +9812,12 @@ func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) { } result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture()) - myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto")) - if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi") { - t.Errorf("Strict updabality lint missing in myjavalib coming from bootclasspath_fragment mybootclasspath-fragment\nActual lint cmd: %v", *sboxProto.Commands[0].Command) - } + apex := result.ModuleForTests("myapex", "android_common_myapex") + apexStrictUpdatabilityCheck := apex.Output("lint_strict_updatability_check.stamp") + android.AssertStringDoesContain(t, "strict updatability check rule for myapex", + apexStrictUpdatabilityCheck.RuleParams.Command, "--disallowed_issues NewApi") + android.AssertStringListContains(t, "strict updatability check baselines for myapex", + apexStrictUpdatabilityCheck.Inputs.Strings(), "lint-baseline.xml") } func TestApexLintBcpFragmentSdkLibDeps(t *testing.T) { diff --git a/apex/builder.go b/apex/builder.go index 19ec1bd46..bf3ba9f99 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -1092,7 +1092,7 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { } depInfos := android.DepNameToDepInfoMap{} - a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { if from.Name() == to.Name() { // This can happen for cc.reuseObjTag. We are not interested in tracking this. // As soon as the dependency graph crosses the APEX boundary, don't go further. @@ -1159,10 +1159,23 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { func (a *apexBundle) buildLintReports(ctx android.ModuleContext) { depSetsBuilder := java.NewLintDepSetBuilder() for _, fi := range a.filesInfo { - depSetsBuilder.Transitive(fi.lintDepSets) + if fi.lintInfo != nil { + depSetsBuilder.Transitive(fi.lintInfo) + } + } + + depSets := depSetsBuilder.Build() + var validations android.Paths + + if a.checkStrictUpdatabilityLinting(ctx) { + baselines := depSets.Baseline.ToList() + if len(baselines) > 0 { + outputFile := java.VerifyStrictUpdatabilityChecks(ctx, baselines) + validations = append(validations, outputFile) + } } - a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build()) + a.lintReports = java.BuildModuleLintReportZips(ctx, depSets, validations) } func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath { diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go index 9c2d89951..f4da31ed2 100644 --- a/apex/platform_bootclasspath_test.go +++ b/apex/platform_bootclasspath_test.go @@ -409,6 +409,9 @@ func TestPlatformBootclasspathDependencies(t *testing.T) { // The fragments. `com.android.art:art-bootclasspath-fragment`, `myapex:my-bootclasspath-fragment`, + + // Impl lib of sdk_library for transitive srcjar generation + `platform:foo.impl`, }) } @@ -565,6 +568,9 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { // The fragments. "myapex:mybootclasspath-fragment", "myapex:prebuilt_mybootclasspath-fragment", + + // Impl lib of sdk_library for transitive srcjar generation + "platform:foo.impl", }) } diff --git a/bazel/configurability.go b/bazel/configurability.go index 2c9a5364a..3a65614da 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -100,9 +100,7 @@ func createPlatformArchMap() map[string]string { // Copy of archFeatures from android/arch_list.go because the bazel // package can't access the android package archFeatures := map[string][]string{ - "arm": { - "neon", - }, + "arm": {}, "arm64": { "dotprod", }, @@ -137,7 +137,7 @@ type Deps struct { // LLNDK headers for the ABI checker to check LLNDK implementation library. // An LLNDK implementation is the core variant. LLNDK header libs are reexported by the vendor variant. - // The core variant cannot depend on the vendor variant because of the order of CreateVariations. + // The core variant cannot depend on the vendor variant because of the order of imageTransitionMutator.Split(). // Instead, the LLNDK implementation depends on the LLNDK header libs. LlndkHeaderLibs []string } diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go index 5aa2a7e3b..e7ac03863 100644 --- a/cc/config/x86_64_device.go +++ b/cc/config/x86_64_device.go @@ -40,6 +40,9 @@ var ( "-march=x86-64", }, + "alderlake": []string{ + "-march=alderlake", + }, "broadwell": []string{ "-march=broadwell", }, diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go index 4b0041c9e..a92881d91 100644 --- a/cc/config/x86_device.go +++ b/cc/config/x86_device.go @@ -42,6 +42,9 @@ var ( "x86_64": []string{ "-march=prescott", }, + "alderlake": []string{ + "-march=alderlake", + }, "atom": []string{ "-march=atom", }, diff --git a/compliance/Android.bp b/compliance/Android.bp index 08736b4f7..80f56857f 100644 --- a/compliance/Android.bp +++ b/compliance/Android.bp @@ -34,6 +34,7 @@ notice_xml { name: "notice_xml_system", partition_name: "system", visibility: [ + "//build/make/target/product/generic", "//device/google/cuttlefish/system_image", ], } diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go index 5c047bc83..8af2ffaab 100644 --- a/filesystem/aconfig_files.go +++ b/filesystem/aconfig_files.go @@ -79,6 +79,7 @@ func (f *filesystem) buildAconfigFlagsFiles(ctx android.ModuleContext, builder * generatePartitionAconfigStorageFile("package_map", "package.map") generatePartitionAconfigStorageFile("flag_map", "flag.map") generatePartitionAconfigStorageFile("flag_val", "flag.val") + generatePartitionAconfigStorageFile("flag_info", "flag.info") android.WriteExecutableFileRuleVerbatim(ctx, aconfigFlagsBuilderPath, sb.String()) } diff --git a/genrule/Android.bp b/genrule/Android.bp index f4197e691..49df48075 100644 --- a/genrule/Android.bp +++ b/genrule/Android.bp @@ -25,3 +25,53 @@ bootstrap_go_package { // Used by plugins visibility: ["//visibility:public"], } + +genrule { + name: "nsjail_genrule_test_input", + cmd: "echo nsjail_genrule_test_input > $(out)", + out: ["nsjail_genrule_test_input.txt"], +} + +// Pseudo-test that's run on checkbuilds to verify consistent directory +// structure for genrules using sbox or nsjail. +genrule_defaults { + name: "nsjail_genrule_test_gen_defaults", + // verify both relative paths and its contents + cmd: "(echo $(out) $(genDir) && sha256sum " + + "$(location get_clang_version) " + + "$(location py3-cmd) " + + "$(location genrule.go) " + + "$(location :nsjail_genrule_test_input) " + + "$(locations *.go)) | sed 's@\\./@@g' > $(out)", + tools: [ + "get_clang_version", // random tool + "py3-cmd", // random prebuilt tool + ], + tool_files: ["genrule.go"], // random local file + srcs: [ + ":nsjail_genrule_test_input", // random OutputFileProducer + "*.go", // random glob + ], + out: ["nsjail_genrule_test.txt"], +} + +genrule { + name: "nsjail_genrule_test_gen_without_nsjail", + defaults: ["nsjail_genrule_test_gen_defaults"], +} + +genrule { + name: "nsjail_genrule_test_gen_with_nsjail", + defaults: ["nsjail_genrule_test_gen_defaults"], + use_nsjail: true, +} + +genrule { + name: "nsjail_genrule_test", + srcs: [ + ":nsjail_genrule_test_gen_without_nsjail", + ":nsjail_genrule_test_gen_with_nsjail", + ], + cmd: "diff $(in) > $(out)", + out: ["nsjail_genrule_test"], +} diff --git a/genrule/genrule.go b/genrule/genrule.go index a48038bac..e5222a432 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -21,6 +21,7 @@ package genrule import ( "fmt" "io" + "path/filepath" "strconv" "strings" @@ -210,6 +211,9 @@ type generateTask struct { // For gensrsc sharding. shard int shards int + + // For nsjail tasks + useNsjail bool } func (g *Module) GeneratedSourceFiles() android.Paths { @@ -313,16 +317,14 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { if len(g.properties.Tools) > 0 { seenTools := make(map[string]bool) - ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) { + ctx.VisitDirectDepsAllowDisabled(func(module android.Module) { switch tag := ctx.OtherModuleDependencyTag(module).(type) { case hostToolDependencyTag: tool := ctx.OtherModuleName(module) - if m, ok := module.(android.Module); ok { - // Necessary to retrieve any prebuilt replacement for the tool, since - // toolDepsMutator runs too late for the prebuilt mutators to have - // replaced the dependency. - module = android.PrebuiltGetPreferred(ctx, m) - } + // Necessary to retrieve any prebuilt replacement for the tool, since + // toolDepsMutator runs too late for the prebuilt mutators to have + // replaced the dependency. + module = android.PrebuiltGetPreferred(ctx, module) switch t := module.(type) { case android.HostToolProvider: @@ -454,21 +456,26 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { // Pick a unique path outside the task.genDir for the sbox manifest textproto, // a unique rule name, and the user-visible description. - manifestName := "genrule.sbox.textproto" + var rule *android.RuleBuilder desc := "generate" name := "generator" - if task.shards > 0 { - manifestName = "genrule_" + strconv.Itoa(task.shard) + ".sbox.textproto" - desc += " " + strconv.Itoa(task.shard) - name += strconv.Itoa(task.shard) - } else if len(task.out) == 1 { - desc += " " + task.out[0].Base() - } + if task.useNsjail { + rule = android.NewRuleBuilder(pctx, ctx).Nsjail(task.genDir, android.PathForModuleOut(ctx, "nsjail_build_sandbox")) + } else { + manifestName := "genrule.sbox.textproto" + if task.shards > 0 { + manifestName = "genrule_" + strconv.Itoa(task.shard) + ".sbox.textproto" + desc += " " + strconv.Itoa(task.shard) + name += strconv.Itoa(task.shard) + } else if len(task.out) == 1 { + desc += " " + task.out[0].Base() + } - manifestPath := android.PathForModuleOut(ctx, manifestName) + manifestPath := android.PathForModuleOut(ctx, manifestName) - // Use a RuleBuilder to create a rule that runs the command inside an sbox sandbox. - rule := getSandboxedRuleBuilder(ctx, android.NewRuleBuilder(pctx, ctx).Sbox(task.genDir, manifestPath)) + // Use a RuleBuilder to create a rule that runs the command inside an sbox sandbox. + rule = getSandboxedRuleBuilder(ctx, android.NewRuleBuilder(pctx, ctx).Sbox(task.genDir, manifestPath)) + } if Bool(g.properties.Write_if_changed) { rule.Restat() } @@ -569,6 +576,15 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx)) } + if task.useNsjail { + for _, input := range task.in { + // can fail if input is a file. + if paths, err := ctx.GlobWithDeps(filepath.Join(input.String(), "**/*"), nil); err == nil { + rule.NsjailImplicits(android.PathsForSource(ctx, paths)) + } + } + } + // Create the rule to run the genrule command inside sbox. rule.Build(name, desc) @@ -832,15 +848,18 @@ func NewGenRule() *Module { properties := &genRuleProperties{} taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask { + useNsjail := Bool(properties.Use_nsjail) + outs := make(android.WritablePaths, len(properties.Out)) for i, out := range properties.Out { outs[i] = android.PathForModuleGen(ctx, out) } return []generateTask{{ - in: srcFiles, - out: outs, - genDir: android.PathForModuleGen(ctx), - cmd: rawCommand, + in: srcFiles, + out: outs, + genDir: android.PathForModuleGen(ctx), + cmd: rawCommand, + useNsjail: useNsjail, }} } @@ -855,6 +874,8 @@ func GenRuleFactory() android.Module { } type genRuleProperties struct { + Use_nsjail *bool + // names of the output files that will be generated Out []string `android:"arch_variant"` } diff --git a/java/Android.bp b/java/Android.bp index a930dd4aa..1101d7a33 100644 --- a/java/Android.bp +++ b/java/Android.bp @@ -72,7 +72,6 @@ bootstrap_go_package { "rro.go", "sdk.go", "sdk_library.go", - "sdk_library_external.go", "sdk_library_internal.go", "support_libraries.go", "system_modules.go", diff --git a/java/aar.go b/java/aar.go index b5e24c4b2..7d73b03e4 100644 --- a/java/aar.go +++ b/java/aar.go @@ -45,7 +45,7 @@ func RegisterAARBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("android_library_import", AARImportFactory) ctx.RegisterModuleType("android_library", AndroidLibraryFactory) ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator) + ctx.Transition("propagate_rro_enforcement", &propagateRROEnforcementTransitionMutator{}) }) } @@ -151,15 +151,67 @@ type split struct { path android.Path } -// Propagate RRO enforcement flag to static lib dependencies transitively. -func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) { +// Propagate RRO enforcement flag to static lib dependencies transitively. If EnforceRROGlobally is set then +// all modules will use the "" variant. If specific modules have RRO enforced, then modules (usually apps) with +// RRO enabled will use the "" variation for themselves, but use the "rro" variant of direct and transitive static +// android_library dependencies. +type propagateRROEnforcementTransitionMutator struct{} + +func (p propagateRROEnforcementTransitionMutator) Split(ctx android.BaseModuleContext) []string { + // Never split modules, apps with or without RRO enabled use the "" variant, static android_library dependencies + // will use create the "rro" variant from incoming tranisitons. + return []string{""} +} + +func (p propagateRROEnforcementTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { + // Non-static dependencies are not involved in RRO and always use the empty variant. + if ctx.DepTag() != staticLibTag { + return "" + } + m := ctx.Module() - if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) { - ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) { - if a, ok := d.(AndroidLibraryDependency); ok { - a.SetRROEnforcedForDependent(true) - } - }) + if _, ok := m.(AndroidLibraryDependency); ok { + // If RRO is enforced globally don't bother using "rro" variants, the empty variant will have RRO enabled. + if ctx.Config().EnforceRROGlobally() { + return "" + } + + // If RRO is enabled for this module use the "rro" variants of static dependencies. IncomingTransition will + // rewrite this back to "" if the dependency is not an android_library. + if ctx.Config().EnforceRROForModule(ctx.Module().Name()) { + return "rro" + } + } + + return sourceVariation +} + +func (p propagateRROEnforcementTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { + // Propagate the "rro" variant to android_library modules, but use the empty variant for everything else. + if incomingVariation == "rro" { + m := ctx.Module() + if _, ok := m.(AndroidLibraryDependency); ok { + return "rro" + } + return "" + } + + return "" +} + +func (p propagateRROEnforcementTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { + m := ctx.Module() + if d, ok := m.(AndroidLibraryDependency); ok { + if variation == "rro" { + // This is the "rro" variant of a module that has both variants, mark this one as RRO enabled and + // hide it from make to avoid collisions with the non-RRO empty variant. + d.SetRROEnforcedForDependent(true) + m.HideFromMake() + } else if ctx.Config().EnforceRROGlobally() { + // RRO is enabled globally, mark it enabled for this module, but there is only one variant so no + // need to hide it from make. + d.SetRROEnforcedForDependent(true) + } } } diff --git a/java/androidmk.go b/java/androidmk.go index a1bc90494..0539d25aa 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -415,7 +415,7 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { } else { var names []string for _, jniLib := range app.jniLibs { - names = append(names, jniLib.name) + names = append(names, jniLib.name+":"+jniLib.target.Arch.ArchType.Bitness()) } entries.AddStrings("LOCAL_REQUIRED_MODULES", names...) } diff --git a/java/androidmk_test.go b/java/androidmk_test.go index 243a2791e..1d98b180d 100644 --- a/java/androidmk_test.go +++ b/java/androidmk_test.go @@ -286,7 +286,7 @@ func TestJniAsRequiredDeps(t *testing.T) { }{ { name: "app", - expected: []string{"libjni"}, + expected: []string{"libjni:64"}, }, { name: "app_embedded", diff --git a/java/app.go b/java/app.go index 4ac42a750..b77793bad 100644 --- a/java/app.go +++ b/java/app.go @@ -1135,7 +1135,7 @@ func collectJniDeps(ctx android.ModuleContext, return jniLibs, prebuiltJniPackages } -func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) { +func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) { ctx.WalkDeps(func(child, parent android.Module) bool { isExternal := !a.DepIsInSameApex(ctx, child) if am, ok := child.(android.ApexModule); ok { @@ -1153,7 +1153,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { } depsInfo := android.DepNameToDepInfoMap{} - a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { depName := to.Name() // Skip dependencies that are only available to APEXes; they are developed with updatability @@ -1417,7 +1417,8 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, - a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs) + a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, + a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options) a.testConfig = a.FixTestConfig(ctx, testConfig) a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs) a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) @@ -1781,16 +1782,15 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext } } - // Skip java_sdk_library dependencies that provide stubs, but not an implementation. - // This will be restricted to optional_uses_libs - if sdklib, ok := m.(SdkLibraryDependency); ok { - if tag == usesLibOptTag && sdklib.DexJarBuildPath(ctx).PathOrNil() == nil { - u.shouldDisableDexpreopt = true - return - } - } - if lib, ok := m.(UsesLibraryDependency); ok { + if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { + // Skip java_sdk_library dependencies that provide stubs, but not an implementation. + // This will be restricted to optional_uses_libs + if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil { + u.shouldDisableDexpreopt = true + return + } + } libName := dep if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil { libName = *ulib.ProvidesUsesLib() diff --git a/java/app_import.go b/java/app_import.go index 045a89a34..a54cf2fc3 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -533,10 +533,6 @@ func (a *AndroidAppImport) MinSdkVersion(ctx android.EarlyModuleContext) android return android.SdkSpecPrivate.ApiLevel } -func (a *AndroidAppImport) LintDepSets() LintDepSets { - return LintDepSets{} -} - var _ android.ApexModule = (*AndroidAppImport)(nil) // Implements android.ApexModule diff --git a/java/app_test.go b/java/app_test.go index d7f5f0c62..2a2611d8e 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -1419,26 +1419,31 @@ func TestAndroidResourceProcessor(t *testing.T) { } func TestAndroidResourceOverlays(t *testing.T) { + type moduleAndVariant struct { + module string + variant string + } + testCases := []struct { name string enforceRROTargets []string enforceRROExcludedOverlays []string - resourceFiles map[string][]string - overlayFiles map[string][]string - rroDirs map[string][]string + resourceFiles map[moduleAndVariant][]string + overlayFiles map[moduleAndVariant][]string + rroDirs map[moduleAndVariant][]string }{ { name: "no RRO", enforceRROTargets: nil, enforceRROExcludedOverlays: nil, - resourceFiles: map[string][]string{ - "foo": nil, - "bar": {"bar/res/res/values/strings.xml"}, - "lib": nil, - "lib2": {"lib2/res/res/values/strings.xml"}, + resourceFiles: map[moduleAndVariant][]string{ + {"foo", "android_common"}: nil, + {"bar", "android_common"}: {"bar/res/res/values/strings.xml"}, + {"lib", "android_common"}: nil, + {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"}, }, - overlayFiles: map[string][]string{ - "foo": { + overlayFiles: map[moduleAndVariant][]string{ + {"foo", "android_common"}: { "out/soong/.intermediates/lib2/android_common/package-res.apk", "out/soong/.intermediates/lib/android_common/package-res.apk", "out/soong/.intermediates/lib3/android_common/package-res.apk", @@ -1447,57 +1452,65 @@ func TestAndroidResourceOverlays(t *testing.T) { "device/vendor/blah/overlay/foo/res/values/strings.xml", "product/vendor/blah/overlay/foo/res/values/strings.xml", }, - "bar": { + {"bar", "android_common"}: { "device/vendor/blah/static_overlay/bar/res/values/strings.xml", "device/vendor/blah/overlay/bar/res/values/strings.xml", }, - "lib": { + {"lib", "android_common"}: { "out/soong/.intermediates/lib2/android_common/package-res.apk", "lib/res/res/values/strings.xml", "device/vendor/blah/overlay/lib/res/values/strings.xml", }, }, - rroDirs: map[string][]string{ - "foo": nil, - "bar": nil, + rroDirs: map[moduleAndVariant][]string{ + {"foo", "android_common"}: nil, + {"bar", "android_common"}: nil, }, }, { name: "enforce RRO on foo", enforceRROTargets: []string{"foo"}, enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"}, - resourceFiles: map[string][]string{ - "foo": nil, - "bar": {"bar/res/res/values/strings.xml"}, - "lib": nil, - "lib2": {"lib2/res/res/values/strings.xml"}, + resourceFiles: map[moduleAndVariant][]string{ + {"foo", "android_common"}: nil, + {"bar", "android_common"}: {"bar/res/res/values/strings.xml"}, + {"lib", "android_common"}: nil, + {"lib", "android_common_rro"}: nil, + {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"}, + {"lib2", "android_common_rro"}: {"lib2/res/res/values/strings.xml"}, }, - overlayFiles: map[string][]string{ - "foo": { - "out/soong/.intermediates/lib2/android_common/package-res.apk", - "out/soong/.intermediates/lib/android_common/package-res.apk", - "out/soong/.intermediates/lib3/android_common/package-res.apk", + overlayFiles: map[moduleAndVariant][]string{ + {"foo", "android_common"}: { + "out/soong/.intermediates/lib2/android_common_rro/package-res.apk", + "out/soong/.intermediates/lib/android_common_rro/package-res.apk", + "out/soong/.intermediates/lib3/android_common_rro/package-res.apk", "foo/res/res/values/strings.xml", "device/vendor/blah/static_overlay/foo/res/values/strings.xml", }, - "bar": { + {"bar", "android_common"}: { "device/vendor/blah/static_overlay/bar/res/values/strings.xml", "device/vendor/blah/overlay/bar/res/values/strings.xml", }, - "lib": { + {"lib", "android_common"}: { "out/soong/.intermediates/lib2/android_common/package-res.apk", "lib/res/res/values/strings.xml", + "device/vendor/blah/overlay/lib/res/values/strings.xml", + }, + {"lib", "android_common_rro"}: { + "out/soong/.intermediates/lib2/android_common_rro/package-res.apk", + "lib/res/res/values/strings.xml", }, }, - rroDirs: map[string][]string{ - "foo": { + rroDirs: map[moduleAndVariant][]string{ + {"foo", "android_common"}: { "device:device/vendor/blah/overlay/foo/res", "product:product/vendor/blah/overlay/foo/res", "device:device/vendor/blah/overlay/lib/res", }, - "bar": nil, - "lib": {"device:device/vendor/blah/overlay/lib/res"}, + {"bar", "android_common"}: nil, + {"lib", "android_common"}: nil, + {"lib", "android_common_rro"}: {"device:device/vendor/blah/overlay/lib/res"}, }, }, { @@ -1508,35 +1521,35 @@ func TestAndroidResourceOverlays(t *testing.T) { "device/vendor/blah/static_overlay/foo", "device/vendor/blah/static_overlay/bar/res", }, - resourceFiles: map[string][]string{ - "foo": nil, - "bar": {"bar/res/res/values/strings.xml"}, - "lib": nil, - "lib2": {"lib2/res/res/values/strings.xml"}, + resourceFiles: map[moduleAndVariant][]string{ + {"foo", "android_common"}: nil, + {"bar", "android_common"}: {"bar/res/res/values/strings.xml"}, + {"lib", "android_common"}: nil, + {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"}, }, - overlayFiles: map[string][]string{ - "foo": { + overlayFiles: map[moduleAndVariant][]string{ + {"foo", "android_common"}: { "out/soong/.intermediates/lib2/android_common/package-res.apk", "out/soong/.intermediates/lib/android_common/package-res.apk", "out/soong/.intermediates/lib3/android_common/package-res.apk", "foo/res/res/values/strings.xml", "device/vendor/blah/static_overlay/foo/res/values/strings.xml", }, - "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"}, - "lib": { + {"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"}, + {"lib", "android_common"}: { "out/soong/.intermediates/lib2/android_common/package-res.apk", "lib/res/res/values/strings.xml", }, }, - rroDirs: map[string][]string{ - "foo": { + rroDirs: map[moduleAndVariant][]string{ + {"foo", "android_common"}: { "device:device/vendor/blah/overlay/foo/res", "product:product/vendor/blah/overlay/foo/res", // Lib dep comes after the direct deps "device:device/vendor/blah/overlay/lib/res", }, - "bar": {"device:device/vendor/blah/overlay/bar/res"}, - "lib": {"device:device/vendor/blah/overlay/lib/res"}, + {"bar", "android_common"}: {"device:device/vendor/blah/overlay/bar/res"}, + {"lib", "android_common"}: {"device:device/vendor/blah/overlay/lib/res"}, }, }, } @@ -1621,19 +1634,19 @@ func TestAndroidResourceOverlays(t *testing.T) { for _, o := range list { res := module.MaybeOutput(o) if res.Rule != nil { - // If the overlay is compiled as part of this module (i.e. a .arsc.flat file), + // If the overlay is compiled as part of this moduleAndVariant (i.e. a .arsc.flat file), // verify the inputs to the .arsc.flat rule. files = append(files, res.Inputs.Strings()...) } else { - // Otherwise, verify the full path to the output of the other module + // Otherwise, verify the full path to the output of the other moduleAndVariant files = append(files, o) } } return files } - getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) { - module := result.ModuleForTests(moduleName, "android_common") + getResources := func(moduleName, variantName string) (resourceFiles, overlayFiles, rroDirs []string) { + module := result.ModuleForTests(moduleName, variantName) resourceList := module.MaybeOutput("aapt2/res.list") if resourceList.Rule != nil { resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs)) @@ -1658,21 +1671,33 @@ func TestAndroidResourceOverlays(t *testing.T) { return resourceFiles, overlayFiles, rroDirs } - modules := []string{"foo", "bar", "lib", "lib2"} - for _, module := range modules { - resourceFiles, overlayFiles, rroDirs := getResources(module) + modules := []moduleAndVariant{ + {"foo", "android_common"}, + {"foo", "android_common_rro"}, + {"bar", "android_common"}, + {"bar", "android_common_rro"}, + {"lib", "android_common"}, + {"lib", "android_common_rro"}, + {"lib2", "android_common"}, + {"lib2", "android_common_rro"}, + } + for _, moduleAndVariant := range modules { + if _, exists := testCase.resourceFiles[moduleAndVariant]; !exists { + continue + } + resourceFiles, overlayFiles, rroDirs := getResources(moduleAndVariant.module, moduleAndVariant.variant) - if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) { + if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[moduleAndVariant]) { t.Errorf("expected %s resource files:\n %#v\n got:\n %#v", - module, testCase.resourceFiles[module], resourceFiles) + moduleAndVariant, testCase.resourceFiles[moduleAndVariant], resourceFiles) } - if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) { + if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[moduleAndVariant]) { t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v", - module, testCase.overlayFiles[module], overlayFiles) + moduleAndVariant, testCase.overlayFiles[moduleAndVariant], overlayFiles) } - if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) { + if !reflect.DeepEqual(rroDirs, testCase.rroDirs[moduleAndVariant]) { t.Errorf("expected %s rroDirs: %#v\n got:\n %#v", - module, testCase.rroDirs[module], rroDirs) + moduleAndVariant, testCase.rroDirs[moduleAndVariant], rroDirs) } } }) diff --git a/java/base.go b/java/base.go index b64eb5b61..7c26cc355 100644 --- a/java/base.go +++ b/java/base.go @@ -708,9 +708,6 @@ func setOutputFiles(ctx android.ModuleContext, m Module) { ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map") } ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars") - if m.linter.outputs.xml != nil { - ctx.SetOutputFiles(android.Paths{m.linter.outputs.xml}, ".lint") - } } func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) { @@ -854,33 +851,6 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { // Add dependency on libraries that provide additional hidden api annotations. ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...) - if ctx.Config().EnforceInterPartitionJavaSdkLibrary() { - // Require java_sdk_library at inter-partition java dependency to ensure stable - // interface between partitions. If inter-partition java_library dependency is detected, - // raise build error because java_library doesn't have a stable interface. - // - // Inputs: - // PRODUCT_ENFORCE_INTER_PARTITION_JAVA_SDK_LIBRARY - // if true, enable enforcement - // PRODUCT_INTER_PARTITION_JAVA_LIBRARY_ALLOWLIST - // exception list of java_library names to allow inter-partition dependency - for idx := range j.properties.Libs { - if libDeps[idx] == nil { - continue - } - - if javaDep, ok := libDeps[idx].(javaSdkLibraryEnforceContext); ok { - // java_sdk_library is always allowed at inter-partition dependency. - // So, skip check. - if _, ok := javaDep.(*SdkLibrary); ok { - continue - } - - j.checkPartitionsForJavaDependency(ctx, "libs", javaDep) - } - } - } - // For library dependencies that are component libraries (like stubs), add the implementation // as a dependency (dexpreopt needs to be against the implementation library, not stubs). for _, dep := range libDeps { @@ -1736,8 +1706,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath return } + completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars + if j.shouldInstrument(ctx) { - outputFile = j.instrument(ctx, flags, outputFile, jarName, specs) + instrumentedOutputFile := j.instrument(ctx, flags, outputFile, jarName, specs) + completeStaticLibsImplementationJarsToCombine = android.NewDepSet(android.PREORDER, android.Paths{instrumentedOutputFile}, nil) + outputFile = instrumentedOutputFile } // merge implementation jar with resources if necessary @@ -1745,7 +1719,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath if ctx.Config().UseTransitiveJarsInClasspath() { resourceJars := completeStaticLibsResourceJars.ToList() if len(resourceJars) > 0 { - implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJars.ToList()...) + implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJarsToCombine.ToList()...) implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...) } } else { @@ -2414,10 +2388,9 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { return } - if _, ok := module.(SdkLibraryDependency); ok { + if sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { switch tag { case sdkLibTag, libTag, staticLibTag: - sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider) generatingLibsString := android.PrettyConcat( getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or") ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString) @@ -2726,7 +2699,7 @@ func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProvid module := ctx.Module() moduleName := module.Name() - ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) { + ctx.VisitDirectDeps(func(m android.Module) { 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 @@ -2749,7 +2722,7 @@ func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProvid if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag { return RenameUseExclude, "tags" } - if _, ok := m.(SdkLibraryDependency); ok { + if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { switch tag { case sdkLibTag, libTag: return RenameUseExclude, "sdklibdep" // matches collectDeps() diff --git a/java/dex.go b/java/dex.go index e0e642c63..faf51a36a 100644 --- a/java/dex.go +++ b/java/dex.go @@ -220,14 +220,28 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext, deps = append(deps, f) } + var requestReleaseMode bool + requestReleaseMode, flags = android.RemoveFromList("--release", flags) + if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" { flags = append(flags, "--debug") + requestReleaseMode = false } if ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" { flags = append(flags, "--debug", "--verbose") + requestReleaseMode = false + } + + // Don't strip out debug information for eng builds, unless the target + // explicitly provided the `--release` build flag. This allows certain + // test targets to remain optimized as part of eng test_suites builds. + if requestReleaseMode { + flags = append(flags, "--release") + } else if ctx.Config().Eng() { + flags = append(flags, "--debug") } // Supplying the platform build flag disables various features like API modeling and desugaring. @@ -384,11 +398,6 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams) // TODO(ccross): if this is an instrumentation test of an obfuscated app, use the // dictionary of the app and move the app from libraryjars to injars. - // Don't strip out debug information for eng builds. - if ctx.Config().Eng() { - r8Flags = append(r8Flags, "--debug") - } - // TODO(b/180878971): missing classes should be added to the relevant builds. // TODO(b/229727645): do not use true as default for Android platform builds. if proptools.BoolDefault(opt.Ignore_warnings, true) { diff --git a/java/dex_test.go b/java/dex_test.go index 4862d06c9..8bc28e678 100644 --- a/java/dex_test.go +++ b/java/dex_test.go @@ -713,3 +713,97 @@ android_app { } }`) } + +func TestDebugReleaseFlags(t *testing.T) { + bp := ` + android_app { + name: "app", + srcs: ["foo.java"], + platform_apis: true, + dxflags: ["%s"] + } + ` + + testcases := []struct { + name string + envVar string + isEng bool + dxFlags string + expectedFlags string + }{ + { + name: "app_no_optimize_dx", + envVar: "NO_OPTIMIZE_DX", + expectedFlags: "--debug", + }, + { + name: "app_release_no_optimize_dx", + envVar: "NO_OPTIMIZE_DX", + dxFlags: "--release", + // Global env vars override explicit dxflags. + expectedFlags: "--debug", + }, + { + name: "app_generate_dex_debug", + envVar: "GENERATE_DEX_DEBUG", + expectedFlags: "--debug", + }, + { + name: "app_release_generate_dex_debug", + envVar: "GENERATE_DEX_DEBUG", + dxFlags: "--release", + // Global env vars override explicit dxflags. + expectedFlags: "--debug", + }, + { + name: "app_eng", + isEng: true, + expectedFlags: "--debug", + }, + { + name: "app_release_eng", + isEng: true, + dxFlags: "--release", + // Eng mode does *not* override explicit dxflags. + expectedFlags: "--release", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + fixturePreparer := PrepareForTestWithJavaDefaultModules + fixturePreparer = android.GroupFixturePreparers( + fixturePreparer, + android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.Eng = proptools.BoolPtr(tc.isEng) + }, + ), + ) + if tc.envVar != "" { + fixturePreparer = android.GroupFixturePreparers( + fixturePreparer, + android.FixtureMergeEnv(map[string]string{ + tc.envVar: "true", + }), + ) + } + result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, tc.dxFlags)) + + appR8 := result.ModuleForTests("app", "android_common").Rule("r8") + android.AssertStringDoesContain(t, "expected flag in R8 flags", + appR8.Args["r8Flags"], tc.expectedFlags) + + var unexpectedFlags string + if tc.expectedFlags == "--debug" { + unexpectedFlags = "--release" + } else if tc.expectedFlags == "--release" { + unexpectedFlags = "--debug" + } + if unexpectedFlags != "" { + android.AssertStringDoesNotContain(t, "unexpected flag in R8 flags", + appR8.Args["r8Flags"], unexpectedFlags) + } + }) + } +} diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index a2e473469..7a77b1596 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -463,6 +463,7 @@ func dexpreoptBootJarsFactory() android.SingletonModule { func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) { ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory) + ctx.RegisterModuleType("art_boot_images", artBootImagesFactory) ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator).Parallel() }) @@ -601,6 +602,7 @@ func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContex d.defaultBootImage = defaultBootImageConfig(ctx) d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1) var profileInstalls android.RuleBuilderInstalls + var artBootImageHostInstalls android.RuleBuilderInstalls for _, name := range getImageNames() { config := imageConfigs[name] if config != d.defaultBootImage { @@ -616,6 +618,18 @@ func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContex d.bootFrameworkProfile = bootProfile profileInstalls = append(profileInstalls, installs...) } + // Gather the install files of the host variant of the ART boot image. + // These installed files will be used in ART tests. + if config.name == "art" { + for _, variant := range config.variants { + if variant.target.Os != ctx.Config().BuildOS { + // not a host variant + continue + } + artBootImageHostInstalls = append(artBootImageHostInstalls, variant.installs...) + artBootImageHostInstalls = append(artBootImageHostInstalls, variant.vdexInstalls...) + } + } } if len(profileInstalls) > 0 { android.SetProvider(ctx, profileInstallInfoProvider, profileInstallInfo{ @@ -626,6 +640,15 @@ func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContex installFile(ctx, install) } } + // Set a provider containing the install files of the host variant of the ART boot image. + // The actual install rules will be created by `art_boot_images` + android.SetProvider( + ctx, + artBootImageHostInfoProvider, + artBootImageHostInfo{ + installs: artBootImageHostInstalls, + }, + ) } // GenerateSingletonBuildActions generates build rules for the dexpreopt config for Make. @@ -968,6 +991,14 @@ func packageFileForTargetImage(ctx android.ModuleContext, image *bootImageVarian } } +var artBootImageHostInfoProvider = blueprint.NewProvider[artBootImageHostInfo]() + +// artBootImageHostInfo contains the install locations of the host variant of ART boot image +// this contains both the primary and secondary arch locations +type artBootImageHostInfo struct { + installs android.RuleBuilderInstalls +} + // Generate boot image build rules for a specific target. func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs { @@ -1344,18 +1375,7 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { } image := d.defaultBootImage - if image != nil { - if profileInstallInfo, ok := android.OtherModuleProvider(ctx, d, profileInstallInfoProvider); ok { - ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", profileInstallInfo.profileInstalls.String()) - if profileInstallInfo.profileLicenseMetadataFile.Valid() { - ctx.Strict("DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA", profileInstallInfo.profileLicenseMetadataFile.String()) - } - } - - if SkipDexpreoptBootJars(ctx) { - return - } - + if image != nil && !SkipDexpreoptBootJars(ctx) { global := dexpreopt.GetGlobalConfig(ctx) dexPaths, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " ")) @@ -1396,3 +1416,70 @@ func (d *dexpreoptBootJars) AndroidMkEntries() []android.AndroidMkEntries { OutputFile: android.OptionalPathForPath(d.bootFrameworkProfile), }} } + +// artBootImages is a thin wrapper around `dex_bootjars`. +// it creates the installation rules for the host variant of the ART boot image. +type artBootImages struct { + android.ModuleBase + + // A non-empty file that will be written as `LOCAL_SOONG_INSTALLED_MODULE` in out/soong/Android-*.mk + outputFile android.OptionalPath +} + +func artBootImagesFactory() android.Module { + m := &artBootImages{} + android.InitAndroidMultiTargetsArchModule(m, android.HostSupported, android.MultilibCommon) + return m +} + +func (dbj *artBootImages) DepsMutator(ctx android.BottomUpMutatorContext) { + // Create a dependency on `dex_bootjars` to access the intermediate locations of host art boot image. + ctx.AddDependency(ctx.Module(), dexpreoptBootJarDepTag, "dex_bootjars") +} + +func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) { + ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(m android.Module) { + hostInstallsInfo, ok := android.OtherModuleProvider(ctx, m, artBootImageHostInfoProvider) + if !ok { + ctx.ModuleErrorf("Could not find information about the host variant of ART boot image") + } + installs := d.installFile(ctx, hostInstallsInfo.installs) + if len(installs) > 0 { + d.outputFile = android.OptionalPathForPath(installs[0]) + // Create a phony target that can ART run-tests can depend on. + ctx.Phony(d.Name(), installs...) + } else { + // this might be true e.g. when building with `WITH_DEXPREOPT=false` + // create an empty file so that the `art_boot_images` is known to the packaging system. + d.outputFile = android.OptionalPathForPath(android.PathForModuleOut(ctx, "undefined_art_boot_images")) + } + }) +} + +// Creates an installation rule for host variant of ART boot image files. +// Returns the list of install locations (out/host/linux-x86/...) +func (d *artBootImages) installFile(ctx android.ModuleContext, ruleBuilderInstalls android.RuleBuilderInstalls) android.Paths { + var ret android.Paths + for _, ruleBuilderInstall := range ruleBuilderInstalls { + installDir := android.PathForModuleInstall( + ctx, + strings.TrimPrefix(filepath.Dir(ruleBuilderInstall.To), "/"), + ) + filename := filepath.Base(ruleBuilderInstall.To) + ctx.InstallFile( + installDir, + filename, + ruleBuilderInstall.From, + ) + ret = append(ret, installDir.Join(ctx, filename)) + } + return ret +} + +// Set `OutputFile` expclitly so that this module does not get elided when generating out/soong/Android-*.mk +func (d *artBootImages) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{{ + Class: "ETC", + OutputFile: d.outputFile, + }} +} diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go index 37c54b915..33c682bfa 100644 --- a/java/dexpreopt_config_testing.go +++ b/java/dexpreopt_config_testing.go @@ -1335,8 +1335,6 @@ DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/dexpreopt_arm64/dex_artjars/andro DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTmainline=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art:out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/boot-framework-foo.art DEXPREOPT_IMAGE_NAMES=art boot mainline -DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof:/system/etc/boot-image.prof out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof -DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-extra1.oat:/apex/art_boot_images/javalib/arm/boot-extra1.oat DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat:/apex/art_boot_images/javalib/arm64/boot-extra1.oat DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat:/apex/art_boot_images/javalib/x86/boot-extra1.oat diff --git a/java/droiddoc.go b/java/droiddoc.go index a7e92d9ef..2980d91de 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -373,8 +373,7 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName())) } case libTag, sdkLibTag: - if _, ok := module.(SdkLibraryDependency); ok { - sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider) + if sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { generatingLibsString := android.PrettyConcat( getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or") ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString) diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 4144de82b..365005835 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -298,13 +298,12 @@ func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScop // available, or reports an error. func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path { var dexJar OptionalDexJarPath - if sdkLibrary, ok := module.(SdkLibraryDependency); ok { + if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { if ctx.Config().ReleaseHiddenApiExportableStubs() { - dexJar = sdkLibrary.SdkApiExportableStubDexJar(ctx, kind) + dexJar = sdkLibrary.ExportableStubDexJarPaths[kind] } else { - dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind) + dexJar = sdkLibrary.EverythingStubDexJarPaths[kind] } - } else if j, ok := module.(UsesLibraryDependency); ok { dexJar = j.DexJarBuildPath(ctx) } else { @@ -853,15 +852,15 @@ func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, conten i.StubDexJarsByScope.addStubDexJar(ctx, module, apiScope, dexJar) } - if sdkLibrary, ok := module.(SdkLibraryDependency); ok { - removedTxtFile := sdkLibrary.SdkRemovedTxtFile(ctx, sdkKind) + if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { + removedTxtFile := sdkLibrary.RemovedTxtFiles[sdkKind] i.RemovedTxtFiles = append(i.RemovedTxtFiles, removedTxtFile.AsPaths()...) } } // If the contents includes any java_sdk_library modules then add them to the stubs. for _, module := range contents { - if _, ok := module.(SdkLibraryDependency); ok { + if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { // Add information for every possible API scope needed by hidden API. for _, apiScope := range hiddenAPISdkLibrarySupportedScopes { addFromModule(ctx, module, apiScope) diff --git a/java/java.go b/java/java.go index 91c4d6dfc..92dcc6322 100644 --- a/java/java.go +++ b/java/java.go @@ -2612,17 +2612,6 @@ func (a *Import) JacocoReportClassesFile() android.Path { return nil } -func (j *Import) LintDepSets() LintDepSets { - return LintDepSets{} -} - -func (j *Import) getStrictUpdatabilityLinting() bool { - return false -} - -func (j *Import) setStrictUpdatabilityLinting(bool) { -} - func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs.GetOrDefault(ctx, nil)...) @@ -2700,7 +2689,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) } } - } else if _, ok := module.(SdkLibraryDependency); ok { + } else if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { switch tag { case libTag, sdkLibTag: sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider) @@ -3098,21 +3087,10 @@ func (a *DexImport) JacocoReportClassesFile() android.Path { return nil } -func (a *DexImport) LintDepSets() LintDepSets { - return LintDepSets{} -} - func (j *DexImport) IsInstallable() bool { return true } -func (j *DexImport) getStrictUpdatabilityLinting() bool { - return false -} - -func (j *DexImport) setStrictUpdatabilityLinting(bool) { -} - func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { if len(j.properties.Jars) != 1 { ctx.PropertyErrorf("jars", "exactly one jar must be provided") @@ -3315,7 +3293,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule)) var sdkLib *string - if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() { + if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary { // A shared SDK library. This should be added as a top-level CLC element. sdkLib = &depName } else if lib, ok := depModule.(SdkLibraryComponentDependency); ok && lib.OptionalSdkLibraryImplementation() != nil { diff --git a/java/java_test.go b/java/java_test.go index e0fd0f24e..641bf4030 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -3065,6 +3065,43 @@ func TestJavaLibraryOutputFilesRel(t *testing.T) { "baz.jar", bazOutputPaths[0].Rel()) } +func TestCoverage(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + prepareForTestWithFrameworkJacocoInstrumentation, + PrepareForTestWithTransitiveClasspathEnabled, + ).RunTestWithBp(t, ` + android_app { + name: "foo", + srcs: ["foo.java"], + static_libs: ["android.car"], + platform_apis: true, + } + + // A library in InstrumentFrameworkModules + java_library { + name: "android.car", + srcs: ["android.car.java"], + } + `) + + foo := result.ModuleForTests("foo", "android_common") + androidCar := result.ModuleForTests("android.car", "android_common") + + fooJacoco := foo.Rule("jacoco") + fooCombine := foo.Description("for javac") + + androidCarJacoco := androidCar.Rule("jacoco") + androidCarJavac := androidCar.Rule("javac") + + android.AssertStringEquals(t, "foo instrumentation rule inputs", fooJacoco.Input.String(), fooCombine.Output.String()) + android.AssertStringEquals(t, "android.car instrumentation rule inputs", androidCarJacoco.Input.String(), androidCarJavac.Output.String()) + + // The input to instrumentation for the `foo` app contains the non-instrumented android.car classes. + android.AssertStringListContains(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJavac.Output.String()) + android.AssertStringListDoesNotContain(t, "foo combined inputs", fooCombine.Inputs.Strings(), androidCarJacoco.Output.String()) +} + func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) { t.Helper() actualTrueModules := []string{} diff --git a/java/lint.go b/java/lint.go index 6782adc5f..2cbefc3bb 100644 --- a/java/lint.go +++ b/java/lint.go @@ -19,6 +19,7 @@ import ( "sort" "strings" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" @@ -90,7 +91,6 @@ type linter struct { compileSdkKind android.SdkKind javaLanguageLevel string kotlinLanguageLevel string - outputs lintOutputs properties LintProperties extraMainlineLintErrors []string compile_data android.Paths @@ -100,68 +100,55 @@ type linter struct { buildModuleReportZip bool } -type lintOutputs struct { - html android.Path - text android.Path - xml android.Path - referenceBaseline android.Path - - depSets LintDepSets -} - -type lintOutputsIntf interface { - lintOutputs() *lintOutputs -} - -type LintDepSetsIntf interface { - LintDepSets() LintDepSets - - // Methods used to propagate strict_updatability_linting values. - GetStrictUpdatabilityLinting() bool - SetStrictUpdatabilityLinting(bool) -} - type LintDepSets struct { - HTML, Text, XML *android.DepSet[android.Path] + HTML, Text, XML, Baseline *android.DepSet[android.Path] } type LintDepSetsBuilder struct { - HTML, Text, XML *android.DepSetBuilder[android.Path] + HTML, Text, XML, Baseline *android.DepSetBuilder[android.Path] } func NewLintDepSetBuilder() LintDepSetsBuilder { return LintDepSetsBuilder{ - HTML: android.NewDepSetBuilder[android.Path](android.POSTORDER), - Text: android.NewDepSetBuilder[android.Path](android.POSTORDER), - XML: android.NewDepSetBuilder[android.Path](android.POSTORDER), + HTML: android.NewDepSetBuilder[android.Path](android.POSTORDER), + Text: android.NewDepSetBuilder[android.Path](android.POSTORDER), + XML: android.NewDepSetBuilder[android.Path](android.POSTORDER), + Baseline: android.NewDepSetBuilder[android.Path](android.POSTORDER), } } -func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder { +func (l LintDepSetsBuilder) Direct(html, text, xml android.Path, baseline android.OptionalPath) LintDepSetsBuilder { l.HTML.Direct(html) l.Text.Direct(text) l.XML.Direct(xml) + if baseline.Valid() { + l.Baseline.Direct(baseline.Path()) + } return l } -func (l LintDepSetsBuilder) Transitive(depSets LintDepSets) LintDepSetsBuilder { - if depSets.HTML != nil { - l.HTML.Transitive(depSets.HTML) +func (l LintDepSetsBuilder) Transitive(info *LintInfo) LintDepSetsBuilder { + if info.TransitiveHTML != nil { + l.HTML.Transitive(info.TransitiveHTML) + } + if info.TransitiveText != nil { + l.Text.Transitive(info.TransitiveText) } - if depSets.Text != nil { - l.Text.Transitive(depSets.Text) + if info.TransitiveXML != nil { + l.XML.Transitive(info.TransitiveXML) } - if depSets.XML != nil { - l.XML.Transitive(depSets.XML) + if info.TransitiveBaseline != nil { + l.Baseline.Transitive(info.TransitiveBaseline) } return l } func (l LintDepSetsBuilder) Build() LintDepSets { return LintDepSets{ - HTML: l.HTML.Build(), - Text: l.Text.Build(), - XML: l.XML.Build(), + HTML: l.HTML.Build(), + Text: l.Text.Build(), + XML: l.XML.Build(), + Baseline: l.Baseline.Build(), } } @@ -209,24 +196,18 @@ var allLintDatabasefiles = map[android.SdkKind]lintDatabaseFiles{ }, } -func (l *linter) LintDepSets() LintDepSets { - return l.outputs.depSets -} +var LintProvider = blueprint.NewProvider[*LintInfo]() -func (l *linter) GetStrictUpdatabilityLinting() bool { - return BoolDefault(l.properties.Lint.Strict_updatability_linting, false) -} +type LintInfo struct { + HTML android.Path + Text android.Path + XML android.Path + ReferenceBaseline android.Path -func (l *linter) SetStrictUpdatabilityLinting(strictLinting bool) { - l.properties.Lint.Strict_updatability_linting = &strictLinting -} - -var _ LintDepSetsIntf = (*linter)(nil) - -var _ lintOutputsIntf = (*linter)(nil) - -func (l *linter) lintOutputs() *lintOutputs { - return &l.outputs + TransitiveHTML *android.DepSet[android.Path] + TransitiveText *android.DepSet[android.Path] + TransitiveXML *android.DepSet[android.Path] + TransitiveBaseline *android.DepSet[android.Path] } func (l *linter) enabled() bool { @@ -262,7 +243,9 @@ func lintRBEExecStrategy(ctx android.ModuleContext) string { return ctx.Config().GetenvWithDefault("RBE_LINT_EXEC_STRATEGY", remoteexec.LocalExecStrategy) } -func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.RuleBuilder, srcsList android.Path) lintPaths { +func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.RuleBuilder, srcsList android.Path, + baselines android.Paths) lintPaths { + projectXMLPath := android.PathForModuleOut(ctx, "lint", "project.xml") // Lint looks for a lint.xml file next to the project.xml file, give it one. configXMLPath := android.PathForModuleOut(ctx, "lint", "lint.xml") @@ -325,12 +308,10 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.Ru cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks) cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks) - if l.GetStrictUpdatabilityLinting() { + if Bool(l.properties.Lint.Strict_updatability_linting) && len(baselines) > 0 { // Verify the module does not baseline issues that endanger safe updatability. - if l.properties.Lint.Baseline_filename != nil { - cmd.FlagWithInput("--baseline ", android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename)) - cmd.FlagForEachArg("--disallowed_issues ", updatabilityChecks) - } + strictUpdatabilityChecksOutputFile := VerifyStrictUpdatabilityChecks(ctx, baselines) + cmd.Validation(strictUpdatabilityChecksOutputFile) } return lintPaths{ @@ -342,6 +323,22 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.Ru } +func VerifyStrictUpdatabilityChecks(ctx android.ModuleContext, baselines android.Paths) android.Path { + rule := android.NewRuleBuilder(pctx, ctx) + baselineRspFile := android.PathForModuleOut(ctx, "lint_strict_updatability_check_baselines.rsp") + outputFile := android.PathForModuleOut(ctx, "lint_strict_updatability_check.stamp") + rule.Command().Text("rm -f").Output(outputFile) + rule.Command(). + BuiltTool("lint_strict_updatability_checks"). + FlagWithArg("--name ", ctx.ModuleName()). + FlagWithRspFileInputList("--baselines ", baselineRspFile, baselines). + FlagForEachArg("--disallowed_issues ", updatabilityChecks) + rule.Command().Text("touch").Output(outputFile) + rule.Build("lint_strict_updatability_checks", "lint strict updatability checks") + + return outputFile +} + // generateManifest adds a command to the rule to write a simple manifest that contains the // minSdkVersion and targetSdkVersion for modules (like java_library) that don't have a manifest. func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleBuilder) android.WritablePath { @@ -411,6 +408,26 @@ func (l *linter) lint(ctx android.ModuleContext) { l.extraLintCheckJars = append(l.extraLintCheckJars, android.PathForSource(ctx, "prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar")) + var baseline android.OptionalPath + if l.properties.Lint.Baseline_filename != nil { + baseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename)) + } + + html := android.PathForModuleOut(ctx, "lint", "lint-report.html") + text := android.PathForModuleOut(ctx, "lint", "lint-report.txt") + xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml") + referenceBaseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml") + + depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml, baseline) + + ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) { + if info, ok := android.OtherModuleProvider(ctx, dep, LintProvider); ok { + depSetsBuilder.Transitive(info) + } + }) + + depSets := depSetsBuilder.Build() + rule := android.NewRuleBuilder(pctx, ctx). Sbox(android.PathForModuleOut(ctx, "lint"), android.PathForModuleOut(ctx, "lint.sbox.textproto")). @@ -437,20 +454,9 @@ func (l *linter) lint(ctx android.ModuleContext) { srcsListRsp := android.PathForModuleOut(ctx, "lint-srcs.list.rsp") rule.Command().Text("cp").FlagWithRspFileInputList("", srcsListRsp, l.srcs).Output(srcsList).Implicits(l.compile_data) - lintPaths := l.writeLintProjectXML(ctx, rule, srcsList) + baselines := depSets.Baseline.ToList() - html := android.PathForModuleOut(ctx, "lint", "lint-report.html") - text := android.PathForModuleOut(ctx, "lint", "lint-report.txt") - xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml") - referenceBaseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml") - - depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml) - - ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) { - if depLint, ok := dep.(LintDepSetsIntf); ok { - depSetsBuilder.Transitive(depLint.LintDepSets()) - } - }) + lintPaths := l.writeLintProjectXML(ctx, rule, srcsList, baselines) rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String()) rule.Command().Text("mkdir -p").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String()) @@ -505,8 +511,8 @@ func (l *linter) lint(ctx android.ModuleContext) { cmd.FlagWithArg("--check ", checkOnly) } - if l.properties.Lint.Baseline_filename != nil { - cmd.FlagWithInput("--baseline ", android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename)) + if baseline.Valid() { + cmd.FlagWithInput("--baseline ", baseline.Path()) } cmd.FlagWithOutput("--write-reference-baseline ", referenceBaseline) @@ -530,25 +536,30 @@ func (l *linter) lint(ctx android.ModuleContext) { rule.Build("lint", "lint") - l.outputs = lintOutputs{ - html: html, - text: text, - xml: xml, - referenceBaseline: referenceBaseline, + android.SetProvider(ctx, LintProvider, &LintInfo{ + HTML: html, + Text: text, + XML: xml, + ReferenceBaseline: referenceBaseline, - depSets: depSetsBuilder.Build(), - } + TransitiveHTML: depSets.HTML, + TransitiveText: depSets.Text, + TransitiveXML: depSets.XML, + TransitiveBaseline: depSets.Baseline, + }) if l.buildModuleReportZip { - l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets()) + l.reports = BuildModuleLintReportZips(ctx, depSets, nil) } // Create a per-module phony target to run the lint check. phonyName := ctx.ModuleName() + "-lint" ctx.Phony(phonyName, xml) + + ctx.SetOutputFiles(android.Paths{xml}, ".lint") } -func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths { +func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets, validations android.Paths) android.Paths { htmlList := android.SortedUniquePaths(depSets.HTML.ToList()) textList := android.SortedUniquePaths(depSets.Text.ToList()) xmlList := android.SortedUniquePaths(depSets.XML.ToList()) @@ -558,13 +569,13 @@ func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) a } htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip") - lintZip(ctx, htmlList, htmlZip) + lintZip(ctx, htmlList, htmlZip, validations) textZip := android.PathForModuleOut(ctx, "lint-report-text.zip") - lintZip(ctx, textList, textZip) + lintZip(ctx, textList, textZip, validations) xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip") - lintZip(ctx, xmlList, xmlZip) + lintZip(ctx, xmlList, xmlZip, validations) return android.Paths{htmlZip, textZip, xmlZip} } @@ -642,7 +653,7 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { return } - var outputs []*lintOutputs + var outputs []*LintInfo var dirs []string ctx.VisitAllModules(func(m android.Module) { if ctx.Config().KatiEnabled() && !m.ExportedToMake() { @@ -658,14 +669,14 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { } } - if l, ok := m.(lintOutputsIntf); ok { - outputs = append(outputs, l.lintOutputs()) + if lintInfo, ok := android.OtherModuleProvider(ctx, m, LintProvider); ok { + outputs = append(outputs, lintInfo) } }) dirs = android.SortedUniqueStrings(dirs) - zip := func(outputPath android.WritablePath, get func(*lintOutputs) android.Path) { + zip := func(outputPath android.WritablePath, get func(*LintInfo) android.Path) { var paths android.Paths for _, output := range outputs { @@ -674,20 +685,20 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { } } - lintZip(ctx, paths, outputPath) + lintZip(ctx, paths, outputPath, nil) } l.htmlZip = android.PathForOutput(ctx, "lint-report-html.zip") - zip(l.htmlZip, func(l *lintOutputs) android.Path { return l.html }) + zip(l.htmlZip, func(l *LintInfo) android.Path { return l.HTML }) l.textZip = android.PathForOutput(ctx, "lint-report-text.zip") - zip(l.textZip, func(l *lintOutputs) android.Path { return l.text }) + zip(l.textZip, func(l *LintInfo) android.Path { return l.Text }) l.xmlZip = android.PathForOutput(ctx, "lint-report-xml.zip") - zip(l.xmlZip, func(l *lintOutputs) android.Path { return l.xml }) + zip(l.xmlZip, func(l *LintInfo) android.Path { return l.XML }) l.referenceBaselineZip = android.PathForOutput(ctx, "lint-report-reference-baselines.zip") - zip(l.referenceBaselineZip, func(l *lintOutputs) android.Path { return l.referenceBaseline }) + zip(l.referenceBaselineZip, func(l *LintInfo) android.Path { return l.ReferenceBaseline }) ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip) } @@ -703,17 +714,9 @@ var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil) func init() { android.RegisterParallelSingletonType("lint", func() android.Singleton { return &lintSingleton{} }) - - registerLintBuildComponents(android.InitRegistrationContext) -} - -func registerLintBuildComponents(ctx android.RegistrationContext) { - ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("enforce_strict_updatability_linting", enforceStrictUpdatabilityLintingMutator).Parallel() - }) } -func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android.WritablePath) { +func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android.WritablePath, validations android.Paths) { paths = android.SortedUniquePaths(android.CopyOfPaths(paths)) sort.Slice(paths, func(i, j int) bool { @@ -725,19 +728,8 @@ func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android rule.Command().BuiltTool("soong_zip"). FlagWithOutput("-o ", outputPath). FlagWithArg("-C ", android.PathForIntermediates(ctx).String()). - FlagWithRspFileInputList("-r ", outputPath.ReplaceExtension(ctx, "rsp"), paths) + FlagWithRspFileInputList("-r ", outputPath.ReplaceExtension(ctx, "rsp"), paths). + Validations(validations) rule.Build(outputPath.Base(), outputPath.Base()) } - -// Enforce the strict updatability linting to all applicable transitive dependencies. -func enforceStrictUpdatabilityLintingMutator(ctx android.TopDownMutatorContext) { - m := ctx.Module() - if d, ok := m.(LintDepSetsIntf); ok && d.GetStrictUpdatabilityLinting() { - ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) { - if a, ok := d.(LintDepSetsIntf); ok { - a.SetStrictUpdatabilityLinting(true) - } - }) - } -} diff --git a/java/lint_test.go b/java/lint_test.go index b51753f71..afe3914ff 100644 --- a/java/lint_test.go +++ b/java/lint_test.go @@ -164,7 +164,7 @@ func TestJavaLintStrictUpdatabilityLinting(t *testing.T) { sdk_version: "current", lint: { strict_updatability_linting: true, - baseline_filename: "lint-baseline.xml", + baseline_filename: "foo_lint_baseline.xml", }, } @@ -176,7 +176,7 @@ func TestJavaLintStrictUpdatabilityLinting(t *testing.T) { min_sdk_version: "29", sdk_version: "current", lint: { - baseline_filename: "lint-baseline.xml", + baseline_filename: "bar_lint_baseline.xml", } } ` @@ -188,18 +188,13 @@ func TestJavaLintStrictUpdatabilityLinting(t *testing.T) { RunTestWithBp(t, bp) foo := result.ModuleForTests("foo", "android_common") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto")) - if !strings.Contains(*sboxProto.Commands[0].Command, - "--baseline lint-baseline.xml --disallowed_issues NewApi") { - t.Error("did not restrict baselining NewApi") - } - - bar := result.ModuleForTests("bar", "android_common") - sboxProto = android.RuleBuilderSboxProtoForTests(t, result.TestContext, bar.Output("lint.sbox.textproto")) - if !strings.Contains(*sboxProto.Commands[0].Command, - "--baseline lint-baseline.xml --disallowed_issues NewApi") { + strictUpdatabilityCheck := foo.Output("lint_strict_updatability_check.stamp") + if !strings.Contains(strictUpdatabilityCheck.RuleParams.Command, + "--disallowed_issues NewApi") { t.Error("did not restrict baselining NewApi") } + android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "foo_lint_baseline.xml") + android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "bar_lint_baseline.xml") } func TestJavaLintDatabaseSelectionFull(t *testing.T) { diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index d794e511b..5bb77542c 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -33,6 +33,7 @@ var ( platformBootclasspathArtBootJarDepTag = bootclasspathDependencyTag{name: "art-boot-jar"} platformBootclasspathBootJarDepTag = bootclasspathDependencyTag{name: "platform-boot-jar"} platformBootclasspathApexBootJarDepTag = bootclasspathDependencyTag{name: "apex-boot-jar"} + platformBootclasspathImplLibDepTag = dependencyTag{name: "impl-lib-tag"} ) type platformBootclasspathModule struct { @@ -111,12 +112,18 @@ func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.Botto // Add dependencies on all the ART jars. global := dexpreopt.GetGlobalConfig(ctx) addDependenciesOntoSelectedBootImageApexes(ctx, "com.android.art") + + var bootImageModuleNames []string + // TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag) + bootImageModuleNames = append(bootImageModuleNames, global.ArtApexJars.CopyOfJars()...) // Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable // APEXes. - addDependenciesOntoBootImageModules(ctx, b.platformJars(ctx), platformBootclasspathBootJarDepTag) + platformJars := b.platformJars(ctx) + addDependenciesOntoBootImageModules(ctx, platformJars, platformBootclasspathBootJarDepTag) + bootImageModuleNames = append(bootImageModuleNames, platformJars.CopyOfJars()...) // Add dependencies on all the updatable jars, except the ART jars. apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars @@ -127,9 +134,17 @@ func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.Botto addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...) // TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag) + bootImageModuleNames = append(bootImageModuleNames, apexJars.CopyOfJars()...) // Add dependencies on all the fragments. b.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx) + + for _, bootImageModuleName := range bootImageModuleNames { + implLibName := implLibraryModuleName(bootImageModuleName) + if ctx.OtherModuleExists(implLibName) { + ctx.AddFarVariationDependencies(nil, platformBootclasspathImplLibDepTag, implLibName) + } + } } func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList, tag bootclasspathDependencyTag) { @@ -166,8 +181,15 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo allModules = append(allModules, apexModules...) b.configuredModules = allModules + // Do not add implLibModule to allModules as the impl lib is only used to collect the + // transitive source files + var implLibModule []android.Module + ctx.VisitDirectDepsWithTag(implLibraryTag, func(m android.Module) { + implLibModule = append(implLibModule, m) + }) + var transitiveSrcFiles android.Paths - for _, module := range allModules { + for _, module := range append(allModules, implLibModule...) { if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { if depInfo.TransitiveSrcFiles != nil { transitiveSrcFiles = append(transitiveSrcFiles, depInfo.TransitiveSrcFiles.ToList()...) diff --git a/java/rro_test.go b/java/rro_test.go index 742c83982..4d791305e 100644 --- a/java/rro_test.go +++ b/java/rro_test.go @@ -282,7 +282,7 @@ func TestEnforceRRO_propagatesToDependencies(t *testing.T) { enforceRROTargets: []string{"foo"}, rroDirs: map[string][]string{ "foo": {"product/vendor/blah/overlay/lib2/res"}, - "bar": {"product/vendor/blah/overlay/lib2/res"}, + "bar": nil, }, }, } diff --git a/java/sdk_library.go b/java/sdk_library.go index c2b1c4f31..f30877258 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -922,7 +922,7 @@ func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImpor c.initSdkLibraryComponent(module) } -func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool { +func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied() bool { namePtr := proptools.StringPtr(c.module.RootLibraryName()) c.sdkLibraryComponentProperties.SdkLibraryName = namePtr @@ -944,12 +944,32 @@ func (c *commonToSdkLibraryAndImport) uniqueApexVariations() bool { return c.sharedLibrary() } -func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) { +func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) SdkLibraryInfo { c.doctagPaths = android.PathsForModuleSrc(ctx, c.commonSdkLibraryProperties.Doctag_files) -} -func (c *commonToSdkLibraryAndImport) getImplLibraryModule() *Library { - return c.implLibraryModule + everythingStubPaths := make(map[android.SdkKind]OptionalDexJarPath) + exportableStubPaths := make(map[android.SdkKind]OptionalDexJarPath) + removedApiFilePaths := make(map[android.SdkKind]android.OptionalPath) + for kind := android.SdkNone; kind <= android.SdkPrivate; kind += 1 { + everythingStubPath := makeUnsetDexJarPath() + exportableStubPath := makeUnsetDexJarPath() + removedApiFilePath := android.OptionalPath{} + if scopePath := c.findClosestScopePath(sdkKindToApiScope(kind)); scopePath != nil { + everythingStubPath = scopePath.stubsDexJarPath + exportableStubPath = scopePath.exportableStubsDexJarPath + removedApiFilePath = scopePath.removedApiFilePath + } + everythingStubPaths[kind] = everythingStubPath + exportableStubPaths[kind] = exportableStubPath + removedApiFilePaths[kind] = removedApiFilePath + } + + return SdkLibraryInfo{ + EverythingStubDexJarPaths: everythingStubPaths, + ExportableStubDexJarPaths: exportableStubPaths, + RemovedTxtFiles: removedApiFilePaths, + SharedLibrary: c.sharedLibrary(), + } } // The component names for different outputs of the java_sdk_library. @@ -1023,29 +1043,6 @@ func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *sco return nil } -// selectScopePaths returns the *scopePaths appropriate for the specific kind. -// -// If the module does not support the specific kind then it will return the *scopePaths for the -// closest kind which is a subset of the requested kind. e.g. if requesting android.SdkModule then -// it will return *scopePaths for android.SdkSystem if available or android.SdkPublic of not. -func (c *commonToSdkLibraryAndImport) selectScopePaths(ctx android.BaseModuleContext, kind android.SdkKind) *scopePaths { - apiScope := sdkKindToApiScope(kind) - - paths := c.findClosestScopePath(apiScope) - if paths == nil { - var scopes []string - for _, s := range AllApiScopes { - if c.findScopePaths(s) != nil { - scopes = append(scopes, s.name) - } - } - ctx.ModuleErrorf("requires api scope %s from %s but it only has %q available", apiScope.name, c.module.RootLibraryName(), scopes) - return nil - } - - return paths -} - // sdkKindToApiScope maps from android.SdkKind to apiScope. func sdkKindToApiScope(kind android.SdkKind) *apiScope { var apiScope *apiScope @@ -1064,37 +1061,6 @@ func sdkKindToApiScope(kind android.SdkKind) *apiScope { return apiScope } -// to satisfy SdkLibraryDependency interface -func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath { - paths := c.selectScopePaths(ctx, kind) - if paths == nil { - return makeUnsetDexJarPath() - } - - return paths.stubsDexJarPath -} - -// to satisfy SdkLibraryDependency interface -func (c *commonToSdkLibraryAndImport) SdkApiExportableStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath { - paths := c.selectScopePaths(ctx, kind) - if paths == nil { - return makeUnsetDexJarPath() - } - - return paths.exportableStubsDexJarPath -} - -// to satisfy SdkLibraryDependency interface -func (c *commonToSdkLibraryAndImport) SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath { - apiScope := sdkKindToApiScope(kind) - paths := c.findScopePaths(apiScope) - if paths == nil { - return android.OptionalPath{} - } - - return paths.removedApiFilePath -} - func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} { componentProps := &struct { SdkLibraryName *string @@ -1185,36 +1151,25 @@ var _ SdkLibraryComponentDependency = (*Import)(nil) var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil) var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil) -// Provides access to sdk_version related files, e.g. header and implementation jars. -type SdkLibraryDependency interface { - SdkLibraryComponentDependency - - // SdkApiStubDexJar returns the dex jar for the stubs for the prebuilt - // java_sdk_library_import module. It is needed by the hiddenapi processing tool which - // processes dex files. - SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath - - // SdkApiExportableStubDexJar returns the exportable dex jar for the stubs for - // java_sdk_library module. It is needed by the hiddenapi processing tool which processes - // dex files. - SdkApiExportableStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath - - // SdkRemovedTxtFile returns the optional path to the removed.txt file for the specified sdk kind. - SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath - - // sharedLibrary returns true if this can be used as a shared library. - sharedLibrary() bool - - // getImplLibraryModule returns the pointer to the implementation library submodule of this - // sdk library. - getImplLibraryModule() *Library -} - type SdkLibraryInfo struct { // GeneratingLibs is the names of the library modules that this sdk library // generates. Note that this only includes the name of the modules that other modules can // depend on, and is not a holistic list of generated modules. GeneratingLibs []string + + // Map of sdk kind to the dex jar for the "everything" stubs. + // It is needed by the hiddenapi processing tool which processes dex files. + EverythingStubDexJarPaths map[android.SdkKind]OptionalDexJarPath + + // Map of sdk kind to the dex jar for the "exportable" stubs. + // It is needed by the hiddenapi processing tool which processes dex files. + ExportableStubDexJarPaths map[android.SdkKind]OptionalDexJarPath + + // Map of sdk kind to the optional path to the removed.txt file. + RemovedTxtFiles map[android.SdkKind]android.OptionalPath + + // Whether if this can be used as a shared library. + SharedLibrary bool } var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]() @@ -1248,12 +1203,13 @@ type SdkLibrary struct { builtInstalledForApex []dexpreopterInstall } -var _ SdkLibraryDependency = (*SdkLibrary)(nil) - func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool { return module.sdkLibraryProperties.Generate_system_and_test_apis } +var _ UsesLibraryDependency = (*SdkLibrary)(nil) + +// To satisfy the UsesLibraryDependency interface func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { if module.implLibraryModule != nil { return module.implLibraryModule.DexJarBuildPath(ctx) @@ -1261,6 +1217,7 @@ func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) Optio return makeUnsetDexJarPath() } +// To satisfy the UsesLibraryDependency interface func (module *SdkLibrary) DexJarInstallPath() android.Path { if module.implLibraryModule != nil { return module.implLibraryModule.DexJarInstallPath() @@ -1323,7 +1280,7 @@ func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) { } func CheckMinSdkVersion(ctx android.ModuleContext, module *Library) { - android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.ModuleContext, do android.PayloadDepsCallback) { + android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.BaseModuleContext, do android.PayloadDepsCallback) { ctx.WalkDeps(func(child android.Module, parent android.Module) bool { isExternal := !module.depIsInSameApex(ctx, child) if am, ok := child.(android.ApexModule); ok { @@ -1448,8 +1405,6 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) module.HideFromMake() } - module.generateCommonBuildActions(ctx) - module.stem = proptools.StringDefault(module.overridableProperties.Stem, ctx.ModuleName()) module.provideHiddenAPIPropertyInfo(ctx) @@ -1482,11 +1437,11 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok { module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...) module.implLibraryModule = to.(*Library) - android.SetProvider(ctx, JavaInfoProvider, dep) } } }) + sdkLibInfo := module.generateCommonBuildActions(ctx) apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if !apexInfo.IsForPlatform() { module.hideApexVariantFromMake = true @@ -1515,7 +1470,10 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) module.dexer.proguardDictionary = module.implLibraryModule.dexer.proguardDictionary module.dexer.proguardUsageZip = module.implLibraryModule.dexer.proguardUsageZip module.linter.reports = module.implLibraryModule.linter.reports - module.linter.outputs.depSets = module.implLibraryModule.LintDepSets() + + if lintInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, LintProvider); ok { + android.SetProvider(ctx, LintProvider, lintInfo) + } if !module.Host() { module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile @@ -1570,9 +1528,8 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) setOutputFiles(ctx, module.implLibraryModule.Module) } - android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{ - GeneratingLibs: generatingLibs, - }) + sdkLibInfo.GeneratingLibs = generatingLibs + android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) } func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall { @@ -1883,7 +1840,7 @@ func SdkLibraryFactory() android.Module { module.commonSdkLibraryProperties.Shared_library = proptools.BoolPtr(false) } - if module.initCommonAfterDefaultsApplied(ctx) { + if module.initCommonAfterDefaultsApplied() { module.CreateInternalModules(ctx) } }) @@ -1962,8 +1919,6 @@ type SdkLibraryImport struct { installFile android.Path } -var _ SdkLibraryDependency = (*SdkLibraryImport)(nil) - // The type of a structure that contains a field of type sdkLibraryScopeProperties // for each apiscope in allApiScopes, e.g. something like: // @@ -2019,7 +1974,7 @@ func sdkLibraryImportFactory() android.Module { InitJavaModule(module, android.HostAndDeviceSupported) module.SetDefaultableHook(func(mctx android.DefaultableHookContext) { - if module.initCommonAfterDefaultsApplied(mctx) { + if module.initCommonAfterDefaultsApplied() { module.createInternalModules(mctx) } }) @@ -2140,8 +2095,6 @@ func (module *SdkLibraryImport) MinSdkVersion(ctx android.EarlyModuleContext) an var _ hiddenAPIModule = (*SdkLibraryImport)(nil) func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { - module.generateCommonBuildActions(ctx) - // Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar") @@ -2171,6 +2124,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo } } }) + sdkLibInfo := module.generateCommonBuildActions(ctx) // Populate the scope paths with information from the properties. for apiScope, scopeProperties := range module.scopeProperties { @@ -2212,11 +2166,12 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo setOutputFiles(ctx, module.implLibraryModule.Module) } - android.SetProvider(ctx, SdkLibraryInfoProvider, SdkLibraryInfo{ - GeneratingLibs: generatingLibs, - }) + sdkLibInfo.GeneratingLibs = generatingLibs + android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) } +var _ UsesLibraryDependency = (*SdkLibraryImport)(nil) + // to satisfy UsesLibraryDependency interface func (module *SdkLibraryImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { // The dex implementation jar extracted from the .apex file should be used in preference to the @@ -2254,29 +2209,6 @@ func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path { } // to satisfy apex.javaDependency interface -func (module *SdkLibraryImport) LintDepSets() LintDepSets { - if module.implLibraryModule == nil { - return LintDepSets{} - } else { - return module.implLibraryModule.LintDepSets() - } -} - -func (module *SdkLibraryImport) GetStrictUpdatabilityLinting() bool { - if module.implLibraryModule == nil { - return false - } else { - return module.implLibraryModule.GetStrictUpdatabilityLinting() - } -} - -func (module *SdkLibraryImport) SetStrictUpdatabilityLinting(strictLinting bool) { - if module.implLibraryModule != nil { - module.implLibraryModule.SetStrictUpdatabilityLinting(strictLinting) - } -} - -// to satisfy apex.javaDependency interface func (module *SdkLibraryImport) Stem() string { return module.BaseModuleName() } @@ -2462,7 +2394,7 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk - implLibrary := sdk.getImplLibraryModule() + implLibrary := sdk.implLibraryModule if implLibrary != nil && implLibrary.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided { s.DexPreoptProfileGuided = proptools.BoolPtr(true) } diff --git a/java/sdk_library_external.go b/java/sdk_library_external.go deleted file mode 100644 index 4f8398194..000000000 --- a/java/sdk_library_external.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2020 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 java - -import ( - "android/soong/android" -) - -type partitionGroup int - -// Representation of partition group for checking inter-partition library dependencies. -// Between system and system_ext, there are no restrictions of dependencies, -// so we can treat these partitions as the same in terms of inter-partition dependency. -// Same policy is applied between vendor and odm partiton. -const ( - partitionGroupNone partitionGroup = iota - // group for system, and system_ext partition - partitionGroupSystem - // group for vendor and odm partition - partitionGroupVendor - // product partition - partitionGroupProduct -) - -func (g partitionGroup) String() string { - switch g { - case partitionGroupSystem: - return "system" - case partitionGroupVendor: - return "vendor" - case partitionGroupProduct: - return "product" - } - - return "" -} - -// Get partition group of java module that can be used at inter-partition dependency check. -// We currently have three groups -// -// (system, system_ext) => system partition group -// (vendor, odm) => vendor partition group -// (product) => product partition group -func (j *Module) partitionGroup(ctx android.EarlyModuleContext) partitionGroup { - // system and system_ext partition can be treated as the same in terms of inter-partition dependency. - if j.Platform() || j.SystemExtSpecific() { - return partitionGroupSystem - } - - // vendor and odm partition can be treated as the same in terms of inter-partition dependency. - if j.SocSpecific() || j.DeviceSpecific() { - return partitionGroupVendor - } - - // product partition is independent. - if j.ProductSpecific() { - return partitionGroupProduct - } - - panic("Cannot determine partition type") -} - -func (j *Module) allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool { - return inList(j.Name(), ctx.Config().InterPartitionJavaLibraryAllowList()) -} - -func (j *Module) syspropWithPublicStubs() bool { - return j.deviceProperties.SyspropPublicStub != "" -} - -type javaSdkLibraryEnforceContext interface { - Name() string - allowListedInterPartitionJavaLibrary(ctx android.EarlyModuleContext) bool - partitionGroup(ctx android.EarlyModuleContext) partitionGroup - syspropWithPublicStubs() bool -} - -var _ javaSdkLibraryEnforceContext = (*Module)(nil) - -func (j *Module) checkPartitionsForJavaDependency(ctx android.EarlyModuleContext, propName string, dep javaSdkLibraryEnforceContext) { - if dep.allowListedInterPartitionJavaLibrary(ctx) { - return - } - - if dep.syspropWithPublicStubs() { - return - } - - // If product interface is not enforced, skip check between system and product partition. - // But still need to check between product and vendor partition because product interface flag - // just represents enforcement between product and system, and vendor interface enforcement - // that is enforced here by precondition is representing enforcement between vendor and other partitions. - if !ctx.Config().EnforceProductPartitionInterface() { - productToSystem := j.partitionGroup(ctx) == partitionGroupProduct && dep.partitionGroup(ctx) == partitionGroupSystem - systemToProduct := j.partitionGroup(ctx) == partitionGroupSystem && dep.partitionGroup(ctx) == partitionGroupProduct - - if productToSystem || systemToProduct { - return - } - } - - // If module and dependency library is inter-partition - if j.partitionGroup(ctx) != dep.partitionGroup(ctx) { - errorFormat := "dependency on java_library (%q) is not allowed across the partitions (%s -> %s), use java_sdk_library instead" - ctx.PropertyErrorf(propName, errorFormat, dep.Name(), j.partitionGroup(ctx), dep.partitionGroup(ctx)) - } -} diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go index 6f24902e1..ca088cf68 100644 --- a/java/sdk_library_internal.go +++ b/java/sdk_library_internal.go @@ -33,9 +33,13 @@ const ( implLibSuffix = ".impl" ) +func implLibraryModuleName(sdkLibName string) string { + return sdkLibName + implLibSuffix +} + // Module name of the runtime implementation library func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string { - return c.module.RootLibraryName() + implLibSuffix + return implLibraryModuleName(c.module.RootLibraryName()) } // Module name of the XML file for the lib diff --git a/java/testing.go b/java/testing.go index 0c79e9f7e..d5a19e9d2 100644 --- a/java/testing.go +++ b/java/testing.go @@ -388,7 +388,6 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterStubsBuildComponents(ctx) RegisterSystemModulesBuildComponents(ctx) registerSystemserverClasspathBuildComponents(ctx) - registerLintBuildComponents(ctx) android.RegisterApexContributionsBuildComponents(ctx) } @@ -424,7 +423,9 @@ func gatherRequiredDepsForTest() string { "kotlin-stdlib-jdk8", "kotlin-annotations", "stub-annotations", + "aconfig-annotations-lib", + "aconfig_storage_reader_java", "unsupportedappusage", } diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go index fee1923b0..3c484d894 100644 --- a/rust/config/x86_64_device.go +++ b/rust/config/x86_64_device.go @@ -29,6 +29,7 @@ var ( x86_64ArchVariantRustFlags = map[string][]string{ "": []string{}, + "alderlake": []string{"-C target-cpu=alderlake"}, "broadwell": []string{"-C target-cpu=broadwell"}, "goldmont": []string{"-C target-cpu=goldmont"}, "goldmont-plus": []string{"-C target-cpu=goldmont-plus"}, diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go index 5d9d88aef..3c597cc23 100644 --- a/rust/config/x86_device.go +++ b/rust/config/x86_device.go @@ -27,6 +27,7 @@ var ( x86ArchVariantRustFlags = map[string][]string{ "": []string{}, + "alderlake": []string{"-C target-cpu=alderlake"}, "atom": []string{"-C target-cpu=atom"}, "broadwell": []string{"-C target-cpu=broadwell"}, "goldmont": []string{"-C target-cpu=goldmont"}, diff --git a/scripts/Android.bp b/scripts/Android.bp index 3d81b83c2..00b3ca591 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -184,12 +184,21 @@ python_binary_host { libs: ["ninja_rsp"], } +python_binary_host { + name: "lint_strict_updatability_checks", + main: "lint_strict_updatability_checks.py", + srcs: [ + "lint_strict_updatability_checks.py", + ], + libs: ["ninja_rsp"], +} + python_test_host { - name: "lint_project_xml_test", - main: "lint_project_xml_test.py", + name: "lint_strict_updatability_checks_test", + main: "lint_strict_updatability_checks_test.py", srcs: [ - "lint_project_xml_test.py", - "lint_project_xml.py", + "lint_strict_updatability_checks_test.py", + "lint_strict_updatability_checks.py", ], libs: ["ninja_rsp"], test_suites: ["general-tests"], diff --git a/scripts/lint_project_xml.py b/scripts/lint_project_xml.py index c40b07d38..ce6aa21a2 100755 --- a/scripts/lint_project_xml.py +++ b/scripts/lint_project_xml.py @@ -75,8 +75,6 @@ def parse_args(): help='file containing the module\'s manifest.') parser.add_argument('--merged_manifest', dest='merged_manifest', help='file containing merged manifest for the module and its dependencies.') - parser.add_argument('--baseline', dest='baseline_path', - help='file containing baseline lint issues.') parser.add_argument('--library', dest='library', action='store_true', help='mark the module as a library.') parser.add_argument('--test', dest='test', action='store_true', @@ -94,8 +92,6 @@ def parse_args(): help='treat a lint issue as a warning.') group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[], help='disable a lint issue.') - group.add_argument('--disallowed_issues', dest='disallowed_issues', default=[], - help='lint issues disallowed in the baseline file') return parser.parse_args() @@ -140,30 +136,10 @@ def write_config_xml(f, args): f.write("</lint>\n") -def check_baseline_for_disallowed_issues(baseline, forced_checks): - issues_element = baseline.documentElement - if issues_element.tagName != 'issues': - raise RuntimeError('expected issues tag at root') - issues = issues_element.getElementsByTagName('issue') - disallowed = set() - for issue in issues: - id = issue.getAttribute('id') - if id in forced_checks: - disallowed.add(id) - return disallowed - - def main(): """Program entry point.""" args = parse_args() - if args.baseline_path: - baseline = minidom.parse(args.baseline_path) - disallowed_issues = check_baseline_for_disallowed_issues(baseline, args.disallowed_issues) - if disallowed_issues: - sys.exit('disallowed issues %s found in lint baseline file %s for module %s' - % (disallowed_issues, args.baseline_path, args.name)) - if args.project_out: with open(args.project_out, 'w') as f: write_project_xml(f, args) diff --git a/scripts/lint_strict_updatability_checks.py b/scripts/lint_strict_updatability_checks.py new file mode 100755 index 000000000..5b5dfd81a --- /dev/null +++ b/scripts/lint_strict_updatability_checks.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 The Android Open Source Project +# +# 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. +# + +"""This file checks baselines passed to Android Lint for checks that must not be baselined.""" + +import argparse +import sys +from xml.dom import minidom + +from ninja_rsp import NinjaRspFileReader + + +def parse_args(): + """Parse commandline arguments.""" + + def convert_arg_line_to_args(arg_line): + for arg in arg_line.split(): + if arg.startswith('#'): + return + if not arg.strip(): + continue + yield arg + + parser = argparse.ArgumentParser(fromfile_prefix_chars='@') + parser.convert_arg_line_to_args = convert_arg_line_to_args + parser.add_argument('--name', dest='name', + help='name of the module.') + parser.add_argument('--baselines', dest='baselines', action='append', default=[], + help='file containing whitespace separated list of baseline files.') + parser.add_argument('--disallowed_issues', dest='disallowed_issues', default=[], + help='lint issues disallowed in the baseline file') + return parser.parse_args() + + +def check_baseline_for_disallowed_issues(baseline, forced_checks): + issues_element = baseline.documentElement + if issues_element.tagName != 'issues': + raise RuntimeError('expected issues tag at root') + issues = issues_element.getElementsByTagName('issue') + disallowed = set() + for issue in issues: + id = issue.getAttribute('id') + if id in forced_checks: + disallowed.add(id) + return disallowed + + +def main(): + """Program entry point.""" + args = parse_args() + + error = False + for baseline_rsp_file in args.baselines: + for baseline_path in NinjaRspFileReader(baseline_rsp_file): + baseline = minidom.parse(baseline_path) + disallowed_issues = check_baseline_for_disallowed_issues(baseline, args.disallowed_issues) + if disallowed_issues: + print('disallowed issues %s found in lint baseline file %s for module %s' + % (disallowed_issues, baseline_path, args.name)) + error = True + + if error: + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/scripts/lint_project_xml_test.py b/scripts/lint_strict_updatability_checks_test.py index 344691d00..fd8610f3a 100644..100755 --- a/scripts/lint_project_xml_test.py +++ b/scripts/lint_strict_updatability_checks_test.py @@ -15,12 +15,12 @@ # limitations under the License. # -"""Unit tests for lint_project_xml.py.""" +"""Unit tests for lint_strict_updatability_checks.py.""" import unittest from xml.dom import minidom -import lint_project_xml +import lint_strict_updatability_checks class CheckBaselineForDisallowedIssuesTest(unittest.TestCase): @@ -44,7 +44,7 @@ class CheckBaselineForDisallowedIssuesTest(unittest.TestCase): '</issues>\n') def test_check_baseline_for_disallowed_issues(self): - disallowed_issues = lint_project_xml.check_baseline_for_disallowed_issues(self.baseline_xml, ["foo", "bar", "qux"]) + disallowed_issues = lint_strict_updatability_checks.check_baseline_for_disallowed_issues(self.baseline_xml, ["foo", "bar", "qux"]) self.assertEqual({"foo", "bar"}, disallowed_issues) diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 09a7c9e8c..15e13dbcb 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -1360,10 +1360,9 @@ java_sdk_library_import { } `), snapshotTestChecker(checkSnapshotWithSourcePreferred, func(t *testing.T, result *android.TestResult) { - ctx := android.ModuleInstallPathContextForTesting(result.Config) dexJarBuildPath := func(name string, kind android.SdkKind) string { - dep := result.Module(name, "android_common").(java.SdkLibraryDependency) - path := dep.SdkApiExportableStubDexJar(ctx, kind).Path() + sdkLibInfo, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), result.Module(name, "android_common"), java.SdkLibraryInfoProvider) + path := sdkLibInfo.ExportableStubDexJarPaths[kind].Path() return path.RelativeToTop().String() } diff --git a/tradefed/autogen.go b/tradefed/autogen.go index ddd0a800c..e23079591 100644 --- a/tradefed/autogen.go +++ b/tradefed/autogen.go @@ -196,16 +196,16 @@ func AutoGenTestConfig(ctx android.ModuleContext, options AutoGenTestConfigOptio } var autogenInstrumentationTest = pctx.StaticRule("autogenInstrumentationTest", blueprint.RuleParams{ - Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template ${extraConfigs}", + Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template ${extraConfigs} ${extraTestRunnerConfigs}", CommandDeps: []string{ "${AutoGenTestConfigScript}", "${EmptyTestConfig}", "$template", }, -}, "name", "template", "extraConfigs") +}, "name", "template", "extraConfigs", "extraTestRunnerConfigs") func AutoGenInstrumentationTestConfig(ctx android.ModuleContext, testConfigProp *string, - testConfigTemplateProp *string, manifest android.Path, testSuites []string, autoGenConfig *bool, configs []Config) android.Path { + testConfigTemplateProp *string, manifest android.Path, testSuites []string, autoGenConfig *bool, configs []Config, testRunnerConfigs []Option) android.Path { path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp) var configStrings []string if autogenPath != nil { @@ -220,15 +220,26 @@ func AutoGenInstrumentationTestConfig(ctx android.ModuleContext, testConfigProp extraConfigs := strings.Join(configStrings, fmt.Sprintf("\\n%s", test_xml_indent)) extraConfigs = fmt.Sprintf("--extra-configs '%s'", extraConfigs) + var testRunnerConfigStrings []string + for _, config := range testRunnerConfigs { + testRunnerConfigStrings = append(testRunnerConfigStrings, config.Config()) + } + extraTestRunnerConfigs := strings.Join(testRunnerConfigStrings, fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent)) + if len(extraTestRunnerConfigs) > 0 { + extraTestRunnerConfigs += fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent) + } + extraTestRunnerConfigs = fmt.Sprintf("--extra-test-runner-configs '%s'", extraTestRunnerConfigs) + ctx.Build(pctx, android.BuildParams{ Rule: autogenInstrumentationTest, Description: "test config", Input: manifest, Output: autogenPath, Args: map[string]string{ - "name": ctx.ModuleName(), - "template": template, - "extraConfigs": extraConfigs, + "name": ctx.ModuleName(), + "template": template, + "extraConfigs": extraConfigs, + "extraTestRunnerConfigs": extraTestRunnerConfigs, }, }) return autogenPath diff --git a/ui/build/soong.go b/ui/build/soong.go index eb51022af..41425ac13 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -27,6 +27,7 @@ import ( "strings" "sync" "sync/atomic" + "syscall" "time" "android/soong/ui/tracer" @@ -780,7 +781,7 @@ func checkGlobs(ctx Context, finalOutFile string) error { hasNewDep := false for _, dep := range cachedGlob.Deps { info, err := os.Stat(dep) - if errors.Is(err, fs.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) { hasNewDep = true break } else if err != nil { |