Add the initial implementation of bp2build converter for java_library,
java_library_host, java_binary_host and cc_library_host_shared so
signapk tool can be built with Bazel.
Test: b build //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal
Test: jarsigner -verify -verbose build.bazel.examples.apex.minimal.apex
Bug: 209876137
Bug: 196204358
Bug: 210158864
Bug: 210159074
Bug: 210158872
Change-Id: I855884159d25e69d8f9623792c376da820a1eb4c
diff --git a/android/bazel.go b/android/bazel.go
index fd3f23e..8c63204 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -15,6 +15,8 @@
package android
import (
+ "bufio"
+ "errors"
"fmt"
"io/ioutil"
"path/filepath"
@@ -206,7 +208,8 @@
"build/bazel/platforms":/* recursive = */ true,
"build/bazel/product_variables":/* recursive = */ true,
"build/bazel_common_rules":/* recursive = */ true,
- "build/make/tools":/* recursive = */ true,
+ // build/make/tools/signapk BUILD file is generated, so build/make/tools is not recursive.
+ "build/make/tools":/* recursive = */ false,
"build/pesto":/* recursive = */ true,
// external/bazelbuild-rules_android/... is needed by mixed builds, otherwise mixed builds analysis fails
@@ -237,6 +240,7 @@
"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
+ "build/make/tools/signapk": Bp2BuildDefaultTrue,
"build/soong": Bp2BuildDefaultTrue,
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
@@ -279,7 +283,9 @@
"development/sdk": Bp2BuildDefaultTrueRecursively,
"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
"external/boringssl": Bp2BuildDefaultTrueRecursively,
+ "external/bouncycastle": Bp2BuildDefaultTrue,
"external/brotli": Bp2BuildDefaultTrue,
+ "external/conscrypt": Bp2BuildDefaultTrue,
"external/fmtlib": Bp2BuildDefaultTrueRecursively,
"external/google-benchmark": Bp2BuildDefaultTrueRecursively,
"external/googletest": Bp2BuildDefaultTrueRecursively,
@@ -349,6 +355,8 @@
"system/timezone/output_data": Bp2BuildDefaultTrueRecursively,
"system/unwinding/libbacktrace": Bp2BuildDefaultTrueRecursively,
"system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively,
+ "tools/apksig": Bp2BuildDefaultTrue,
+ "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively,
}
// Per-module denylist to always opt modules out of both bp2build and mixed builds.
@@ -404,8 +412,11 @@
"lib_linker_config_proto_lite", // contains .proto sources
"libprotobuf-python", // contains .proto sources
- "libprotobuf-internal-protos", // we don't handle path property for fileegroups
- "libprotobuf-internal-python-srcs", // we don't handle path property for fileegroups
+ "libprotobuf-internal-protos", // b/210751803, we don't handle path property for filegroups
+ "libprotobuf-internal-python-srcs", // b/210751803, we don't handle path property for filegroups
+ "libprotobuf-java-full", // b/210751803, we don't handle path property for filegroups
+ "libprotobuf-java-util-full", // b/210751803, we don't handle path property for filegroups
+ "conscrypt", // b/210751803, we don't handle path property for filegroups
"libseccomp_policy", // b/201094425: depends on func_to_syscall_nrs, which depends on py_binary, which is unsupported in mixed builds.
"libfdtrack", // depends on unconverted module libunwindstack
@@ -640,3 +651,22 @@
bModule.ConvertWithBp2build(ctx)
}
+
+// GetMainClassInManifest scans the manifest file specified in filepath and returns
+// the value of attribute Main-Class in the manifest file if it exists, or returns error.
+// WARNING: this is for bp2build converters of java_* modules only.
+func GetMainClassInManifest(c Config, filepath string) (string, error) {
+ file, err := c.fs.Open(filepath)
+ if err != nil {
+ return "", err
+ }
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := scanner.Text()
+ if strings.HasPrefix(line, "Main-Class:") {
+ return strings.TrimSpace(line[len("Main-Class:"):]), nil
+ }
+ }
+
+ return "", errors.New("Main-Class is not found.")
+}
diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go
new file mode 100644
index 0000000..96b8958
--- /dev/null
+++ b/bp2build/java_binary_host_conversion_test.go
@@ -0,0 +1,63 @@
+// Copyright 2021 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 bp2build
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/cc"
+ "android/soong/java"
+)
+
+func runJavaBinaryHostTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ (&tc).moduleTypeUnderTest = "java_binary_host"
+ (&tc).moduleTypeUnderTestFactory = java.BinaryHostFactory
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("cc_library_host_shared", cc.LibraryHostSharedFactory)
+ }, tc)
+}
+
+var fs = map[string]string{
+ "test.mf": "Main-Class: com.android.test.MainClass",
+ "other/Android.bp": `cc_library_host_shared {
+ name: "jni-lib-1",
+ stl: "none",
+}`,
+}
+
+func TestJavaBinaryHost(t *testing.T) {
+ runJavaBinaryHostTestCase(t, bp2buildTestCase{
+ description: "java_binary_host with srcs, exclude_srcs, jni_libs and manifest.",
+ filesystem: fs,
+ blueprint: `java_binary_host {
+ name: "java-binary-host-1",
+ srcs: ["a.java", "b.java"],
+ exclude_srcs: ["b.java"],
+ manifest: "test.mf",
+ jni_libs: ["jni-lib-1"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("java_binary", "java-binary-host-1", attrNameToString{
+ "srcs": `["a.java"]`,
+ "main_class": `"com.android.test.MainClass"`,
+ "deps": `["//other:jni-lib-1"]`,
+ "jvm_flags": `["-Djava.library.path=$${RUNPATH}other"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
new file mode 100644
index 0000000..5c65ec2
--- /dev/null
+++ b/bp2build/java_library_conversion_test.go
@@ -0,0 +1,57 @@
+// Copyright 2021 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 bp2build
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+func runJavaLibraryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ (&tc).moduleTypeUnderTest = "java_library"
+ (&tc).moduleTypeUnderTestFactory = java.LibraryFactory
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
+func TestJavaLibrary(t *testing.T) {
+ runJavaLibraryTestCase(t, bp2buildTestCase{
+ description: "java_library with srcs, exclude_srcs and libs",
+ blueprint: `java_library {
+ name: "java-lib-1",
+ srcs: ["a.java", "b.java"],
+ exclude_srcs: ["b.java"],
+ libs: ["java-lib-2"],
+ bazel_module: { bp2build_available: true },
+}
+
+java_library {
+ name: "java-lib-2",
+ srcs: ["b.java"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("java_library", "java-lib-1", attrNameToString{
+ "srcs": `["a.java"]`,
+ "deps": `[":java-lib-2"]`,
+ }),
+ makeBazelTarget("java_library", "java-lib-2", attrNameToString{
+ "srcs": `["b.java"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/java_library_host_conversion_test.go b/bp2build/java_library_host_conversion_test.go
new file mode 100644
index 0000000..6ac82db
--- /dev/null
+++ b/bp2build/java_library_host_conversion_test.go
@@ -0,0 +1,57 @@
+// Copyright 2021 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 bp2build
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+func runJavaLibraryHostTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ (&tc).moduleTypeUnderTest = "java_library_host"
+ (&tc).moduleTypeUnderTestFactory = java.LibraryHostFactory
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
+func TestJavaLibraryHost(t *testing.T) {
+ runJavaLibraryHostTestCase(t, bp2buildTestCase{
+ description: "java_library_host with srcs, exclude_srcs and libs",
+ blueprint: `java_library_host {
+ name: "java-lib-host-1",
+ srcs: ["a.java", "b.java"],
+ exclude_srcs: ["b.java"],
+ libs: ["java-lib-host-2"],
+ bazel_module: { bp2build_available: true },
+}
+
+java_library_host {
+ name: "java-lib-host-2",
+ srcs: ["c.java"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("java_library", "java-lib-host-1", attrNameToString{
+ "srcs": `["a.java"]`,
+ "deps": `[":java-lib-host-2"]`,
+ }),
+ makeBazelTarget("java_library", "java-lib-host-2", attrNameToString{
+ "srcs": `["c.java"]`,
+ }),
+ },
+ })
+}
diff --git a/cc/cc.go b/cc/cc.go
index 0904bd9..7211359 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3458,10 +3458,6 @@
} else if c.Object() {
objectBp2Build(ctx, c)
} else if c.CcLibrary() {
- if c.hod == android.HostSupported {
- return
- }
-
static := c.BuildStaticVariant()
shared := c.BuildSharedVariant()
prebuilt := c.IsPrebuilt()
diff --git a/cc/library.go b/cc/library.go
index aec699c..216c124 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -447,6 +447,8 @@
module, library := NewLibrary(android.HostSupported)
library.BuildOnlyShared()
module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
+ module.bazelable = true
+ module.bazelHandler = &ccLibraryBazelHandler{module: module}
return module.Init()
}
diff --git a/java/base.go b/java/base.go
index c0da215..c45ef64 100644
--- a/java/base.go
+++ b/java/base.go
@@ -372,6 +372,7 @@
android.DefaultableModuleBase
android.ApexModuleBase
android.SdkBase
+ android.BazelModuleBase
// Functionality common to Module and Import.
embeddableInModuleAndImport
@@ -1952,3 +1953,17 @@
}
var _ ModuleWithStem = (*Module)(nil)
+
+func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+ switch ctx.ModuleType() {
+ case "java_library", "java_library_host":
+ if lib, ok := ctx.Module().(*Library); ok {
+ javaLibraryBp2Build(ctx, lib)
+ }
+ case "java_binary_host":
+ if binary, ok := ctx.Module().(*Binary); ok {
+ javaBinaryHostBp2Build(ctx, binary)
+ }
+ }
+
+}
diff --git a/java/java.go b/java/java.go
index e7b1f4f..f77c694 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,7 +21,9 @@
import (
"fmt"
"path/filepath"
+ "strings"
+ "android/soong/bazel"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -756,6 +758,7 @@
android.InitApexModule(module)
android.InitSdkAwareModule(module)
+ android.InitBazelModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
@@ -778,6 +781,7 @@
android.InitApexModule(module)
android.InitSdkAwareModule(module)
+ android.InitBazelModule(module)
InitJavaModule(module, android.HostSupported)
return module
}
@@ -1228,6 +1232,8 @@
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
android.InitDefaultableModule(module)
+ android.InitBazelModule(module)
+
return module
}
@@ -1245,6 +1251,7 @@
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
android.InitDefaultableModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -1961,3 +1968,103 @@
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
}
}
+
+type javaLibraryAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Javacopts bazel.StringListAttribute
+}
+
+func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) {
+ srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs))
+ attrs := &javaLibraryAttributes{
+ Srcs: srcs,
+ }
+
+ if m.properties.Javacflags != nil {
+ attrs.Javacopts = bazel.MakeStringListAttribute(m.properties.Javacflags)
+ }
+
+ if m.properties.Libs != nil {
+ attrs.Deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.properties.Libs))
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "java_library",
+ Bzl_load_location: "//build/bazel/rules/java:library.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+}
+
+type javaBinaryHostAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Main_class string
+ Jvm_flags bazel.StringListAttribute
+}
+
+// JavaBinaryHostBp2Build is for java_binary_host bp2build.
+func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) {
+ mainClass := ""
+ if m.binaryProperties.Main_class != nil {
+ mainClass = *m.binaryProperties.Main_class
+ }
+ if m.properties.Manifest != nil {
+ mainClassInManifest, err := android.GetMainClassInManifest(ctx.Config(), android.PathForModuleSrc(ctx, *m.properties.Manifest).String())
+ if err != nil {
+ return
+ }
+ mainClass = mainClassInManifest
+ }
+ srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs))
+ attrs := &javaBinaryHostAttributes{
+ Srcs: srcs,
+ Main_class: mainClass,
+ }
+
+ // Attribute deps
+ deps := []string{}
+ if m.properties.Static_libs != nil {
+ deps = append(deps, m.properties.Static_libs...)
+ }
+ if m.binaryProperties.Jni_libs != nil {
+ deps = append(deps, m.binaryProperties.Jni_libs...)
+ }
+ if len(deps) > 0 {
+ attrs.Deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, deps))
+ }
+
+ // Attribute jvm_flags
+ if m.binaryProperties.Jni_libs != nil {
+ jniLibPackages := map[string]bool{}
+ for _, jniLibLabel := range android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs).Includes {
+ jniLibPackage := jniLibLabel.Label
+ indexOfColon := strings.Index(jniLibLabel.Label, ":")
+ if indexOfColon > 0 {
+ // JNI lib from other package
+ jniLibPackage = jniLibLabel.Label[2:indexOfColon]
+ } else if indexOfColon == 0 {
+ // JNI lib in the same package of java_binary
+ packageOfCurrentModule := m.GetBazelLabel(ctx, m)
+ jniLibPackage = packageOfCurrentModule[2:strings.Index(packageOfCurrentModule, ":")]
+ }
+ if _, inMap := jniLibPackages[jniLibPackage]; !inMap {
+ jniLibPackages[jniLibPackage] = true
+ }
+ }
+ jniLibPaths := []string{}
+ for jniLibPackage, _ := range jniLibPackages {
+ // See cs/f:.*/third_party/bazel/.*java_stub_template.txt for the use of RUNPATH
+ jniLibPaths = append(jniLibPaths, "$${RUNPATH}"+jniLibPackage)
+ }
+ attrs.Jvm_flags = bazel.MakeStringListAttribute([]string{"-Djava.library.path=" + strings.Join(jniLibPaths, ":")})
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "java_binary",
+ }
+
+ // Create the BazelTargetModule.
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+}