Loading java/classpath_fragment.go +90 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ package java import ( "fmt" "strings" "android/soong/android" ) Loading Loading @@ -47,21 +50,102 @@ type classpathFragmentProperties struct { type classpathFragment interface { android.Module classpathFragmentBase() *classpathFragmentBase classpathFragmentBase() *ClasspathFragmentBase } // classpathFragmentBase is meant to be embedded in any module types that implement classpathFragment; // ClasspathFragmentBase is meant to be embedded in any module types that implement classpathFragment; // such modules are expected to call initClasspathFragment(). type classpathFragmentBase struct { type ClasspathFragmentBase struct { properties classpathFragmentProperties classpathType classpathType outputFilepath android.OutputPath installDirPath android.InstallPath } func (c *ClasspathFragmentBase) classpathFragmentBase() *ClasspathFragmentBase { return c } // Initializes classpathFragmentBase struct. Must be called by all modules that include classpathFragmentBase. // Initializes ClasspathFragmentBase struct. Must be called by all modules that include ClasspathFragmentBase. func initClasspathFragment(c classpathFragment) { base := c.classpathFragmentBase() c.AddProperties(&base.properties) } // Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto type classpathJar struct { path string classpath classpathType // TODO(satayev): propagate min/max sdk versions for the jars minSdkVersion int32 maxSdkVersion int32 } func (c *ClasspathFragmentBase) generateAndroidBuildActions(ctx android.ModuleContext) { outputFilename := ctx.ModuleName() + ".pb" c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths") var jars []classpathJar jars = appendClasspathJar(jars, BOOTCLASSPATH, defaultBootclasspath(ctx)...) jars = appendClasspathJar(jars, DEX2OATBOOTCLASSPATH, defaultBootImageConfig(ctx).getAnyAndroidVariant().dexLocationsDeps...) jars = appendClasspathJar(jars, SYSTEMSERVERCLASSPATH, systemServerClasspath(ctx)...) generatedJson := android.PathForModuleOut(ctx, outputFilename+".json") writeClasspathsJson(ctx, generatedJson, jars) rule := android.NewRuleBuilder(pctx, ctx) rule.Command(). BuiltTool("conv_classpaths_proto"). Flag("encode"). Flag("--format=json"). FlagWithInput("--input=", generatedJson). FlagWithOutput("--output=", c.outputFilepath) rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String()) } func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) { var content strings.Builder fmt.Fprintf(&content, "{\n") fmt.Fprintf(&content, "\"jars\": [\n") for idx, jar := range jars { fmt.Fprintf(&content, "{\n") fmt.Fprintf(&content, "\"relativePath\": \"%s\",\n", jar.path) fmt.Fprintf(&content, "\"classpath\": \"%s\"\n", jar.classpath) if idx < len(jars)-1 { fmt.Fprintf(&content, "},\n") } else { fmt.Fprintf(&content, "}\n") } } fmt.Fprintf(&content, "]\n") fmt.Fprintf(&content, "}\n") android.WriteFileRule(ctx, output, content.String()) } func appendClasspathJar(slice []classpathJar, classpathType classpathType, paths ...string) (result []classpathJar) { result = append(result, slice...) for _, path := range paths { result = append(result, classpathJar{ path: path, classpath: classpathType, }) } return } func (c *ClasspathFragmentBase) getAndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "ETC", OutputFile: android.OptionalPathForPath(c.outputFilepath), ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetString("LOCAL_MODULE_PATH", c.installDirPath.ToMakePath().String()) entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.outputFilepath.Base()) }, }, }} } java/dexpreopt_config.go +1 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import ( // systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed // once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same // ctx.Config(). func systemServerClasspath(ctx android.MakeVarsContext) []string { func systemServerClasspath(ctx android.PathContext) []string { return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string { global := dexpreopt.GetGlobalConfig(ctx) var systemServerClasspathLocations []string Loading java/platform_bootclasspath.go +14 −10 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathDepende type platformBootclasspathModule struct { android.ModuleBase ClasspathFragmentBase properties platformBootclasspathProperties Loading Loading @@ -105,22 +106,23 @@ type platformBootclasspathProperties struct { func platformBootclasspathFactory() android.Module { m := &platformBootclasspathModule{} m.AddProperties(&m.properties) // TODO(satayev): split systemserver and apex jars into separate configs. initClasspathFragment(m) android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) return m } var _ android.OutputFileProducer = (*platformBootclasspathModule)(nil) // A minimal AndroidMkEntries is needed in order to support the dists property. func (b *platformBootclasspathModule) AndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{ { func (b *platformBootclasspathModule) AndroidMkEntries() (entries []android.AndroidMkEntries) { entries = append(entries, android.AndroidMkEntries{ Class: "FAKE", // Need at least one output file in order for this to take effect. OutputFile: android.OptionalPathForPath(b.hiddenAPIFlagsCSV), Include: "$(BUILD_PHONY_PACKAGE)", }, } }) entries = append(entries, b.classpathFragmentBase().getAndroidMkEntries()...) return } // Make the hidden API files available from the platform-bootclasspath module. Loading Loading @@ -245,6 +247,8 @@ func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, mod } func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { b.classpathFragmentBase().generateAndroidBuildActions(ctx) ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) if tag == platformBootclasspathModuleDepTag { Loading java/platform_bootclasspath_test.go +83 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,89 @@ func TestPlatformBootclasspath(t *testing.T) { }) } func TestPlatformBootclasspathVariant(t *testing.T) { result := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, android.FixtureWithRootAndroidBp(` platform_bootclasspath { name: "platform-bootclasspath", } `), ).RunTest(t) variants := result.ModuleVariantsForTests("platform-bootclasspath") android.AssertIntEquals(t, "expect 1 variant", 1, len(variants)) } func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) { result := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, android.FixtureWithRootAndroidBp(` platform_bootclasspath { name: "platform-bootclasspath", } `), ).RunTest(t) p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) android.AssertStringEquals(t, "output filepath", p.Name()+".pb", p.ClasspathFragmentBase.outputFilepath.Base()) android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath) } func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) { preparer := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, android.FixtureWithRootAndroidBp(` platform_bootclasspath { name: "platform-bootclasspath", } `), ) t.Run("AndroidMkEntries", func(t *testing.T) { result := preparer.RunTest(t) p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) android.AssertIntEquals(t, "AndroidMkEntries count", 2, len(entries)) }) t.Run("hiddenapi-flags-entry", func(t *testing.T) { result := preparer.RunTest(t) p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) got := entries[0].OutputFile android.AssertBoolEquals(t, "valid output path", true, got.Valid()) android.AssertSame(t, "output filepath", p.hiddenAPIFlagsCSV, got.Path()) }) t.Run("classpath-fragment-entry", func(t *testing.T) { result := preparer.RunTest(t) want := map[string][]string{ "LOCAL_MODULE": {"platform-bootclasspath"}, "LOCAL_MODULE_CLASS": {"ETC"}, "LOCAL_INSTALLED_MODULE_STEM": {"platform-bootclasspath.pb"}, // Output and Install paths are tested separately in TestPlatformBootclasspath_ClasspathFragmentPaths } p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) got := entries[1] for k, expectedValue := range want { if value, ok := got.EntryMap[k]; ok { android.AssertDeepEquals(t, k, expectedValue, value) } else { t.Errorf("No %s defined, saw %q", k, got.EntryMap) } } }) } func TestPlatformBootclasspath_Dist(t *testing.T) { result := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, Loading Loading
java/classpath_fragment.go +90 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ package java import ( "fmt" "strings" "android/soong/android" ) Loading Loading @@ -47,21 +50,102 @@ type classpathFragmentProperties struct { type classpathFragment interface { android.Module classpathFragmentBase() *classpathFragmentBase classpathFragmentBase() *ClasspathFragmentBase } // classpathFragmentBase is meant to be embedded in any module types that implement classpathFragment; // ClasspathFragmentBase is meant to be embedded in any module types that implement classpathFragment; // such modules are expected to call initClasspathFragment(). type classpathFragmentBase struct { type ClasspathFragmentBase struct { properties classpathFragmentProperties classpathType classpathType outputFilepath android.OutputPath installDirPath android.InstallPath } func (c *ClasspathFragmentBase) classpathFragmentBase() *ClasspathFragmentBase { return c } // Initializes classpathFragmentBase struct. Must be called by all modules that include classpathFragmentBase. // Initializes ClasspathFragmentBase struct. Must be called by all modules that include ClasspathFragmentBase. func initClasspathFragment(c classpathFragment) { base := c.classpathFragmentBase() c.AddProperties(&base.properties) } // Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto type classpathJar struct { path string classpath classpathType // TODO(satayev): propagate min/max sdk versions for the jars minSdkVersion int32 maxSdkVersion int32 } func (c *ClasspathFragmentBase) generateAndroidBuildActions(ctx android.ModuleContext) { outputFilename := ctx.ModuleName() + ".pb" c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths") var jars []classpathJar jars = appendClasspathJar(jars, BOOTCLASSPATH, defaultBootclasspath(ctx)...) jars = appendClasspathJar(jars, DEX2OATBOOTCLASSPATH, defaultBootImageConfig(ctx).getAnyAndroidVariant().dexLocationsDeps...) jars = appendClasspathJar(jars, SYSTEMSERVERCLASSPATH, systemServerClasspath(ctx)...) generatedJson := android.PathForModuleOut(ctx, outputFilename+".json") writeClasspathsJson(ctx, generatedJson, jars) rule := android.NewRuleBuilder(pctx, ctx) rule.Command(). BuiltTool("conv_classpaths_proto"). Flag("encode"). Flag("--format=json"). FlagWithInput("--input=", generatedJson). FlagWithOutput("--output=", c.outputFilepath) rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String()) } func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) { var content strings.Builder fmt.Fprintf(&content, "{\n") fmt.Fprintf(&content, "\"jars\": [\n") for idx, jar := range jars { fmt.Fprintf(&content, "{\n") fmt.Fprintf(&content, "\"relativePath\": \"%s\",\n", jar.path) fmt.Fprintf(&content, "\"classpath\": \"%s\"\n", jar.classpath) if idx < len(jars)-1 { fmt.Fprintf(&content, "},\n") } else { fmt.Fprintf(&content, "}\n") } } fmt.Fprintf(&content, "]\n") fmt.Fprintf(&content, "}\n") android.WriteFileRule(ctx, output, content.String()) } func appendClasspathJar(slice []classpathJar, classpathType classpathType, paths ...string) (result []classpathJar) { result = append(result, slice...) for _, path := range paths { result = append(result, classpathJar{ path: path, classpath: classpathType, }) } return } func (c *ClasspathFragmentBase) getAndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "ETC", OutputFile: android.OptionalPathForPath(c.outputFilepath), ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetString("LOCAL_MODULE_PATH", c.installDirPath.ToMakePath().String()) entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.outputFilepath.Base()) }, }, }} }
java/dexpreopt_config.go +1 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import ( // systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed // once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same // ctx.Config(). func systemServerClasspath(ctx android.MakeVarsContext) []string { func systemServerClasspath(ctx android.PathContext) []string { return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string { global := dexpreopt.GetGlobalConfig(ctx) var systemServerClasspathLocations []string Loading
java/platform_bootclasspath.go +14 −10 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathDepende type platformBootclasspathModule struct { android.ModuleBase ClasspathFragmentBase properties platformBootclasspathProperties Loading Loading @@ -105,22 +106,23 @@ type platformBootclasspathProperties struct { func platformBootclasspathFactory() android.Module { m := &platformBootclasspathModule{} m.AddProperties(&m.properties) // TODO(satayev): split systemserver and apex jars into separate configs. initClasspathFragment(m) android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) return m } var _ android.OutputFileProducer = (*platformBootclasspathModule)(nil) // A minimal AndroidMkEntries is needed in order to support the dists property. func (b *platformBootclasspathModule) AndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{ { func (b *platformBootclasspathModule) AndroidMkEntries() (entries []android.AndroidMkEntries) { entries = append(entries, android.AndroidMkEntries{ Class: "FAKE", // Need at least one output file in order for this to take effect. OutputFile: android.OptionalPathForPath(b.hiddenAPIFlagsCSV), Include: "$(BUILD_PHONY_PACKAGE)", }, } }) entries = append(entries, b.classpathFragmentBase().getAndroidMkEntries()...) return } // Make the hidden API files available from the platform-bootclasspath module. Loading Loading @@ -245,6 +247,8 @@ func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, mod } func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { b.classpathFragmentBase().generateAndroidBuildActions(ctx) ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) if tag == platformBootclasspathModuleDepTag { Loading
java/platform_bootclasspath_test.go +83 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,89 @@ func TestPlatformBootclasspath(t *testing.T) { }) } func TestPlatformBootclasspathVariant(t *testing.T) { result := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, android.FixtureWithRootAndroidBp(` platform_bootclasspath { name: "platform-bootclasspath", } `), ).RunTest(t) variants := result.ModuleVariantsForTests("platform-bootclasspath") android.AssertIntEquals(t, "expect 1 variant", 1, len(variants)) } func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) { result := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, android.FixtureWithRootAndroidBp(` platform_bootclasspath { name: "platform-bootclasspath", } `), ).RunTest(t) p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) android.AssertStringEquals(t, "output filepath", p.Name()+".pb", p.ClasspathFragmentBase.outputFilepath.Base()) android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath) } func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) { preparer := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, android.FixtureWithRootAndroidBp(` platform_bootclasspath { name: "platform-bootclasspath", } `), ) t.Run("AndroidMkEntries", func(t *testing.T) { result := preparer.RunTest(t) p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) android.AssertIntEquals(t, "AndroidMkEntries count", 2, len(entries)) }) t.Run("hiddenapi-flags-entry", func(t *testing.T) { result := preparer.RunTest(t) p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) got := entries[0].OutputFile android.AssertBoolEquals(t, "valid output path", true, got.Valid()) android.AssertSame(t, "output filepath", p.hiddenAPIFlagsCSV, got.Path()) }) t.Run("classpath-fragment-entry", func(t *testing.T) { result := preparer.RunTest(t) want := map[string][]string{ "LOCAL_MODULE": {"platform-bootclasspath"}, "LOCAL_MODULE_CLASS": {"ETC"}, "LOCAL_INSTALLED_MODULE_STEM": {"platform-bootclasspath.pb"}, // Output and Install paths are tested separately in TestPlatformBootclasspath_ClasspathFragmentPaths } p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) got := entries[1] for k, expectedValue := range want { if value, ok := got.EntryMap[k]; ok { android.AssertDeepEquals(t, k, expectedValue, value) } else { t.Errorf("No %s defined, saw %q", k, got.EntryMap) } } }) } func TestPlatformBootclasspath_Dist(t *testing.T) { result := android.GroupFixturePreparers( prepareForTestWithPlatformBootclasspath, Loading