Loading android/config.go +5 −0 Original line number Diff line number Diff line Loading @@ -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") } Loading cc/cc_test.go +24 −6 Original line number Diff line number Diff line Loading @@ -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) { Loading cc/library.go +73 −9 Original line number Diff line number Diff line Loading @@ -1138,7 +1138,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 { Loading Loading @@ -1207,6 +1207,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 { Loading Loading @@ -1317,13 +1356,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)), Loading @@ -1331,8 +1372,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 Loading @@ -1347,10 +1405,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) } Loading @@ -1361,8 +1424,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 } Loading @@ -1383,7 +1450,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()) } } Loading Loading @@ -1750,9 +1817,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 } Loading Loading
android/config.go +5 −0 Original line number Diff line number Diff line Loading @@ -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") } Loading
cc/cc_test.go +24 −6 Original line number Diff line number Diff line Loading @@ -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) { Loading
cc/library.go +73 −9 Original line number Diff line number Diff line Loading @@ -1138,7 +1138,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 { Loading Loading @@ -1207,6 +1207,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 { Loading Loading @@ -1317,13 +1356,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)), Loading @@ -1331,8 +1372,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 Loading @@ -1347,10 +1405,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) } Loading @@ -1361,8 +1424,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 } Loading @@ -1383,7 +1450,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()) } } Loading Loading @@ -1750,9 +1817,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 } Loading