Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 865171ed authored by Paul Duffin's avatar Paul Duffin
Browse files

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
parent 04c93a40
Loading
Loading
Loading
Loading
+123 −0
Original line number Diff line number Diff line
@@ -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
`),
	)
}
+1 −0
Original line number Diff line number Diff line
@@ -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
+59 −11
Original line number Diff line number Diff line
@@ -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)
	}
}