Simplify cc library sdk snapshot handling of include dirs/headers

Previously, the code for generating a snapshot of a cc library was
split into two separate phases. The first phase copied the files that
needed copying and the second phase added the properties for the
include dirs. This separation made it difficult to make sure that the
two phases were in sync.

This change merges those two phases together so the same paths used to
copy the files are used in the properties ensuring consistency. As the
various type of include dir and header were treated slightly different
to each other this parameterizes that behavior.

Bug: 142935992
Test: m nothing
Change-Id: I7877464987bbdae9662e5e3f02bb5e5a75dca5a3
This commit is contained in:
Paul Duffin 2020-02-20 14:33:54 +00:00
parent 180a006a3b
commit 64f54b0ae8
1 changed files with 121 additions and 87 deletions

View File

@ -92,7 +92,7 @@ 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 := mt.organizeVariants(member)
buildSharedNativeLibSnapshot(sdkModuleContext, info, builder, member)
info.generatePrebuiltLibrary(sdkModuleContext, builder, member)
}
// Organize the variants by architecture.
@ -197,85 +197,144 @@ func extractCommonProperties(commonProperties interface{}, inputPropertiesSlice
}
}
func buildSharedNativeLibSnapshot(sdkModuleContext android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder, member android.SdkMember) {
// a function for emitting include dirs
addExportedDirCopyCommandsForNativeLibs := func(lib nativeLibInfoProperties) {
// Do not include exportedGeneratedIncludeDirs in the list of directories whose
// contents are copied as they are copied from exportedGeneratedHeaders below.
includeDirs := lib.ExportedIncludeDirs
includeDirs = append(includeDirs, lib.ExportedSystemIncludeDirs...)
for _, dir := range includeDirs {
// lib.ArchType is "" for common properties.
targetDir := filepath.Join(lib.archType, nativeIncludeDir)
// TODO(jiyong) copy headers having other suffixes
headers, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.h", nil)
for _, file := range headers {
src := android.PathForSource(sdkModuleContext, file)
dest := filepath.Join(targetDir, file)
builder.CopyToSnapshot(src, dest)
}
}
genHeaders := lib.exportedGeneratedHeaders
for _, file := range genHeaders {
// lib.ArchType is "" for common properties.
targetDir := filepath.Join(lib.archType, nativeGeneratedIncludeDir)
dest := filepath.Join(targetDir, lib.name, file.Rel())
builder.CopyToSnapshot(file, dest)
}
}
addExportedDirCopyCommandsForNativeLibs(info.commonProperties)
// for each architecture
for _, av := range info.archVariantProperties {
builder.CopyToSnapshot(av.outputFile, nativeLibraryPathFor(av))
addExportedDirCopyCommandsForNativeLibs(av)
}
info.generatePrebuiltLibrary(sdkModuleContext, builder, member)
}
func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
pbm := builder.AddPrebuiltModule(member, info.memberType.prebuiltModuleType)
addPossiblyArchSpecificProperties(info.commonProperties, pbm)
addPossiblyArchSpecificProperties(sdkModuleContext, builder, info.commonProperties, pbm)
archProperties := pbm.AddPropertySet("arch")
for _, av := range info.archVariantProperties {
archTypeProperties := archProperties.AddPropertySet(av.archType)
// Add any arch specific properties inside the appropriate arch: {<arch>: {...}} block
archTypeProperties.AddProperty("srcs", []string{nativeLibraryPathFor(av)})
addPossiblyArchSpecificProperties(av, archTypeProperties)
// Copy the generated library to the snapshot and add a reference to it in the .bp module.
nativeLibraryPath := nativeLibraryPathFor(av)
builder.CopyToSnapshot(av.outputFile, nativeLibraryPath)
archTypeProperties.AddProperty("srcs", []string{nativeLibraryPath})
// Add any arch specific properties inside the appropriate arch: {<arch>: {...}} block
addPossiblyArchSpecificProperties(sdkModuleContext, builder, av, archTypeProperties)
}
pbm.AddProperty("stl", "none")
pbm.AddProperty("system_shared_libs", []string{})
}
// Add properties that may, or may not, be arch specific.
func addPossiblyArchSpecificProperties(libInfo nativeLibInfoProperties, outputProperties android.BpPropertySet) {
addExportedDirsForNativeLibs(libInfo, outputProperties, false /*systemInclude*/)
addExportedDirsForNativeLibs(libInfo, outputProperties, true /*systemInclude*/)
type includeDirsProperty struct {
// Accessor to retrieve the paths
pathsGetter func(libInfo nativeLibInfoProperties) android.Paths
// The name of the property in the prebuilt library, "" means there is no property.
propertyName string
// The directory within the snapshot directory into which items should be copied.
snapshotDir string
// True if the items on the path should be copied.
copy bool
// True if the paths represent directories, files if they represent files.
dirs bool
}
// a function for emitting include dirs
func addExportedDirsForNativeLibs(lib nativeLibInfoProperties, properties android.BpPropertySet, systemInclude bool) {
includeDirs := nativeIncludeDirPathsFor(lib, systemInclude)
if len(includeDirs) == 0 {
return
var includeDirProperties = []includeDirsProperty{
{
// ExportedIncludeDirs lists directories that contains some header files to be
// copied into a directory in the snapshot. The snapshot directories must be added to
// the export_include_dirs property in the prebuilt module in the snapshot.
pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.ExportedIncludeDirs },
propertyName: "export_include_dirs",
snapshotDir: nativeIncludeDir,
copy: true,
dirs: true,
},
{
// ExportedSystemIncludeDirs lists directories that contains some system header files to
// be copied into a directory in the snapshot. The snapshot directories must be added to
// the export_system_include_dirs property in the prebuilt module in the snapshot.
pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.ExportedSystemIncludeDirs },
propertyName: "export_system_include_dirs",
snapshotDir: nativeIncludeDir,
copy: true,
dirs: true,
},
{
// exportedGeneratedIncludeDirs lists directories that contains some header files
// that are explicitly listed in the exportedGeneratedHeaders property. So, the contents
// of these directories do not need to be copied, but these directories do need adding to
// the export_include_dirs property in the prebuilt module in the snapshot.
pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.exportedGeneratedIncludeDirs },
propertyName: "export_include_dirs",
snapshotDir: nativeGeneratedIncludeDir,
copy: false,
dirs: true,
},
{
// exportedGeneratedHeaders lists header files that are in one of the directories
// specified in exportedGeneratedIncludeDirs must be copied into the snapshot.
// As they are in a directory in exportedGeneratedIncludeDirs they do not need adding to a
// property in the prebuilt module in the snapshot.
pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.exportedGeneratedHeaders },
propertyName: "",
snapshotDir: nativeGeneratedIncludeDir,
copy: true,
dirs: false,
},
}
// Add properties that may, or may not, be arch specific.
func addPossiblyArchSpecificProperties(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, libInfo nativeLibInfoProperties, outputProperties android.BpPropertySet) {
// Map from property name to the include dirs to add to the prebuilt module in the snapshot.
includeDirs := make(map[string][]string)
// Iterate over each include directory property, copying files and collating property
// values where necessary.
for _, propertyInfo := range includeDirProperties {
// Calculate the base directory in the snapshot into which the files will be copied.
// lib.ArchType is "" for common properties.
targetDir := filepath.Join(libInfo.archType, propertyInfo.snapshotDir)
propertyName := propertyInfo.propertyName
// Iterate over each path in one of the include directory properties.
for _, path := range propertyInfo.pathsGetter(libInfo) {
// Copy the files/directories when necessary.
if propertyInfo.copy {
if propertyInfo.dirs {
// When copying a directory glob and copy all the headers within it.
// TODO(jiyong) copy headers having other suffixes
headers, _ := sdkModuleContext.GlobWithDeps(path.String()+"/**/*.h", nil)
for _, file := range headers {
src := android.PathForSource(sdkModuleContext, file)
dest := filepath.Join(targetDir, file)
builder.CopyToSnapshot(src, dest)
}
} else {
// Otherwise, just copy the files.
dest := filepath.Join(targetDir, libInfo.name, path.Rel())
builder.CopyToSnapshot(path, dest)
}
}
// Only directories are added to a property.
if propertyInfo.dirs {
var snapshotPath string
if isGeneratedHeaderDirectory(path) {
snapshotPath = filepath.Join(targetDir, libInfo.name)
} else {
snapshotPath = filepath.Join(targetDir, path.String())
}
includeDirs[propertyName] = append(includeDirs[propertyName], snapshotPath)
}
}
}
var propertyName string
if !systemInclude {
propertyName = "export_include_dirs"
} else {
propertyName = "export_system_include_dirs"
// Add the collated include dir properties to the output.
for property, dirs := range includeDirs {
outputProperties.AddProperty(property, dirs)
}
properties.AddProperty(propertyName, includeDirs)
}
const (
@ -290,31 +349,6 @@ func nativeLibraryPathFor(lib nativeLibInfoProperties) string {
nativeStubDir, lib.outputFile.Base())
}
// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
func nativeIncludeDirPathsFor(lib nativeLibInfoProperties, systemInclude bool) []string {
var result []string
var includeDirs []android.Path
if !systemInclude {
// Include the generated include dirs in the exported include dirs.
includeDirs = append(lib.ExportedIncludeDirs, lib.exportedGeneratedIncludeDirs...)
} else {
includeDirs = lib.ExportedSystemIncludeDirs
}
for _, dir := range includeDirs {
var path string
if isGeneratedHeaderDirectory(dir) {
path = filepath.Join(nativeGeneratedIncludeDir, lib.name)
} else {
path = filepath.Join(nativeIncludeDir, dir.String())
}
// lib.ArchType is "" for common properties.
path = filepath.Join(lib.archType, path)
result = append(result, path)
}
return result
}
// nativeLibInfoProperties represents properties of a native lib
//
// The exported (capitalized) fields will be examined and may be changed during common value extraction.