Support multilib in apex.
Bug: b/208325023
Test: Added unit tests, also tested with adbd apex build manually.
Change-Id: I47e04cd4eb5d05227f0a84683dcb66dff00e3514
diff --git a/android/module.go b/android/module.go
index 4da201c..3c8c777 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1932,6 +1932,10 @@
return append(Paths{}, m.vintfFragmentsPaths...)
}
+func (m *ModuleBase) CompileMultilib() *string {
+ return m.base().commonProperties.Compile_multilib
+}
+
// SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
// apex container for use when generation the license metadata file.
func (m *ModuleBase) SetLicenseInstallMap(installMap []string) {
diff --git a/apex/apex.go b/apex/apex.go
index 635ff30..05e3b20 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -3263,17 +3263,23 @@
// For Bazel / bp2build
type bazelApexBundleAttributes struct {
- Manifest bazel.LabelAttribute
- Android_manifest bazel.LabelAttribute
- File_contexts bazel.LabelAttribute
- Key bazel.LabelAttribute
- Certificate bazel.LabelAttribute
- Min_sdk_version *string
- Updatable bazel.BoolAttribute
- Installable bazel.BoolAttribute
- Native_shared_libs bazel.LabelListAttribute
- Binaries bazel.LabelListAttribute
- Prebuilts bazel.LabelListAttribute
+ Manifest bazel.LabelAttribute
+ Android_manifest bazel.LabelAttribute
+ File_contexts bazel.LabelAttribute
+ Key bazel.LabelAttribute
+ Certificate bazel.LabelAttribute
+ Min_sdk_version *string
+ Updatable bazel.BoolAttribute
+ Installable bazel.BoolAttribute
+ Binaries bazel.LabelListAttribute
+ Prebuilts bazel.LabelListAttribute
+ Native_shared_libs_32 bazel.LabelListAttribute
+ Native_shared_libs_64 bazel.LabelListAttribute
+}
+
+type convertedNativeSharedLibs struct {
+ Native_shared_libs_32 bazel.LabelListAttribute
+ Native_shared_libs_64 bazel.LabelListAttribute
}
// ConvertWithBp2build performs bp2build conversion of an apex
@@ -3313,9 +3319,21 @@
certificateLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Certificate))
}
- nativeSharedLibs := a.properties.ApexNativeDependencies.Native_shared_libs
- nativeSharedLibsLabelList := android.BazelLabelForModuleDeps(ctx, nativeSharedLibs)
- nativeSharedLibsLabelListAttribute := bazel.MakeLabelListAttribute(nativeSharedLibsLabelList)
+ nativeSharedLibs := &convertedNativeSharedLibs{
+ Native_shared_libs_32: bazel.LabelListAttribute{},
+ Native_shared_libs_64: bazel.LabelListAttribute{},
+ }
+ compileMultilib := "both"
+ if a.CompileMultilib() != nil {
+ compileMultilib = *a.CompileMultilib()
+ }
+
+ // properties.Native_shared_libs is treated as "both"
+ convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
+ convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
+ convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
+ convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
+ convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
prebuilts := a.overridableProperties.Prebuilts
prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
@@ -3335,17 +3353,18 @@
}
attrs := &bazelApexBundleAttributes{
- Manifest: manifestLabelAttribute,
- Android_manifest: androidManifestLabelAttribute,
- File_contexts: fileContextsLabelAttribute,
- Min_sdk_version: minSdkVersion,
- Key: keyLabelAttribute,
- Certificate: certificateLabelAttribute,
- Updatable: updatableAttribute,
- Installable: installableAttribute,
- Native_shared_libs: nativeSharedLibsLabelListAttribute,
- Binaries: binariesLabelListAttribute,
- Prebuilts: prebuiltsLabelListAttribute,
+ Manifest: manifestLabelAttribute,
+ Android_manifest: androidManifestLabelAttribute,
+ File_contexts: fileContextsLabelAttribute,
+ Min_sdk_version: minSdkVersion,
+ Key: keyLabelAttribute,
+ Certificate: certificateLabelAttribute,
+ Updatable: updatableAttribute,
+ Installable: installableAttribute,
+ Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
+ Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
+ Binaries: binariesLabelListAttribute,
+ Prebuilts: prebuiltsLabelListAttribute,
}
props := bazel.BazelTargetModuleProperties{
@@ -3355,3 +3374,107 @@
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs)
}
+
+// The following conversions are based on this table where the rows are the compile_multilib
+// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
+// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
+// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
+// should not be compiled.
+// multib/compile_multilib, 32, 64, both, first
+// 32, 32/32, none/none, 32/32, none/32
+// 64, none/none, 64/none, 64/none, 64/none
+// both, 32/32, 64/none, 32&64/32, 64/32
+// first, 32/32, 64/none, 64/32, 64/32
+
+func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
+ libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
+ libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
+ switch compileMultilb {
+ case "both", "32":
+ makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "first":
+ make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "64":
+ // Incompatible, ignore
+ default:
+ invalidCompileMultilib(ctx, compileMultilb)
+ }
+}
+
+func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
+ libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
+ libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
+ switch compileMultilb {
+ case "both", "64", "first":
+ make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "32":
+ // Incompatible, ignore
+ default:
+ invalidCompileMultilib(ctx, compileMultilb)
+ }
+}
+
+func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
+ libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
+ libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
+ switch compileMultilb {
+ case "both":
+ makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "first":
+ makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "32":
+ makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "64":
+ make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ default:
+ invalidCompileMultilib(ctx, compileMultilb)
+ }
+}
+
+func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
+ libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
+ libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
+ switch compileMultilb {
+ case "both", "first":
+ makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "32":
+ make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ case "64":
+ make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ default:
+ invalidCompileMultilib(ctx, compileMultilb)
+ }
+}
+
+func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
+ make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+ make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
+}
+
+func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
+ list := bazel.LabelListAttribute{}
+ list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
+ nativeSharedLibs.Native_shared_libs_32.Append(list)
+}
+
+func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
+ makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
+ makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
+}
+
+func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
+ makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
+ makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
+}
+
+func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
+ labelListAttr *bazel.LabelListAttribute) {
+ list := bazel.LabelListAttribute{}
+ list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
+ labelListAttr.Append(list)
+}
+
+func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
+ ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
+}
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index a3825e6..4b141c9 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -131,10 +131,21 @@
"key": `":com.android.apogee.key"`,
"manifest": `"apogee_manifest.json"`,
"min_sdk_version": `"29"`,
- "native_shared_libs": `[
+ "native_shared_libs_32": `[
":native_shared_lib_1",
":native_shared_lib_2",
]`,
+ "native_shared_libs_64": `select({
+ "//build/bazel/platforms/arch:arm64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_2",
+ ],
+ "//build/bazel/platforms/arch:x86_64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_2",
+ ],
+ "//conditions:default": [],
+ })`,
"prebuilts": `[
":pretend_prebuilt_1",
":pretend_prebuilt_2",
@@ -144,6 +155,126 @@
}})
}
+func TestApexBundleCompileMultilibBoth(t *testing.T) {
+ runApexTestCase(t, bp2buildTestCase{
+ description: "apex - example with compile_multilib=both",
+ moduleTypeUnderTest: "apex",
+ moduleTypeUnderTestFactory: apex.BundleFactory,
+ filesystem: map[string]string{},
+ blueprint: createMultilibBlueprint("both"),
+ expectedBazelTargets: []string{
+ makeBazelTarget("apex", "com.android.apogee", attrNameToString{
+ "native_shared_libs_32": `[
+ ":native_shared_lib_1",
+ ":native_shared_lib_3",
+ ] + select({
+ "//build/bazel/platforms/arch:arm": [":native_shared_lib_2"],
+ "//build/bazel/platforms/arch:x86": [":native_shared_lib_2"],
+ "//conditions:default": [],
+ })`,
+ "native_shared_libs_64": `select({
+ "//build/bazel/platforms/arch:arm64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_4",
+ ":native_shared_lib_2",
+ ],
+ "//build/bazel/platforms/arch:x86_64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_4",
+ ":native_shared_lib_2",
+ ],
+ "//conditions:default": [],
+ })`,
+ }),
+ }})
+}
+
+func TestApexBundleCompileMultilibFirst(t *testing.T) {
+ runApexTestCase(t, bp2buildTestCase{
+ description: "apex - example with compile_multilib=first",
+ moduleTypeUnderTest: "apex",
+ moduleTypeUnderTestFactory: apex.BundleFactory,
+ filesystem: map[string]string{},
+ blueprint: createMultilibBlueprint("first"),
+ expectedBazelTargets: []string{
+ makeBazelTarget("apex", "com.android.apogee", attrNameToString{
+ "native_shared_libs_32": `select({
+ "//build/bazel/platforms/arch:arm": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_3",
+ ":native_shared_lib_2",
+ ],
+ "//build/bazel/platforms/arch:x86": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_3",
+ ":native_shared_lib_2",
+ ],
+ "//conditions:default": [],
+ })`,
+ "native_shared_libs_64": `select({
+ "//build/bazel/platforms/arch:arm64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_4",
+ ":native_shared_lib_2",
+ ],
+ "//build/bazel/platforms/arch:x86_64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_4",
+ ":native_shared_lib_2",
+ ],
+ "//conditions:default": [],
+ })`,
+ }),
+ }})
+}
+
+func TestApexBundleCompileMultilib32(t *testing.T) {
+ runApexTestCase(t, bp2buildTestCase{
+ description: "apex - example with compile_multilib=32",
+ moduleTypeUnderTest: "apex",
+ moduleTypeUnderTestFactory: apex.BundleFactory,
+ filesystem: map[string]string{},
+ blueprint: createMultilibBlueprint("32"),
+ expectedBazelTargets: []string{
+ makeBazelTarget("apex", "com.android.apogee", attrNameToString{
+ "native_shared_libs_32": `[
+ ":native_shared_lib_1",
+ ":native_shared_lib_3",
+ ] + select({
+ "//build/bazel/platforms/arch:arm": [":native_shared_lib_2"],
+ "//build/bazel/platforms/arch:x86": [":native_shared_lib_2"],
+ "//conditions:default": [],
+ })`,
+ }),
+ }})
+}
+
+func TestApexBundleCompileMultilib64(t *testing.T) {
+ runApexTestCase(t, bp2buildTestCase{
+ description: "apex - example with compile_multilib=64",
+ moduleTypeUnderTest: "apex",
+ moduleTypeUnderTestFactory: apex.BundleFactory,
+ filesystem: map[string]string{},
+ blueprint: createMultilibBlueprint("64"),
+ expectedBazelTargets: []string{
+ makeBazelTarget("apex", "com.android.apogee", attrNameToString{
+ "native_shared_libs_64": `select({
+ "//build/bazel/platforms/arch:arm64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_4",
+ ":native_shared_lib_2",
+ ],
+ "//build/bazel/platforms/arch:x86_64": [
+ ":native_shared_lib_1",
+ ":native_shared_lib_4",
+ ":native_shared_lib_2",
+ ],
+ "//conditions:default": [],
+ })`,
+ }),
+ }})
+}
+
func TestApexBundleDefaultPropertyValues(t *testing.T) {
runApexTestCase(t, bp2buildTestCase{
description: "apex - default property values",
@@ -180,3 +311,53 @@
}),
}})
}
+
+func createMultilibBlueprint(compile_multilib string) string {
+ return `
+cc_library {
+ name: "native_shared_lib_1",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "native_shared_lib_2",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "native_shared_lib_3",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "native_shared_lib_4",
+ bazel_module: { bp2build_available: false },
+}
+
+apex {
+ name: "com.android.apogee",
+ compile_multilib: "` + compile_multilib + `",
+ multilib: {
+ both: {
+ native_shared_libs: [
+ "native_shared_lib_1",
+ ],
+ },
+ first: {
+ native_shared_libs: [
+ "native_shared_lib_2",
+ ],
+ },
+ lib32: {
+ native_shared_libs: [
+ "native_shared_lib_3",
+ ],
+ },
+ lib64: {
+ native_shared_libs: [
+ "native_shared_lib_4",
+ ],
+ },
+ },
+}`
+}