Add header_abi_checker properties for vendor, product, and platform

The developers can apply different configurations to vendor, product,
and platform libraries. In LSDUMP_PATHS_FILE, the vendor and product
variants are tagged with VENDOR and PRODUCT. Their ABI dumps will not be
generated in the directories under prebuilts/abi-dumps.

Test: make libutils.vendor libutils
Bug: 227282691
Change-Id: I747ceb174a070a67d592c5a47fcc848a6129661d
This commit is contained in:
Hsin-Yi Chen
2022-12-26 15:54:36 +08:00
parent 328770db88
commit 8feb41392a
2 changed files with 81 additions and 45 deletions

View File

@@ -85,10 +85,19 @@ type LibraryProperties struct {
// set suffix of the name of the output // set suffix of the name of the output
Suffix *string `android:"arch_variant"` Suffix *string `android:"arch_variant"`
// Properties for ABI compatibility checker.
Header_abi_checker headerAbiCheckerProperties
Target struct { Target struct {
Vendor, Product struct { Vendor, Product struct {
// set suffix of the name of the output // set suffix of the name of the output
Suffix *string `android:"arch_variant"` Suffix *string `android:"arch_variant"`
Header_abi_checker headerAbiCheckerProperties
}
Platform struct {
Header_abi_checker headerAbiCheckerProperties
} }
} }
@@ -99,32 +108,6 @@ type LibraryProperties struct {
// from PRODUCT_PACKAGES. // from PRODUCT_PACKAGES.
Overrides []string Overrides []string
// Properties for ABI compatibility checker
Header_abi_checker struct {
// Enable ABI checks (even if this is not an LLNDK/VNDK lib)
Enabled *bool
// Path to a symbol file that specifies the symbols to be included in the generated
// ABI dump file
Symbol_file *string `android:"path"`
// Symbol versions that should be ignored from the symbol file
Exclude_symbol_versions []string
// Symbol tags that should be ignored from the symbol file
Exclude_symbol_tags []string
// Run checks on all APIs (in addition to the ones referred by
// one of exported ELF symbols.)
Check_all_apis *bool
// Extra flags passed to header-abi-diff
Diff_flags []string
// Opt-in reference dump directories
Ref_dump_dirs []string
}
// Inject boringssl hash into the shared library. This is only intended for use by external/boringssl. // Inject boringssl hash into the shared library. This is only intended for use by external/boringssl.
Inject_bssl_hash *bool `android:"arch_variant"` Inject_bssl_hash *bool `android:"arch_variant"`
@@ -1202,12 +1185,20 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, d
return flags return flags
} }
func (library *libraryDecorator) headerAbiCheckerEnabled() bool { func (library *libraryDecorator) getHeaderAbiCheckerProperties(ctx android.BaseModuleContext) headerAbiCheckerProperties {
return Bool(library.Properties.Header_abi_checker.Enabled) m := ctx.Module().(*Module)
variantProps := &library.Properties.Target.Platform.Header_abi_checker
if m.InVendor() {
variantProps = &library.Properties.Target.Vendor.Header_abi_checker
} else if m.InProduct() {
variantProps = &library.Properties.Target.Product.Header_abi_checker
} }
props := library.Properties.Header_abi_checker
func (library *libraryDecorator) headerAbiCheckerExplicitlyDisabled() bool { err := proptools.AppendProperties(&props, variantProps, nil)
return !BoolDefault(library.Properties.Header_abi_checker.Enabled, true) if err != nil {
ctx.ModuleErrorf("Cannot merge headerAbiCheckerProperties: %s", err.Error())
}
return props
} }
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
@@ -1342,9 +1333,8 @@ type libraryInterface interface {
setStatic() setStatic()
setShared() setShared()
// Check whether header_abi_checker is enabled or explicitly disabled. // Gets the ABI properties for vendor, product, or platform variant
headerAbiCheckerEnabled() bool getHeaderAbiCheckerProperties(ctx android.BaseModuleContext) headerAbiCheckerProperties
headerAbiCheckerExplicitlyDisabled() bool
// Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff // Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff
androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer)
@@ -1876,7 +1866,8 @@ func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext, refere
sourceDump := library.sAbiOutputFile.Path() sourceDump := library.sAbiOutputFile.Path()
extraFlags := []string{"-target-version", sourceVersion} extraFlags := []string{"-target-version", sourceVersion}
if Bool(library.Properties.Header_abi_checker.Check_all_apis) { headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
if Bool(headerAbiChecker.Check_all_apis) {
extraFlags = append(extraFlags, "-check-all-apis") extraFlags = append(extraFlags, "-check-all-apis")
} else { } else {
extraFlags = append(extraFlags, extraFlags = append(extraFlags,
@@ -1889,7 +1880,7 @@ func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext, refere
if allowExtensions { if allowExtensions {
extraFlags = append(extraFlags, "-allow-extensions") extraFlags = append(extraFlags, "-allow-extensions")
} }
extraFlags = append(extraFlags, library.Properties.Header_abi_checker.Diff_flags...) extraFlags = append(extraFlags, headerAbiChecker.Diff_flags...)
library.sAbiDiff = append( library.sAbiDiff = append(
library.sAbiDiff, library.sAbiDiff,
@@ -1937,10 +1928,11 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude) SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude)
} }
exportedHeaderFlags := strings.Join(SourceAbiFlags, " ") exportedHeaderFlags := strings.Join(SourceAbiFlags, " ")
headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
library.sAbiOutputFile = transformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags, library.sAbiOutputFile = transformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags,
android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)), android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
library.Properties.Header_abi_checker.Exclude_symbol_versions, headerAbiChecker.Exclude_symbol_versions,
library.Properties.Header_abi_checker.Exclude_symbol_tags) headerAbiChecker.Exclude_symbol_tags)
addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String()) addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String())
@@ -1971,7 +1963,7 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
fileName, isLlndk || isNdk, ctx.IsVndkExt()) fileName, isLlndk || isNdk, ctx.IsVndkExt())
} }
// Check against the opt-in reference dumps. // Check against the opt-in reference dumps.
for i, optInDumpDir := range library.Properties.Header_abi_checker.Ref_dump_dirs { for i, optInDumpDir := range headerAbiChecker.Ref_dump_dirs {
optInDumpDirPath := android.PathForModuleSrc(ctx, optInDumpDir) optInDumpDirPath := android.PathForModuleSrc(ctx, optInDumpDir)
// Ref_dump_dirs are not versioned. // Ref_dump_dirs are not versioned.
// They do not contain subdir for binder bitness because 64-bit binder has been mandatory. // They do not contain subdir for binder bitness because 64-bit binder has been mandatory.
@@ -2330,8 +2322,8 @@ func (library *libraryDecorator) buildStubs() bool {
} }
func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string { func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string {
if library.Properties.Header_abi_checker.Symbol_file != nil { if props := library.getHeaderAbiCheckerProperties(ctx); props.Symbol_file != nil {
return library.Properties.Header_abi_checker.Symbol_file return props.Symbol_file
} }
if ctx.Module().(*Module).IsLlndk() { if ctx.Module().(*Module).IsLlndk() {
return library.Properties.Llndk.Symbol_file return library.Properties.Llndk.Symbol_file
@@ -2807,7 +2799,7 @@ func bp2buildParseAbiCheckerProps(ctx android.TopDownMutatorContext, module *Mod
return bazelCcHeaderAbiCheckerAttributes{} return bazelCcHeaderAbiCheckerAttributes{}
} }
abiChecker := lib.Properties.Header_abi_checker abiChecker := lib.getHeaderAbiCheckerProperties(ctx)
abiCheckerAttrs := bazelCcHeaderAbiCheckerAttributes{ abiCheckerAttrs := bazelCcHeaderAbiCheckerAttributes{
Abi_checker_enabled: abiChecker.Enabled, Abi_checker_enabled: abiChecker.Enabled,

View File

@@ -26,6 +26,40 @@ var (
lsdumpPathsLock sync.Mutex lsdumpPathsLock sync.Mutex
) )
// Properties for ABI compatibility checker in Android.bp.
type headerAbiCheckerProperties struct {
// Enable ABI checks (even if this is not an LLNDK/VNDK lib)
Enabled *bool
// Path to a symbol file that specifies the symbols to be included in the generated
// ABI dump file
Symbol_file *string `android:"path"`
// Symbol versions that should be ignored from the symbol file
Exclude_symbol_versions []string
// Symbol tags that should be ignored from the symbol file
Exclude_symbol_tags []string
// Run checks on all APIs (in addition to the ones referred by
// one of exported ELF symbols.)
Check_all_apis *bool
// Extra flags passed to header-abi-diff
Diff_flags []string
// Opt-in reference dump directories
Ref_dump_dirs []string
}
func (props *headerAbiCheckerProperties) enabled() bool {
return Bool(props.Enabled)
}
func (props *headerAbiCheckerProperties) explicitlyDisabled() bool {
return !BoolDefault(props.Enabled, true)
}
type SAbiProperties struct { type SAbiProperties struct {
// Whether ABI dump should be created for this module. // Whether ABI dump should be created for this module.
// Set by `sabiDepsMutator` if this module is a shared library that needs ABI check, or a static // Set by `sabiDepsMutator` if this module is a shared library that needs ABI check, or a static
@@ -67,7 +101,8 @@ func (sabi *sabi) shouldCreateSourceAbiDump() bool {
// Returns an empty string if ABI check is disabled for this library. // Returns an empty string if ABI check is disabled for this library.
func classifySourceAbiDump(ctx android.BaseModuleContext) string { func classifySourceAbiDump(ctx android.BaseModuleContext) string {
m := ctx.Module().(*Module) m := ctx.Module().(*Module)
if m.library.headerAbiCheckerExplicitlyDisabled() { headerAbiChecker := m.library.getHeaderAbiCheckerProperties(ctx)
if headerAbiChecker.explicitlyDisabled() {
return "" return ""
} }
// Return NDK if the library is both NDK and LLNDK. // Return NDK if the library is both NDK and LLNDK.
@@ -92,7 +127,16 @@ func classifySourceAbiDump(ctx android.BaseModuleContext) string {
} }
} }
} }
if m.library.headerAbiCheckerEnabled() || m.library.hasStubsVariants() { if m.library.hasStubsVariants() && !m.InProduct() && !m.InVendor() {
return "PLATFORM"
}
if headerAbiChecker.enabled() {
if m.InProduct() {
return "PRODUCT"
}
if m.InVendor() {
return "VENDOR"
}
return "PLATFORM" return "PLATFORM"
} }
return "" return ""