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

Commit 9ab556fd authored by Paul Duffin's avatar Paul Duffin
Browse files

Added support for using static libraries in sdk snapshot

Parameterized the cc.librarySdkMemberType to allow it to support
both static and shared libraries. Created two instances, one for shared
and one for static libraries. A follow up change will add support for
libraries that can be both.

Added *librarySdkMemberType to nativeMemberInfo as information from
there is needed when generating the snapshot.

Made organizeVariants() func a method of *librarySdkMemberType so that
it can initialize the new field. Moved it to be with all the other
methods of that type.

Added host and device tests for the new module type.

Bug: 142918168
Test: m nothing
Change-Id: I00b1e8424b9d81f7d15edc4883971d10668ec2cc
parent c62a5107
Loading
Loading
Loading
Loading
+68 −51
Original line number Original line Diff line number Diff line
@@ -1438,9 +1438,21 @@ func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.Modu
	return outputFile
	return outputFile
}
}


var LibrarySdkMemberType = &librarySdkMemberType{}
var SharedLibrarySdkMemberType = &librarySdkMemberType{
	prebuiltModuleType: "cc_prebuilt_library_shared",
	linkTypes:          []string{"shared"},
}

var StaticLibrarySdkMemberType = &librarySdkMemberType{
	prebuiltModuleType: "cc_prebuilt_library_static",
	linkTypes:          []string{"static"},
}


type librarySdkMemberType struct {
type librarySdkMemberType struct {
	prebuiltModuleType string

	// The set of link types supported, set of "static", "shared".
	linkTypes []string
}
}


func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
@@ -1451,14 +1463,16 @@ func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorCont
			if version == "" {
			if version == "" {
				version = LatestStubsVersionFor(mctx.Config(), name)
				version = LatestStubsVersionFor(mctx.Config(), name)
			}
			}
			for _, linkType := range mt.linkTypes {
				mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
				mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
					{Mutator: "image", Variation: android.CoreVariation},
					{Mutator: "image", Variation: android.CoreVariation},
				{Mutator: "link", Variation: "shared"},
					{Mutator: "link", Variation: linkType},
					{Mutator: "version", Variation: version},
					{Mutator: "version", Variation: version},
				}...), dependencyTag, name)
				}...), dependencyTag, name)
			}
			}
		}
		}
	}
	}
}


func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
	_, ok := module.(*Module)
	_, ok := module.(*Module)
