From 74d73e2bfb016bd137a4fb7e125576b5f9a6cda4 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 2 Aug 2017 11:05:49 -0700 Subject: [PATCH] Rename java_prebuilt_library to java_import And make it work like bazel's java_import, using a "jars" property instead of "srcs", and allowing multiple jars to be listed. Test: soong tests Change-Id: Ida2ace6412bd77b4feb423646000a1401004e0ea --- android/prebuilt.go | 61 +++++++++++++--------- android/prebuilt_test.go | 10 ++-- cc/prebuilt.go | 34 +++++++------ java/androidmk.go | 15 +++++- java/app.go | 13 ++--- java/builder.go | 8 +-- java/java.go | 106 +++++++++++++++++++++++++-------------- java/java_test.go | 12 ++--- 8 files changed, 163 insertions(+), 96 deletions(-) diff --git a/android/prebuilt.go b/android/prebuilt.go index 507aa5fbe..f61a0dd85 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -14,7 +14,11 @@ package android -import "github.com/google/blueprint" +import ( + "fmt" + + "github.com/google/blueprint" +) // This file implements common functionality for handling modules that may exist as prebuilts, // source, or both. @@ -25,35 +29,43 @@ type prebuiltDependencyTag struct { var prebuiltDepTag prebuiltDependencyTag -type Prebuilt struct { - Properties struct { - Srcs []string `android:"arch_variant"` - // When prefer is set to true the prebuilt will be used instead of any source module with - // a matching name. - Prefer bool `android:"arch_variant"` +type PrebuiltProperties struct { + // When prefer is set to true the prebuilt will be used instead of any source module with + // a matching name. + Prefer bool `android:"arch_variant"` - SourceExists bool `blueprint:"mutated"` - UsePrebuilt bool `blueprint:"mutated"` - } - module Module + SourceExists bool `blueprint:"mutated"` + UsePrebuilt bool `blueprint:"mutated"` +} + +type Prebuilt struct { + properties PrebuiltProperties + module Module + srcs *[]string } func (p *Prebuilt) Name(name string) string { return "prebuilt_" + name } -func (p *Prebuilt) Path(ctx ModuleContext) Path { - if len(p.Properties.Srcs) == 0 { +func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path { + if len(*p.srcs) == 0 { ctx.PropertyErrorf("srcs", "missing prebuilt source file") return nil } - if len(p.Properties.Srcs) > 1 { + if len(*p.srcs) > 1 { ctx.PropertyErrorf("srcs", "multiple prebuilt source files") return nil } - return PathForModuleSrc(ctx, p.Properties.Srcs[0]) + return PathForModuleSrc(ctx, (*p.srcs)[0]) +} + +func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) { + p := module.Prebuilt() + module.AddProperties(&p.properties) + p.srcs = srcs } type PrebuiltInterface interface { @@ -78,7 +90,7 @@ func prebuiltMutator(ctx BottomUpMutatorContext) { name := m.base().BaseModuleName() if ctx.OtherModuleExists(name) { ctx.AddReverseDependency(ctx.Module(), prebuiltDepTag, name) - p.Properties.SourceExists = true + p.properties.SourceExists = true } else { ctx.Rename(name) } @@ -90,15 +102,18 @@ func prebuiltMutator(ctx BottomUpMutatorContext) { func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) { if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { p := m.Prebuilt() - if !p.Properties.SourceExists { - p.Properties.UsePrebuilt = p.usePrebuilt(ctx, nil) + if p.srcs == nil { + panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it")) + } + if !p.properties.SourceExists { + p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil) } } else if s, ok := ctx.Module().(Module); ok { ctx.VisitDirectDeps(func(m blueprint.Module) { if ctx.OtherModuleDependencyTag(m) == prebuiltDepTag { p := m.(PrebuiltInterface).Prebuilt() if p.usePrebuilt(ctx, s) { - p.Properties.UsePrebuilt = true + p.properties.UsePrebuilt = true s.SkipInstall() } } @@ -113,8 +128,8 @@ func PrebuiltReplaceMutator(ctx BottomUpMutatorContext) { if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { p := m.Prebuilt() name := m.base().BaseModuleName() - if p.Properties.UsePrebuilt { - if p.Properties.SourceExists { + if p.properties.UsePrebuilt { + if p.properties.SourceExists { ctx.ReplaceDependencies(name) } } else { @@ -126,12 +141,12 @@ func PrebuiltReplaceMutator(ctx BottomUpMutatorContext) { // 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 TopDownMutatorContext, source Module) bool { - if len(p.Properties.Srcs) == 0 { + if len(*p.srcs) == 0 { return false } // TODO: use p.Properties.Name and ctx.ModuleDir to override preference - if p.Properties.Prefer { + if p.properties.Prefer { return true } diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index 774a15c6b..9a1de9c75 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -151,7 +151,7 @@ func TestPrebuilts(t *testing.T) { } if p, ok := m.(*prebuiltModule); ok { dependsOnPrebuiltModule = true - if !p.Prebuilt().Properties.UsePrebuilt { + if !p.Prebuilt().properties.UsePrebuilt { t.Errorf("dependency on prebuilt module not marked used") } } @@ -180,12 +180,16 @@ func TestPrebuilts(t *testing.T) { type prebuiltModule struct { ModuleBase - prebuilt Prebuilt + prebuilt Prebuilt + properties struct { + Srcs []string + } } func newPrebuiltModule() Module { m := &prebuiltModule{} - m.AddProperties(&m.prebuilt.Properties) + m.AddProperties(&m.properties) + InitPrebuiltModule(m, &m.properties.Srcs) InitAndroidModule(m) return m } diff --git a/cc/prebuilt.go b/cc/prebuilt.go index 976c711dd..089ce2890 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -31,12 +31,19 @@ type prebuiltLinkerInterface interface { type prebuiltLinker struct { android.Prebuilt + properties struct { + Srcs []string `android:"arch_variant"` + } } func (p *prebuiltLinker) prebuilt() *android.Prebuilt { return &p.Prebuilt } +func (p *prebuiltLinker) PrebuiltSrcs() []string { + return p.properties.Srcs +} + type prebuiltLibraryLinker struct { *libraryDecorator prebuiltLinker @@ -44,20 +51,15 @@ type prebuiltLibraryLinker struct { var _ prebuiltLinkerInterface = (*prebuiltLibraryLinker)(nil) -func (p *prebuiltLibraryLinker) linkerProps() []interface{} { - props := p.libraryDecorator.linkerProps() - return append(props, &p.Prebuilt.Properties) -} - func (p *prebuiltLibraryLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { // TODO(ccross): verify shared library dependencies - if len(p.Prebuilt.Properties.Srcs) > 0 { + if len(p.properties.Srcs) > 0 { p.libraryDecorator.exportIncludes(ctx, "-I") p.libraryDecorator.reexportFlags(deps.ReexportedFlags) p.libraryDecorator.reexportDeps(deps.ReexportedFlagsDeps) // TODO(ccross): .toc optimization, stripping, packing - return p.Prebuilt.Path(ctx) + return p.Prebuilt.SingleSourcePath(ctx) } return nil @@ -78,6 +80,9 @@ func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libr } module.linker = prebuilt + module.AddProperties(&prebuilt.properties) + + android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) return module, library } @@ -96,6 +101,9 @@ func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libr } module.linker = prebuilt + module.AddProperties(&prebuilt.properties) + + android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) return module, library } @@ -106,15 +114,10 @@ type prebuiltBinaryLinker struct { var _ prebuiltLinkerInterface = (*prebuiltBinaryLinker)(nil) -func (p *prebuiltBinaryLinker) linkerProps() []interface{} { - props := p.binaryDecorator.linkerProps() - return append(props, &p.Prebuilt.Properties) -} - func (p *prebuiltBinaryLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { // TODO(ccross): verify shared library dependencies - if len(p.Prebuilt.Properties.Srcs) > 0 { + if len(p.properties.Srcs) > 0 { // TODO(ccross): .toc optimization, stripping, packing // Copy binaries to a name matching the final installed name @@ -125,7 +128,7 @@ func (p *prebuiltBinaryLinker) link(ctx ModuleContext, Rule: android.Cp, Description: "prebuilt", Output: outputFile, - Input: p.Prebuilt.Path(ctx), + Input: p.Prebuilt.SingleSourcePath(ctx), }) return outputFile @@ -148,5 +151,8 @@ func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecor } module.linker = prebuilt + module.AddProperties(&prebuilt.properties) + + android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) return module, binary } diff --git a/java/androidmk.go b/java/androidmk.go index 9ccf8561d..92af0ed2d 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -15,17 +15,28 @@ package java import ( + "fmt" + "io" + "android/soong/android" ) func (library *Library) AndroidMk() (ret android.AndroidMkData, err error) { ret.Class = "JAVA_LIBRARIES" ret.OutputFile = android.OptionalPathForPath(library.outputFile) + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error { + fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := .jar") + return nil + }) return } -func (prebuilt *Prebuilt) AndroidMk() (ret android.AndroidMkData, err error) { +func (prebuilt *Import) AndroidMk() (ret android.AndroidMkData, err error) { ret.Class = "JAVA_LIBRARIES" - ret.OutputFile = android.OptionalPathForPath(prebuilt.classpathFile) + ret.OutputFile = android.OptionalPathForPath(prebuilt.combinedClasspathFile) + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error { + fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := .jar") + return nil + }) return } diff --git a/java/app.go b/java/app.go index 8a221ef65..ceb7791fa 100644 --- a/java/app.go +++ b/java/app.go @@ -231,18 +231,19 @@ func (a *AndroidApp) aaptFlags(ctx android.ModuleContext) ([]string, android.Pat aaptFlags = append(aaptFlags, android.JoinWithPrefix(resourceDirs.Strings(), "-S ")) ctx.VisitDirectDeps(func(module blueprint.Module) { - var depFile android.OptionalPath + var depFiles android.Paths if sdkDep, ok := module.(sdkDependency); ok { - depFile = android.OptionalPathForPath(sdkDep.ClasspathFile()) + depFiles = sdkDep.ClasspathFiles() } else if javaDep, ok := module.(Dependency); ok { if ctx.OtherModuleName(module) == "framework-res" { - depFile = android.OptionalPathForPath(javaDep.(*AndroidApp).exportPackage) + depFiles = android.Paths{javaDep.(*AndroidApp).exportPackage} } } - if depFile.Valid() { - aaptFlags = append(aaptFlags, "-I "+depFile.String()) - aaptDeps = append(aaptDeps, depFile.Path()) + + for _, dep := range depFiles { + aaptFlags = append(aaptFlags, "-I "+dep.String()) } + aaptDeps = append(aaptDeps, depFiles...) }) sdkVersion := a.deviceProperties.Sdk_version diff --git a/java/builder.go b/java/builder.go index ed9d82c24..2e41a6047 100644 --- a/java/builder.go +++ b/java/builder.go @@ -237,11 +237,11 @@ func TransformJarJar(ctx android.ModuleContext, classesJar android.Path, rulesFi } func TransformPrebuiltJarToClasses(ctx android.ModuleContext, - prebuilt android.Path) (classJarSpec, resourceJarSpec jarSpec) { + subdir string, prebuilt android.Path) (classJarSpec, resourceJarSpec jarSpec) { - classDir := android.PathForModuleOut(ctx, "extracted/classes") - classFileList := android.PathForModuleOut(ctx, "extracted/classes.list") - resourceFileList := android.PathForModuleOut(ctx, "extracted/resources.list") + classDir := android.PathForModuleOut(ctx, subdir, "classes") + classFileList := android.PathForModuleOut(ctx, subdir, "classes.list") + resourceFileList := android.PathForModuleOut(ctx, subdir, "resources.list") ctx.ModuleBuild(pctx, android.ModuleBuildParams{ Rule: extractPrebuilt, diff --git a/java/java.go b/java/java.go index f7191bfbc..37d959bc6 100644 --- a/java/java.go +++ b/java/java.go @@ -20,6 +20,7 @@ package java import ( "fmt" + "strconv" "strings" "github.com/google/blueprint" @@ -37,7 +38,8 @@ func init() { android.RegisterModuleType("java_library_host", LibraryHostFactory) android.RegisterModuleType("java_binary", BinaryFactory) android.RegisterModuleType("java_binary_host", BinaryHostFactory) - android.RegisterModuleType("java_prebuilt_library", PrebuiltFactory) + android.RegisterModuleType("java_import", ImportFactory) + android.RegisterModuleType("java_import_host", ImportFactoryHost) android.RegisterModuleType("android_prebuilt_sdk", SdkPrebuiltFactory) android.RegisterModuleType("android_app", AndroidAppFactory) @@ -144,7 +146,7 @@ type Module struct { } type Dependency interface { - ClasspathFile() android.Path + ClasspathFiles() android.Paths ClassJarSpecs() []jarSpec ResourceJarSpecs() []jarSpec AidlIncludeDirs() android.Paths @@ -220,7 +222,7 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt } func (j *Module) collectDeps(ctx android.ModuleContext) (classpath android.Paths, - bootClasspath android.OptionalPath, classJarSpecs, resourceJarSpecs []jarSpec, aidlPreprocess android.OptionalPath, + bootClasspath android.Paths, classJarSpecs, resourceJarSpecs []jarSpec, aidlPreprocess android.OptionalPath, aidlIncludeDirs android.Paths, srcFileLists android.Paths) { ctx.VisitDirectDeps(func(module blueprint.Module) { @@ -239,11 +241,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) (classpath android.Paths switch tag { case bootClasspathTag: - bootClasspath = android.OptionalPathForPath(dep.ClasspathFile()) + bootClasspath = append(bootClasspath, dep.ClasspathFiles()...) case libTag: - classpath = append(classpath, dep.ClasspathFile()) + classpath = append(classpath, dep.ClasspathFiles()...) case staticLibTag: - classpath = append(classpath, dep.ClasspathFile()) + classpath = append(classpath, dep.ClasspathFiles()...) classJarSpecs = append(classJarSpecs, dep.ClassJarSpecs()...) resourceJarSpecs = append(resourceJarSpecs, dep.ResourceJarSpecs()...) case frameworkResTag: @@ -296,9 +298,9 @@ func (j *Module) compile(ctx android.ModuleContext) { var deps android.Paths - if bootClasspath.Valid() { - flags.bootClasspath = "-bootclasspath " + bootClasspath.String() - deps = append(deps, bootClasspath.Path()) + if len(bootClasspath) > 0 { + flags.bootClasspath = "-bootclasspath " + strings.Join(bootClasspath.Strings(), ":") + deps = append(deps, bootClasspath...) } if len(classpath) > 0 { @@ -350,7 +352,7 @@ func (j *Module) compile(ctx android.ModuleContext) { return } - classes, _ := TransformPrebuiltJarToClasses(ctx, outputFile) + classes, _ := TransformPrebuiltJarToClasses(ctx, "jarjar_extracted", outputFile) classJarSpecs = []jarSpec{classes} } @@ -399,8 +401,8 @@ func (j *Module) compile(ctx android.ModuleContext) { var _ Dependency = (*Library)(nil) -func (j *Module) ClasspathFile() android.Path { - return j.classpathFile +func (j *Module) ClasspathFiles() android.Paths { + return android.Paths{j.classpathFile} } func (j *Module) ClassJarSpecs() []jarSpec { @@ -519,63 +521,92 @@ func BinaryHostFactory() android.Module { // Java prebuilts // -type Prebuilt struct { +type ImportProperties struct { + Jars []string +} + +type Import struct { android.ModuleBase prebuilt android.Prebuilt - classpathFile android.Path + properties ImportProperties + + classpathFiles android.Paths + combinedClasspathFile android.Path classJarSpecs, resourceJarSpecs []jarSpec } -func (j *Prebuilt) Prebuilt() *android.Prebuilt { +func (j *Import) Prebuilt() *android.Prebuilt { return &j.prebuilt } -func (j *Prebuilt) Name() string { +func (j *Import) PrebuiltSrcs() []string { + return j.properties.Jars +} + +func (j *Import) Name() string { return j.prebuilt.Name(j.ModuleBase.Name()) } -func (j *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { +func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { } -func (j *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { - prebuilt := j.prebuilt.Path(ctx) +func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { + j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars) - classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, prebuilt) + for i, prebuilt := range j.classpathFiles { + subdir := "extracted" + strconv.Itoa(i) + classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, subdir, prebuilt) + j.classJarSpecs = append(j.classJarSpecs, classJarSpec) + j.resourceJarSpecs = append(j.resourceJarSpecs, resourceJarSpec) + } - j.classpathFile = prebuilt - j.classJarSpecs = []jarSpec{classJarSpec} - j.resourceJarSpecs = []jarSpec{resourceJarSpec} - ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.classpathFile) + j.combinedClasspathFile = TransformClassesToJar(ctx, j.classJarSpecs, android.OptionalPath{}) + + ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), + ctx.ModuleName()+".jar", j.combinedClasspathFile) } -var _ Dependency = (*Prebuilt)(nil) +var _ Dependency = (*Import)(nil) -func (j *Prebuilt) ClasspathFile() android.Path { - return j.classpathFile +func (j *Import) ClasspathFiles() android.Paths { + return j.classpathFiles } -func (j *Prebuilt) ClassJarSpecs() []jarSpec { +func (j *Import) ClassJarSpecs() []jarSpec { return j.classJarSpecs } -func (j *Prebuilt) ResourceJarSpecs() []jarSpec { +func (j *Import) ResourceJarSpecs() []jarSpec { return j.resourceJarSpecs } -func (j *Prebuilt) AidlIncludeDirs() android.Paths { +func (j *Import) AidlIncludeDirs() android.Paths { return nil } -func PrebuiltFactory() android.Module { - module := &Prebuilt{} +var _ android.PrebuiltInterface = (*Import)(nil) - module.AddProperties(&module.prebuilt.Properties) +func ImportFactory() android.Module { + module := &Import{} + module.AddProperties(&module.properties) + + android.InitPrebuiltModule(module, &module.properties.Jars) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) return module } +func ImportFactoryHost() android.Module { + module := &Import{} + + module.AddProperties(&module.properties) + + android.InitPrebuiltModule(module, &module.properties.Jars) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) + return module +} + // // SDK java prebuilts (.jar containing resources plus framework.aidl) // @@ -592,7 +623,7 @@ type sdkPrebuiltProperties struct { } type sdkPrebuilt struct { - Prebuilt + Import sdkProperties sdkPrebuiltProperties @@ -600,7 +631,7 @@ type sdkPrebuilt struct { } func (j *sdkPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { - j.Prebuilt.GenerateAndroidBuildActions(ctx) + j.Import.GenerateAndroidBuildActions(ctx) j.aidlPreprocessed = android.OptionalPathForModuleSrc(ctx, j.sdkProperties.Aidl_preprocessed) } @@ -612,10 +643,9 @@ func (j *sdkPrebuilt) AidlPreprocessed() android.OptionalPath { func SdkPrebuiltFactory() android.Module { module := &sdkPrebuilt{} - module.AddProperties( - &module.prebuilt.Properties, - &module.sdkProperties) + module.AddProperties(&module.sdkProperties) + android.InitPrebuiltModule(module, &module.properties.Jars) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) return module } diff --git a/java/java_test.go b/java/java_test.go index de3be494a..eb116c994 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -55,7 +55,7 @@ func testJava(t *testing.T, bp string) *android.TestContext { ctx := android.NewTestContext() ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory)) ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory)) - ctx.RegisterModuleType("java_prebuilt_library", android.ModuleFactoryAdaptor(PrebuiltFactory)) + ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory)) ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory)) ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators) ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators) @@ -209,14 +209,14 @@ func TestPrebuilts(t *testing.T) { static_libs: ["baz"], } - java_prebuilt_library { + java_import { name: "bar", - srcs: ["a.jar"], + jars: ["a.jar"], } - java_prebuilt_library { + java_import { name: "baz", - srcs: ["b.jar"], + jars: ["b.jar"], } `) @@ -228,7 +228,7 @@ func TestPrebuilts(t *testing.T) { t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar) } - baz := filepath.Join(buildDir, ".intermediates", "baz", "extracted", "classes.list") + baz := filepath.Join(buildDir, ".intermediates", "baz", "extracted0", "classes.list") if !strings.Contains(jar.Args["jarArgs"], baz) { t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz) }