diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/androidmk.go | 4 | ||||
| -rw-r--r-- | java/app.go | 7 | ||||
| -rw-r--r-- | java/builder.go | 2 | ||||
| -rw-r--r-- | java/java.go | 310 | ||||
| -rw-r--r-- | java/java_test.go | 285 |
5 files changed, 469 insertions, 139 deletions
diff --git a/java/androidmk.go b/java/androidmk.go index 9ffd35f5f..086ba7a1f 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -20,14 +20,14 @@ import ( "android/soong/android" ) -func (*JavaLibrary) AndroidMk() (ret android.AndroidMkData, err error) { +func (*Library) AndroidMk() (ret android.AndroidMkData, err error) { ret.Class = "JAVA_LIBRARIES" // TODO err = fmt.Errorf("Not yet implemented") return } -func (*JavaPrebuilt) AndroidMk() (ret android.AndroidMkData, err error) { +func (*Prebuilt) AndroidMk() (ret android.AndroidMkData, err error) { ret.Class = "JAVA_LIBRARIES" // TODO err = fmt.Errorf("Not yet implemented") diff --git a/java/app.go b/java/app.go index 2f2b899d1..8a221ef65 100644 --- a/java/app.go +++ b/java/app.go @@ -68,17 +68,14 @@ type AndroidApp struct { func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { a.Module.deps(ctx) - var deps []string if !a.properties.No_standard_libraries { switch a.deviceProperties.Sdk_version { // TODO: Res_sdk_version? case "current", "system_current", "": - deps = append(deps, "framework-res") + ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res") default: // We'll already have a dependency on an sdk prebuilt android.jar } } - - ctx.AddDependency(ctx.Module(), nil, deps...) } func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -237,7 +234,7 @@ func (a *AndroidApp) aaptFlags(ctx android.ModuleContext) ([]string, android.Pat var depFile android.OptionalPath if sdkDep, ok := module.(sdkDependency); ok { depFile = android.OptionalPathForPath(sdkDep.ClasspathFile()) - } else if javaDep, ok := module.(JavaDependency); ok { + } else if javaDep, ok := module.(Dependency); ok { if ctx.OtherModuleName(module) == "framework-res" { depFile = android.OptionalPathForPath(javaDep.(*AndroidApp).exportPackage) } diff --git a/java/builder.go b/java/builder.go index 041c30398..ed9d82c24 100644 --- a/java/builder.go +++ b/java/builder.go @@ -40,7 +40,7 @@ var ( javac = pctx.AndroidGomaStaticRule("javac", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + - `${config.JavacWrapper}$javacCmd ` + + `${JavacWrapper}$javacCmd ` + `-encoding UTF-8 $javacFlags $bootClasspath $classpath ` + `-extdirs "" -d $outDir @$out.rsp || ( rm -rf "$outDir"; exit 41 ) && ` + `find $outDir -name "*.class" > $out`, diff --git a/java/java.go b/java/java.go index 3cc552f0a..1ef1c2661 100644 --- a/java/java.go +++ b/java/java.go @@ -30,13 +30,15 @@ import ( ) func init() { - android.RegisterModuleType("java_library", JavaLibraryFactory) - android.RegisterModuleType("java_library_static", JavaLibraryFactory) - android.RegisterModuleType("java_library_host", JavaLibraryHostFactory) - android.RegisterModuleType("java_binary", JavaBinaryFactory) - android.RegisterModuleType("java_binary_host", JavaBinaryHostFactory) - android.RegisterModuleType("prebuilt_java_library", JavaPrebuiltFactory) - android.RegisterModuleType("prebuilt_sdk", SdkPrebuiltFactory) + android.RegisterModuleType("java_defaults", defaultsFactory) + + android.RegisterModuleType("java_library", LibraryFactory) + android.RegisterModuleType("java_library_static", LibraryFactory) + 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("android_prebuilt_sdk", SdkPrebuiltFactory) android.RegisterModuleType("android_app", AndroidAppFactory) android.RegisterSingletonType("logtags", LogtagsSingleton) @@ -55,7 +57,7 @@ func init() { // DroidDoc // Findbugs -type compilerProperties struct { +type CompilerProperties struct { // list of source files used to compile the Java module. May be .java, .logtags, .proto, // or .aidl files. Srcs []string `android:"arch_variant"` @@ -65,10 +67,10 @@ type compilerProperties struct { Exclude_srcs []string `android:"arch_variant"` // list of directories containing Java resources - Java_resource_dirs []string `android:"arch_variant"` + Resource_dirs []string `android:"arch_variant"` - // list of directories that should be excluded from java_resource_dirs - Exclude_java_resource_dirs []string `android:"arch_variant"` + // list of directories that should be excluded from resource_dirs + Exclude_resource_dirs []string `android:"arch_variant"` // don't build against the default libraries (legacy-test, core-junit, // ext, and framework for device targets) @@ -78,10 +80,10 @@ type compilerProperties struct { Javacflags []string `android:"arch_variant"` // list of of java libraries that will be in the classpath - Java_libs []string `android:"arch_variant"` + Libs []string `android:"arch_variant"` // list of java libraries that will be compiled into the resulting jar - Java_static_libs []string `android:"arch_variant"` + Static_libs []string `android:"arch_variant"` // manifest file to be included in resulting jar Manifest *string @@ -90,7 +92,7 @@ type compilerProperties struct { Jarjar_rules *string } -type compilerDeviceProperties struct { +type CompilerDeviceProperties struct { // list of module-specific flags that will be used for dex compiles Dxflags []string `android:"arch_variant"` @@ -112,9 +114,10 @@ type compilerDeviceProperties struct { // Module contains the properties and members used by all java module types type Module struct { android.ModuleBase + android.DefaultableModuleBase - properties compilerProperties - deviceProperties compilerDeviceProperties + properties CompilerProperties + deviceProperties CompilerDeviceProperties // output file suitable for inserting into the classpath of another compile classpathFile android.Path @@ -140,52 +143,58 @@ type Module struct { installFile android.Path } -type JavaDependency interface { +type Dependency interface { ClasspathFile() android.Path ClassJarSpecs() []jarSpec ResourceJarSpecs() []jarSpec AidlIncludeDirs() android.Paths } -func (j *Module) BootClasspath(ctx android.BaseContext) string { - if ctx.Device() { - switch j.deviceProperties.Sdk_version { - case "": - return "core-libart" - case "current": - // TODO: !TARGET_BUILD_APPS - // TODO: export preprocessed framework.aidl from android_stubs_current - return "android_stubs_current" - case "system_current": - return "android_system_stubs_current" - default: - return "sdk_v" + j.deviceProperties.Sdk_version - } - } else { - if j.deviceProperties.Dex { - return "core-libart" - } else { - return "" - } - } +func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) { + android.InitAndroidArchModule(module, hod, android.MultilibCommon) + android.InitDefaultableModule(module) } -func (j *Module) deps(ctx android.BottomUpMutatorContext) { - var deps []string +type dependencyTag struct { + blueprint.BaseDependencyTag + name string +} + +var ( + staticLibTag = dependencyTag{name: "staticlib"} + libTag = dependencyTag{name: "javalib"} + bootClasspathTag = dependencyTag{name: "bootclasspath"} + frameworkResTag = dependencyTag{name: "framework-res"} + sdkDependencyTag = dependencyTag{name: "sdk"} +) +func (j *Module) deps(ctx android.BottomUpMutatorContext) { if !j.properties.No_standard_libraries { - bootClasspath := j.BootClasspath(ctx) - if bootClasspath != "" { - deps = append(deps, bootClasspath) + if ctx.Device() { + switch j.deviceProperties.Sdk_version { + case "": + ctx.AddDependency(ctx.Module(), bootClasspathTag, "core-libart") + case "current": + // TODO: !TARGET_BUILD_APPS + // TODO: export preprocessed framework.aidl from android_stubs_current + ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_stubs_current") + case "system_current": + ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_system_stubs_current") + default: + ctx.AddDependency(ctx.Module(), sdkDependencyTag, "sdk_v"+j.deviceProperties.Sdk_version) + } + } else { + if j.deviceProperties.Dex { + ctx.AddDependency(ctx.Module(), bootClasspathTag, "core-libart") + } } + if ctx.Device() && j.deviceProperties.Sdk_version == "" { - deps = append(deps, config.DefaultLibraries...) + ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...) } } - deps = append(deps, j.properties.Java_libs...) - deps = append(deps, j.properties.Java_static_libs...) - - ctx.AddDependency(ctx.Module(), nil, deps...) + ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...) + ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...) } func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath, @@ -203,7 +212,9 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I")) flags = append(flags, android.JoinWithPrefix(localAidlIncludes.Strings(), "-I")) flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String()) - flags = append(flags, "-I"+android.PathForModuleSrc(ctx, "src").String()) + if src := android.ExistentPathForSource(ctx, "", "src"); src.Valid() { + flags = append(flags, "-I"+src.String()) + } return flags } @@ -214,38 +225,48 @@ func (j *Module) collectDeps(ctx android.ModuleContext) (classpath android.Paths ctx.VisitDirectDeps(func(module blueprint.Module) { otherName := ctx.OtherModuleName(module) - if javaDep, ok := module.(JavaDependency); ok { - if otherName == j.BootClasspath(ctx) { - bootClasspath = android.OptionalPathForPath(javaDep.ClasspathFile()) - } else if inList(otherName, config.DefaultLibraries) { - classpath = append(classpath, javaDep.ClasspathFile()) - } else if inList(otherName, j.properties.Java_libs) { - classpath = append(classpath, javaDep.ClasspathFile()) - } else if inList(otherName, j.properties.Java_static_libs) { - classpath = append(classpath, javaDep.ClasspathFile()) - classJarSpecs = append(classJarSpecs, javaDep.ClassJarSpecs()...) - resourceJarSpecs = append(resourceJarSpecs, javaDep.ResourceJarSpecs()...) - } else if otherName == "framework-res" { - if ctx.ModuleName() == "framework" { - // framework.jar has a one-off dependency on the R.java and Manifest.java files - // generated by framework-res.apk - srcFileLists = append(srcFileLists, module.(*AndroidApp).aaptJavaFileList) - } - } else { - panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName())) + tag := ctx.OtherModuleDependencyTag(module) + + dep, _ := module.(Dependency) + if dep == nil { + switch tag { + case android.DefaultsDepTag, android.SourceDepTag: + default: + ctx.ModuleErrorf("depends on non-java module %q", otherName) } - aidlIncludeDirs = append(aidlIncludeDirs, javaDep.AidlIncludeDirs()...) - if sdkDep, ok := module.(sdkDependency); ok { - if sdkDep.AidlPreprocessed().Valid() { - if aidlPreprocess.Valid() { - ctx.ModuleErrorf("multiple dependencies with preprocessed aidls:\n %q\n %q", - aidlPreprocess, sdkDep.AidlPreprocessed()) - } else { - aidlPreprocess = sdkDep.AidlPreprocessed() - } + return + } + + switch tag { + case bootClasspathTag: + bootClasspath = android.OptionalPathForPath(dep.ClasspathFile()) + case libTag: + classpath = append(classpath, dep.ClasspathFile()) + case staticLibTag: + classpath = append(classpath, dep.ClasspathFile()) + classJarSpecs = append(classJarSpecs, dep.ClassJarSpecs()...) + resourceJarSpecs = append(resourceJarSpecs, dep.ResourceJarSpecs()...) + case frameworkResTag: + if ctx.ModuleName() == "framework" { + // framework.jar has a one-off dependency on the R.java and Manifest.java files + // generated by framework-res.apk + srcFileLists = append(srcFileLists, module.(*AndroidApp).aaptJavaFileList) + } + case sdkDependencyTag: + sdkDep := module.(sdkDependency) + if sdkDep.AidlPreprocessed().Valid() { + if aidlPreprocess.Valid() { + ctx.ModuleErrorf("multiple dependencies with preprocessed aidls:\n %q\n %q", + aidlPreprocess, sdkDep.AidlPreprocessed()) + } else { + aidlPreprocess = sdkDep.AidlPreprocessed() } } + default: + panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName())) } + + aidlIncludeDirs = append(aidlIncludeDirs, dep.AidlIncludeDirs()...) }) return classpath, bootClasspath, classJarSpecs, resourceJarSpecs, aidlPreprocess, @@ -273,16 +294,16 @@ func (j *Module) compile(ctx android.ModuleContext) { flags.aidlFlags = "$aidlFlags" } - var javacDeps android.Paths + var deps android.Paths if bootClasspath.Valid() { flags.bootClasspath = "-bootclasspath " + bootClasspath.String() - javacDeps = append(javacDeps, bootClasspath.Path()) + deps = append(deps, bootClasspath.Path()) } if len(classpath) > 0 { flags.classpath = "-classpath " + strings.Join(classpath.Strings(), ":") - javacDeps = append(javacDeps, classpath...) + deps = append(deps, classpath...) } srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs) @@ -299,7 +320,7 @@ func (j *Module) compile(ctx android.ModuleContext) { if len(srcFiles) > 0 { // Compile java sources into .class files - classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, javacDeps) + classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, deps) if ctx.Failed() { return } @@ -307,7 +328,7 @@ func (j *Module) compile(ctx android.ModuleContext) { classJarSpecs = append([]jarSpec{classes}, classJarSpecs...) } - resourceJarSpecs = append(ResourceDirsToJarSpecs(ctx, j.properties.Java_resource_dirs, j.properties.Exclude_java_resource_dirs), + resourceJarSpecs = append(ResourceDirsToJarSpecs(ctx, j.properties.Resource_dirs, j.properties.Exclude_resource_dirs), resourceJarSpecs...) manifest := android.OptionalPathForModuleSrc(ctx, j.properties.Manifest) @@ -376,7 +397,7 @@ func (j *Module) compile(ctx android.ModuleContext) { j.outputFile = outputFile } -var _ JavaDependency = (*JavaLibrary)(nil) +var _ Dependency = (*Library)(nil) func (j *Module) ClasspathFile() android.Path { return j.classpathFile @@ -404,22 +425,22 @@ func (j *Module) logtags() android.Paths { // Java libraries (.jar file) // -type JavaLibrary struct { +type Library struct { Module } -func (j *JavaLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { +func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.compile(ctx) j.installFile = ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.outputFile) } -func (j *JavaLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { +func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { j.deps(ctx) } -func JavaLibraryFactory() android.Module { - module := &JavaLibrary{} +func LibraryFactory() android.Module { + module := &Library{} module.deviceProperties.Dex = true @@ -427,16 +448,16 @@ func JavaLibraryFactory() android.Module { &module.Module.properties, &module.Module.deviceProperties) - android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) + InitJavaModule(module, android.HostAndDeviceSupported) return module } -func JavaLibraryHostFactory() android.Module { - module := &JavaLibrary{} +func LibraryHostFactory() android.Module { + module := &Library{} module.AddProperties(&module.Module.properties) - android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) + InitJavaModule(module, android.HostSupported) return module } @@ -444,19 +465,19 @@ func JavaLibraryHostFactory() android.Module { // Java Binaries (.jar file plus wrapper script) // -type javaBinaryProperties struct { +type binaryProperties struct { // installable script to execute the resulting jar Wrapper string } -type JavaBinary struct { - JavaLibrary +type Binary struct { + Library - binaryProperties javaBinaryProperties + binaryProperties binaryProperties } -func (j *JavaBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { - j.JavaLibrary.GenerateAndroidBuildActions(ctx) +func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + j.Library.GenerateAndroidBuildActions(ctx) // Depend on the installed jar (j.installFile) so that the wrapper doesn't get executed by // another build rule before the jar has been installed. @@ -464,12 +485,12 @@ func (j *JavaBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.installFile) } -func (j *JavaBinary) DepsMutator(ctx android.BottomUpMutatorContext) { +func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { j.deps(ctx) } -func JavaBinaryFactory() android.Module { - module := &JavaBinary{} +func BinaryFactory() android.Module { + module := &Binary{} module.deviceProperties.Dex = true @@ -478,19 +499,19 @@ func JavaBinaryFactory() android.Module { &module.Module.deviceProperties, &module.binaryProperties) - android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) + InitJavaModule(module, android.HostAndDeviceSupported) return module } -func JavaBinaryHostFactory() android.Module { - module := &JavaBinary{} +func BinaryHostFactory() android.Module { + module := &Binary{} module.AddProperties( &module.Module.properties, &module.Module.deviceProperties, &module.binaryProperties) - android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) + InitJavaModule(module, android.HostSupported) return module } @@ -498,28 +519,23 @@ func JavaBinaryHostFactory() android.Module { // Java prebuilts // -type javaPrebuiltProperties struct { - Srcs []string -} - -type JavaPrebuilt struct { +type Prebuilt struct { android.ModuleBase - - properties javaPrebuiltProperties + prebuilt android.Prebuilt classpathFile android.Path classJarSpecs, resourceJarSpecs []jarSpec } -func (j *JavaPrebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { +func (j *Prebuilt) Prebuilt() *android.Prebuilt { + return &j.prebuilt } -func (j *JavaPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { - if len(j.properties.Srcs) != 1 { - ctx.ModuleErrorf("expected exactly one jar in srcs") - return - } - prebuilt := android.PathForModuleSrc(ctx, j.properties.Srcs[0]) +func (j *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { +} + +func (j *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { + prebuilt := j.prebuilt.Path(ctx) classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, prebuilt) @@ -529,28 +545,28 @@ func (j *JavaPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.classpathFile) } -var _ JavaDependency = (*JavaPrebuilt)(nil) +var _ Dependency = (*Prebuilt)(nil) -func (j *JavaPrebuilt) ClasspathFile() android.Path { +func (j *Prebuilt) ClasspathFile() android.Path { return j.classpathFile } -func (j *JavaPrebuilt) ClassJarSpecs() []jarSpec { +func (j *Prebuilt) ClassJarSpecs() []jarSpec { return j.classJarSpecs } -func (j *JavaPrebuilt) ResourceJarSpecs() []jarSpec { +func (j *Prebuilt) ResourceJarSpecs() []jarSpec { return j.resourceJarSpecs } -func (j *JavaPrebuilt) AidlIncludeDirs() android.Paths { +func (j *Prebuilt) AidlIncludeDirs() android.Paths { return nil } -func JavaPrebuiltFactory() android.Module { - module := &JavaPrebuilt{} +func PrebuiltFactory() android.Module { + module := &Prebuilt{} - module.AddProperties(&module.properties) + module.AddProperties(&module.prebuilt.Properties) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) return module @@ -561,7 +577,7 @@ func JavaPrebuiltFactory() android.Module { // type sdkDependency interface { - JavaDependency + Dependency AidlPreprocessed() android.OptionalPath } @@ -572,7 +588,7 @@ type sdkPrebuiltProperties struct { } type sdkPrebuilt struct { - JavaPrebuilt + Prebuilt sdkProperties sdkPrebuiltProperties @@ -580,7 +596,7 @@ type sdkPrebuilt struct { } func (j *sdkPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { - j.JavaPrebuilt.GenerateAndroidBuildActions(ctx) + j.Prebuilt.GenerateAndroidBuildActions(ctx) j.aidlPreprocessed = android.OptionalPathForModuleSrc(ctx, j.sdkProperties.Aidl_preprocessed) } @@ -593,7 +609,7 @@ func SdkPrebuiltFactory() android.Module { module := &sdkPrebuilt{} module.AddProperties( - &module.properties, + &module.prebuilt.Properties, &module.sdkProperties) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) @@ -608,3 +624,35 @@ func inList(s string, l []string) bool { } return false } + +// +// Defaults +// +type Defaults struct { + android.ModuleBase + android.DefaultsModuleBase +} + +func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) { +} + +func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) { +} + +func defaultsFactory() android.Module { + return DefaultsFactory() +} + +func DefaultsFactory(props ...interface{}) android.Module { + module := &Defaults{} + + module.AddProperties(props...) + module.AddProperties( + &CompilerProperties{}, + &CompilerDeviceProperties{}, + ) + + android.InitDefaultsModule(module) + + return module +} diff --git a/java/java_test.go b/java/java_test.go new file mode 100644 index 000000000..344361058 --- /dev/null +++ b/java/java_test.go @@ -0,0 +1,285 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package java + +import ( + "android/soong/android" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + "testing" +) + +var buildDir string + +func setUp() { + var err error + buildDir, err = ioutil.TempDir("", "soong_java_test") + if err != nil { + panic(err) + } +} + +func tearDown() { + os.RemoveAll(buildDir) +} + +func TestMain(m *testing.M) { + run := func() int { + setUp() + defer tearDown() + + return m.Run() + } + + os.Exit(run()) +} + +func testJava(t *testing.T, bp string) *android.TestContext { + config := android.TestConfig(buildDir) + + 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_defaults", android.ModuleFactoryAdaptor(defaultsFactory)) + ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) + ctx.Register() + + extraModules := []string{"core-libart", "frameworks", "sdk_v14"} + + for _, extra := range extraModules { + bp += fmt.Sprintf(` + java_library { + name: "%s", + no_standard_libraries: true, + } + `, extra) + } + + ctx.MockFileSystem(map[string][]byte{ + "Android.bp": []byte(bp), + "a.java": nil, + "b.java": nil, + "c.java": nil, + "a.jar": nil, + "b.jar": nil, + }) + + _, errs := ctx.ParseBlueprintsFiles("Android.bp") + fail(t, errs) + _, errs = ctx.PrepareBuildActions(config) + fail(t, errs) + + return ctx +} + +func TestSimple(t *testing.T) { + ctx := testJava(t, ` + java_library { + name: "foo", + srcs: ["a.java"], + libs: ["bar"], + static_libs: ["baz"], + } + + java_library { + name: "bar", + srcs: ["b.java"], + } + + java_library { + name: "baz", + srcs: ["c.java"], + } + `) + + javac := ctx.ModuleForTests("foo", "").Rule("javac") + jar := ctx.ModuleForTests("foo", "").Rule("jar") + + if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { + t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) + } + + bar := filepath.Join(buildDir, ".intermediates", "bar", "classes-full-debug.jar") + if !strings.Contains(javac.Args["classpath"], bar) { + t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar) + } + + baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.list") + if !strings.Contains(jar.Args["jarArgs"], baz) { + t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz) + } +} + +func TestSdk(t *testing.T) { + ctx := testJava(t, ` + java_library { + name: "foo1", + srcs: ["a.java"], + } + + java_library { + name: "foo2", + srcs: ["a.java"], + sdk_version: "", + } + + java_library { + name: "foo3", + srcs: ["a.java"], + sdk_version: "14", + } + + java_library { + name: "foo4", + srcs: ["a.java"], + sdk_version: "current", + } + + java_library { + name: "foo5", + srcs: ["a.java"], + sdk_version: "system_current", + } + + java_library { + name: "foo6", + srcs: ["a.java"], + sdk_version: "test_current", + } + `) + + type depType int + const ( + staticLib = iota + classpathLib + bootclasspathLib + ) + + check := func(module, dep string, depType depType) { + if dep != "" { + dep = filepath.Join(buildDir, ".intermediates", dep, "classes-full-debug.jar") + } + + javac := ctx.ModuleForTests(module, "").Rule("javac") + + if depType == bootclasspathLib { + got := strings.TrimPrefix(javac.Args["bootClasspath"], "-bootclasspath ") + if got != dep { + t.Errorf("module %q bootclasspath %q != %q", module, got, dep) + } + } else if depType == classpathLib { + got := strings.TrimPrefix(javac.Args["classpath"], "-classpath ") + if got != dep { + t.Errorf("module %q classpath %q != %q", module, got, dep) + } + } + + if len(javac.Implicits) != 1 || javac.Implicits[0].String() != dep { + t.Errorf("module %q implicits != [%q]", dep) + } + } + + check("foo1", "core-libart", bootclasspathLib) +} + +func TestPrebuilts(t *testing.T) { + ctx := testJava(t, ` + java_library { + name: "foo", + srcs: ["a.java"], + libs: ["bar"], + static_libs: ["baz"], + } + + java_prebuilt_library { + name: "bar", + srcs: ["a.jar"], + } + + java_prebuilt_library { + name: "baz", + srcs: ["b.jar"], + } + `) + + javac := ctx.ModuleForTests("foo", "").Rule("javac") + jar := ctx.ModuleForTests("foo", "").Rule("jar") + + bar := "a.jar" + if !strings.Contains(javac.Args["classpath"], bar) { + t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar) + } + + baz := filepath.Join(buildDir, ".intermediates", "baz", "extracted", "classes.list") + if !strings.Contains(jar.Args["jarArgs"], baz) { + t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz) + } +} + +func TestDefaults(t *testing.T) { + ctx := testJava(t, ` + java_defaults { + name: "defaults", + srcs: ["a.java"], + libs: ["bar"], + static_libs: ["baz"], + } + + java_library { + name: "foo", + defaults: ["defaults"], + } + + java_library { + name: "bar", + srcs: ["b.java"], + } + + java_library { + name: "baz", + srcs: ["c.java"], + } + `) + + javac := ctx.ModuleForTests("foo", "").Rule("javac") + jar := ctx.ModuleForTests("foo", "").Rule("jar") + + if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { + t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) + } + + bar := filepath.Join(buildDir, ".intermediates", "bar", "classes-full-debug.jar") + if !strings.Contains(javac.Args["classpath"], bar) { + t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar) + } + + baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.list") + if !strings.Contains(jar.Args["jarArgs"], baz) { + t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz) + } +} + +func fail(t *testing.T, errs []error) { + if len(errs) > 0 { + for _, err := range errs { + t.Error(err) + } + t.FailNow() + } +} |