Handle multiple linkages in sdk snapshots
Currently, if the same library is specified for multiple of native_libs,
native_shared_libs, and native_static_libs for different arch/oses,
there can be a few errors:
1. specifying a .so file as `srcs` within a cc_prebuilt_library rather
than being specified only for shared
2. the final type of prebuilt library is dependent on the arch/os
This change introduces:
* an ability for a member type to override the type for specified
properties
* checks for a library being used with incompatible member types
* basing linkage nesting on the member type in addition to variants
This will ensure that the correct library type is used, regardless of
the order of iteration over oses/arches, and support nesting linkages
where necessary but only one linkage variant exists.
Test: soong tests
Test: CI
Change-Id: I81dee013b09b99c34ca6c18f9cfcc12ee56d33d1
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 571d214..a4c7a85 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -1740,6 +1740,229 @@
)
}
+func TestSnapshotSameLibraryWithNativeLibsAndNativeSharedLib(t *testing.T) {
+ result := testSdkWithCc(t, `
+ module_exports {
+ host_supported: true,
+ name: "myexports",
+ target: {
+ android: {
+ native_shared_libs: [
+ "mynativelib",
+ ],
+ },
+ not_windows: {
+ native_libs: [
+ "mynativelib",
+ ],
+ },
+ },
+ }
+
+ cc_library {
+ name: "mynativelib",
+ host_supported: true,
+ srcs: [
+ "Test.cpp",
+ ],
+ stl: "none",
+ recovery_available: true,
+ vendor_available: true,
+ }
+ `)
+
+ CheckSnapshot(t, result, "myexports", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library {
+ name: "mynativelib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ host_supported: true,
+ vendor_available: true,
+ stl: "none",
+ compile_multilib: "both",
+ target: {
+ host: {
+ enabled: false,
+ },
+ android_arm64: {
+ shared: {
+ srcs: ["android/arm64/lib/mynativelib.so"],
+ },
+ static: {
+ enabled: false,
+ },
+ },
+ android_arm: {
+ shared: {
+ srcs: ["android/arm/lib/mynativelib.so"],
+ },
+ static: {
+ enabled: false,
+ },
+ },
+ linux_glibc_x86_64: {
+ enabled: true,
+ static: {
+ srcs: ["linux_glibc/x86_64/lib/mynativelib.a"],
+ },
+ shared: {
+ srcs: ["linux_glibc/x86_64/lib/mynativelib.so"],
+ },
+ },
+ linux_glibc_x86: {
+ enabled: true,
+ static: {
+ srcs: ["linux_glibc/x86/lib/mynativelib.a"],
+ },
+ shared: {
+ srcs: ["linux_glibc/x86/lib/mynativelib.so"],
+ },
+ },
+ },
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> android/arm64/lib/mynativelib.so
+.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> android/arm/lib/mynativelib.so
+.intermediates/mynativelib/linux_glibc_x86_64_static/mynativelib.a -> linux_glibc/x86_64/lib/mynativelib.a
+.intermediates/mynativelib/linux_glibc_x86_64_shared/mynativelib.so -> linux_glibc/x86_64/lib/mynativelib.so
+.intermediates/mynativelib/linux_glibc_x86_static/mynativelib.a -> linux_glibc/x86/lib/mynativelib.a
+.intermediates/mynativelib/linux_glibc_x86_shared/mynativelib.so -> linux_glibc/x86/lib/mynativelib.so
+`),
+ )
+}
+
+func TestSnapshotSameLibraryWithAndroidNativeLibsAndHostNativeSharedLib(t *testing.T) {
+ result := testSdkWithCc(t, `
+ module_exports {
+ host_supported: true,
+ name: "myexports",
+ target: {
+ android: {
+ native_libs: [
+ "mynativelib",
+ ],
+ },
+ not_windows: {
+ native_shared_libs: [
+ "mynativelib",
+ ],
+ },
+ },
+ }
+
+ cc_library {
+ name: "mynativelib",
+ host_supported: true,
+ srcs: [
+ "Test.cpp",
+ ],
+ stl: "none",
+ recovery_available: true,
+ vendor_available: true,
+ }
+ `)
+
+ CheckSnapshot(t, result, "myexports", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library {
+ name: "mynativelib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ host_supported: true,
+ vendor_available: true,
+ stl: "none",
+ compile_multilib: "both",
+ target: {
+ host: {
+ enabled: false,
+ },
+ android_arm64: {
+ static: {
+ srcs: ["android/arm64/lib/mynativelib.a"],
+ },
+ shared: {
+ srcs: ["android/arm64/lib/mynativelib.so"],
+ },
+ },
+ android_arm: {
+ static: {
+ srcs: ["android/arm/lib/mynativelib.a"],
+ },
+ shared: {
+ srcs: ["android/arm/lib/mynativelib.so"],
+ },
+ },
+ linux_glibc_x86_64: {
+ enabled: true,
+ shared: {
+ srcs: ["linux_glibc/x86_64/lib/mynativelib.so"],
+ },
+ static: {
+ enabled: false,
+ },
+ },
+ linux_glibc_x86: {
+ enabled: true,
+ shared: {
+ srcs: ["linux_glibc/x86/lib/mynativelib.so"],
+ },
+ static: {
+ enabled: false,
+ },
+ },
+ },
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mynativelib/android_arm64_armv8-a_static/mynativelib.a -> android/arm64/lib/mynativelib.a
+.intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> android/arm64/lib/mynativelib.so
+.intermediates/mynativelib/android_arm_armv7-a-neon_static/mynativelib.a -> android/arm/lib/mynativelib.a
+.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> android/arm/lib/mynativelib.so
+.intermediates/mynativelib/linux_glibc_x86_64_shared/mynativelib.so -> linux_glibc/x86_64/lib/mynativelib.so
+.intermediates/mynativelib/linux_glibc_x86_shared/mynativelib.so -> linux_glibc/x86/lib/mynativelib.so
+`),
+ )
+}
+
+func TestSnapshotSameLibraryWithNativeStaticLibsAndNativeSharedLib(t *testing.T) {
+ testSdkError(t, "Incompatible member types", `
+ module_exports {
+ host_supported: true,
+ name: "myexports",
+ target: {
+ android: {
+ native_shared_libs: [
+ "mynativelib",
+ ],
+ },
+ not_windows: {
+ native_static_libs: [
+ "mynativelib",
+ ],
+ },
+ },
+ }
+
+ cc_library {
+ name: "mynativelib",
+ host_supported: true,
+ srcs: [
+ ],
+ stl: "none",
+ recovery_available: true,
+ vendor_available: true,
+ }
+ `)
+}
+
func TestHostSnapshotWithMultiLib64(t *testing.T) {
result := testSdkWithCc(t, `
module_exports {
diff --git a/sdk/update.go b/sdk/update.go
index 71bd042..c3a426f 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -268,13 +268,19 @@
member = &sdkMember{memberType: memberType, name: name}
byName[name] = member
byType[memberType] = append(byType[memberType], member)
+ } else if member.memberType != memberType {
+ // validate whether this is the same member type or and overriding member type
+ if memberType.Overrides(member.memberType) {
+ member.memberType = memberType
+ } else if !member.memberType.Overrides(memberType) {
+ ctx.ModuleErrorf("Incompatible member types %q %q", member.memberType, memberType)
+ }
}
// Only append new variants to the list. This is needed because a member can be both
// exported by the sdk and also be a transitive sdk member.
member.variants = appendUniqueVariants(member.variants, variant)
}
-
var members []*sdkMember
for _, memberListProperty := range s.memberTypeListProperties() {
membersOfType := byType[memberListProperty.memberType]
@@ -1777,7 +1783,9 @@
// added.
archInfo.Properties = variantPropertiesFactory()
- if len(archVariants) == 1 {
+ // if there are multiple supported link variants, we want to nest based on linkage even if there
+ // is only one variant, otherwise, if there is only one variant we can populate based on the arch
+ if len(archVariants) == 1 && len(ctx.MemberType().SupportedLinkages()) <= 1 {
archInfo.Properties.PopulateFromVariant(ctx, archVariants[0])
} else {
// Group the variants by image type.
@@ -1904,11 +1912,13 @@
// Create the properties into which the image variant specific properties will be added.
imageInfo.Properties = variantPropertiesFactory()
- if len(imageVariants) == 1 {
+ // if there are multiple supported link variants, we want to nest even if there is only one
+ // variant, otherwise, if there is only one variant we can populate based on the image
+ if len(imageVariants) == 1 && len(ctx.MemberType().SupportedLinkages()) <= 1 {
imageInfo.Properties.PopulateFromVariant(ctx, imageVariants[0])
} else {
// There is more than one variant for this image variant which must be differentiated by link
- // type.
+ // type. Or there are multiple supported linkages and we need to nest based on link type.
for _, linkVariant := range imageVariants {
linkType := getLinkType(linkVariant)
if linkType == "" {
@@ -1952,10 +1962,22 @@
addSdkMemberPropertiesToSet(ctx, imageInfo.Properties, propertySet)
+ usedLinkages := make(map[string]bool, len(imageInfo.linkInfos))
for _, linkInfo := range imageInfo.linkInfos {
+ usedLinkages[linkInfo.linkType] = true
linkInfo.addToPropertySet(ctx, propertySet)
}
+ // If not all supported linkages had existing variants, we need to disable the unsupported variant
+ if len(imageInfo.linkInfos) < len(ctx.MemberType().SupportedLinkages()) {
+ for _, l := range ctx.MemberType().SupportedLinkages() {
+ if _, ok := usedLinkages[l]; !ok {
+ otherLinkagePropertySet := propertySet.AddPropertySet(l)
+ otherLinkagePropertySet.AddProperty("enabled", false)
+ }
+ }
+ }
+
// If this is for a non-core image variant then make sure that the property set does not contain
// any properties as providing non-core image variant specific properties for prebuilts is not
// currently supported.