Filter ABI dumps by LLNDK headers and version scripts

This commit changes the parameters to create LLNDK ABI dumps for 202404
and later versions. Soong invokes header-abi-linker with LLNDK headers
and version script rather than the implementation library's parameters.
The output dump contains more precise ABI information.

When soong compares the ABI with the prebuilt dumps in old versions,
it creates the source ABI dumps with the old parameters.

Test: make findlsdumps
Bug: 314010764
Change-Id: I228736188d07029ee1588b3502fd7c0061c104b9
This commit is contained in:
Hsin-Yi Chen
2024-03-29 19:12:35 +08:00
parent d22fcc425e
commit 64b2d0389c
3 changed files with 102 additions and 15 deletions

View File

@@ -1409,6 +1409,11 @@ func (c *config) PrevVendorApiLevel() string {
return strconv.Itoa(vendorApiLevel - 100)
}
func IsTrunkStableVendorApiLevel(level string) bool {
levelInt, err := strconv.Atoi(level)
return err == nil && levelInt >= 202404
}
func (c *config) VendorApiLevelFrozen() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
}

View File

@@ -998,12 +998,30 @@ func TestLlndkLibrary(t *testing.T) {
expectedDirs, f.IncludeDirs)
}
checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include")
checkExportedIncludeDirs("libllndk", "android_vendor_arm64_armv8-a_shared", "include")
checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include")
checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor_arm64_armv8-a_shared", "include_llndk")
checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include")
checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor_arm64_armv8-a_shared", "include_llndk")
checkExportedIncludeDirs("libllndk", coreVariant, "include")
checkExportedIncludeDirs("libllndk", vendorVariant, "include")
checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, "include")
checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant, "include_llndk")
checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, "include")
checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, "include_llndk")
checkAbiLinkerIncludeDirs := func(module string) {
t.Helper()
coreModule := result.ModuleForTests(module, coreVariant)
abiCheckFlags := ""
for _, output := range coreModule.AllOutputs() {
if strings.HasSuffix(output, ".so.llndk.lsdump") {
abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
}
}
vendorModule := result.ModuleForTests(module, vendorVariant).Module()
vendorInfo, _ := android.SingletonModuleProvider(result, vendorModule, FlagExporterInfoProvider)
android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
android.JoinPathsWithPrefix(vendorInfo.IncludeDirs, "-I"), abiCheckFlags)
}
checkAbiLinkerIncludeDirs("libllndk")
checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
}
func TestLlndkHeaders(t *testing.T) {

View File

@@ -1153,7 +1153,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
library.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
library.linkSAbiDumpFiles(ctx, objs, fileName, unstrippedOutputFile)
library.linkSAbiDumpFiles(ctx, deps, objs, fileName, unstrippedOutputFile)
var transitiveStaticLibrariesForOrdering *android.DepSet[android.Path]
if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
@@ -1222,6 +1222,45 @@ func (library *libraryDecorator) exportedIncludeDirsForAbiCheck(ctx ModuleContex
return exportIncludeDirs
}
func (library *libraryDecorator) llndkIncludeDirsForAbiCheck(ctx ModuleContext, deps PathDeps) []string {
// The ABI checker does not need the preprocess which adds macro guards to function declarations.
includeDirs := android.PathsForModuleSrc(ctx, library.Properties.Llndk.Export_preprocessed_headers).Strings()
if library.Properties.Llndk.Override_export_include_dirs != nil {
includeDirs = append(includeDirs, android.PathsForModuleSrc(
ctx, library.Properties.Llndk.Override_export_include_dirs).Strings()...)
} else {
includeDirs = append(includeDirs, library.flagExporter.exportedIncludes(ctx).Strings()...)
// Ignore library.sabi.Properties.ReexportedIncludes because
// LLNDK does not reexport the implementation's dependencies, such as export_header_libs.
}
systemIncludeDirs := []string{}
if Bool(library.Properties.Llndk.Export_headers_as_system) {
systemIncludeDirs = append(systemIncludeDirs, includeDirs...)
includeDirs = nil
}
// Header libs.
includeDirs = append(includeDirs, deps.LlndkIncludeDirs.Strings()...)
systemIncludeDirs = append(systemIncludeDirs, deps.LlndkSystemIncludeDirs.Strings()...)
// The ABI checker does not distinguish normal and system headers.
return append(includeDirs, systemIncludeDirs...)
}
func (library *libraryDecorator) linkLlndkSAbiDumpFiles(ctx ModuleContext,
deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string,
excludeSymbolVersions, excludeSymbolTags []string) android.Path {
// NDK symbols in version 34 are LLNDK symbols. Those in version 35 are not.
// TODO(b/314010764): Add parameters to read LLNDK symbols from the symbol file.
return transformDumpToLinkedDump(ctx,
sAbiDumpFiles, soFile, libFileName+".llndk",
library.llndkIncludeDirsForAbiCheck(ctx, deps),
android.OptionalPathForModuleSrc(ctx, library.Properties.Llndk.Symbol_file),
append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
append([]string{"platform-only"}, excludeSymbolTags...),
"34")
}
func getRefAbiDumpFile(ctx android.ModuleInstallPathContext,
versionedDumpDir, fileName string) android.OptionalPath {
@@ -1332,13 +1371,15 @@ func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext,
false /* isLlndkOrNdk */, false /* allowExtensions */, "current", errorMessage)
}
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, deps PathDeps, objs Objects, fileName string, soFile android.Path) {
if library.sabi.shouldCreateSourceAbiDump() {
exportedIncludeDirs := library.exportedIncludeDirsForAbiCheck(ctx)
headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
currSdkVersion := currRefAbiDumpSdkVersion(ctx)
currVendorVersion := ctx.Config().VendorApiLevel()
sourceDump := transformDumpToLinkedDump(ctx,
// Generate source dumps.
implDump := transformDumpToLinkedDump(ctx,
objs.sAbiDumpFiles, soFile, fileName,
exportedIncludeDirs,
android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
@@ -1346,8 +1387,25 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
headerAbiChecker.Exclude_symbol_tags,
currSdkVersion)
for _, tag := range classifySourceAbiDump(ctx) {
addLsdumpPath(string(tag) + ":" + sourceDump.String())
var llndkDump android.Path
tags := classifySourceAbiDump(ctx)
for _, tag := range tags {
if tag == llndkLsdumpTag {
if llndkDump == nil {
// TODO(b/323447559): Evaluate if replacing sAbiDumpFiles with implDump is faster
llndkDump = library.linkLlndkSAbiDumpFiles(ctx,
deps, objs.sAbiDumpFiles, soFile, fileName,
headerAbiChecker.Exclude_symbol_versions,
headerAbiChecker.Exclude_symbol_tags)
}
addLsdumpPath(string(tag) + ":" + llndkDump.String())
} else {
addLsdumpPath(string(tag) + ":" + implDump.String())
}
}
// Diff source dumps and reference dumps.
for _, tag := range tags {
dumpDirName := tag.dirName()
if dumpDirName == "" {
continue
@@ -1362,10 +1420,15 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
}
// Check against the previous version.
var prevVersion, currVersion string
sourceDump := implDump
// If this release config does not define VendorApiLevel, fall back to the old policy.
if isLlndk && currVendorVersion != "" {
prevVersion = ctx.Config().PrevVendorApiLevel()
currVersion = currVendorVersion
// LLNDK dumps are generated by different rules after trunk stable.
if android.IsTrunkStableVendorApiLevel(prevVersion) {
sourceDump = llndkDump
}
} else {
prevVersion, currVersion = crossVersionAbiDiffSdkVersions(ctx, dumpDir)
}
@@ -1376,8 +1439,12 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
fileName, isLlndk || isNdk, currVersion, nameExt+prevVersion)
}
// Check against the current version.
sourceDump = implDump
if isLlndk && currVendorVersion != "" {
currVersion = currVendorVersion
if android.IsTrunkStableVendorApiLevel(currVersion) {
sourceDump = llndkDump
}
} else {
currVersion = currSdkVersion
}
@@ -1398,7 +1465,7 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
continue
}
library.optInAbiDiff(ctx,
sourceDump, optInDumpFile.Path(),
implDump, optInDumpFile.Path(),
fileName, "opt"+strconv.Itoa(i), optInDumpDirPath.String())
}
}
@@ -1765,9 +1832,6 @@ func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *strin
if props := library.getHeaderAbiCheckerProperties(ctx); props.Symbol_file != nil {
return props.Symbol_file
}
if ctx.Module().(*Module).IsLlndk() {
return library.Properties.Llndk.Symbol_file
}
if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
return library.Properties.Stubs.Symbol_file
}