From 865171ed402856a25345bcd23b376a27f160c340 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Mon, 2 Mar 2020 18:38:15 +0000 Subject: [PATCH] Allow sdk members to vary by os type Adds support for specifying separate members to an sdk/module_exports for different os types, e.g. separate ones for android and host. Adds 'android:"arch_variant"' tag to the dynamically generated fields for the sdk member types. Merges the exported members from all variants together. Determines the device/host_supported flags of the member snapshots by whether the OsClasses used by their variants rather than the sdk's host/device supported properties as they may be different. Bug: 150451422 Test: m nothing Change-Id: I41fbbcd8723aafd54826aad9b78eced9f66ef51c --- sdk/java_sdk_test.go | 123 +++++++++++++++++++++++++++++++++++++++++++ sdk/sdk.go | 1 + sdk/update.go | 70 ++++++++++++++++++++---- 3 files changed, 183 insertions(+), 11 deletions(-) diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 45da1f957..c60002b08 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -816,3 +816,126 @@ sdk_snapshot { checkAllCopyRules(".intermediates/system-module/linux_glibc_common/javac/system-module.jar -> java/system-module.jar"), ) } + +func TestDeviceAndHostSnapshotWithOsSpecificMembers(t *testing.T) { + // b/145598135 - Generating host snapshots for anything other than linux is not supported. + SkipIfNotLinux(t) + + result := testSdkWithJava(t, ` + module_exports { + name: "myexports", + host_supported: true, + java_libs: ["myjavalib"], + target: { + android: { + java_header_libs: ["androidjavalib"], + }, + host: { + java_header_libs: ["hostjavalib"], + }, + }, + } + + java_library { + name: "myjavalib", + host_supported: true, + srcs: ["Test.java"], + system_modules: "none", + sdk_version: "none", + } + + java_library { + name: "androidjavalib", + srcs: ["Test.java"], + system_modules: "none", + sdk_version: "none", + } + + java_library_host { + name: "hostjavalib", + srcs: ["Test.java"], + } + `) + + result.CheckSnapshot("myexports", "", + checkAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_import { + name: "myexports_hostjavalib@current", + sdk_member_name: "hostjavalib", + device_supported: false, + host_supported: true, + jars: ["java/hostjavalib.jar"], +} + +java_import { + name: "hostjavalib", + prefer: false, + device_supported: false, + host_supported: true, + jars: ["java/hostjavalib.jar"], +} + +java_import { + name: "myexports_androidjavalib@current", + sdk_member_name: "androidjavalib", + jars: ["java/androidjavalib.jar"], +} + +java_import { + name: "androidjavalib", + prefer: false, + jars: ["java/androidjavalib.jar"], +} + +java_import { + name: "myexports_myjavalib@current", + sdk_member_name: "myjavalib", + host_supported: true, + target: { + android: { + jars: ["java/android/myjavalib.jar"], + }, + linux_glibc: { + jars: ["java/linux_glibc/myjavalib.jar"], + }, + }, +} + +java_import { + name: "myjavalib", + prefer: false, + host_supported: true, + target: { + android: { + jars: ["java/android/myjavalib.jar"], + }, + linux_glibc: { + jars: ["java/linux_glibc/myjavalib.jar"], + }, + }, +} + +module_exports_snapshot { + name: "myexports@current", + host_supported: true, + target: { + android: { + java_header_libs: ["myexports_androidjavalib@current"], + }, + linux_glibc: { + java_header_libs: ["myexports_hostjavalib@current"], + }, + }, + java_libs: ["myexports_myjavalib@current"], +} +`), + checkAllCopyRules(` +.intermediates/hostjavalib/linux_glibc_common/javac/hostjavalib.jar -> java/hostjavalib.jar +.intermediates/androidjavalib/android_common/turbine-combined/androidjavalib.jar -> java/androidjavalib.jar +.intermediates/myjavalib/android_common/javac/myjavalib.jar -> java/android/myjavalib.jar +.intermediates/myjavalib/linux_glibc_common/javac/myjavalib.jar -> java/linux_glibc/myjavalib.jar +`), + ) +} diff --git a/sdk/sdk.go b/sdk/sdk.go index db715757d..8b9d5bc80 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -150,6 +150,7 @@ func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynami fields = append(fields, reflect.StructField{ Name: proptools.FieldNameForProperty(p), Type: reflect.TypeOf([]string{}), + Tag: `android:"arch_variant"`, }) // Copy the field index for use in the getter func as using the loop variable directly will diff --git a/sdk/update.go b/sdk/update.go index 282a7a4cd..a43a14b85 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -225,10 +225,17 @@ func versionedSdkMemberName(ctx android.ModuleContext, memberName string, versio // the contents (header files, stub libraries, etc) into the zip file. func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) android.OutputPath { + exportedMembers := make(map[string]struct{}) var memberRefs []sdkMemberRef for _, sdkVariant := range sdkVariants { memberRefs = append(memberRefs, sdkVariant.memberRefs...) + + // Merge the exported member sets from all sdk variants. + for key, _ := range sdkVariant.getExportedMembers() { + exportedMembers[key] = struct{}{} + } } + s.exportedMembers = exportedMembers snapshotDir := android.PathForModuleOut(ctx, "snapshot") @@ -302,23 +309,43 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro snapshotModule.AddProperty("visibility", visibility) } - addHostDeviceSupportedProperties(&s.ModuleBase, snapshotModule) + addHostDeviceSupportedProperties(s.ModuleBase.DeviceSupported(), s.ModuleBase.HostSupported(), snapshotModule) // Compile_multilib defaults to both and must always be set to both on the // device and so only needs to be set when targeted at the host and is neither // unspecified or both. + targetPropertySet := snapshotModule.AddPropertySet("target") if s.HostSupported() && multilib != "" && multilib != "both" { - targetSet := snapshotModule.AddPropertySet("target") - hostSet := targetSet.AddPropertySet("host") + hostSet := targetPropertySet.AddPropertySet("host") hostSet.AddProperty("compile_multilib", multilib) } - for _, memberListProperty := range s.memberListProperties() { - names := memberListProperty.getter(s.dynamicMemberTypeListProperties) - if len(names) > 0 { - snapshotModule.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names)) + var dynamicMemberPropertiesList []interface{} + osTypeToMemberProperties := make(map[android.OsType]*sdk) + for _, sdkVariant := range sdkVariants { + properties := sdkVariant.dynamicMemberTypeListProperties + osTypeToMemberProperties[sdkVariant.Target().Os] = sdkVariant + dynamicMemberPropertiesList = append(dynamicMemberPropertiesList, properties) + } + + // Extract the common lists of members into a separate struct. + commonDynamicMemberProperties := s.dynamicSdkMemberTypes.createMemberListProperties() + extractCommonProperties(commonDynamicMemberProperties, dynamicMemberPropertiesList) + + // Add properties common to all os types. + s.addMemberPropertiesToPropertySet(builder, snapshotModule, commonDynamicMemberProperties) + + // Iterate over the os types in a fixed order. + for _, osType := range s.getPossibleOsTypes() { + if sdkVariant, ok := osTypeToMemberProperties[osType]; ok { + osPropertySet := targetPropertySet.AddPropertySet(sdkVariant.Target().Os.Name) + s.addMemberPropertiesToPropertySet(builder, osPropertySet, sdkVariant.dynamicMemberTypeListProperties) } } + + // Prune any empty property sets. + snapshotModule.transform(pruneEmptySetTransformer{}) + bpFile.AddModule(snapshotModule) // generate Android.bp @@ -369,6 +396,15 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro return outputZipFile } +func (s *sdk) addMemberPropertiesToPropertySet(builder *snapshotBuilder, propertySet android.BpPropertySet, dynamicMemberTypeListProperties interface{}) { + for _, memberListProperty := range s.memberListProperties() { + names := memberListProperty.getter(dynamicMemberTypeListProperties) + if len(names) > 0 { + propertySet.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names)) + } + } +} + type propertyTag struct { name string } @@ -573,7 +609,19 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType } } - addHostDeviceSupportedProperties(&s.sdk.ModuleBase, m) + deviceSupported := false + hostSupported := false + + for _, variant := range member.Variants() { + osClass := variant.Target().Os.Class + if osClass == android.Host || osClass == android.HostCross { + hostSupported = true + } else if osClass == android.Device { + deviceSupported = true + } + } + + addHostDeviceSupportedProperties(deviceSupported, hostSupported, m) // Where available copy apex_available properties from the member. if apexAware, ok := variant.(interface{ ApexAvailable() []string }); ok { @@ -588,11 +636,11 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType return m } -func addHostDeviceSupportedProperties(module *android.ModuleBase, bpModule *bpModule) { - if !module.DeviceSupported() { +func addHostDeviceSupportedProperties(deviceSupported bool, hostSupported bool, bpModule *bpModule) { + if !deviceSupported { bpModule.AddProperty("device_supported", false) } - if module.HostSupported() { + if hostSupported { bpModule.AddProperty("host_supported", true) } }