Merge "Refactor the build rules for ABI diff"

This commit is contained in:
Hsin-Yi Chen
2022-12-01 02:21:07 +00:00
committed by Gerrit Code Review
3 changed files with 98 additions and 106 deletions

View File

@@ -227,27 +227,17 @@ func (library *libraryDecorator) androidMkWriteExportedFlags(entries *android.An
} }
} }
func (library *libraryDecorator) getAbiDiffsForAndroidMkDeps() []string {
if library.static() {
return nil
}
var abiDiffs []string
if library.sAbiDiff.Valid() {
abiDiffs = append(abiDiffs, library.sAbiDiff.String())
}
if library.prevSAbiDiff.Valid() {
abiDiffs = append(abiDiffs, library.prevSAbiDiff.String())
}
return abiDiffs
}
func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) { func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) {
entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", library.getAbiDiffsForAndroidMkDeps()...) if !library.static() {
entries.AddPaths("LOCAL_ADDITIONAL_DEPENDENCIES", library.sAbiDiff)
}
} }
// TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries // TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries
func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) { func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.getAbiDiffsForAndroidMkDeps(), " ")) if !library.static() {
fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.sAbiDiff.Strings(), " "))
}
} }
func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {

View File

@@ -923,47 +923,17 @@ func unzipRefDump(ctx android.ModuleContext, zippedRefDump android.Path, baseNam
return outputFile return outputFile
} }
// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump). func transformAbiDumpToAbiDiff(ctx android.ModuleContext, inputDump, referenceDump android.Path,
func sourceAbiDiff(ctx android.ModuleContext, inputDump, referenceDump android.Path, baseName, nameExt string, extraFlags []string, errorMessage string) android.Path {
baseName string, diffFlags []string, prevVersion int,
checkAllApis, isLlndkOrNdk, isVndkExt, previousVersionDiff bool) android.OptionalPath {
var outputFile android.ModuleOutPath var outputFile android.ModuleOutPath
if previousVersionDiff { if nameExt != "" {
outputFile = android.PathForModuleOut(ctx, baseName+"."+strconv.Itoa(prevVersion)+".abidiff") outputFile = android.PathForModuleOut(ctx, baseName+"."+nameExt+".abidiff")
} else { } else {
outputFile = android.PathForModuleOut(ctx, baseName+".abidiff") outputFile = android.PathForModuleOut(ctx, baseName+".abidiff")
} }
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName)) libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
var extraFlags []string
if checkAllApis {
extraFlags = append(extraFlags, "-check-all-apis")
} else {
extraFlags = append(extraFlags,
"-allow-unreferenced-changes",
"-allow-unreferenced-elf-symbol-changes")
}
var errorMessage string
if previousVersionDiff {
errorMessage = "error: Please follow https://android.googlesource.com/platform/development/+/master/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the ABI difference between your source code and version " + strconv.Itoa(prevVersion) + "."
sourceVersion := prevVersion + 1
extraFlags = append(extraFlags, "-target-version", strconv.Itoa(sourceVersion))
} else {
errorMessage = "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
extraFlags = append(extraFlags, "-target-version", "current")
}
if isLlndkOrNdk {
extraFlags = append(extraFlags, "-consider-opaque-types-different")
}
if isVndkExt || previousVersionDiff {
extraFlags = append(extraFlags, "-allow-extensions")
}
// TODO(b/232891473): Simplify the above logic with diffFlags.
extraFlags = append(extraFlags, diffFlags...)
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: sAbiDiff, Rule: sAbiDiff,
Description: "header-abi-diff " + outputFile.Base(), Description: "header-abi-diff " + outputFile.Base(),
@@ -978,7 +948,7 @@ func sourceAbiDiff(ctx android.ModuleContext, inputDump, referenceDump android.P
"errorMessage": errorMessage, "errorMessage": errorMessage,
}, },
}) })
return android.OptionalPathForPath(outputFile) return outputFile
} }
// Generate a rule for extracting a table of contents from a shared library (.so) // Generate a rule for extracting a table of contents from a shared library (.so)

View File