@@ -1467,10 +1481,50 @@ func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {


// copy exported header files and stub *.so files
// copy exported header files and stub *.so files
func (mt *librarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
func (mt *librarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
	info := organizeVariants(member)
	info := mt.organizeVariants(member)
	buildSharedNativeLibSnapshot(sdkModuleContext, info, builder, member)
	buildSharedNativeLibSnapshot(sdkModuleContext, info, builder, member)
}
}


// Organize the variants by architecture.
func (mt *librarySdkMemberType) organizeVariants(member android.SdkMember) *nativeLibInfo {
	info := &nativeLibInfo{
		name:       member.Name(),
		memberType: mt,
	}

	for _, variant := range member.Variants() {
		ccModule := variant.(*Module)

		info.archVariants = append(info.archVariants, archSpecificNativeLibInfo{
			name:                      ccModule.BaseModuleName(),
			archType:                  ccModule.Target().Arch.ArchType.String(),
			exportedIncludeDirs:       ccModule.ExportedIncludeDirs(),
			exportedSystemIncludeDirs: ccModule.ExportedSystemIncludeDirs(),
			exportedFlags:             ccModule.ExportedFlags(),
			exportedGeneratedHeaders:  ccModule.ExportedGeneratedHeaders(),
			outputFile:                ccModule.OutputFile().Path(),
		})
	}

	// Determine if include dirs and flags for each variant are different across arch-specific
	// variants or not. And set hasArchSpecificFlags accordingly
	// by default, include paths and flags are assumed to be the same across arches
	info.hasArchSpecificFlags = false
	oldSignature := ""
	for _, av := range info.archVariants {
		newSignature := av.signature()
		if oldSignature == "" {
			oldSignature = newSignature
		}
		if oldSignature != newSignature {
			info.hasArchSpecificFlags = true
			break
		}
	}

	return info
}

func buildSharedNativeLibSnapshot(sdkModuleContext android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder, member android.SdkMember) {
func buildSharedNativeLibSnapshot(sdkModuleContext android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder, member android.SdkMember) {
	// a function for emitting include dirs
	// a function for emitting include dirs
	printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
	printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
@@ -1515,7 +1569,7 @@ func buildSharedNativeLibSnapshot(sdkModuleContext android.ModuleContext, info *


	// for each architecture
	// for each architecture
	for _, av := range info.archVariants {
	for _, av := range info.archVariants {
		builder.CopyToSnapshot(av.outputFile, nativeStubFilePathFor(av))
		builder.CopyToSnapshot(av.outputFile, nativeLibraryPathFor(av))


		if info.hasArchSpecificFlags {
		if info.hasArchSpecificFlags {
			printExportedDirCopyCommandsForNativeLibs(av)
			printExportedDirCopyCommandsForNativeLibs(av)
@@ -1542,7 +1596,7 @@ func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.Modu
		properties.AddProperty(propertyName, includeDirs)
		properties.AddProperty(propertyName, includeDirs)
	}
	}


	pbm := builder.AddPrebuiltModule(member, "cc_prebuilt_library_shared")
	pbm := builder.AddPrebuiltModule(member, info.memberType.prebuiltModuleType)


	if !info.hasArchSpecificFlags {
	if !info.hasArchSpecificFlags {
		addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
		addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
@@ -1552,7 +1606,7 @@ func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.Modu
	archProperties := pbm.AddPropertySet("arch")
	archProperties := pbm.AddPropertySet("arch")
	for _, av := range info.archVariants {
	for _, av := range info.archVariants {
		archTypeProperties := archProperties.AddPropertySet(av.archType)
		archTypeProperties := archProperties.AddPropertySet(av.archType)
		archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
		archTypeProperties.AddProperty("srcs", []string{nativeLibraryPathFor(av)})
		if info.hasArchSpecificFlags {
		if info.hasArchSpecificFlags {
			// export_* properties are added inside the arch: {<arch>: {...}} block
			// export_* properties are added inside the arch: {<arch>: {...}} block
			addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
			addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
@@ -1567,13 +1621,12 @@ const (
	nativeIncludeDir          = "include"
	nativeIncludeDir          = "include"
	nativeGeneratedIncludeDir = "include_gen"
	nativeGeneratedIncludeDir = "include_gen"
	nativeStubDir             = "lib"
	nativeStubDir             = "lib"
	nativeStubFileSuffix      = ".so"
)
)


// path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir>
// path to the native library. Relative to <sdk_root>/<api_dir>
func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string {
func nativeLibraryPathFor(lib archSpecificNativeLibInfo) string {
	return filepath.Join(lib.archType,
	return filepath.Join(lib.archType,
		nativeStubDir, lib.name+nativeStubFileSuffix)
		nativeStubDir, lib.outputFile.Base())
}
}


// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
@@ -1622,45 +1675,9 @@ func (lib *archSpecificNativeLibInfo) signature() string {
// nativeLibInfo represents a collection of arch-specific modules having the same name
// nativeLibInfo represents a collection of arch-specific modules having the same name
type nativeLibInfo struct {
type nativeLibInfo struct {
	name         string
	name         string
	memberType   *librarySdkMemberType
	archVariants []archSpecificNativeLibInfo
	archVariants []archSpecificNativeLibInfo
	// hasArchSpecificFlags is set to true if modules for each architecture all have the same
	// hasArchSpecificFlags is set to true if modules for each architecture all have the same
	// include dirs, flags, etc, in which case only those of the first arch is selected.
	// include dirs, flags, etc, in which case only those of the first arch is selected.
	hasArchSpecificFlags bool
	hasArchSpecificFlags bool
}
}

// Organize the variants by architecture.
func organizeVariants(member android.SdkMember) *nativeLibInfo {
	info := &nativeLibInfo{name: member.Name()}

	for _, variant := range member.Variants() {
		ccModule := variant.(*Module)

		info.archVariants = append(info.archVariants, archSpecificNativeLibInfo{
			name:                      ccModule.BaseModuleName(),
			archType:                  ccModule.Target().Arch.ArchType.String(),
			exportedIncludeDirs:       ccModule.ExportedIncludeDirs(),
			exportedSystemIncludeDirs: ccModule.ExportedSystemIncludeDirs(),
			exportedFlags:             ccModule.ExportedFlags(),
			exportedGeneratedHeaders:  ccModule.ExportedGeneratedHeaders(),
			outputFile:                ccModule.OutputFile().Path(),
		})
	}

	// Determine if include dirs and flags for each variant are different across arch-specific
	// variants or not. And set hasArchSpecificFlags accordingly
	// by default, include paths and flags are assumed to be the same across arches
	info.hasArchSpecificFlags = false
	oldSignature := ""
	for _, av := range info.archVariants {
		newSignature := av.signature()
		if oldSignature == "" {
			oldSignature = newSignature
		}
		if oldSignature != newSignature {
			info.hasArchSpecificFlags = true
			break
		}
	}

	return info
}
+199 −2
Original line number Original line Diff line number Diff line
@@ -181,7 +181,7 @@ include/Test.h -> include/include/Test.h
	)
	)
}
}


func TestSnapshotWithCcShared(t *testing.T) {
func TestSnapshotWithCcSharedLibrary(t *testing.T) {
	result := testSdkWithCc(t, `
	result := testSdkWithCc(t, `
		sdk {
		sdk {
			name: "mysdk",
			name: "mysdk",
@@ -273,7 +273,7 @@ include/Test.h -> arm/include/include/Test.h
	)
	)
}
}


func TestHostSnapshotWithCcShared(t *testing.T) {
func TestHostSnapshotWithCcSharedLibrary(t *testing.T) {
	// b/145598135 - Generating host snapshots for anything other than linux is not supported.
	// b/145598135 - Generating host snapshots for anything other than linux is not supported.
	SkipIfNotLinux(t)
	SkipIfNotLinux(t)


@@ -377,3 +377,200 @@ include/Test.h -> x86/include/include/Test.h
`),
`),
	)
	)
}
}

func TestSnapshotWithCcStaticLibrary(t *testing.T) {
	result := testSdkWithCc(t, `
		sdk {
			name: "mysdk",
			native_static_libs: ["mynativelib"],
		}

		cc_library_static {
			name: "mynativelib",
			srcs: [
				"Test.cpp",
				"aidl/foo/bar/Test.aidl",
			],
			export_include_dirs: ["include"],
			aidl: {
				export_aidl_headers: true,
			},
			system_shared_libs: [],
			stl: "none",
		}
	`)

	result.CheckSnapshot("mysdk", "android_common", "",
		checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.

cc_prebuilt_library_static {
    name: "mysdk_mynativelib@current",
    sdk_member_name: "mynativelib",
    arch: {
        arm64: {
            srcs: ["arm64/lib/mynativelib.a"],
            export_include_dirs: [
                "arm64/include/include",
                "arm64/include_gen/mynativelib",
            ],
        },
        arm: {
            srcs: ["arm/lib/mynativelib.a"],
            export_include_dirs: [
                "arm/include/include",
                "arm/include_gen/mynativelib",
            ],
        },
    },
    stl: "none",
    system_shared_libs: [],
}

cc_prebuilt_library_static {
    name: "mynativelib",
    prefer: false,
    arch: {
        arm64: {
            srcs: ["arm64/lib/mynativelib.a"],
            export_include_dirs: [
                "arm64/include/include",
                "arm64/include_gen/mynativelib",
            ],
        },
        arm: {
            srcs: ["arm/lib/mynativelib.a"],
            export_include_dirs: [
                "arm/include/include",
                "arm/include_gen/mynativelib",
            ],
        },
    },
    stl: "none",
    system_shared_libs: [],
}

sdk_snapshot {
    name: "mysdk@current",
    native_static_libs: ["mysdk_mynativelib@current"],
}
`),
		checkAllCopyRules(`
.intermediates/mynativelib/android_arm64_armv8-a_core_static/mynativelib.a -> arm64/lib/mynativelib.a
include/Test.h -> arm64/include/include/Test.h
.intermediates/mynativelib/android_arm64_armv8-a_core_static/gen/aidl/aidl/foo/bar/Test.h -> arm64/include_gen/mynativelib/aidl/foo/bar/Test.h
.intermediates/mynativelib/android_arm64_armv8-a_core_static/gen/aidl/aidl/foo/bar/BnTest.h -> arm64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
.intermediates/mynativelib/android_arm64_armv8-a_core_static/gen/aidl/aidl/foo/bar/BpTest.h -> arm64/include_gen/mynativelib/aidl/foo/bar/BpTest.h
.intermediates/mynativelib/android_arm_armv7-a-neon_core_static/mynativelib.a -> arm/lib/mynativelib.a
include/Test.h -> arm/include/include/Test.h
.intermediates/mynativelib/android_arm_armv7-a-neon_core_static/gen/aidl/aidl/foo/bar/Test.h -> arm/include_gen/mynativelib/aidl/foo/bar/Test.h
.intermediates/mynativelib/android_arm_armv7-a-neon_core_static/gen/aidl/aidl/foo/bar/BnTest.h -> arm/include_gen/mynativelib/aidl/foo/bar/BnTest.h
.intermediates/mynativelib/android_arm_armv7-a-neon_core_static/gen/aidl/aidl/foo/bar/BpTest.h -> arm/include_gen/mynativelib/aidl/foo/bar/BpTest.h
`),
	)
}

func TestHostSnapshotWithCcStaticLibrary(t *testing.T) {
	// b/145598135 - Generating host snapshots for anything other than linux is not supported.
	SkipIfNotLinux(t)

	result := testSdkWithCc(t, `
		sdk {
			name: "mysdk",
			device_supported: false,
			host_supported: true,
			native_static_libs: ["mynativelib"],
		}

		cc_library_static {
			name: "mynativelib",
			device_supported: false,
			host_supported: true,
			srcs: [
				"Test.cpp",
				"aidl/foo/bar/Test.aidl",
			],
			export_include_dirs: ["include"],
			aidl: {
				export_aidl_headers: true,
			},
			system_shared_libs: [],
			stl: "none",
		}
	`)

	result.CheckSnapshot("mysdk", "linux_glibc_common", "",
		checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.

cc_prebuilt_library_static {
    name: "mysdk_mynativelib@current",
    sdk_member_name: "mynativelib",
    device_supported: false,
    host_supported: true,
    arch: {
        x86_64: {
            srcs: ["x86_64/lib/mynativelib.a"],
            export_include_dirs: [
                "x86_64/include/include",
                "x86_64/include_gen/mynativelib",
            ],
        },
        x86: {
            srcs: ["x86/lib/mynativelib.a"],
            export_include_dirs: [
                "x86/include/include",
                "x86/include_gen/mynativelib",
            ],
        },
    },
    stl: "none",
    system_shared_libs: [],
}

cc_prebuilt_library_static {
    name: "mynativelib",
    prefer: false,
    device_supported: false,
    host_supported: true,
    arch: {
        x86_64: {
            srcs: ["x86_64/lib/mynativelib.a"],
            export_include_dirs: [
                "x86_64/include/include",
                "x86_64/include_gen/mynativelib",
            ],
        },
        x86: {
            srcs: ["x86/lib/mynativelib.a"],
            export_include_dirs: [
                "x86/include/include",
                "x86/include_gen/mynativelib",
            ],
        },
    },
    stl: "none",
    system_shared_libs: [],
}

sdk_snapshot {
    name: "mysdk@current",
    device_supported: false,
    host_supported: true,
    native_static_libs: ["mysdk_mynativelib@current"],
}
`),
		checkAllCopyRules(`
.intermediates/mynativelib/linux_glibc_x86_64_static/mynativelib.a -> x86_64/lib/mynativelib.a
include/Test.h -> x86_64/include/include/Test.h
.intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/Test.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h
.intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/BnTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
.intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/BpTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BpTest.h
.intermediates/mynativelib/linux_glibc_x86_static/mynativelib.a -> x86/lib/mynativelib.a
include/Test.h -> x86/include/include/Test.h
.intermediates/mynativelib/linux_glibc_x86_static/gen/aidl/aidl/foo/bar/Test.h -> x86/include_gen/mynativelib/aidl/foo/bar/Test.h
.intermediates/mynativelib/linux_glibc_x86_static/gen/aidl/aidl/foo/bar/BnTest.h -> x86/include_gen/mynativelib/aidl/foo/bar/BnTest.h
.intermediates/mynativelib/linux_glibc_x86_static/gen/aidl/aidl/foo/bar/BpTest.h -> x86/include_gen/mynativelib/aidl/foo/bar/BpTest.h
`),
	)
}
+10 −2
Original line number Original line Diff line number Diff line
@@ -63,9 +63,12 @@ type sdk struct {
type sdkProperties struct {
type sdkProperties struct {
	// For module types from the cc package
	// For module types from the cc package


	// The list of native libraries in this SDK
	// The list of shared native libraries in this SDK
	Native_shared_libs []string
	Native_shared_libs []string


	// The list of static native libraries in this SDK
	Native_static_libs []string

	// For module types from the java package
	// For module types from the java package


	// The list of java header libraries in this SDK
	// The list of java header libraries in this SDK
@@ -114,7 +117,12 @@ var sdkMemberListProperties = []*sdkMemberListProperty{
	{
	{
		name:       "native_shared_libs",
		name:       "native_shared_libs",
		getter:     func(properties *sdkProperties) []string { return properties.Native_shared_libs },
		getter:     func(properties *sdkProperties) []string { return properties.Native_shared_libs },
		memberType: cc.LibrarySdkMemberType,
		memberType: cc.SharedLibrarySdkMemberType,
	},
	{
		name:       "native_static_libs",
		getter:     func(properties *sdkProperties) []string { return properties.Native_static_libs },
		memberType: cc.StaticLibrarySdkMemberType,
	},
	},
	// Members from java package.
	// Members from java package.
	{
	{
+1 −0
Original line number Original line Diff line number Diff line
@@ -59,6 +59,7 @@ func testSdkContext(bp string, fs map[string][]byte) (*android.TestContext, andr
	// from cc package
	// from cc package
	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
	ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory)
	ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory)
	ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
	ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
	ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
	ctx.RegisterModuleType("cc_prebuilt_library_shared", cc.PrebuiltSharedLibraryFactory)
	ctx.RegisterModuleType("cc_prebuilt_library_shared", cc.PrebuiltSharedLibraryFactory)
	ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
	ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)