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
This commit is contained in:
Paul Duffin 2019-12-11 18:42:17 +00:00
parent c62a5107f8
commit 9ab556fd8e
4 changed files with 278 additions and 55 deletions

View File

@ -1438,9 +1438,21 @@ func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.Modu
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 {
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) {
@ -1451,11 +1463,13 @@ func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorCont
if version == "" {
version = LatestStubsVersionFor(mctx.Config(), name)
}
mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
{Mutator: "image", Variation: android.CoreVariation},
{Mutator: "link", Variation: "shared"},
{Mutator: "version", Variation: version},
}...), dependencyTag, name)
for _, linkType := range mt.linkTypes {
mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
{Mutator: "image", Variation: android.CoreVariation},
{Mutator: "link", Variation: linkType},
{Mutator: "version", Variation: version},
}...), dependencyTag, name)
}
}
}
}
@ -1467,10 +1481,50 @@ func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
// copy exported header files and stub *.so files
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)
}
// 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) {
// a function for emitting include dirs
printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
@ -1515,7 +1569,7 @@ func buildSharedNativeLibSnapshot(sdkModuleContext android.ModuleContext, info *
// for each architecture
for _, av := range info.archVariants {
builder.CopyToSnapshot(av.outputFile, nativeStubFilePathFor(av))
builder.CopyToSnapshot(av.outputFile, nativeLibraryPathFor(av))
if info.hasArchSpecificFlags {
printExportedDirCopyCommandsForNativeLibs(av)
@ -1542,7 +1596,7 @@ func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.Modu
properties.AddProperty(propertyName, includeDirs)
}
pbm := builder.AddPrebuiltModule(member, "cc_prebuilt_library_shared")
pbm := builder.AddPrebuiltModule(member, info.memberType.prebuiltModuleType)
if !info.hasArchSpecificFlags {
addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
@ -1552,7 +1606,7 @@ func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.Modu
archProperties := pbm.AddPropertySet("arch")
for _, av := range info.archVariants {
archTypeProperties := archProperties.AddPropertySet(av.archType)
archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
archTypeProperties.AddProperty("srcs", []string{nativeLibraryPathFor(av)})
if info.hasArchSpecificFlags {
// export_* properties are added inside the arch: {<arch>: {...}} block
addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
@ -1567,13 +1621,12 @@ const (
nativeIncludeDir = "include"
nativeGeneratedIncludeDir = "include_gen"
nativeStubDir = "lib"
nativeStubFileSuffix = ".so"
)
// path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir>
func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string {
// path to the native library. Relative to <sdk_root>/<api_dir>
func nativeLibraryPathFor(lib archSpecificNativeLibInfo) string {
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>
@ -1622,45 +1675,9 @@ func (lib *archSpecificNativeLibInfo) signature() string {
// nativeLibInfo represents a collection of arch-specific modules having the same name
type nativeLibInfo struct {
name string
memberType *librarySdkMemberType
archVariants []archSpecificNativeLibInfo
// 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.
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
}

View File

@ -181,7 +181,7 @@ include/Test.h -> include/include/Test.h
)
}
func TestSnapshotWithCcShared(t *testing.T) {
func TestSnapshotWithCcSharedLibrary(t *testing.T) {
result := testSdkWithCc(t, `
sdk {
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.
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
`),
)
}

View File

@ -63,9 +63,12 @@ type sdk struct {
type sdkProperties struct {
// 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
// The list of static native libraries in this SDK
Native_static_libs []string
// For module types from the java package
// The list of java header libraries in this SDK
@ -114,7 +117,12 @@ var sdkMemberListProperties = []*sdkMemberListProperty{
{
name: "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.
{

View File

@ -59,6 +59,7 @@ func testSdkContext(bp string, fs map[string][]byte) (*android.TestContext, andr
// from cc package
ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory)
ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
ctx.RegisterModuleType("cc_prebuilt_library_shared", cc.PrebuiltSharedLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)