@@ -804,10 +804,7 @@ type libraryDecorator struct {
sAbiOutputFile android.OptionalPath sAbiOutputFile android.OptionalPath
// Source Abi Diff // Source Abi Diff
sAbiDiff android.OptionalPath sAbiDiff android.Paths
// Source Abi Diff against previous SDK version
prevSAbiDiff android.OptionalPath
// Location of the static library in the sysroot. Empty if the library is // Location of the static library in the sysroot. Empty if the library is
// not included in the NDK. // not included in the NDK.
@@ -1797,10 +1794,10 @@ func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath {
return library.coverageOutputFile return library.coverageOutputFile
} }
// pathForVndkRefAbiDump returns an OptionalPath representing the path of the // pathForRefAbiDump returns an OptionalPath representing the path of the
// reference abi dump for the given module. This is not guaranteed to be valid. // reference abi dump for the given module. This is not guaranteed to be valid.
func pathForVndkRefAbiDump(ctx android.ModuleInstallPathContext, version, fileName string, func pathForRefAbiDump(ctx android.ModuleInstallPathContext,
isNdk, isVndk, isGzip bool) android.OptionalPath { versionedDumpDir, fileName string, isGzip bool) android.OptionalPath {
currentArchType := ctx.Arch().ArchType currentArchType := ctx.Arch().ArchType
primaryArchType := ctx.Config().DevicePrimaryArchType() primaryArchType := ctx.Config().DevicePrimaryArchType()
@@ -1809,17 +1806,6 @@ func pathForVndkRefAbiDump(ctx android.ModuleInstallPathContext, version, fileNa
archName += "_" + primaryArchType.String() archName += "_" + primaryArchType.String()
} }
var dirName string
if isNdk {
dirName = "ndk"
} else if isVndk {
dirName = "vndk"
} else {
dirName = "platform" // opt-in libs
}
binderBitness := ctx.DeviceConfig().BinderBitness()
var ext string var ext string
if isGzip { if isGzip {
ext = ".lsdump.gz" ext = ".lsdump.gz"
@@ -1827,18 +1813,25 @@ func pathForVndkRefAbiDump(ctx android.ModuleInstallPathContext, version, fileNa
ext = ".lsdump" ext = ".lsdump"
} }
return android.ExistentPathForSource(ctx, "prebuilts", "abi-dumps", dirName, return android.ExistentPathForSource(ctx, versionedDumpDir, archName, "source-based",
version, binderBitness, archName, "source-based",
fileName+ext) fileName+ext)
} }
func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path { func getRefAbiDumpDir(isNdk, isVndk bool) string {
// The logic must be consistent with classifySourceAbiDump. var dirName string
isNdk := ctx.isNdk(ctx.Config()) if isNdk {
isVndk := ctx.useVndk() && ctx.isVndk() dirName = "ndk"
} else if isVndk {
dirName = "vndk"
} else {
dirName = "platform"
}
return filepath.Join("prebuilts", "abi-dumps", dirName)
}
refAbiDumpTextFile := pathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isVndk, false) func getRefAbiDumpFile(ctx ModuleContext, versionedDumpDir, fileName string) android.Path {
refAbiDumpGzipFile := pathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isVndk, true) refAbiDumpTextFile := pathForRefAbiDump(ctx, versionedDumpDir, fileName, /* isGzip */ false)
refAbiDumpGzipFile := pathForRefAbiDump(ctx, versionedDumpDir, fileName, /* isGzip */ true)
if refAbiDumpTextFile.Valid() { if refAbiDumpTextFile.Valid() {
if refAbiDumpGzipFile.Valid() { if refAbiDumpGzipFile.Valid() {
@@ -1855,27 +1848,18 @@ func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.
return nil return nil
} }
func prevDumpRefVersion(ctx ModuleContext) int { func prevRefAbiDumpVersion(ctx ModuleContext, dumpDir string) int {
sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt() sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt()
sdkVersionStr := ctx.Config().PlatformSdkVersion().String() sdkVersionStr := ctx.Config().PlatformSdkVersion().String()
if ctx.Config().PlatformSdkFinal() { if ctx.Config().PlatformSdkFinal() {
return sdkVersionInt - 1 return sdkVersionInt - 1
} else { } else {
var dirName string
isNdk := ctx.isNdk(ctx.Config())
if isNdk {
dirName = "ndk"
} else {
dirName = "platform"
}
// The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't // The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't
// been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version. // been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version.
// This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory. // This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory.
refDumpDir := android.ExistentPathForSource(ctx, "prebuilts", "abi-dumps", dirName, sdkVersionStr) versionedDumpDir := android.ExistentPathForSource(ctx, dumpDir, sdkVersionStr)
if refDumpDir.Valid() { if versionedDumpDir.Valid() {
return sdkVersionInt return sdkVersionInt
} else { } else {
return sdkVersionInt - 1 return sdkVersionInt - 1
@@ -1896,6 +1880,54 @@ func currRefAbiDumpVersion(ctx ModuleContext, isVndk bool) string {
} }
} }
// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
baseName, nameExt string, isLlndkOrNdk, allowExtensions bool,
sourceVersion, errorMessage string) {
sourceDump := library.sAbiOutputFile.Path()
extraFlags := []string{"-target-version", sourceVersion}
if Bool(library.Properties.Header_abi_checker.Check_all_apis) {
extraFlags = append(extraFlags, "-check-all-apis")
} else {
extraFlags = append(extraFlags,
"-allow-unreferenced-changes",
"-allow-unreferenced-elf-symbol-changes")
}
if isLlndkOrNdk {
extraFlags = append(extraFlags, "-consider-opaque-types-different")
}
if allowExtensions {
extraFlags = append(extraFlags, "-allow-extensions")
}
extraFlags = append(extraFlags, library.Properties.Header_abi_checker.Diff_flags...)
library.sAbiDiff = append(
library.sAbiDiff,
transformAbiDumpToAbiDiff(ctx, sourceDump, referenceDump,
baseName, nameExt, extraFlags, errorMessage))
}
func (library *libraryDecorator) crossVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
baseName string, isLlndkOrNdk bool, sourceVersion, prevVersion string) {
errorMessage := "error: Please follow https://android.googlesource.com/platform/development/+/master/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the ABI difference between your source code and version " + prevVersion + "."
library.sourceAbiDiff(ctx, referenceDump, baseName, prevVersion,
isLlndkOrNdk, /* allowExtensions */ true, sourceVersion, errorMessage)
}
func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
baseName string, isLlndkOrNdk, allowExtensions bool) {
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
library.sourceAbiDiff(ctx, referenceDump, baseName, /* nameExt */ "",
isLlndkOrNdk, allowExtensions, "current", errorMessage)
}
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) { func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
if library.sabi.shouldCreateSourceAbiDump() { if library.sabi.shouldCreateSourceAbiDump() {
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
@@ -1914,31 +1946,31 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String()) addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String())
// The logic must be consistent with classifySourceAbiDump.
isVndk := ctx.useVndk() && ctx.isVndk() isVndk := ctx.useVndk() && ctx.isVndk()
isNdk := ctx.isNdk(ctx.Config()) isNdk := ctx.isNdk(ctx.Config())
isLlndk := ctx.isImplementationForLLNDKPublic() isLlndk := ctx.isImplementationForLLNDKPublic()
dumpDir := getRefAbiDumpDir(isNdk, isVndk)
binderBitness := ctx.DeviceConfig().BinderBitness()
// If NDK or PLATFORM library, check against previous version ABI. // If NDK or PLATFORM library, check against previous version ABI.
if !isVndk { if !isVndk {
prevVersion := prevDumpRefVersion(ctx) prevVersionInt := prevRefAbiDumpVersion(ctx, dumpDir)
prevRefAbiDumpFile := getRefAbiDumpFile(ctx, strconv.Itoa(prevVersion), fileName) prevVersion := strconv.Itoa(prevVersionInt)
if prevRefAbiDumpFile != nil { prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness)
library.prevSAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(), prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName)
prevRefAbiDumpFile, fileName, if prevDumpFile != nil {
library.Properties.Header_abi_checker.Diff_flags, prevVersion, library.crossVersionAbiDiff(ctx, prevDumpFile,
Bool(library.Properties.Header_abi_checker.Check_all_apis), fileName, isLlndk || isNdk,
isLlndk || isNdk, ctx.IsVndkExt(), true) strconv.Itoa(prevVersionInt+1), prevVersion)
} }
} }
// Check against the current version.
currVersion := currRefAbiDumpVersion(ctx, isVndk) currVersion := currRefAbiDumpVersion(ctx, isVndk)
refAbiDumpFile := getRefAbiDumpFile(ctx, currVersion, fileName) currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness)
if refAbiDumpFile != nil { currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName)
library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(), if currDumpFile != nil {
refAbiDumpFile, fileName, library.sameVersionAbiDiff(ctx, currDumpFile,
library.Properties.Header_abi_checker.Diff_flags, fileName, isLlndk || isNdk, ctx.IsVndkExt())
/* unused if not previousVersionDiff */ 0,
Bool(library.Properties.Header_abi_checker.Check_all_apis),
isLlndk || isNdk, ctx.IsVndkExt(), false)
} }
} }
} }