summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/aar.go12
-rw-r--r--java/androidmk.go8
-rw-r--r--java/app.go16
-rw-r--r--java/app_test.go159
-rw-r--r--java/builder.go23
-rw-r--r--java/dexpreopt.go7
-rw-r--r--java/dexpreopt_bootjars.go61
-rw-r--r--java/dexpreopt_config.go48
-rw-r--r--java/droiddoc.go20
-rw-r--r--java/java.go48
-rw-r--r--java/java_test.go15
-rw-r--r--java/robolectric.go84
-rw-r--r--java/robolectric_test.go88
-rw-r--r--java/sdk.go31
-rw-r--r--java/sdk_library.go28
-rw-r--r--java/sdk_test.go16
-rw-r--r--java/system_modules.go35
-rw-r--r--java/testing.go12
18 files changed, 563 insertions, 148 deletions
diff --git a/java/aar.go b/java/aar.go
index 1e8e6d8c4..47f6e5f6a 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -188,8 +188,7 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, mani
return linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
}
-func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkContext sdkContext) {
- sdkDep := decodeSdkDep(ctx, sdkContext)
+func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
if sdkDep.frameworkResModule != "" {
ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
}
@@ -401,8 +400,9 @@ var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
a.Module.deps(ctx)
- if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
- a.aapt.deps(ctx, sdkContext(a))
+ sdkDep := decodeSdkDep(ctx, sdkContext(a))
+ if sdkDep.hasFrameworkLibs() {
+ a.aapt.deps(ctx, sdkDep)
}
}
@@ -513,6 +513,10 @@ func (a *AARImport) targetSdkVersion() string {
return a.sdkVersion()
}
+func (a *AARImport) noFrameworkLibs() bool {
+ return false
+}
+
var _ AndroidLibraryDependency = (*AARImport)(nil)
func (a *AARImport) ExportPackage() android.Path {
diff --git a/java/androidmk.go b/java/androidmk.go
index 5491b3eba..39c2d1342 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -97,14 +97,6 @@ func (library *Library) AndroidMk() android.AndroidMkData {
if library.proguardDictionary != nil {
fmt.Fprintln(w, "LOCAL_SOONG_PROGUARD_DICT :=", library.proguardDictionary.String())
}
-
- // Temporary hack: export sources used to compile framework.jar to Make
- // to be used for droiddoc
- // TODO(ccross): remove this once droiddoc is in soong
- if (library.Name() == "framework") || (library.Name() == "framework-annotation-proc") {
- fmt.Fprintln(w, "SOONG_FRAMEWORK_SRCS :=", strings.Join(library.compiledJavaSrcs.Strings(), " "))
- fmt.Fprintln(w, "SOONG_FRAMEWORK_SRCJARS :=", strings.Join(library.compiledSrcJars.Strings(), " "))
- }
},
},
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
diff --git a/java/app.go b/java/app.go
index 78e05012c..cab97de45 100644
--- a/java/app.go
+++ b/java/app.go
@@ -159,8 +159,9 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
}
- if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
- a.aapt.deps(ctx, sdkContext(a))
+ sdkDep := decodeSdkDep(ctx, sdkContext(a))
+ if sdkDep.hasFrameworkLibs() {
+ a.aapt.deps(ctx, sdkDep)
}
embedJni := a.shouldEmbedJnis(ctx)
@@ -180,7 +181,7 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
}
}
- a.usesLibrary.deps(ctx, Bool(a.properties.No_framework_libs))
+ a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
}
func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
@@ -783,7 +784,7 @@ func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
- a.usesLibrary.deps(ctx, false)
+ a.usesLibrary.deps(ctx, true)
}
func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
@@ -937,11 +938,14 @@ type usesLibrary struct {
usesLibraryProperties UsesLibraryProperties
}
-func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, noFrameworkLibs bool) {
+func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
if !ctx.Config().UnbundledBuild() {
ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...)
- if !noFrameworkLibs {
+ // Only add these extra dependencies if the module depends on framework libs. This avoids
+ // creating a cyclic dependency:
+ // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
+ if hasFrameworkLibs {
// dexpreopt/dexpreopt.go needs the paths to the dex jars of these libraries in case construct_context.sh needs
// to pass them to dex2oat. Add them as a dependency so we can determine the path to the dex jar of each
// library to dexpreopt.
diff --git a/java/app_test.go b/java/app_test.go
index bb39c165c..27802cd21 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -546,7 +546,7 @@ func TestAppSdkVersion(t *testing.T) {
}
}
-func TestJNIABI(t *testing.T) {
+func TestJNIABI_no_framework_libs_true(t *testing.T) {
ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -619,7 +619,80 @@ func TestJNIABI(t *testing.T) {
}
}
-func TestJNIPackaging(t *testing.T) {
+func TestJNIABI(t *testing.T) {
+ ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
+ cc_library {
+ name: "libjni",
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ android_test {
+ name: "test",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni"],
+ }
+
+ android_test {
+ name: "test_first",
+ sdk_version: "core_platform",
+ compile_multilib: "first",
+ jni_libs: ["libjni"],
+ }
+
+ android_test {
+ name: "test_both",
+ sdk_version: "core_platform",
+ compile_multilib: "both",
+ jni_libs: ["libjni"],
+ }
+
+ android_test {
+ name: "test_32",
+ sdk_version: "core_platform",
+ compile_multilib: "32",
+ jni_libs: ["libjni"],
+ }
+
+ android_test {
+ name: "test_64",
+ sdk_version: "core_platform",
+ compile_multilib: "64",
+ jni_libs: ["libjni"],
+ }
+ `)
+
+ testCases := []struct {
+ name string
+ abis []string
+ }{
+ {"test", []string{"arm64-v8a"}},
+ {"test_first", []string{"arm64-v8a"}},
+ {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
+ {"test_32", []string{"armeabi-v7a"}},
+ {"test_64", []string{"arm64-v8a"}},
+ }
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ app := ctx.ModuleForTests(test.name, "android_common")
+ jniLibZip := app.Output("jnilibs.zip")
+ var abis []string
+ args := strings.Fields(jniLibZip.Args["jarArgs"])
+ for i := 0; i < len(args); i++ {
+ if args[i] == "-P" {
+ abis = append(abis, filepath.Base(args[i+1]))
+ i++
+ }
+ }
+ if !reflect.DeepEqual(abis, test.abis) {
+ t.Errorf("want abis %v, got %v", test.abis, abis)
+ }
+ })
+ }
+}
+
+func TestJNIPackaging_no_framework_libs_true(t *testing.T) {
ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -700,7 +773,89 @@ func TestJNIPackaging(t *testing.T) {
}
})
}
+}
+
+func TestJNIPackaging(t *testing.T) {
+ ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
+ cc_library {
+ name: "libjni",
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ android_app {
+ name: "app",
+ jni_libs: ["libjni"],
+ }
+
+ android_app {
+ name: "app_noembed",
+ jni_libs: ["libjni"],
+ use_embedded_native_libs: false,
+ }
+
+ android_app {
+ name: "app_embed",
+ jni_libs: ["libjni"],
+ use_embedded_native_libs: true,
+ }
+
+ android_test {
+ name: "test",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni"],
+ }
+
+ android_test {
+ name: "test_noembed",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni"],
+ use_embedded_native_libs: false,
+ }
+
+ android_test_helper_app {
+ name: "test_helper",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni"],
+ }
+
+ android_test_helper_app {
+ name: "test_helper_noembed",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni"],
+ use_embedded_native_libs: false,
+ }
+ `)
+
+ testCases := []struct {
+ name string
+ packaged bool
+ compressed bool
+ }{
+ {"app", false, false},
+ {"app_noembed", false, false},
+ {"app_embed", true, false},
+ {"test", true, false},
+ {"test_noembed", true, true},
+ {"test_helper", true, false},
+ {"test_helper_noembed", true, true},
+ }
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ app := ctx.ModuleForTests(test.name, "android_common")
+ jniLibZip := app.MaybeOutput("jnilibs.zip")
+ if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
+ t.Errorf("expected jni packaged %v, got %v", w, g)
+ }
+ if jniLibZip.Rule != nil {
+ if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
+ t.Errorf("expected jni compressed %v, got %v", w, g)
+ }
+ }
+ })
+ }
}
func TestCertificates(t *testing.T) {
diff --git a/java/builder.go b/java/builder.go
index e1a912b2f..a48e8b1a2 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -148,15 +148,16 @@ func init() {
}
type javaBuilderFlags struct {
- javacFlags string
- bootClasspath classpath
- classpath classpath
- processorPath classpath
- processor string
- systemModules classpath
- aidlFlags string
- aidlDeps android.Paths
- javaVersion string
+ javacFlags string
+ bootClasspath classpath
+ classpath classpath
+ processorPath classpath
+ processor string
+ systemModules classpath
+ systemModulesDeps android.Paths
+ aidlFlags string
+ aidlDeps android.Paths
+ javaVersion string
errorProneExtraJavacFlags string
errorProneProcessorPath classpath
@@ -248,7 +249,7 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
var bootClasspath string
if flags.javaVersion == "1.9" {
- deps = append(deps, flags.systemModules...)
+ deps = append(deps, flags.systemModulesDeps...)
bootClasspath = flags.systemModules.FormJavaSystemModulesPath("--system=", ctx.Device())
} else {
deps = append(deps, flags.bootClasspath...)
@@ -430,7 +431,7 @@ func (x *classpath) FormJavaSystemModulesPath(optName string, forceEmpty bool) s
if len(*x) > 1 {
panic("more than one system module")
} else if len(*x) == 1 {
- return optName + strings.TrimSuffix((*x)[0].String(), "lib/modules")
+ return optName + (*x)[0].String()
} else if forceEmpty {
return optName + "none"
} else {
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 23d2aa6e3..ed12fe6d2 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -132,8 +132,10 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
}
var images android.Paths
+ var imagesDeps []android.Paths
for _, arch := range archs {
images = append(images, bootImage.images[arch])
+ imagesDeps = append(imagesDeps, bootImage.imagesDeps[arch])
}
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
@@ -173,8 +175,9 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
UsesLibraries: d.usesLibs,
LibraryPaths: d.libraryPaths,
- Archs: archs,
- DexPreoptImages: images,
+ Archs: archs,
+ DexPreoptImages: images,
+ DexPreoptImagesDeps: imagesDeps,
// We use the dex paths and dex locations of the default boot image, as it
// contains the full dexpreopt boot classpath. Other images may just contain a subset of
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 2a1a901b7..eb735c162 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -58,9 +58,32 @@ type bootImageConfig struct {
symbolsDir android.OutputPath
targets []android.Target
images map[android.ArchType]android.OutputPath
+ imagesDeps map[android.ArchType]android.Paths
zip android.WritablePath
}
+func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) []android.OutputPath {
+ ret := make([]android.OutputPath, 0, len(image.modules)*len(exts))
+
+ // dex preopt on the bootclasspath produces multiple files. The first dex file
+ // is converted into to 'name'.art (to match the legacy assumption that 'name'.art
+ // exists), and the rest are converted to 'name'-<jar>.art.
+ // In addition, each .art file has an associated .oat and .vdex file, and an
+ // unstripped .oat file
+ for i, m := range image.modules {
+ name := image.name
+ if i != 0 {
+ name += "-" + m
+ }
+
+ for _, ext := range exts {
+ ret = append(ret, dir.Join(ctx, name+ext))
+ }
+ }
+
+ return ret
+}
+
type bootImage struct {
bootImageConfig
@@ -302,49 +325,38 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
installDir := filepath.Join("/system/framework", arch.String())
vdexInstallDir := filepath.Join("/system/framework")
- var extraFiles android.WritablePaths
var vdexInstalls android.RuleBuilderInstalls
var unstrippedInstalls android.RuleBuilderInstalls
var zipFiles android.WritablePaths
- // dex preopt on the bootclasspath produces multiple files. The first dex file
- // is converted into to 'name'.art (to match the legacy assumption that 'name'.art
- // exists), and the rest are converted to 'name'-<jar>.art.
- // In addition, each .art file has an associated .oat and .vdex file, and an
- // unstripped .oat file
- for i, m := range image.modules {
- name := image.name
- if i != 0 {
- name += "-" + m
- }
-
- art := outputDir.Join(ctx, name+".art")
- oat := outputDir.Join(ctx, name+".oat")
- vdex := outputDir.Join(ctx, name+".vdex")
- unstrippedOat := symbolsDir.Join(ctx, name+".oat")
-
- extraFiles = append(extraFiles, art, oat, vdex, unstrippedOat)
+ for _, artOrOat := range image.moduleFiles(ctx, outputDir, ".art", ".oat") {
+ cmd.ImplicitOutput(artOrOat)
+ zipFiles = append(zipFiles, artOrOat)
- zipFiles = append(zipFiles, art, oat, vdex)
+ // Install the .oat and .art files
+ rule.Install(artOrOat, filepath.Join(installDir, artOrOat.Base()))
+ }
- // Install the .oat and .art files.
- rule.Install(art, filepath.Join(installDir, art.Base()))
- rule.Install(oat, filepath.Join(installDir, oat.Base()))
+ for _, vdex := range image.moduleFiles(ctx, outputDir, ".vdex") {
+ cmd.ImplicitOutput(vdex)
+ zipFiles = append(zipFiles, vdex)
// The vdex files are identical between architectures, install them to a shared location. The Make rules will
// only use the install rules for one architecture, and will create symlinks into the architecture-specific
// directories.
vdexInstalls = append(vdexInstalls,
android.RuleBuilderInstall{vdex, filepath.Join(vdexInstallDir, vdex.Base())})
+ }
+
+ for _, unstrippedOat := range image.moduleFiles(ctx, symbolsDir, ".oat") {
+ cmd.ImplicitOutput(unstrippedOat)
// Install the unstripped oat files. The Make rules will put these in $(TARGET_OUT_UNSTRIPPED)
unstrippedInstalls = append(unstrippedInstalls,
android.RuleBuilderInstall{unstrippedOat, filepath.Join(installDir, unstrippedOat.Base())})
}
- cmd.ImplicitOutputs(extraFiles)
-
rule.Build(pctx, ctx, image.name+"JarsDexpreopt_"+arch.String(), "dexpreopt "+image.name+" jars "+arch.String())
// save output and installed files for makevars
@@ -496,6 +508,7 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
for _, arch := range arches {
ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.vdexInstalls[arch].String())
ctx.Strict("DEXPREOPT_IMAGE_"+current.name+"_"+arch.String(), current.images[arch].String())
+ ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+current.name+"_"+arch.String(), strings.Join(current.imagesDeps[arch].Strings(), " "))
ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.installs[arch].String())
ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.unstrippedInstalls[arch].String())
if current.zip != nil {
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index d903f456a..c396d3ea0 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -137,27 +137,35 @@ func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars")
symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_unstripped")
- images := make(map[android.ArchType]android.OutputPath)
zip := dir.Join(ctx, "boot.zip")
targets := dexpreoptTargets(ctx)
- for _, target := range targets {
- images[target.Arch.ArchType] = dir.Join(ctx,
- "system/framework", target.Arch.ArchType.String()).Join(ctx, "boot.art")
- }
-
- return bootImageConfig{
+ imageConfig := bootImageConfig{
name: "boot",
modules: nonUpdatableBootModules,
dexLocations: nonUpdatableBootLocations,
dexPaths: nonUpdatableBootDexPaths,
dir: dir,
symbolsDir: symbolsDir,
- images: images,
+ images: make(map[android.ArchType]android.OutputPath),
+ imagesDeps: make(map[android.ArchType]android.Paths),
targets: targets,
zip: zip,
}
+
+ for _, target := range targets {
+ imageDir := dir.Join(ctx, "system/framework", target.Arch.ArchType.String())
+ imageConfig.images[target.Arch.ArchType] = imageDir.Join(ctx, "boot.art")
+
+ imagesDeps := make([]android.Path, 0, len(imageConfig.modules)*3)
+ for _, dep := range imageConfig.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex") {
+ imagesDeps = append(imagesDeps, dep)
+ }
+ imageConfig.imagesDeps[target.Arch.ArchType] = imagesDeps
+ }
+
+ return imageConfig
}).(bootImageConfig)
}
@@ -196,16 +204,10 @@ func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars")
symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_unstripped")
- images := make(map[android.ArchType]android.OutputPath)
targets := dexpreoptTargets(ctx)
- for _, target := range targets {
- images[target.Arch.ArchType] = dir.Join(ctx,
- "system/framework", target.Arch.ArchType.String(), "apex.art")
- }
-
- return bootImageConfig{
+ imageConfig := bootImageConfig{
name: "apex",
modules: imageModules,
dexLocations: bootLocations,
@@ -213,8 +215,22 @@ func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
dir: dir,
symbolsDir: symbolsDir,
targets: targets,
- images: images,
+ images: make(map[android.ArchType]android.OutputPath),
+ imagesDeps: make(map[android.ArchType]android.Paths),
}
+
+ for _, target := range targets {
+ imageDir := dir.Join(ctx, "system/framework", target.Arch.ArchType.String())
+ imageConfig.images[target.Arch.ArchType] = imageDir.Join(ctx, "apex.art")
+
+ imagesDeps := make([]android.Path, 0, len(imageConfig.modules)*3)
+ for _, dep := range imageConfig.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex") {
+ imagesDeps = append(imagesDeps, dep)
+ }
+ imageConfig.imagesDeps[target.Arch.ArchType] = imagesDeps
+ }
+
+ return imageConfig
}).(bootImageConfig)
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 992c8b57c..be1b28153 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -171,10 +171,6 @@ type JavadocProperties struct {
// list of java libraries that will be in the classpath.
Libs []string `android:"arch_variant"`
- // don't build against the default libraries (bootclasspath, ext, and framework for device
- // targets)
- No_standard_libs *bool
-
// don't build against the framework libraries (ext, and framework for device targets)
No_framework_libs *bool
@@ -538,16 +534,20 @@ func (j *Javadoc) targetSdkVersion() string {
return j.sdkVersion()
}
+func (j *Javadoc) noFrameworkLibs() bool {
+ return Bool(j.properties.No_framework_libs)
+}
+
func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
- if !Bool(j.properties.No_standard_libs) {
- sdkDep := decodeSdkDep(ctx, sdkContext(j))
+ sdkDep := decodeSdkDep(ctx, sdkContext(j))
+ if sdkDep.hasStandardLibs() {
if sdkDep.useDefaultLibs {
ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
if ctx.Config().TargetOpenJDK9() {
ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
}
- if !Bool(j.properties.No_framework_libs) {
+ if sdkDep.hasFrameworkLibs() {
ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
}
} else if sdkDep.useModule {
@@ -692,10 +692,11 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
panic("Found two system module dependencies")
}
sm := module.(*SystemModules)
- if sm.outputFile == nil {
+ if sm.outputDir == nil && len(sm.outputDeps) == 0 {
panic("Missing directory for system module dependency")
}
- deps.systemModules = sm.outputFile
+ deps.systemModules = sm.outputDir
+ deps.systemModulesDeps = sm.outputDeps
}
})
// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
@@ -776,6 +777,7 @@ func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if deps.systemModules != nil {
systemModules = append(systemModules, deps.systemModules)
}
+ implicits = append(implicits, deps.systemModulesDeps...)
bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
}
diff --git a/java/java.go b/java/java.go
index a1addb38c..a2e9ab023 100644
--- a/java/java.go
+++ b/java/java.go
@@ -82,10 +82,6 @@ type CompilerProperties struct {
// list of files that should be excluded from java_resources and java_resource_dirs
Exclude_java_resources []string `android:"path,arch_variant"`
- // don't build against the default libraries (bootclasspath, ext, and framework for device
- // targets)
- No_standard_libs *bool
-
// don't build against the framework libraries (ext, and framework for device targets)
No_framework_libs *bool
@@ -440,6 +436,16 @@ type sdkDep struct {
jars android.Paths
aidl android.OptionalPath
+
+ noStandardLibs, noFrameworksLibs bool
+}
+
+func (s sdkDep) hasStandardLibs() bool {
+ return !s.noStandardLibs
+}
+
+func (s sdkDep) hasFrameworkLibs() bool {
+ return !s.noStandardLibs && !s.noFrameworksLibs
}
type jniLib struct {
@@ -476,14 +482,18 @@ func (j *Module) targetSdkVersion() string {
return j.sdkVersion()
}
+func (j *Module) noFrameworkLibs() bool {
+ return Bool(j.properties.No_framework_libs)
+}
+
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
- if !Bool(j.properties.No_standard_libs) {
- sdkDep := decodeSdkDep(ctx, sdkContext(j))
+ sdkDep := decodeSdkDep(ctx, sdkContext(j))
+ if sdkDep.hasStandardLibs() {
if sdkDep.useDefaultLibs {
ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
- if !Bool(j.properties.No_framework_libs) {
+ if sdkDep.hasFrameworkLibs() {
ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
}
} else if sdkDep.useModule {
@@ -495,8 +505,8 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
}
}
} else if j.deviceProperties.System_modules == nil {
- ctx.PropertyErrorf("no_standard_libs",
- "system_modules is required to be set when no_standard_libs is true, did you mean no_framework_libs?")
+ ctx.PropertyErrorf("sdk_version",
+ `system_modules is required to be set when sdk_version is "none", did you mean no_framework_libs?`)
} else if *j.deviceProperties.System_modules != "none" {
ctx.AddVariationDependencies(nil, systemModulesTag, *j.deviceProperties.System_modules)
}
@@ -618,6 +628,7 @@ type deps struct {
srcs android.Paths
srcJars android.Paths
systemModules android.Path
+ systemModulesDeps android.Paths
aidlPreprocess android.OptionalPath
kotlinStdlib android.Paths
kotlinAnnotations android.Paths
@@ -664,7 +675,7 @@ func getLinkType(m *Module, name string) (ret linkType, stubs bool) {
return javaSdk, true
case ver == "current":
return javaSdk, false
- case ver == "":
+ case ver == "" || ver == "none" || ver == "core_platform":
return javaPlatform, false
default:
if _, err := strconv.Atoi(ver); err != nil {
@@ -825,10 +836,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
panic("Found two system module dependencies")
}
sm := module.(*SystemModules)
- if sm.outputFile == nil {
+ if sm.outputDir == nil || len(sm.outputDeps) == 0 {
panic("Missing directory for system module dependency")
}
- deps.systemModules = sm.outputFile
+ deps.systemModules = sm.outputDir
+ deps.systemModulesDeps = sm.outputDeps
}
}
})
@@ -842,7 +854,8 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sd
var ret string
v := sdkContext.sdkVersion()
// For PDK builds, use the latest SDK version instead of "current"
- if ctx.Config().IsPdkBuild() && (v == "" || v == "current") {
+ if ctx.Config().IsPdkBuild() &&
+ (v == "" || v == "none" || v == "core_platform" || v == "current") {
sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
latestSdkVersion := 0
if len(sdkVersions) > 0 {
@@ -861,7 +874,11 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sd
ret = "1.7"
} else if ctx.Device() && sdk <= 29 || !ctx.Config().TargetOpenJDK9() {
ret = "1.8"
- } else if ctx.Device() && sdkContext.sdkVersion() != "" && sdk == android.FutureApiLevel {
+ } else if ctx.Device() &&
+ sdkContext.sdkVersion() != "" &&
+ sdkContext.sdkVersion() != "none" &&
+ sdkContext.sdkVersion() != "core_platform" &&
+ sdk == android.FutureApiLevel {
// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
ret = "1.8"
} else {
@@ -913,7 +930,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
flags.processor = strings.Join(deps.processorClasses, ",")
if len(flags.bootClasspath) == 0 && ctx.Host() && flags.javaVersion != "1.9" &&
- !Bool(j.properties.No_standard_libs) &&
+ decodeSdkDep(ctx, sdkContext(j)).hasStandardLibs() &&
inList(flags.javaVersion, []string{"1.6", "1.7", "1.8"}) {
// Give host-side tools a version of OpenJDK's standard libraries
// close to what they're targeting. As of Dec 2017, AOSP is only
@@ -953,6 +970,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
// systemModules
if deps.systemModules != nil {
flags.systemModules = append(flags.systemModules, deps.systemModules)
+ flags.systemModulesDeps = append(flags.systemModulesDeps, deps.systemModulesDeps...)
}
// aidl flags.
diff --git a/java/java_test.go b/java/java_test.go
index 4c8367bb9..22dec073f 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -842,6 +842,19 @@ func TestExcludeFileGroupInSrcs(t *testing.T) {
}
}
+func TestJavaLibrary(t *testing.T) {
+ config := testConfig(nil)
+ ctx := testContext(config, "", map[string][]byte{
+ "libcore/Android.bp": []byte(`
+ java_library {
+ name: "core",
+ sdk_version: "none",
+ system_modules: "none",
+ }`),
+ })
+ run(t, ctx, config)
+}
+
func TestJavaSdkLibrary(t *testing.T) {
ctx := testJava(t, `
droiddoc_template {
@@ -1000,7 +1013,7 @@ func TestPatchModule(t *testing.T) {
java_library {
name: "bar",
srcs: ["b.java"],
- no_standard_libs: true,
+ sdk_version: "none",
system_modules: "none",
patch_module: "java.base",
}
diff --git a/java/robolectric.go b/java/robolectric.go
index b87ee0d6d..1de56a5cd 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -17,6 +17,7 @@ package java
import (
"fmt"
"io"
+ "strconv"
"strings"
"android/soong/android"
@@ -40,6 +41,9 @@ type robolectricProperties struct {
Test_options struct {
// Timeout in seconds when running the tests.
Timeout *int64
+
+ // Number of shards to use when running the tests.
+ Shards *int64
}
}
@@ -48,7 +52,8 @@ type robolectricTest struct {
robolectricProperties robolectricProperties
- libs []string
+ libs []string
+ tests []string
}
func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -69,6 +74,39 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
r.libs = append(r.libs, ctx.OtherModuleName(dep))
}
+
+ // TODO: this could all be removed if tradefed was used as the test runner, it will find everything
+ // annotated as a test and run it.
+ for _, src := range r.compiledJavaSrcs {
+ s := src.Rel()
+ if !strings.HasSuffix(s, "Test.java") {
+ continue
+ } else if strings.HasSuffix(s, "/BaseRobolectricTest.java") {
+ continue
+ } else if strings.HasPrefix(s, "src/") {
+ s = strings.TrimPrefix(s, "src/")
+ }
+ r.tests = append(r.tests, s)
+ }
+}
+
+func shardTests(paths []string, shards int) [][]string {
+ if shards > len(paths) {
+ shards = len(paths)
+ }
+ if shards == 0 {
+ return nil
+ }
+ ret := make([][]string, 0, shards)
+ shardSize := (len(paths) + shards - 1) / shards
+ for len(paths) > shardSize {
+ ret = append(ret, paths[0:shardSize])
+ paths = paths[shardSize:]
+ }
+ if len(paths) > 0 {
+ ret = append(ret, paths)
+ }
+ return ret
}
func (r *robolectricTest) AndroidMk() android.AndroidMkData {
@@ -77,24 +115,50 @@ func (r *robolectricTest) AndroidMk() android.AndroidMkData {
data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
android.WriteAndroidMkData(w, data)
- fmt.Fprintln(w, "")
- fmt.Fprintln(w, "include $(CLEAR_VARS)")
- fmt.Fprintln(w, "LOCAL_MODULE := Run"+name)
- fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES :=", name)
- fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES += ", strings.Join(r.libs, " "))
- fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for))
- if t := r.robolectricProperties.Test_options.Timeout; t != nil {
- fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
+ if s := r.robolectricProperties.Test_options.Shards; s != nil && *s > 1 {
+ shards := shardTests(r.tests, int(*s))
+ for i, shard := range shards {
+ r.writeTestRunner(w, name, "Run"+name+strconv.Itoa(i), shard)
+ }
+
+ // TODO: add rules to dist the outputs of the individual tests, or combine them together?
+ fmt.Fprintln(w, "")
+ fmt.Fprintln(w, ".PHONY:", "Run"+name)
+ fmt.Fprintln(w, "Run"+name, ": \\")
+ for i := range shards {
+ fmt.Fprintln(w, " ", "Run"+name+strconv.Itoa(i), "\\")
+ }
+ fmt.Fprintln(w, "")
+ } else {
+ r.writeTestRunner(w, name, "Run"+name, r.tests)
}
- fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
}
return data
}
+func (r *robolectricTest) writeTestRunner(w io.Writer, module, name string, tests []string) {
+ fmt.Fprintln(w, "")
+ fmt.Fprintln(w, "include $(CLEAR_VARS)")
+ fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+ fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES :=", module)
+ fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES += ", strings.Join(r.libs, " "))
+ fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for))
+ fmt.Fprintln(w, "LOCAL_ROBOTEST_FILES :=", strings.Join(tests, " "))
+ if t := r.robolectricProperties.Test_options.Timeout; t != nil {
+ fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
+ }
+ fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
+
+}
+
// An android_robolectric_test module compiles tests against the Robolectric framework that can run on the local host
// instead of on a device. It also generates a rule with the name of the module prefixed with "Run" that can be
// used to run the tests. Running the tests with build rule will eventually be deprecated and replaced with atest.
+//
+// The test runner considers any file listed in srcs whose name ends with Test.java to be a test class, unless
+// it is named BaseRobolectricTest.java. The path to the each source file must exactly match the package
+// name, or match the package name when the prefix "src/" is removed.
func RobolectricTestFactory() android.Module {
module := &robolectricTest{}
diff --git a/java/robolectric_test.go b/java/robolectric_test.go
new file mode 100644
index 000000000..e89c6e74c
--- /dev/null
+++ b/java/robolectric_test.go
@@ -0,0 +1,88 @@
+// Copyright 2019 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 (
+ "reflect"
+ "testing"
+)
+
+func Test_shardTests(t *testing.T) {
+ type args struct {
+ paths []string
+ shards int
+ }
+ tests := []struct {
+ name string
+ args args
+ want [][]string
+ }{
+ {
+ name: "empty",
+ args: args{
+ paths: nil,
+ shards: 1,
+ },
+ want: [][]string(nil),
+ },
+ {
+ name: "too many shards",
+ args: args{
+ paths: []string{"a", "b"},
+ shards: 3,
+ },
+ want: [][]string{{"a"}, {"b"}},
+ },
+ {
+ name: "single shard",
+ args: args{
+ paths: []string{"a", "b"},
+ shards: 1,
+ },
+ want: [][]string{{"a", "b"}},
+ },
+ {
+ name: "shard per input",
+ args: args{
+ paths: []string{"a", "b", "c"},
+ shards: 3,
+ },
+ want: [][]string{{"a"}, {"b"}, {"c"}},
+ },
+ {
+ name: "balanced shards",
+ args: args{
+ paths: []string{"a", "b", "c", "d"},
+ shards: 2,
+ },
+ want: [][]string{{"a", "b"}, {"c", "d"}},
+ },
+ {
+ name: "unbalanced shards",
+ args: args{
+ paths: []string{"a", "b", "c"},
+ shards: 2,
+ },
+ want: [][]string{{"a", "b"}, {"c"}},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := shardTests(tt.args.paths, tt.args.shards); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("shardTests() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/java/sdk.go b/java/sdk.go
index 90b8fac28..6ffe399fb 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -38,17 +38,20 @@ var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
type sdkContext interface {
- // sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set.
+ // sdkVersion returns the sdk_version property of the current module, or an empty string if it is not set.
sdkVersion() string
// minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set.
minSdkVersion() string
// targetSdkVersion returns the target_sdk_version property of the current module, or sdkVersion() if it is not set.
targetSdkVersion() string
+
+ // Temporarily provide access to the no_frameworks_libs property (where present).
+ noFrameworkLibs() bool
}
func sdkVersionOrDefault(ctx android.BaseModuleContext, v string) string {
switch v {
- case "", "current", "system_current", "test_current", "core_current":
+ case "", "none", "current", "test_current", "system_current", "core_current", "core_platform":
return ctx.Config().DefaultAppTargetSdk()
default:
return v
@@ -59,7 +62,7 @@ func sdkVersionOrDefault(ctx android.BaseModuleContext, v string) string {
// it returns android.FutureApiLevel (10000).
func sdkVersionToNumber(ctx android.BaseModuleContext, v string) (int, error) {
switch v {
- case "", "current", "test_current", "system_current", "core_current":
+ case "", "none", "current", "test_current", "system_current", "core_current", "core_platform":
return ctx.Config().DefaultAppTargetSdkInt(), nil
default:
n := android.GetNumericSdkVersion(v)
@@ -138,6 +141,9 @@ func decodeSdkDep(ctx android.BaseModuleContext, sdkContext sdkContext) sdkDep {
useFiles: true,
jars: android.Paths{jarPath.Path(), lambdaStubsPath},
aidl: android.OptionalPathForPath(aidlPath.Path()),
+
+ // Pass value straight through for now to match previous behavior.
+ noFrameworksLibs: sdkContext.noFrameworkLibs(),
}
}
@@ -148,6 +154,9 @@ func decodeSdkDep(ctx android.BaseModuleContext, sdkContext sdkContext) sdkDep {
systemModules: m + "_system_modules",
frameworkResModule: r,
aidl: android.OptionalPathForPath(aidl),
+
+ // Pass value straight through for now to match previous behavior.
+ noFrameworksLibs: sdkContext.noFrameworkLibs(),
}
if m == "core.current.stubs" {
@@ -173,7 +182,8 @@ func decodeSdkDep(ctx android.BaseModuleContext, sdkContext sdkContext) sdkDep {
}
}
- if ctx.Config().UnbundledBuildUsePrebuiltSdks() && v != "" {
+ if ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
+ v != "" && v != "none" && v != "core_platform" {
return toPrebuilt(v)
}
@@ -182,6 +192,19 @@ func decodeSdkDep(ctx android.BaseModuleContext, sdkContext sdkContext) sdkDep {
return sdkDep{
useDefaultLibs: true,
frameworkResModule: "framework-res",
+
+ // Pass value straight through for now to match previous behavior.
+ noFrameworksLibs: sdkContext.noFrameworkLibs(),
+ }
+ case "none":
+ return sdkDep{
+ noStandardLibs: true,
+ }
+ case "core_platform":
+ return sdkDep{
+ useDefaultLibs: true,
+ frameworkResModule: "framework-res",
+ noFrameworksLibs: true,
}
case "current":
return toModule("android_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e38353340..b4a3f296c 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -159,7 +159,8 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
- if !Bool(module.properties.No_standard_libs) {
+ sdkDep := decodeSdkDep(ctx, sdkContext(&module.Library))
+ if sdkDep.hasStandardLibs() {
ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
@@ -384,7 +385,6 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.LoadHookContext, apiSc
Device_specific *bool
Product_specific *bool
Compile_dex *bool
- No_standard_libs *bool
System_modules *string
Java_version *string
Product_variables struct {
@@ -401,17 +401,22 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.LoadHookContext, apiSc
}
}{}
+ sdkVersion := module.sdkVersion(apiScope)
+ sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
+ if !sdkDep.hasStandardLibs() {
+ sdkVersion = "none"
+ }
+
props.Name = proptools.StringPtr(module.stubsName(apiScope))
// sources are generated from the droiddoc
props.Srcs = []string{":" + module.docsName(apiScope)}
- props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
+ props.Sdk_version = proptools.StringPtr(sdkVersion)
props.Libs = module.sdkLibraryProperties.Stub_only_libs
// Unbundled apps will use the prebult one from /prebuilts/sdk
if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
}
props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
- props.No_standard_libs = module.Library.Module.properties.No_standard_libs
props.System_modules = module.Library.Module.deviceProperties.System_modules
props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
@@ -441,13 +446,13 @@ func (module *SdkLibrary) createDocs(mctx android.LoadHookContext, apiScope apiS
Srcs_lib *string
Srcs_lib_whitelist_dirs []string
Srcs_lib_whitelist_pkgs []string
+ Sdk_version *string
Libs []string
Arg_files []string
Args *string
Api_tag_name *string
Api_filename *string
Removed_api_filename *string
- No_standard_libs *bool
Java_version *string
Merge_annotations_dirs []string
Merge_inclusion_annotations_dirs []string
@@ -462,9 +467,16 @@ func (module *SdkLibrary) createDocs(mctx android.LoadHookContext, apiScope apiS
}
}{}
+ sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
+ sdkVersion := ""
+ if !sdkDep.hasStandardLibs() {
+ sdkVersion = "none"
+ }
+
props.Name = proptools.StringPtr(module.docsName(apiScope))
props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
+ props.Sdk_version = proptools.StringPtr(sdkVersion)
props.Installable = proptools.BoolPtr(false)
// A droiddoc module has only one Libs property and doesn't distinguish between
// shared libs and static libs. So we need to add both of these libs to Libs property.
@@ -472,7 +484,6 @@ func (module *SdkLibrary) createDocs(mctx android.LoadHookContext, apiScope apiS
props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
- props.No_standard_libs = module.Library.Module.properties.No_standard_libs
props.Java_version = module.Library.Module.properties.Java_version
props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
@@ -593,7 +604,7 @@ func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) {
func (module *SdkLibrary) PrebuiltJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths {
var api, v string
- if sdkVersion == "" {
+ if sdkVersion == "" || sdkVersion == "none" {
api = "system"
v = "current"
} else if strings.Contains(sdkVersion, "_") {
@@ -701,7 +712,8 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.LoadHookContext) {
module.createStubsLibrary(mctx, apiScopePublic)
module.createDocs(mctx, apiScopePublic)
- if !Bool(module.properties.No_standard_libs) {
+ sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
+ if sdkDep.hasStandardLibs() {
// for system API stubs
module.createStubsLibrary(mctx, apiScopeSystem)
module.createDocs(mctx, apiScopeSystem)
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 23d7a98be..953c3722f 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -55,6 +55,14 @@ func TestClasspath(t *testing.T) {
aidl: "",
},
{
+ name: `sdk_version:"core_platform"`,
+ properties: `sdk_version:"core_platform"`,
+ bootclasspath: config.DefaultBootclasspathLibraries,
+ system: config.DefaultSystemModules,
+ classpath: []string{},
+ aidl: "",
+ },
+ {
name: "blank sdk version",
properties: `sdk_version: "",`,
bootclasspath: config.DefaultBootclasspathLibraries,
@@ -114,7 +122,7 @@ func TestClasspath(t *testing.T) {
{
name: "nostdlib",
- properties: `no_standard_libs: true, system_modules: "none"`,
+ properties: `sdk_version: "none", system_modules: "none"`,
system: "none",
bootclasspath: []string{`""`},
classpath: []string{},
@@ -122,7 +130,7 @@ func TestClasspath(t *testing.T) {
{
name: "nostdlib system_modules",
- properties: `no_standard_libs: true, system_modules: "core-platform-api-stubs-system-modules"`,
+ properties: `sdk_version: "none", system_modules: "core-platform-api-stubs-system-modules"`,
system: "core-platform-api-stubs-system-modules",
bootclasspath: []string{`""`},
classpath: []string{},
@@ -147,7 +155,7 @@ func TestClasspath(t *testing.T) {
{
name: "host supported nostdlib",
host: android.Host,
- properties: `host_supported: true, no_standard_libs: true, system_modules: "none"`,
+ properties: `host_supported: true, sdk_version: "none", system_modules: "none"`,
classpath: []string{},
},
{
@@ -246,7 +254,7 @@ func TestClasspath(t *testing.T) {
if testcase.system == "none" {
system = "--system=none"
} else if testcase.system != "" {
- system = "--system=" + filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system") + "/"
+ system = "--system=" + filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system")
}
checkClasspath := func(t *testing.T, ctx *android.TestContext) {
diff --git a/java/system_modules.go b/java/system_modules.go
index 2ec3dfbd5..f71f4523f 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -61,7 +61,7 @@ var (
"moduleName", "classpath", "outDir", "workDir")
)
-func TransformJarsToSystemModules(ctx android.ModuleContext, moduleName string, jars android.Paths) android.WritablePath {
+func TransformJarsToSystemModules(ctx android.ModuleContext, moduleName string, jars android.Paths) (android.Path, android.Paths) {
outDir := android.PathForModuleOut(ctx, "system")
workDir := android.PathForModuleOut(ctx, "modules")
outputFile := android.PathForModuleOut(ctx, "system/lib/modules")
@@ -84,7 +84,7 @@ func TransformJarsToSystemModules(ctx android.ModuleContext, moduleName string,
},
})
- return outputFile
+ return outDir, outputs.Paths()
}
func SystemModulesFactory() android.Module {
@@ -101,18 +101,13 @@ type SystemModules struct {
properties SystemModulesProperties
- outputFile android.Path
+ outputDir android.Path
+ outputDeps android.Paths
}
type SystemModulesProperties struct {
// List of java library modules that should be included in the system modules
Libs []string
-
- // List of prebuilt jars that should be included in the system modules
- Jars []string
-
- // Sdk version that should be included in the system modules
- Sdk_version *string
}
func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -123,9 +118,7 @@ func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleConte
jars = append(jars, dep.HeaderJars()...)
})
- jars = append(jars, android.PathsForModuleSrc(ctx, system.properties.Jars)...)
-
- system.outputFile = TransformJarsToSystemModules(ctx, "java.base", jars)
+ system.outputDir, system.outputDeps = TransformJarsToSystemModules(ctx, "java.base", jars)
}
func (system *SystemModules) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -135,16 +128,22 @@ func (system *SystemModules) DepsMutator(ctx android.BottomUpMutatorContext) {
func (system *SystemModules) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+ fmt.Fprintln(w)
+
makevar := "SOONG_SYSTEM_MODULES_" + name
+ fmt.Fprintln(w, makevar, ":=$=", system.outputDir.String())
fmt.Fprintln(w)
- fmt.Fprintln(w, makevar, ":=", system.outputFile.String())
- fmt.Fprintln(w, ".KATI_READONLY", ":=", makevar)
+
+ makevar = "SOONG_SYSTEM_MODULES_LIBS_" + name
+ fmt.Fprintln(w, makevar, ":=$=", strings.Join(system.properties.Libs, " "))
+ fmt.Fprintln(w)
+
+ makevar = "SOONG_SYSTEM_MODULE_DEPS_" + name
+ fmt.Fprintln(w, makevar, ":=$=", strings.Join(system.outputDeps.Strings(), " "))
+ fmt.Fprintln(w)
+
fmt.Fprintln(w, name+":", "$("+makevar+")")
fmt.Fprintln(w, ".PHONY:", name)
- fmt.Fprintln(w)
- makevar = "SOONG_SYSTEM_MODULES_LIBS_" + name
- fmt.Fprintln(w, makevar, ":=", strings.Join(system.properties.Libs, " "))
- fmt.Fprintln(w, ".KATI_READONLY :=", makevar)
},
}
}
diff --git a/java/testing.go b/java/testing.go
index a9d4670fc..5d116a787 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -54,7 +54,7 @@ func GatherRequiredDepsForTest() string {
java_library {
name: "%s",
srcs: ["a.java"],
- no_standard_libs: true,
+ sdk_version: "none",
system_modules: "core-platform-api-stubs-system-modules",
}
`, extra)
@@ -64,7 +64,7 @@ func GatherRequiredDepsForTest() string {
java_library {
name: "framework",
srcs: ["a.java"],
- no_standard_libs: true,
+ sdk_version: "none",
system_modules: "core-platform-api-stubs-system-modules",
aidl: {
export_include_dirs: ["framework/aidl"],
@@ -73,13 +73,13 @@ func GatherRequiredDepsForTest() string {
android_app {
name: "framework-res",
- no_framework_libs: true,
+ sdk_version: "core_platform",
}
java_library {
name: "android.hidl.base-V1.0-java",
srcs: ["a.java"],
- no_standard_libs: true,
+ sdk_version: "none",
system_modules: "core-platform-api-stubs-system-modules",
installable: true,
}
@@ -87,7 +87,7 @@ func GatherRequiredDepsForTest() string {
java_library {
name: "android.hidl.manager-V1.0-java",
srcs: ["a.java"],
- no_standard_libs: true,
+ sdk_version: "none",
system_modules: "core-platform-api-stubs-system-modules",
installable: true,
}
@@ -95,7 +95,7 @@ func GatherRequiredDepsForTest() string {
java_library {
name: "org.apache.http.legacy",
srcs: ["a.java"],
- no_standard_libs: true,
+ sdk_version: "none",
system_modules: "core-platform-api-stubs-system-modules",
installable: true,
}