diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-03-04 21:55:09 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-03-04 21:55:09 +0000 |
commit | cfe547a09feb68cd2e2e249e21b8b7893353924f (patch) | |
tree | 660e085a9ec8f44ad199008d135cb7668d1cff2d | |
parent | 121a13bf6fd602551b6e61be9971261fcba974bb (diff) | |
parent | 972917d794e1f9a225fa3737cf648f4a8d044d31 (diff) | |
download | soong-simpleperf-release.tar.gz |
Snap for 11526323 from 972917d794e1f9a225fa3737cf648f4a8d044d31 to simpleperf-releasesimpleperf-release
Change-Id: I955ce237a7a39deccc0bae534c1f9fc5ac071246
-rw-r--r-- | android/config.go | 18 | ||||
-rw-r--r-- | android/prebuilt.go | 46 | ||||
-rw-r--r-- | apex/apex.go | 10 | ||||
-rw-r--r-- | apex/apex_test.go | 30 | ||||
-rw-r--r-- | apex/builder.go | 9 | ||||
-rw-r--r-- | cc/prebuilt.go | 3 | ||||
-rw-r--r-- | cc/prebuilt_test.go | 150 | ||||
-rw-r--r-- | cc/stl.go | 12 | ||||
-rw-r--r-- | cmd/soong_build/main.go | 1 | ||||
-rw-r--r-- | java/aar.go | 8 | ||||
-rw-r--r-- | java/androidmk.go | 7 | ||||
-rw-r--r-- | java/app_import.go | 9 | ||||
-rw-r--r-- | java/app_test.go | 4 | ||||
-rw-r--r-- | java/base.go | 14 | ||||
-rw-r--r-- | java/builder.go | 59 | ||||
-rw-r--r-- | java/core-libraries/Android.bp | 4 | ||||
-rw-r--r-- | java/dexpreopt.go | 31 | ||||
-rw-r--r-- | java/droidstubs.go | 17 | ||||
-rw-r--r-- | java/droidstubs_test.go | 1 | ||||
-rw-r--r-- | java/java.go | 52 | ||||
-rw-r--r-- | java/java_test.go | 69 | ||||
-rw-r--r-- | java/sdk_library.go | 2 | ||||
-rw-r--r-- | java/testing.go | 9 | ||||
-rw-r--r-- | rust/config/lints.go | 2 | ||||
-rw-r--r-- | ui/build/config.go | 11 | ||||
-rw-r--r-- | ui/build/config_test.go | 47 | ||||
-rw-r--r-- | ui/build/soong.go | 6 |
27 files changed, 523 insertions, 108 deletions
diff --git a/android/config.go b/android/config.go index e757d504c..936d1d3ae 100644 --- a/android/config.go +++ b/android/config.go @@ -91,8 +91,6 @@ type CmdArgs struct { ModuleActionsFile string DocFile string - MultitreeBuild bool - BuildFromSourceStub bool EnsureAllowlistIntegrity bool @@ -288,10 +286,6 @@ type config struct { BuildMode SoongBuildMode - // If MultitreeBuild is true then this is one inner tree of a multitree - // build directed by the multitree orchestrator. - MultitreeBuild bool - // If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error // in tests when a path doesn't exist. TestAllowNonExistentPaths bool @@ -541,8 +535,6 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) moduleListFile: cmdArgs.ModuleListFile, fs: pathtools.NewOsFs(absSrcDir), - MultitreeBuild: cmdArgs.MultitreeBuild, - buildFromSourceStub: cmdArgs.BuildFromSourceStub, } @@ -2027,25 +2019,35 @@ func (c *config) UseResourceProcessorByDefault() bool { var ( mainlineApexContributionBuildFlags = []string{ + "RELEASE_APEX_CONTRIBUTIONS_ADBD", "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "RELEASE_APEX_CONTRIBUTIONS_APPSEARCH", "RELEASE_APEX_CONTRIBUTIONS_ART", "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH", + "RELEASE_APEX_CONTRIBUTIONS_CAPTIVEPORTALLOGIN", + "RELEASE_APEX_CONTRIBUTIONS_CELLBROADCAST", "RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE", "RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY", "RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT", "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY", "RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK", + "RELEASE_APEX_CONTRIBUTIONS_DOCUMENTSUIGOOGLE", + "RELEASE_APEX_CONTRIBUTIONS_EXTSERVICES", "RELEASE_APEX_CONTRIBUTIONS_HEALTHFITNESS", "RELEASE_APEX_CONTRIBUTIONS_IPSEC", "RELEASE_APEX_CONTRIBUTIONS_MEDIA", "RELEASE_APEX_CONTRIBUTIONS_MEDIAPROVIDER", + "RELEASE_APEX_CONTRIBUTIONS_NETWORKSTACKGOOGLE", + "RELEASE_APEX_CONTRIBUTIONS_NEURALNETWORKS", "RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION", "RELEASE_APEX_CONTRIBUTIONS_PERMISSION", "RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING", + "RELEASE_APEX_CONTRIBUTIONS_RESOLV", "RELEASE_APEX_CONTRIBUTIONS_SCHEDULING", "RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS", + "RELEASE_APEX_CONTRIBUTIONS_SWCODEC", "RELEASE_APEX_CONTRIBUTIONS_STATSD", + "RELEASE_APEX_CONTRIBUTIONS_TZDATA", "RELEASE_APEX_CONTRIBUTIONS_UWB", "RELEASE_APEX_CONTRIBUTIONS_WIFI", } diff --git a/android/prebuilt.go b/android/prebuilt.go index 13cda9dad..5a94a0f23 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -534,6 +534,35 @@ func hideUnflaggedModules(ctx BottomUpMutatorContext, psi PrebuiltSelectionInfoM for _, moduleInFamily := range allModulesInFamily { if moduleInFamily.Name() != selectedModuleInFamily.Name() { moduleInFamily.HideFromMake() + // If this is a prebuilt module, unset properties.UsePrebuilt + // properties.UsePrebuilt might evaluate to true via soong config var fallback mechanism + // Set it to false explicitly so that the following mutator does not replace rdeps to this unselected prebuilt + if p := GetEmbeddedPrebuilt(moduleInFamily); p != nil { + p.properties.UsePrebuilt = false + } + } + } + } + // Do a validation pass to make sure that multiple prebuilts of a specific module are not selected. + // This might happen if the prebuilts share the same soong config var namespace. + // This should be an error, unless one of the prebuilts has been explicitly declared in apex_contributions + var selectedPrebuilt Module + for _, moduleInFamily := range allModulesInFamily { + // Skip if this module is in a different namespace + if !moduleInFamily.ExportedToMake() { + continue + } + // Skip for the top-level java_sdk_library_(_import). This has some special cases that need to be addressed first. + // This does not run into non-determinism because PrebuiltPostDepsMutator also has the special case + if sdkLibrary, ok := moduleInFamily.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil { + continue + } + if p := GetEmbeddedPrebuilt(moduleInFamily); p != nil && p.properties.UsePrebuilt { + if selectedPrebuilt == nil { + selectedPrebuilt = moduleInFamily + } else { + ctx.ModuleErrorf("Multiple prebuilt modules %v and %v have been marked as preferred for this source module. "+ + "Please add the appropriate prebuilt module to apex_contributions for this release config.", selectedPrebuilt.Name(), moduleInFamily.Name()) } } } @@ -562,7 +591,7 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) { // If we do not special-case this here, rdeps referring to a java_sdk_library in next builds via libs // will get prebuilt stubs // TODO (b/308187268): Remove this after the apexes have been added to apex_contributions - if psi.IsSelected(*sdkLibrary.SdkLibraryName()) { + if psi.IsSelected(name) { return false } } @@ -625,6 +654,17 @@ type createdByJavaSdkLibraryName interface { CreatedByJavaSdkLibraryName() *string } +// Returns true if the prebuilt variant is disabled +// e.g. for a cc_prebuilt_library_shared, this will return +// - true for the static variant of the module +// - false for the shared variant of the module +// +// Even though this is a cc_prebuilt_library_shared, we create both the variants today +// https://source.corp.google.com/h/googleplex-android/platform/build/soong/+/e08e32b45a18a77bc3c3e751f730539b1b374f1b:cc/library.go;l=2113-2116;drc=2c4a9779cd1921d0397a12b3d3521f4c9b30d747;bpv=1;bpt=0 +func (p *Prebuilt) variantIsDisabled(ctx BaseMutatorContext, prebuilt Module) bool { + return p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 +} + // usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt // will be used if it is marked "prefer" or if the source module is disabled. func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool { @@ -639,7 +679,7 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M return false } // If the prebuilt module is explicitly listed in the metadata module, use that - if isSelected(psi, prebuilt) { + if isSelected(psi, prebuilt) && !p.variantIsDisabled(ctx, prebuilt) { return true } @@ -647,7 +687,7 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M // fall back to the existing source vs prebuilt selection. // TODO: Drop the fallback mechanisms - if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 { + if p.variantIsDisabled(ctx, prebuilt) { return false } diff --git a/apex/apex.go b/apex/apex.go index c6d8234e2..9d7af189b 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2075,8 +2075,10 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, return true // track transitive dependencies case *java.AndroidAppImport: vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) + addAconfigFiles(vctx, ctx, child) case *java.AndroidTestHelperApp: vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) + addAconfigFiles(vctx, ctx, child) case *java.AndroidAppSet: appDir := "app" if ap.Privileged() { @@ -2090,6 +2092,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap) af.certificate = java.PresignedCertificate vctx.filesInfo = append(vctx.filesInfo, af) + addAconfigFiles(vctx, ctx, child) default: ctx.PropertyErrorf("apps", "%q is not an android_app module", depName) } @@ -2118,6 +2121,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, case prebuiltTag: if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) + addAconfigFiles(vctx, ctx, child) } else { ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName) } @@ -2141,6 +2145,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, af := apexFileForExecutable(ctx, ccTest) af.class = nativeTest vctx.filesInfo = append(vctx.filesInfo, af) + addAconfigFiles(vctx, ctx, child) } return true // track transitive dependencies } else { @@ -2230,11 +2235,13 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } vctx.filesInfo = append(vctx.filesInfo, af) + addAconfigFiles(vctx, ctx, child) return true // track transitive dependencies } else if rm, ok := child.(*rust.Module); ok { af := apexFileForRustLibrary(ctx, rm) af.transitiveDep = true vctx.filesInfo = append(vctx.filesInfo, af) + addAconfigFiles(vctx, ctx, child) return true // track transitive dependencies } } else if cc.IsTestPerSrcDepTag(depTag) { @@ -2263,6 +2270,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, af := apexFileForRustLibrary(ctx, rustm) af.transitiveDep = true vctx.filesInfo = append(vctx.filesInfo, af) + addAconfigFiles(vctx, ctx, child) return true // track transitive dependencies } } else if rust.IsRlibDepTag(depTag) { @@ -2281,6 +2289,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, return false } vctx.filesInfo = append(vctx.filesInfo, af) + addAconfigFiles(vctx, ctx, child) return true // track transitive dependencies default: ctx.PropertyErrorf("bootclasspath_fragments", @@ -2295,6 +2304,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil { vctx.filesInfo = append(vctx.filesInfo, *profileAf) } + addAconfigFiles(vctx, ctx, child) return true // track transitive dependencies default: ctx.PropertyErrorf("systemserverclasspath_fragments", diff --git a/apex/apex_test.go b/apex/apex_test.go index 85d1d712a..54d2d08ff 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -6199,7 +6199,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { `) }) - t.Run("Co-existing unflagged apexes should create a duplicate deapexer error in hiddenapi processing", func(t *testing.T) { + t.Run("Co-existing unflagged apexes should create a duplicate module error", func(t *testing.T) { bp := ` // Source apex { @@ -6273,7 +6273,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { } ` - testDexpreoptWithApexes(t, bp, "Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_myapex.v1 and prebuilt_myapex.v2", preparer, fragment) + testDexpreoptWithApexes(t, bp, "Multiple prebuilt modules prebuilt_myapex.v1 and prebuilt_myapex.v2 have been marked as preferred for this source module", preparer, fragment) }) } @@ -11120,10 +11120,10 @@ func TestAconfigFilesJavaDeps(t *testing.T) { t.Fatalf("Expected 5 commands, got %d in:\n%s", len(copyCmds), s) } - ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex$") - ensureMatches(t, copyCmds[5], "^cp -f .*/package.map .*/image.apex$") - ensureMatches(t, copyCmds[6], "^cp -f .*/flag.map .*/image.apex$") - ensureMatches(t, copyCmds[7], "^cp -f .*/flag.val .*/image.apex$") + ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$") + ensureMatches(t, copyCmds[5], "^cp -f .*/package.map .*/image.apex/etc$") + ensureMatches(t, copyCmds[6], "^cp -f .*/flag.map .*/image.apex/etc$") + ensureMatches(t, copyCmds[7], "^cp -f .*/flag.val .*/image.apex/etc$") inputs := []string{ "my_aconfig_declarations_foo/intermediate.pb", @@ -11244,10 +11244,10 @@ func TestAconfigFilesJavaAndCcDeps(t *testing.T) { t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s) } - ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex$") - ensureMatches(t, copyCmds[9], "^cp -f .*/package.map .*/image.apex$") - ensureMatches(t, copyCmds[10], "^cp -f .*/flag.map .*/image.apex$") - ensureMatches(t, copyCmds[11], "^cp -f .*/flag.val .*/image.apex$") + ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$") + ensureMatches(t, copyCmds[9], "^cp -f .*/package.map .*/image.apex/etc$") + ensureMatches(t, copyCmds[10], "^cp -f .*/flag.map .*/image.apex/etc$") + ensureMatches(t, copyCmds[11], "^cp -f .*/flag.val .*/image.apex/etc$") inputs := []string{ "my_aconfig_declarations_foo/intermediate.pb", @@ -11385,13 +11385,15 @@ func TestAconfigFilesRustDeps(t *testing.T) { t.Fatalf("Expected 26 commands, got %d in:\n%s", len(copyCmds), s) } - ensureMatches(t, copyCmds[22], "^cp -f .*/aconfig_flags.pb .*/image.apex$") - ensureMatches(t, copyCmds[23], "^cp -f .*/package.map .*/image.apex$") - ensureMatches(t, copyCmds[24], "^cp -f .*/flag.map .*/image.apex$") - ensureMatches(t, copyCmds[25], "^cp -f .*/flag.val .*/image.apex$") + ensureMatches(t, copyCmds[22], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$") + ensureMatches(t, copyCmds[23], "^cp -f .*/package.map .*/image.apex/etc$") + ensureMatches(t, copyCmds[24], "^cp -f .*/flag.map .*/image.apex/etc$") + ensureMatches(t, copyCmds[25], "^cp -f .*/flag.val .*/image.apex/etc$") inputs := []string{ "my_aconfig_declarations_foo/intermediate.pb", + "my_aconfig_declarations_bar/intermediate.pb", + "my_aconfig_declarations_baz/intermediate.pb", "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb", } VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") diff --git a/apex/builder.go b/apex/builder.go index e49cf28fd..6ad282ab6 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -645,6 +645,7 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin") defaultReadOnlyFiles := []string{"apex_manifest.json", "apex_manifest.pb"} + aconfigDest := imageDir.Join(ctx, "etc").String() if len(a.aconfigFiles) > 0 { apexAconfigFile := android.PathForModuleOut(ctx, "aconfig_flags.pb") ctx.Build(pctx, android.BuildParams{ @@ -657,9 +658,9 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { }, }) - copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+imageDir.String()) + copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+aconfigDest) implicitInputs = append(implicitInputs, apexAconfigFile) - defaultReadOnlyFiles = append(defaultReadOnlyFiles, apexAconfigFile.Base()) + defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+apexAconfigFile.Base()) for _, info := range createStorageInfo { outputFile := android.PathForModuleOut(ctx, info.Output_file) @@ -675,9 +676,9 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { }, }) - copyCommands = append(copyCommands, "cp -f "+outputFile.String()+" "+imageDir.String()) + copyCommands = append(copyCommands, "cp -f "+outputFile.String()+" "+aconfigDest) implicitInputs = append(implicitInputs, outputFile) - defaultReadOnlyFiles = append(defaultReadOnlyFiles, outputFile.Base()) + defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+outputFile.Base()) } } diff --git a/cc/prebuilt.go b/cc/prebuilt.go index 8f4b7df42..cbb5d58db 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -260,6 +260,9 @@ func (p *prebuiltLibraryLinker) nativeCoverage() bool { func (p *prebuiltLibraryLinker) disablePrebuilt() { p.properties.Srcs = nil + p.properties.Sanitized.None.Srcs = nil + p.properties.Sanitized.Address.Srcs = nil + p.properties.Sanitized.Hwaddress.Srcs = nil } // Implements versionedInterface diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go index f6b5ed56c..71b7e4369 100644 --- a/cc/prebuilt_test.go +++ b/cc/prebuilt_test.go @@ -610,3 +610,153 @@ func TestMultiplePrebuilts(t *testing.T) { android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "libbar", entries.EntryMap["LOCAL_MODULE"][0]) } } + +// Setting prefer on multiple prebuilts is an error, unless one of them is also listed in apex_contributions +func TestMultiplePrebuiltsPreferredUsingLegacyFlags(t *testing.T) { + bp := ` + // an rdep + cc_library { + name: "libfoo", + shared_libs: ["libbar"], + } + + // multiple variations of dep + // source + cc_library { + name: "libbar", + } + // prebuilt "v1" + cc_prebuilt_library_shared { + name: "libbar", + srcs: ["libbar.so"], + prefer: true, + } + // prebuilt "v2" + cc_prebuilt_library_shared { + name: "libbar.v2", + stem: "libbar", + source_module_name: "libbar", + srcs: ["libbar.so"], + prefer: true, + } + + // selectors + apex_contributions { + name: "myapex_contributions", + contents: [%v], + } + all_apex_contributions {name: "all_apex_contributions"} + ` + hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { + t.Helper() + var found bool + ctx.VisitDirectDeps(m, func(dep blueprint.Module) { + if dep == wantDep { + found = true + } + }) + return found + } + + testCases := []struct { + desc string + selectedDependencyName string + expectedDependencyName string + expectedErr string + }{ + { + desc: "Multiple prebuilts have prefer: true", + expectedErr: "Multiple prebuilt modules prebuilt_libbar and prebuilt_libbar.v2 have been marked as preferred for this source module", + }, + { + desc: "Multiple prebuilts have prefer: true. The prebuilt listed in apex_contributions wins.", + selectedDependencyName: `"prebuilt_libbar"`, + expectedDependencyName: "prebuilt_libbar", + }, + } + + for _, tc := range testCases { + preparer := android.GroupFixturePreparers( + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + android.RegisterApexContributionsBuildComponents(ctx) + }), + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.BuildFlags = map[string]string{ + "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", + } + }), + ) + if tc.expectedErr != "" { + preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedErr)) + } + + ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{ + "libbar.so": nil, + "crtx.o": nil, + }, preparer) + if tc.expectedErr != "" { + return // the fixture will assert that the excepted err has been raised + } + libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() + expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module() + android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency)) + } +} + +// If module sdk cannot provide a cc module variant (e.g. static), then the module variant from source should be used +func TestMissingVariantInModuleSdk(t *testing.T) { + bp := ` + // an rdep + cc_library { + name: "libfoo", + static_libs: ["libbar"], + } + + // source + cc_library { + name: "libbar", + } + // prebuilt + // libbar only exists as a shared library + cc_prebuilt_library_shared { + name: "libbar", + srcs: ["libbar.so"], + } + // selectors + apex_contributions { + name: "myapex_contributions", + contents: ["prebuilt_libbar"], + } + all_apex_contributions {name: "all_apex_contributions"} + ` + hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { + t.Helper() + var found bool + ctx.VisitDirectDeps(m, func(dep blueprint.Module) { + if dep == wantDep { + found = true + } + }) + return found + } + + preparer := android.GroupFixturePreparers( + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + android.RegisterApexContributionsBuildComponents(ctx) + }), + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.BuildFlags = map[string]string{ + "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", + } + }), + ) + ctx := testPrebuilt(t, bp, map[string][]byte{ + "libbar.so": nil, + "crtx.o": nil, + }, preparer) + libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() + sourceLibBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_static").Module() + // Even though the prebuilt is listed in apex_contributions, the prebuilt does not have a static variant. + // Therefore source of libbar should be used. + android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from libfoo to source libbar"), true, hasDep(ctx, libfoo, sourceLibBar)) +} @@ -205,12 +205,14 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++") if ctx.Windows() { flags.Local.CppFlags = append(flags.Local.CppFlags, - // Disable visiblity annotations since we're using static - // libc++. - "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS", - "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS", + // These macros can also be defined by libc++'s __config + // or __config_site headers so define them the same way + // (i.e. to nothing). Disable visibility annotations since + // we're using static libc++. + "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=", + "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS=", // Use Win32 threads in libc++. - "-D_LIBCPP_HAS_THREAD_API_WIN32") + "-D_LIBCPP_HAS_THREAD_API_WIN32=") } } case "libstdc++": diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index 673f3055a..d64010e66 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -76,7 +76,6 @@ func init() { flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output") flag.StringVar(&cmdlineArgs.SoongVariables, "soong_variables", "soong.variables", "the file contains all build variables") flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file") - flag.BoolVar(&cmdlineArgs.MultitreeBuild, "multitree-build", false, "this is a multitree build") flag.BoolVar(&cmdlineArgs.BuildFromSourceStub, "build-from-source-stub", false, "build Java stubs from source files instead of API text files") flag.BoolVar(&cmdlineArgs.EnsureAllowlistIntegrity, "ensure-allowlist-integrity", false, "verify that allowlisted modules are mixed-built") flag.StringVar(&cmdlineArgs.ModuleDebugFile, "soong_module_debug", "", "soong module debug info file to write") diff --git a/java/aar.go b/java/aar.go index 0edee835a..7cb362a9f 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1134,7 +1134,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { extractedAARDir := android.PathForModuleOut(ctx, "aar") a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar") a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml") - aarRTxt := extractedAARDir.Join(ctx, "R.txt") + a.rTxt = extractedAARDir.Join(ctx, "R.txt") a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip") a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt") android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{ @@ -1148,7 +1148,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.Build(pctx, android.BuildParams{ Rule: unzipAAR, Input: a.aarPath, - Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt}, + Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt}, Description: "unzip AAR", Args: map[string]string{ "outDir": extractedAARDir.String(), @@ -1166,7 +1166,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk") proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options") - a.rTxt = android.PathForModuleOut(ctx, "R.txt") + aaptRTxt := android.PathForModuleOut(ctx, "R.txt") a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages") var linkDeps android.Paths @@ -1203,7 +1203,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets()) - aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, a.rTxt, + aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, aaptRTxt, linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil) a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar") diff --git a/java/androidmk.go b/java/androidmk.go index b7df9bf9e..498962f88 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -691,9 +691,10 @@ func (a *AndroidAppImport) AndroidMkEntries() []android.AndroidMkEntries { return nil } return []android.AndroidMkEntries{android.AndroidMkEntries{ - Class: "APPS", - OutputFile: android.OptionalPathForPath(a.outputFile), - Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk", + Class: "APPS", + OutputFile: android.OptionalPathForPath(a.outputFile), + OverrideName: a.BaseModuleName(), // TODO (spandandas): Add a test + Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", a.Privileged()) diff --git a/java/app_import.go b/java/app_import.go index 8c90e4c7a..dc84fc26d 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -145,6 +145,11 @@ type AndroidAppImportProperties struct { // Whether or not to skip checking the preprocessed apk for proper alignment and uncompressed // JNI libs and dex files. Default is false Skip_preprocessed_apk_checks *bool + + // Name of the source soong module that gets shadowed by this prebuilt + // If unspecified, follows the naming convention that the source module of + // the prebuilt is Name() without "prebuilt_" prefix + Source_module_name *string } func (a *AndroidAppImport) IsInstallable() bool { @@ -274,6 +279,10 @@ func (a *AndroidAppImport) InstallApkName() string { return a.BaseModuleName() } +func (a *AndroidAppImport) BaseModuleName() string { + return proptools.StringDefault(a.properties.Source_module_name, a.ModuleBase.Name()) +} + func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) { if a.Name() == "prebuilt_framework-res" { ctx.ModuleErrorf("prebuilt_framework-res found. This used to have special handling in soong, but was removed due to prebuilt_framework-res no longer existing. This check is to ensure it doesn't come back without readding the special handling.") diff --git a/java/app_test.go b/java/app_test.go index 125c9716c..28bea0a2b 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -931,8 +931,8 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", }, appCombined: []string{ - "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/app/android_common/javac/app.jar", + "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/direct/android_common/combined/direct.jar", "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", }, @@ -1037,8 +1037,8 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", }, appCombined: []string{ - "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/app/android_common/javac/app.jar", + "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/direct/android_common/combined/direct.jar", "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", }, diff --git a/java/base.go b/java/base.go index 7f4ea08c7..f11e30dc2 100644 --- a/java/base.go +++ b/java/base.go @@ -1307,7 +1307,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath } } - jars := append(android.Paths(nil), kotlinJars...) + jars := slices.Clone(kotlinJars) j.compiledSrcJars = srcJars @@ -1322,7 +1322,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath // allow for the use of annotation processors that do function correctly // with sharding enabled. See: b/77284273. } - extraJars := append(android.CopyOf(extraCombinedJars), kotlinHeaderJars...) + extraJars := append(slices.Clone(kotlinHeaderJars), extraCombinedJars...) headerJarFileWithoutDepsOrJarjar, j.headerJarFile, j.repackagedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars) if ctx.Failed() { @@ -1396,6 +1396,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath } } + jars = append(jars, extraCombinedJars...) + j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles var includeSrcJar android.WritablePath @@ -1482,8 +1484,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath jars = append(jars, servicesJar) } - jars = append(android.CopyOf(extraCombinedJars), jars...) - // Combine the classes built from sources, any manifests, and any static libraries into // classes.jar. If there is only one input jar this step will be skipped. var outputFile android.OutputPath @@ -2408,7 +2408,8 @@ type JarJarProviderData struct { func (this JarJarProviderData) GetDebugString() string { result := "" - for k, v := range this.Rename { + for _, k := range android.SortedKeys(this.Rename) { + v := this.Rename[k] if strings.Contains(k, "android.companion.virtual.flags.FakeFeatureFlagsImpl") { result += k + "-->" + v + ";" } @@ -2664,7 +2665,8 @@ func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProvi // to "" won't be in this list because they shouldn't be renamed yet. func getJarJarRuleText(provider *JarJarProviderData) string { result := "" - for orig, renamed := range provider.Rename { + for _, orig := range android.SortedKeys(provider.Rename) { + renamed := provider.Rename[orig] if renamed != "" { result += "rule " + orig + " " + renamed + "\n" } diff --git a/java/builder.go b/java/builder.go index 74a05f281..b07a622e4 100644 --- a/java/builder.go +++ b/java/builder.go @@ -212,6 +212,14 @@ var ( CommandDeps: []string{"${config.MergeZipsCmd}"}, }, "jarArgs") + combineJarRsp = pctx.AndroidStaticRule("combineJarRsp", + blueprint.RuleParams{ + Command: `${config.MergeZipsCmd} --ignore-duplicates -j $jarArgs $out @$out.rsp`, + CommandDeps: []string{"${config.MergeZipsCmd}"}, + Rspfile: "$out.rsp", + RspfileContent: "$in", + }, + "jarArgs") jarjar = pctx.AndroidStaticRule("jarjar", blueprint.RuleParams{ @@ -418,7 +426,7 @@ func emitXrefRule(ctx android.ModuleContext, xrefFile android.WritablePath, idx }) } -func turbineFlags(ctx android.ModuleContext, flags javaBuilderFlags) (string, android.Paths) { +func turbineFlags(ctx android.ModuleContext, flags javaBuilderFlags, dir string) (string, android.Paths) { var deps android.Paths classpath := flags.classpath @@ -443,13 +451,21 @@ func turbineFlags(ctx android.ModuleContext, flags javaBuilderFlags) (string, an deps = append(deps, classpath...) turbineFlags := bootClasspath + " " + classpath.FormTurbineClassPath("--classpath ") + const flagsLimit = 32 * 1024 + if len(turbineFlags) > flagsLimit { + flagsRspFile := android.PathForModuleOut(ctx, dir, "turbine-flags.rsp") + android.WriteFileRule(ctx, flagsRspFile, turbineFlags) + turbineFlags = "@" + flagsRspFile.String() + deps = append(deps, flagsRspFile) + } + return turbineFlags, deps } func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android.WritablePath, srcFiles, srcJars android.Paths, flags javaBuilderFlags) { - turbineFlags, deps := turbineFlags(ctx, flags) + turbineFlags, deps := turbineFlags(ctx, flags, "turbine") deps = append(deps, srcJars...) @@ -481,7 +497,7 @@ func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android. func TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.WritablePath, srcFiles, srcJars android.Paths, flags javaBuilderFlags) { - turbineFlags, deps := turbineFlags(ctx, flags) + turbineFlags, deps := turbineFlags(ctx, flags, "kapt") deps = append(deps, srcJars...) @@ -534,14 +550,14 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab deps = append(deps, srcJars...) - classpath := flags.classpath + javacClasspath := flags.classpath var bootClasspath string if flags.javaVersion.usesJavaModules() { var systemModuleDeps android.Paths bootClasspath, systemModuleDeps = flags.systemModules.FormJavaSystemModulesPath(ctx.Device()) deps = append(deps, systemModuleDeps...) - classpath = append(flags.java9Classpath, classpath...) + javacClasspath = append(flags.java9Classpath, javacClasspath...) } else { deps = append(deps, flags.bootClasspath...) if len(flags.bootClasspath) == 0 && ctx.Device() { @@ -553,7 +569,19 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab } } - deps = append(deps, classpath...) + classpathArg := javacClasspath.FormJavaClassPath("-classpath") + + // Keep the command line under the MAX_ARG_STRLEN limit by putting the classpath argument into an rsp file + // if it is too long. + const classpathLimit = 64 * 1024 + if len(classpathArg) > classpathLimit { + classpathRspFile := outputFile.ReplaceExtension(ctx, "classpath") + android.WriteFileRule(ctx, classpathRspFile, classpathArg) + deps = append(deps, classpathRspFile) + classpathArg = "@" + classpathRspFile.String() + } + + deps = append(deps, javacClasspath...) deps = append(deps, flags.processorPath...) processor := "-proc:none" @@ -584,7 +612,7 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab Args: map[string]string{ "javacFlags": flags.javacFlags, "bootClasspath": bootClasspath, - "classpath": classpath.FormJavaClassPath("-classpath"), + "classpath": classpathArg, "processorpath": flags.processorPath.FormJavaClassPath("-processorpath"), "processor": processor, "srcJars": strings.Join(srcJars.Strings(), " "), @@ -643,8 +671,23 @@ func TransformJarsToJar(ctx android.ModuleContext, outputFile android.WritablePa jarArgs = append(jarArgs, "-D") } + rule := combineJar + // Keep the command line under the MAX_ARG_STRLEN limit by putting the list of jars into an rsp file + // if it is too long. + const jarsLengthLimit = 64 * 1024 + jarsLength := 0 + for i, jar := range jars { + if i != 0 { + jarsLength += 1 + } + jarsLength += len(jar.String()) + } + if jarsLength > jarsLengthLimit { + rule = combineJarRsp + } + ctx.Build(pctx, android.BuildParams{ - Rule: combineJar, + Rule: rule, Description: desc, Output: outputFile, Inputs: jars, diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp index 8ffe5113c..ab72e8b6d 100644 --- a/java/core-libraries/Android.bp +++ b/java/core-libraries/Android.bp @@ -64,6 +64,7 @@ java_api_library { "stub-annotations", ], enable_validation: false, + stubs_type: "everything", } java_library { @@ -248,6 +249,7 @@ java_api_library { "stub-annotations", ], visibility: ["//visibility:private"], + stubs_type: "everything", } // Produces a dist file that is used by the @@ -358,6 +360,7 @@ java_api_library { libs: [ "stub-annotations", ], + stubs_type: "everything", } java_library { @@ -446,6 +449,7 @@ java_api_library { libs: [ "stub-annotations", ], + stubs_type: "everything", } java_library { diff --git a/java/dexpreopt.go b/java/dexpreopt.go index 1cfa64245..38ed856ee 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -187,6 +187,33 @@ func forPrebuiltApex(ctx android.BaseModuleContext) bool { return apexInfo.ForPrebuiltApex } +// For apex variant of modules, this returns true on the source variant if the prebuilt apex +// has been selected using apex_contributions. +// The prebuilt apex will be responsible for generating the dexpreopt rules of the deapexed java lib. +func disableSourceApexVariant(ctx android.BaseModuleContext) bool { + if !isApexVariant(ctx) { + return false // platform variant + } + apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) + psi := android.PrebuiltSelectionInfoMap{} + ctx.VisitDirectDepsWithTag(android.PrebuiltDepTag, func(am android.Module) { + psi, _ = android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider) + }) + // Find the apex variant for this module + _, apexVariantsWithoutTestApexes, _ := android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes) + disableSource := false + // find the selected apexes + for _, apexVariant := range apexVariantsWithoutTestApexes { + for _, selected := range psi.GetSelectedModulesForApiDomain(apexVariant) { + // If the apex_contribution for this api domain contains a prebuilt apex, disable the source variant + if strings.HasPrefix(selected, "prebuilt_com.google.android") { + disableSource = true + } + } + } + return disableSource +} + // Returns whether dexpreopt is applicable to the module. // When it returns true, neither profile nor dexpreopt artifacts will be generated. func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext, libName string) bool { @@ -216,6 +243,10 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext, libName s return true } + if disableSourceApexVariant(ctx) { + return true + } + if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex { // dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes return false diff --git a/java/droidstubs.go b/java/droidstubs.go index b1126146c..f4bcaca15 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -52,6 +52,19 @@ func (s StubsType) String() string { } } +func StringToStubsType(s string) StubsType { + switch strings.ToLower(s) { + case Everything.String(): + return Everything + case Runtime.String(): + return Runtime + case Exportable.String(): + return Exportable + default: + return Unavailable + } +} + func init() { RegisterStubsBuildComponents(android.InitRegistrationContext) } @@ -731,7 +744,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi // defined for a module, simply revert all flagged apis annotations. If aconfig_declarations // property is defined, apply transformations and only revert the flagged apis that are not // enabled via release configurations and are not specified in aconfig_declarations -func (d *Droidstubs) generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) { +func generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) { if len(aconfigFlagsPaths) == 0 { cmd.Flag("--revert-annotation android.annotation.FlaggedApi") @@ -1106,7 +1119,7 @@ func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsComm cmd := d.commonMetalavaStubCmd(ctx, rule, params) - d.generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles) + generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles) if params.stubConfig.doApiLint { // Pass the lint baseline file as an input to resolve the lint errors. diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go index ca34e0ef1..c86e8bf0f 100644 --- a/java/droidstubs_test.go +++ b/java/droidstubs_test.go @@ -337,6 +337,7 @@ func TestGeneratedApiContributionVisibilityTest(t *testing.T) { name: "bar", api_surface: "public", api_contributions: ["foo.api.contribution"], + stubs_type: "everything", } ` ctx, _ := testJavaWithFS(t, ` diff --git a/java/java.go b/java/java.go index af4c3be3b..794020dc5 100644 --- a/java/java.go +++ b/java/java.go @@ -24,6 +24,7 @@ import ( "sort" "strings" + "android/soong/aconfig" "android/soong/remoteexec" "android/soong/testing" @@ -1863,6 +1864,10 @@ type ApiLibrary struct { dexJarFile OptionalDexJarPath validationPaths android.Paths + + stubsType StubsType + + aconfigProtoFiles android.Paths } type JavaApiLibraryProperties struct { @@ -1904,6 +1909,20 @@ type JavaApiLibraryProperties struct { // in sync with the source Java files. However, the environment variable // DISABLE_STUB_VALIDATION has precedence over this property. Enable_validation *bool + + // Type of stubs the module should generate. Must be one of "everything", "runtime" or + // "exportable". Defaults to "everything". + // - "everything" stubs include all non-flagged apis and flagged apis, regardless of the state + // of the flag. + // - "runtime" stubs include all non-flagged apis and flagged apis that are ENABLED or + // READ_WRITE, and all other flagged apis are stripped. + // - "exportable" stubs include all non-flagged apis and flagged apis that are ENABLED and + // READ_ONLY, and all other flagged apis are stripped. + Stubs_type *string + + // List of aconfig_declarations module names that the stubs generated in this module + // depend on. + Aconfig_declarations []string } func ApiLibraryFactory() android.Module { @@ -2067,6 +2086,9 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { if al.properties.System_modules != nil { ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules)) } + for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations { + ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName) + } } // Map where key is the api scope name and value is the int value @@ -2087,7 +2109,23 @@ func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFiles return srcFilesInfo } +var validstubsType = []StubsType{Everything, Runtime, Exportable} + +func (al *ApiLibrary) validateProperties(ctx android.ModuleContext) { + if al.properties.Stubs_type == nil { + ctx.ModuleErrorf("java_api_library module type must specify stubs_type property.") + } else { + al.stubsType = StringToStubsType(proptools.String(al.properties.Stubs_type)) + } + + if !android.InList(al.stubsType, validstubsType) { + ctx.PropertyErrorf("stubs_type", "%s is not a valid stubs_type property value. "+ + "Must be one of %s.", proptools.String(al.properties.Stubs_type), validstubsType) + } +} + func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + al.validateProperties(ctx) rule := android.NewRuleBuilder(pctx, ctx) @@ -2131,6 +2169,18 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok { al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp()) } + case aconfigDeclarationTag: + if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok { + al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath) + } else if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok { + al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...) + } else { + ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+ + "module type is allowed for flags_packages property, but %s is neither "+ + "of these supported module types", + dep.Name(), + ) + } } }) @@ -2156,6 +2206,8 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { al.addValidation(ctx, cmd, al.validationPaths) + generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles) + al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar") al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar") al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName())) diff --git a/java/java_test.go b/java/java_test.go index 42301d866..2f3ccb98d 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1756,6 +1756,7 @@ func TestJavaApiContributionEmptyApiFile(t *testing.T) { name: "bar", api_surface: "public", api_contributions: ["foo"], + stubs_type: "everything", } `) } @@ -1792,12 +1793,14 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) { name: "bar1", api_surface: "public", api_contributions: ["foo1"], + stubs_type: "everything", } java_api_library { name: "bar2", api_surface: "system", api_contributions: ["foo1", "foo2"], + stubs_type: "everything", } `) @@ -1885,12 +1888,14 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { name: "bar1", api_surface: "public", api_contributions: ["foo1"], + stubs_type: "everything", } java_api_library { name: "bar2", api_surface: "public", defaults:["baz1"], + stubs_type: "everything", } java_api_library { @@ -1898,6 +1903,7 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { api_surface: "system", defaults:["baz1", "baz2"], api_contributions: ["foo4"], + stubs_type: "everything", } `) @@ -1962,12 +1968,14 @@ func TestJavaApiLibraryJarGeneration(t *testing.T) { name: "bar1", api_surface: "public", api_contributions: ["foo1"], + stubs_type: "everything", } java_api_library { name: "bar2", api_surface: "system", api_contributions: ["foo1", "foo2"], + stubs_type: "everything", } `) @@ -2044,6 +2052,7 @@ func TestJavaApiLibraryLibsLink(t *testing.T) { api_surface: "public", api_contributions: ["foo1"], libs: ["lib1"], + stubs_type: "everything", } java_api_library { @@ -2051,6 +2060,7 @@ func TestJavaApiLibraryLibsLink(t *testing.T) { api_surface: "system", api_contributions: ["foo1", "foo2"], libs: ["lib1", "lib2", "bar1"], + stubs_type: "everything", } `) @@ -2130,6 +2140,7 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) { api_surface: "public", api_contributions: ["foo1"], static_libs: ["lib1"], + stubs_type: "everything", } java_api_library { @@ -2137,6 +2148,7 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) { api_surface: "system", api_contributions: ["foo1", "foo2"], static_libs: ["lib1", "lib2", "bar1"], + stubs_type: "everything", } `) @@ -2184,6 +2196,7 @@ func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) { name: "lib1", api_surface: "public", api_contributions: ["foo1", "foo2"], + stubs_type: "everything", } ` @@ -2207,6 +2220,7 @@ func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) { api_surface: "public", api_contributions: ["foo1"], full_api_surface_stub: "lib1", + stubs_type: "everything", } `) @@ -2368,6 +2382,7 @@ func TestJavaApiContributionImport(t *testing.T) { java_api_library { name: "foo", api_contributions: ["bar"], + stubs_type: "everything", } java_api_contribution_import { name: "bar", @@ -2394,6 +2409,7 @@ func TestJavaApiLibraryApiFilesSorting(t *testing.T) { "module-lib-api-stubs-docs-non-updatable.api.contribution", "api-stubs-docs-non-updatable.api.contribution", ], + stubs_type: "everything", } `) m := ctx.ModuleForTests("foo", "android_common") @@ -2466,6 +2482,7 @@ func TestApiLibraryDroidstubsDependency(t *testing.T) { "api-stubs-docs-non-updatable.api.contribution", ], enable_validation: true, + stubs_type: "everything", } java_api_library { name: "bar", @@ -2473,6 +2490,7 @@ func TestApiLibraryDroidstubsDependency(t *testing.T) { "api-stubs-docs-non-updatable.api.contribution", ], enable_validation: false, + stubs_type: "everything", } `) @@ -2624,3 +2642,54 @@ func TestMultiplePrebuilts(t *testing.T) { android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0]) } } + +func TestApiLibraryAconfigDeclarations(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + }), + android.FixtureMergeMockFs(map[string][]byte{ + "a/A.java": nil, + "a/current.txt": nil, + "a/removed.txt": nil, + }), + ).RunTestWithBp(t, ` + aconfig_declarations { + name: "bar", + package: "com.example.package", + srcs: [ + "bar.aconfig", + ], + } + java_api_contribution { + name: "baz", + api_file: "a/current.txt", + api_surface: "public", + } + java_api_library { + name: "foo", + api_surface: "public", + api_contributions: [ + "baz", + ], + aconfig_declarations: [ + "bar", + ], + stubs_type: "exportable", + enable_validation: false, + } + `) + + // Check if java_api_library depends on aconfig_declarations + android.AssertBoolEquals(t, "foo expected to depend on bar", + CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true) + + m := result.ModuleForTests("foo", "android_common") + android.AssertStringDoesContain(t, "foo generates revert annotations file", + strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt") + + // revert-annotations.txt passed to exportable stubs generation metalava command + manifest := m.Output("metalava.sbox.textproto") + cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command) + android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt") +} diff --git a/java/sdk_library.go b/java/sdk_library.go index d532aaa00..cdd04483d 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2024,6 +2024,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, Full_api_surface_stub *string System_modules *string Enable_validation *bool + Stubs_type *string }{} props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) @@ -2073,6 +2074,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, props.System_modules = module.deviceProperties.System_modules props.Enable_validation = proptools.BoolPtr(true) + props.Stubs_type = proptools.StringPtr("everything") mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary()) } diff --git a/java/testing.go b/java/testing.go index 04e8c734e..631d51662 100644 --- a/java/testing.go +++ b/java/testing.go @@ -523,10 +523,11 @@ func gatherRequiredDepsForTest() string { for libName, droidstubs := range extraApiLibraryModules { bp += fmt.Sprintf(` - java_api_library { - name: "%s", - api_contributions: ["%s"], - } + java_api_library { + name: "%s", + api_contributions: ["%s"], + stubs_type: "everything", + } `, libName, droidstubs.name+".api.contribution") } diff --git a/rust/config/lints.go b/rust/config/lints.go index 7770af03e..735aa169b 100644 --- a/rust/config/lints.go +++ b/rust/config/lints.go @@ -53,6 +53,8 @@ var ( // It should be assumed that any warning lint will be promoted to a // deny. defaultClippyLints = []string{ + // Let people hack in peace. ;) + "-A clippy::disallowed_names", "-A clippy::type-complexity", "-A clippy::unnecessary_fallible_conversions", "-A clippy::unnecessary-wraps", diff --git a/ui/build/config.go b/ui/build/config.go index e29d23929..1a2539793 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -75,7 +75,6 @@ type configImpl struct { queryview bool reportMkMetrics bool // Collect and report mk2bp migration progress metrics. soongDocs bool - multitreeBuild bool // This is a multitree build. skipConfig bool skipKati bool skipKatiNinja bool @@ -424,10 +423,6 @@ func NewConfig(ctx Context, args ...string) Config { // zip files produced by soong_zip. Disable zipbomb detection. ret.environ.Set("UNZIP_DISABLE_ZIPBOMB_DETECTION", "TRUE") - if ret.MultitreeBuild() { - ret.environ.Set("MULTITREE_BUILD", "true") - } - outDir := ret.OutDir() buildDateTimeFile := filepath.Join(outDir, "build_date.txt") if buildDateTime, ok := ret.environ.Get("BUILD_DATETIME"); ok && buildDateTime != "" { @@ -789,8 +784,6 @@ func (c *configImpl) parseArgs(ctx Context, args []string) { c.skipMetricsUpload = true } else if arg == "--mk-metrics" { c.reportMkMetrics = true - } else if arg == "--multitree-build" { - c.multitreeBuild = true } else if arg == "--search-api-dir" { c.searchApiDir = true } else if strings.HasPrefix(arg, "--ninja_weight_source=") { @@ -1095,10 +1088,6 @@ func (c *configImpl) IsVerbose() bool { return c.verbose } -func (c *configImpl) MultitreeBuild() bool { - return c.multitreeBuild -} - func (c *configImpl) NinjaWeightListSource() NinjaWeightListSource { return c.ninjaWeightListSource } diff --git a/ui/build/config_test.go b/ui/build/config_test.go index 5182b1226..b1222fe93 100644 --- a/ui/build/config_test.go +++ b/ui/build/config_test.go @@ -860,23 +860,24 @@ func TestGetConfigArgsBuildModules(t *testing.T) { } func TestGetConfigArgsBuildModulesInDirectory(t *testing.T) { - tests := []buildActionTestCase{{ - description: "normal execution in a directory", - dirsInTrees: []string{"0/1/2"}, - buildFiles: []string{"0/1/2/Android.mk"}, - args: []string{"fake-module"}, - curDir: "0/1/2", - tidyOnly: "", - expectedArgs: []string{"fake-module", "MODULES-IN-0-1-2"}, - }, { - description: "build file in parent directory", - dirsInTrees: []string{"0/1/2"}, - buildFiles: []string{"0/1/Android.mk"}, - args: []string{}, - curDir: "0/1/2", - tidyOnly: "", - expectedArgs: []string{"MODULES-IN-0-1"}, - }, + tests := []buildActionTestCase{ + { + description: "normal execution in a directory", + dirsInTrees: []string{"0/1/2"}, + buildFiles: []string{"0/1/2/Android.mk"}, + args: []string{"fake-module"}, + curDir: "0/1/2", + tidyOnly: "", + expectedArgs: []string{"fake-module", "MODULES-IN-0-1-2"}, + }, { + description: "build file in parent directory", + dirsInTrees: []string{"0/1/2"}, + buildFiles: []string{"0/1/Android.mk"}, + args: []string{}, + curDir: "0/1/2", + tidyOnly: "", + expectedArgs: []string{"MODULES-IN-0-1"}, + }, { description: "build file in parent directory, multiple module names passed in", dirsInTrees: []string{"0/1/2"}, @@ -903,15 +904,6 @@ func TestGetConfigArgsBuildModulesInDirectory(t *testing.T) { tidyOnly: "", expectedArgs: []string{}, }, { - description: "multitree build action executed at root directory", - dirsInTrees: []string{}, - buildFiles: []string{}, - rootSymlink: false, - args: []string{"--multitree-build"}, - curDir: ".", - tidyOnly: "", - expectedArgs: []string{"--multitree-build"}, - }, { description: "build action executed at root directory in symlink", dirsInTrees: []string{}, buildFiles: []string{}, @@ -953,7 +945,8 @@ func TestGetConfigArgsBuildModulesInDirectory(t *testing.T) { curDir: "", tidyOnly: "", expectedArgs: []string{"-j", "-k", "fake_module"}, - }} + }, + } for _, tt := range tests { t.Run("build action BUILD_MODULES_IN_DIR, "+tt.description, func(t *testing.T) { testGetConfigArgs(t, tt, BUILD_MODULES_IN_A_DIRECTORY) diff --git a/ui/build/soong.go b/ui/build/soong.go index a201ac5d7..79584c66f 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -197,9 +197,6 @@ func (pb PrimaryBuilderFactory) primaryBuilderInvocation(config Config) bootstra commonArgs = append(commonArgs, "-t") } - if pb.config.multitreeBuild { - commonArgs = append(commonArgs, "--multitree-build") - } if pb.config.buildFromSourceStub { commonArgs = append(commonArgs, "--build-from-source-stub") } @@ -305,9 +302,6 @@ func bootstrapBlueprint(ctx Context, config Config) { if config.EmptyNinjaFile() { mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--empty-ninja-file") } - if config.MultitreeBuild() { - mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--multitree-build") - } if config.buildFromSourceStub { mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--build-from-source-stub") } |