add java_import to mixed build
Bug: 220168131
Test: go test ./java -run TestImportMixedBuild
Test: USE_BAZEL_ANALYSIS=1 m CtsManagedProfileApp && verify jars are
included from execroot/__main__ directory
Test: build/bazel/ci/mixed_droid.sh
Change-Id: I6d35a2389ea35525d532efc8474c71d2c8825646
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index ab71d99..9decfbd 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -217,6 +217,7 @@
"system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively,
"tools/apksig": Bp2BuildDefaultTrue,
"tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively,
+ "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively,
}
Bp2buildKeepExistingBuildFile = map[string]bool{
@@ -526,5 +527,20 @@
"simpleperf_ndk",
"toybox-static",
"zlib_bench",
+
+ // java_import[_host] issues
+ // tradefed prebuilts depend on libprotobuf
+ "prebuilt_tradefed",
+ "prebuilt_tradefed-test-framework",
+ // handcrafted BUILD.bazel files in //prebuilts/...
+ "prebuilt_r8lib-prebuilt",
+ "prebuilt_sdk-core-lambda-stubs",
+ "prebuilt_android-support-collections-nodeps",
+ "prebuilt_android-arch-core-common-nodeps",
+ "prebuilt_android-arch-lifecycle-common-java8-nodeps",
+ "prebuilt_android-arch-lifecycle-common-nodeps",
+ "prebuilt_android-support-annotations-nodeps",
+ "prebuilt_android-arch-paging-common-nodeps",
+ "prebuilt_android-arch-room-common-nodeps",
}
)
diff --git a/java/java.go b/java/java.go
index dae69dc..f4ec04e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -24,6 +24,7 @@
"strings"
"android/soong/bazel"
+ "android/soong/bazel/cquery"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -1610,7 +1611,8 @@
}
}
-func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (j *Import) commonBuildActions(ctx android.ModuleContext) {
+ //TODO(b/231322772) these should come from Bazel once available
j.sdkVersion = j.SdkVersion(ctx)
j.minSdkVersion = j.MinSdkVersion(ctx)
@@ -1621,6 +1623,10 @@
if ctx.Windows() {
j.HideFromMake()
}
+}
+
+func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ j.commonBuildActions(ctx)
jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
@@ -1662,19 +1668,7 @@
addCLCFromDep(ctx, module, j.classLoaderContexts)
})
- if Bool(j.properties.Installable) {
- var installDir android.InstallPath
- if ctx.InstallInTestcases() {
- var archDir string
- if !ctx.Host() {
- archDir = ctx.DeviceConfig().DeviceArch()
- }
- installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir)
- } else {
- installDir = android.PathForModuleInstall(ctx, "framework")
- }
- ctx.InstallFile(installDir, jarName, outputFile)
- }
+ j.maybeInstall(ctx, jarName, outputFile)
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
@@ -1748,6 +1742,24 @@
})
}
+func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) {
+ if !Bool(j.properties.Installable) {
+ return
+ }
+
+ var installDir android.InstallPath
+ if ctx.InstallInTestcases() {
+ var archDir string
+ if !ctx.Host() {
+ archDir = ctx.DeviceConfig().DeviceArch()
+ }
+ installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir)
+ } else {
+ installDir = android.PathForModuleInstall(ctx, "framework")
+ }
+ ctx.InstallFile(installDir, jarName, outputFile)
+}
+
func (j *Import) OutputFiles(tag string) (android.Paths, error) {
switch tag {
case "", ".jar":
@@ -2046,9 +2058,7 @@
return module
}
-//
// Defaults
-//
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
@@ -2063,29 +2073,29 @@
//
// Example:
//
-// java_defaults {
-// name: "example_defaults",
-// srcs: ["common/**/*.java"],
-// javacflags: ["-Xlint:all"],
-// aaptflags: ["--auto-add-overlay"],
-// }
+// java_defaults {
+// name: "example_defaults",
+// srcs: ["common/**/*.java"],
+// javacflags: ["-Xlint:all"],
+// aaptflags: ["--auto-add-overlay"],
+// }
//
-// java_library {
-// name: "example",
-// defaults: ["example_defaults"],
-// srcs: ["example/**/*.java"],
-// }
+// java_library {
+// name: "example",
+// defaults: ["example_defaults"],
+// srcs: ["example/**/*.java"],
+// }
//
// is functionally identical to:
//
-// java_library {
-// name: "example",
-// srcs: [
-// "common/**/*.java",
-// "example/**/*.java",
-// ],
-// javacflags: ["-Xlint:all"],
-// }
+// java_library {
+// name: "example",
+// srcs: [
+// "common/**/*.java",
+// "example/**/*.java",
+// ],
+// javacflags: ["-Xlint:all"],
+// }
func DefaultsFactory() android.Module {
module := &Defaults{}
@@ -2483,5 +2493,54 @@
props := bazel.BazelTargetModuleProperties{Rule_class: "java_import"}
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: android.RemoveOptionalPrebuiltPrefix(i.Name())}, attrs)
+}
+var _ android.MixedBuildBuildable = (*Import)(nil)
+
+func (i *Import) getBazelModuleLabel(ctx android.BaseModuleContext) string {
+ return android.RemoveOptionalPrebuiltPrefixFromBazelLabel(i.GetBazelLabel(ctx, i))
+}
+
+func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) {
+ i.commonBuildActions(ctx)
+
+ bazelCtx := ctx.Config().BazelContext
+ filePaths, err := bazelCtx.GetOutputFiles(i.getBazelModuleLabel(ctx), android.GetConfigKey(ctx))
+ if err != nil {
+ ctx.ModuleErrorf(err.Error())
+ return
+ }
+
+ bazelJars := android.Paths{}
+ for _, bazelOutputFile := range filePaths {
+ bazelJars = append(bazelJars, android.PathForBazelOut(ctx, bazelOutputFile))
+ }
+
+ jarName := android.RemoveOptionalPrebuiltPrefix(i.Name()) + ".jar"
+ outputFile := android.PathForModuleOut(ctx, "bazelCombined", jarName)
+ TransformJarsToJar(ctx, outputFile, "combine prebuilt jars", bazelJars,
+ android.OptionalPath{}, // manifest
+ false, // stripDirEntries
+ []string{}, // filesToStrip
+ []string{}, // dirsToStrip
+ )
+ i.combinedClasspathFile = outputFile
+
+ ctx.SetProvider(JavaInfoProvider, JavaInfo{
+ HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile),
+ ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile),
+ //TODO(b/240308299) include AIDL information from Bazel
+ })
+
+ i.maybeInstall(ctx, jarName, outputFile)
+}
+
+func (i *Import) QueueBazelCall(ctx android.BaseModuleContext) {
+ bazelCtx := ctx.Config().BazelContext
+ bazelCtx.QueueBazelRequest(i.getBazelModuleLabel(ctx), cquery.GetOutputFiles, android.GetConfigKey(ctx))
+}
+
+func (i *Import) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
+ return true
}
diff --git a/java/java_test.go b/java/java_test.go
index 32b0b0f..9e5cf0c 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1667,3 +1667,48 @@
})
}
}
+
+func TestImportMixedBuild(t *testing.T) {
+ bp := `
+ java_import {
+ name: "baz",
+ jars: [
+ "test1.jar",
+ "test2.jar",
+ ],
+ bazel_module: { label: "//foo/bar:baz" },
+ }
+ `
+
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.BazelContext = android.MockBazelContext{
+ OutputBaseDir: "outputbase",
+ LabelToOutputFiles: map[string][]string{
+ "//foo/bar:baz": []string{"test1.jar", "test2.jar"},
+ },
+ }
+ }),
+ ).RunTestWithBp(t, bp)
+
+ bazMod := ctx.ModuleForTests("baz", "android_common").Module()
+ producer := bazMod.(android.OutputFileProducer)
+ expectedOutputFiles := []string{".intermediates/baz/android_common/bazelCombined/baz.jar"}
+
+ outputFiles, err := producer.OutputFiles("")
+ if err != nil {
+ t.Errorf("Unexpected error getting java_import outputfiles %s", err)
+ }
+ actualOutputFiles := android.NormalizePathsForTesting(outputFiles)
+ android.AssertDeepEquals(t, "Output files are produced", expectedOutputFiles, actualOutputFiles)
+
+ javaInfoProvider := ctx.ModuleProvider(bazMod, JavaInfoProvider)
+ javaInfo, ok := javaInfoProvider.(JavaInfo)
+ if !ok {
+ t.Error("could not get JavaInfo from java_import module")
+ }
+ android.AssertDeepEquals(t, "Header JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.HeaderJars))
+ android.AssertDeepEquals(t, "Implementation/Resources JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.ImplementationAndResourcesJars))
+ android.AssertDeepEquals(t, "Implementation JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.ImplementationJars))
+}