Loading java/boot_jars.go +7 −94 Original line number Diff line number Diff line Loading @@ -18,37 +18,6 @@ import ( "android/soong/android" ) func init() { android.RegisterSingletonType("boot_jars", bootJarsSingletonFactory) } func bootJarsSingletonFactory() android.Singleton { return &bootJarsSingleton{} } type bootJarsSingleton struct{} func populateMapFromConfiguredJarList(ctx android.SingletonContext, moduleToApex map[string]string, list android.ConfiguredJarList, name string) bool { for i := 0; i < list.Len(); i++ { module := list.Jar(i) // Ignore jacocoagent it is only added when instrumenting and so has no impact on // app compatibility. if module == "jacocoagent" { continue } apex := list.Apex(i) if existing, ok := moduleToApex[module]; ok { ctx.Errorf("Configuration property %q is invalid as it contains multiple references to module (%s) in APEXes (%s and %s)", module, existing, apex) return false } moduleToApex[module] = apex } return true } // isActiveModule returns true if the given module should be considered for boot // jars, i.e. if it's enabled and the preferred one in case of source and // prebuilt alternatives. Loading @@ -59,73 +28,17 @@ func isActiveModule(module android.Module) bool { return android.IsModulePreferred(module) } func (b *bootJarsSingleton) GenerateBuildActions(ctx android.SingletonContext) { config := ctx.Config() if config.SkipBootJarsCheck() { return } // Populate a map from module name to APEX from the boot jars. If there is a // problem such as duplicate modules then fail and return immediately. Note // that both module and APEX names are tracked by base names here, so we need // to be careful to remove "prebuilt_" prefixes when comparing them with // actual modules and APEX bundles. moduleToApex := make(map[string]string) if !populateMapFromConfiguredJarList(ctx, moduleToApex, config.NonUpdatableBootJars(), "BootJars") || !populateMapFromConfiguredJarList(ctx, moduleToApex, config.UpdatableBootJars(), "UpdatableBootJars") { return } // Map from module name to the correct apex variant. nameToApexVariant := make(map[string]android.Module) // Scan all the modules looking for the module/apex variants corresponding to the // boot jars. ctx.VisitAllModules(func(module android.Module) { if !isActiveModule(module) { return } name := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName(module)) if apex, ok := moduleToApex[name]; ok { apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) if (apex == "platform" && apexInfo.IsForPlatform()) || apexInfo.InApexModule(apex) { // The module name/apex variant should be unique in the system but double check // just in case something has gone wrong. if existing, ok := nameToApexVariant[name]; ok { ctx.Errorf("found multiple variants matching %s:%s: %q and %q", apex, name, existing, module) } nameToApexVariant[name] = module } } }) // buildRuleForBootJarsPackageCheck generates the build rule to perform the boot jars package // check. func buildRuleForBootJarsPackageCheck(ctx android.ModuleContext, bootDexJarByModule bootDexJarByModule) { timestamp := android.PathForOutput(ctx, "boot-jars-package-check/stamp") rule := android.NewRuleBuilder(pctx, ctx) checkBootJars := rule.Command().BuiltTool("check_boot_jars"). rule.Command().BuiltTool("check_boot_jars"). Input(ctx.Config().HostToolPath(ctx, "dexdump")). Input(android.PathForSource(ctx, "build/soong/scripts/check_boot_jars/package_allowed_list.txt")) // If this is not an unbundled build and missing dependencies are not allowed // then all the boot jars listed must have been found. strict := !config.UnbundledBuild() && !config.AllowMissingDependencies() // Iterate over the module names on the boot classpath in order for _, name := range android.SortedStringKeys(moduleToApex) { if apexVariant, ok := nameToApexVariant[name]; ok { if dep, ok := apexVariant.(interface{ DexJarBuildPath() android.Path }); ok { // Add the dex implementation jar for the module to be checked. checkBootJars.Input(dep.DexJarBuildPath()) } else { ctx.Errorf("module %q is of type %q which is not supported as a boot jar", name, ctx.ModuleType(apexVariant)) } } else if strict { ctx.Errorf("boot jars package check failed as it could not find module %q for apex %q", name, moduleToApex[name]) } } checkBootJars.Text("&& touch").Output(timestamp) Input(android.PathForSource(ctx, "build/soong/scripts/check_boot_jars/package_allowed_list.txt")). Inputs(bootDexJarByModule.bootDexJars()). Text("&& touch").Output(timestamp) rule.Build("boot_jars_package_check", "check boot jar packages") // The check-boot-jars phony target depends on the timestamp created if the check succeeds. Loading java/platform_bootclasspath.go +6 −3 Original line number Diff line number Diff line Loading @@ -189,7 +189,8 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo b.generateClasspathProtoBuildActions(ctx) b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments) bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments) buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule) // Nothing to do if skipping the dexpreopt of boot image jars. if SkipDexpreoptBootJars(ctx) { Loading Loading @@ -258,7 +259,7 @@ func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleCont } // generateHiddenAPIBuildActions generates all the hidden API related build rules. func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) { func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) bootDexJarByModule { // Save the paths to the monolithic files for retrieval via OutputFiles(). b.hiddenAPIFlagsCSV = hiddenAPISingletonPaths(ctx).flags Loading @@ -276,7 +277,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. Output: path, }) } return return nil } monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, fragments) Loading Loading @@ -322,6 +323,8 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. // jars. indexCSV := hiddenAPISingletonPaths(ctx).index buildRuleToGenerateIndex(ctx, "monolithic hidden API index", classesJars, indexCSV) return bootDexJarByModule } // createAndProvideMonolithicHiddenAPIInfo creates a MonolithicHiddenAPIInfo and provides it for Loading sdk/bootclasspath_fragment_sdk_test.go +21 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ func fixtureAddPlatformBootclasspathForBootclasspathFragment(apex, fragment stri } `, apex, fragment)), android.FixtureAddFile("frameworks/base/config/boot-profile.txt", nil), android.FixtureAddFile("build/soong/scripts/check_boot_jars/package_allowed_list.txt", nil), ) } Loading Loading @@ -173,9 +174,29 @@ sdk_snapshot { .intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar `), snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot), // Check the behavior of the snapshot without the source. snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) { // Make sure that the boot jars package check rule includes the dex jar retrieved from the prebuilt apex. checkBootJarsPackageCheckRule(t, result, "out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/mybootlib.jar") }), snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot), snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot), ) // Make sure that the boot jars package check rule includes the dex jar created from the source. checkBootJarsPackageCheckRule(t, result, "out/soong/.intermediates/mybootlib/android_common_apex10000/aligned/mybootlib.jar") } // checkBootJarsPackageCheckRule checks that the supplied module is an input to the boot jars // package check rule. func checkBootJarsPackageCheckRule(t *testing.T, result *android.TestResult, expectedModule string) { platformBcp := result.ModuleForTests("platform-bootclasspath", "android_common") bootJarsCheckRule := platformBcp.Rule("boot_jars_package_check") command := bootJarsCheckRule.RuleParams.Command expectedCommandArgs := " out/soong/host/linux-x86/bin/dexdump build/soong/scripts/check_boot_jars/package_allowed_list.txt " + expectedModule + " &&" android.AssertStringDoesContain(t, "boot jars package check", command, expectedCommandArgs) } func TestSnapshotWithBootClasspathFragment_Contents(t *testing.T) { Loading Loading
java/boot_jars.go +7 −94 Original line number Diff line number Diff line Loading @@ -18,37 +18,6 @@ import ( "android/soong/android" ) func init() { android.RegisterSingletonType("boot_jars", bootJarsSingletonFactory) } func bootJarsSingletonFactory() android.Singleton { return &bootJarsSingleton{} } type bootJarsSingleton struct{} func populateMapFromConfiguredJarList(ctx android.SingletonContext, moduleToApex map[string]string, list android.ConfiguredJarList, name string) bool { for i := 0; i < list.Len(); i++ { module := list.Jar(i) // Ignore jacocoagent it is only added when instrumenting and so has no impact on // app compatibility. if module == "jacocoagent" { continue } apex := list.Apex(i) if existing, ok := moduleToApex[module]; ok { ctx.Errorf("Configuration property %q is invalid as it contains multiple references to module (%s) in APEXes (%s and %s)", module, existing, apex) return false } moduleToApex[module] = apex } return true } // isActiveModule returns true if the given module should be considered for boot // jars, i.e. if it's enabled and the preferred one in case of source and // prebuilt alternatives. Loading @@ -59,73 +28,17 @@ func isActiveModule(module android.Module) bool { return android.IsModulePreferred(module) } func (b *bootJarsSingleton) GenerateBuildActions(ctx android.SingletonContext) { config := ctx.Config() if config.SkipBootJarsCheck() { return } // Populate a map from module name to APEX from the boot jars. If there is a // problem such as duplicate modules then fail and return immediately. Note // that both module and APEX names are tracked by base names here, so we need // to be careful to remove "prebuilt_" prefixes when comparing them with // actual modules and APEX bundles. moduleToApex := make(map[string]string) if !populateMapFromConfiguredJarList(ctx, moduleToApex, config.NonUpdatableBootJars(), "BootJars") || !populateMapFromConfiguredJarList(ctx, moduleToApex, config.UpdatableBootJars(), "UpdatableBootJars") { return } // Map from module name to the correct apex variant. nameToApexVariant := make(map[string]android.Module) // Scan all the modules looking for the module/apex variants corresponding to the // boot jars. ctx.VisitAllModules(func(module android.Module) { if !isActiveModule(module) { return } name := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName(module)) if apex, ok := moduleToApex[name]; ok { apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) if (apex == "platform" && apexInfo.IsForPlatform()) || apexInfo.InApexModule(apex) { // The module name/apex variant should be unique in the system but double check // just in case something has gone wrong. if existing, ok := nameToApexVariant[name]; ok { ctx.Errorf("found multiple variants matching %s:%s: %q and %q", apex, name, existing, module) } nameToApexVariant[name] = module } } }) // buildRuleForBootJarsPackageCheck generates the build rule to perform the boot jars package // check. func buildRuleForBootJarsPackageCheck(ctx android.ModuleContext, bootDexJarByModule bootDexJarByModule) { timestamp := android.PathForOutput(ctx, "boot-jars-package-check/stamp") rule := android.NewRuleBuilder(pctx, ctx) checkBootJars := rule.Command().BuiltTool("check_boot_jars"). rule.Command().BuiltTool("check_boot_jars"). Input(ctx.Config().HostToolPath(ctx, "dexdump")). Input(android.PathForSource(ctx, "build/soong/scripts/check_boot_jars/package_allowed_list.txt")) // If this is not an unbundled build and missing dependencies are not allowed // then all the boot jars listed must have been found. strict := !config.UnbundledBuild() && !config.AllowMissingDependencies() // Iterate over the module names on the boot classpath in order for _, name := range android.SortedStringKeys(moduleToApex) { if apexVariant, ok := nameToApexVariant[name]; ok { if dep, ok := apexVariant.(interface{ DexJarBuildPath() android.Path }); ok { // Add the dex implementation jar for the module to be checked. checkBootJars.Input(dep.DexJarBuildPath()) } else { ctx.Errorf("module %q is of type %q which is not supported as a boot jar", name, ctx.ModuleType(apexVariant)) } } else if strict { ctx.Errorf("boot jars package check failed as it could not find module %q for apex %q", name, moduleToApex[name]) } } checkBootJars.Text("&& touch").Output(timestamp) Input(android.PathForSource(ctx, "build/soong/scripts/check_boot_jars/package_allowed_list.txt")). Inputs(bootDexJarByModule.bootDexJars()). Text("&& touch").Output(timestamp) rule.Build("boot_jars_package_check", "check boot jar packages") // The check-boot-jars phony target depends on the timestamp created if the check succeeds. Loading
java/platform_bootclasspath.go +6 −3 Original line number Diff line number Diff line Loading @@ -189,7 +189,8 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo b.generateClasspathProtoBuildActions(ctx) b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments) bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments) buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule) // Nothing to do if skipping the dexpreopt of boot image jars. if SkipDexpreoptBootJars(ctx) { Loading Loading @@ -258,7 +259,7 @@ func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleCont } // generateHiddenAPIBuildActions generates all the hidden API related build rules. func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) { func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) bootDexJarByModule { // Save the paths to the monolithic files for retrieval via OutputFiles(). b.hiddenAPIFlagsCSV = hiddenAPISingletonPaths(ctx).flags Loading @@ -276,7 +277,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. Output: path, }) } return return nil } monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, fragments) Loading Loading @@ -322,6 +323,8 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. // jars. indexCSV := hiddenAPISingletonPaths(ctx).index buildRuleToGenerateIndex(ctx, "monolithic hidden API index", classesJars, indexCSV) return bootDexJarByModule } // createAndProvideMonolithicHiddenAPIInfo creates a MonolithicHiddenAPIInfo and provides it for Loading
sdk/bootclasspath_fragment_sdk_test.go +21 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ func fixtureAddPlatformBootclasspathForBootclasspathFragment(apex, fragment stri } `, apex, fragment)), android.FixtureAddFile("frameworks/base/config/boot-profile.txt", nil), android.FixtureAddFile("build/soong/scripts/check_boot_jars/package_allowed_list.txt", nil), ) } Loading Loading @@ -173,9 +174,29 @@ sdk_snapshot { .intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar `), snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot), // Check the behavior of the snapshot without the source. snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) { // Make sure that the boot jars package check rule includes the dex jar retrieved from the prebuilt apex. checkBootJarsPackageCheckRule(t, result, "out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/mybootlib.jar") }), snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot), snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot), ) // Make sure that the boot jars package check rule includes the dex jar created from the source. checkBootJarsPackageCheckRule(t, result, "out/soong/.intermediates/mybootlib/android_common_apex10000/aligned/mybootlib.jar") } // checkBootJarsPackageCheckRule checks that the supplied module is an input to the boot jars // package check rule. func checkBootJarsPackageCheckRule(t *testing.T, result *android.TestResult, expectedModule string) { platformBcp := result.ModuleForTests("platform-bootclasspath", "android_common") bootJarsCheckRule := platformBcp.Rule("boot_jars_package_check") command := bootJarsCheckRule.RuleParams.Command expectedCommandArgs := " out/soong/host/linux-x86/bin/dexdump build/soong/scripts/check_boot_jars/package_allowed_list.txt " + expectedModule + " &&" android.AssertStringDoesContain(t, "boot jars package check", command, expectedCommandArgs) } func TestSnapshotWithBootClasspathFragment_Contents(t *testing.T) { Loading