123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- // Copyright 2017 Google Inc. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package cc
- import (
- "sync"
- "android/soong/android"
- "android/soong/cc/config"
- )
- var (
- lsdumpPaths []string
- 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 {
- // 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
- // library that is depended on by an ABI checked library.
- ShouldCreateSourceAbiDump bool `blueprint:"mutated"`
- // Include directories that may contain ABI information exported by a library.
- // These directories are passed to the header-abi-dumper.
- ReexportedIncludes []string `blueprint:"mutated"`
- }
- type sabi struct {
- Properties SAbiProperties
- }
- func (sabi *sabi) props() []interface{} {
- return []interface{}{&sabi.Properties}
- }
- func (sabi *sabi) flags(ctx ModuleContext, flags Flags) Flags {
- // Filter out flags which libTooling don't understand.
- // This is here for legacy reasons and future-proof, in case the version of libTooling and clang
- // diverge.
- flags.Local.ToolingCFlags = config.ClangLibToolingFilterUnknownCflags(flags.Local.CFlags)
- flags.Global.ToolingCFlags = config.ClangLibToolingFilterUnknownCflags(flags.Global.CFlags)
- flags.Local.ToolingCppFlags = config.ClangLibToolingFilterUnknownCflags(flags.Local.CppFlags)
- flags.Global.ToolingCppFlags = config.ClangLibToolingFilterUnknownCflags(flags.Global.CppFlags)
- return flags
- }
- // Returns true if ABI dump should be created for this library, either because library is ABI
- // checked or is depended on by an ABI checked library.
- // Could be called as a nil receiver.
- func (sabi *sabi) shouldCreateSourceAbiDump() bool {
- return sabi != nil && sabi.Properties.ShouldCreateSourceAbiDump
- }
- // Returns a string that represents the class of the ABI dump.
- // Returns an empty string if ABI check is disabled for this library.
- func classifySourceAbiDump(ctx android.BaseModuleContext) string {
- m := ctx.Module().(*Module)
- headerAbiChecker := m.library.getHeaderAbiCheckerProperties(ctx)
- if headerAbiChecker.explicitlyDisabled() {
- return ""
- }
- // Return NDK if the library is both NDK and LLNDK.
- if m.IsNdk(ctx.Config()) {
- return "NDK"
- }
- if m.isImplementationForLLNDKPublic() {
- return "LLNDK"
- }
- if m.UseVndk() && m.IsVndk() && !m.IsVndkPrivate() {
- if m.IsVndkSp() {
- if m.IsVndkExt() {
- return "VNDK-SP-ext"
- } else {
- return "VNDK-SP"
- }
- } else {
- if m.IsVndkExt() {
- return "VNDK-ext"
- } else {
- return "VNDK-core"
- }
- }
- }
- 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 ""
- }
- // Called from sabiDepsMutator to check whether ABI dumps should be created for this module.
- // ctx should be wrapping a native library type module.
- func shouldCreateSourceAbiDumpForLibrary(ctx android.BaseModuleContext) bool {
- // Only generate ABI dump for device modules.
- if !ctx.Device() {
- return false
- }
- m := ctx.Module().(*Module)
- // Only create ABI dump for native library module types.
- if m.library == nil {
- return false
- }
- // Create ABI dump for static libraries only if they are dependencies of ABI checked libraries.
- if m.library.static() {
- return m.sabi.shouldCreateSourceAbiDump()
- }
- // Module is shared library type.
- // Don't check uninstallable modules.
- if m.IsHideFromMake() {
- return false
- }
- // Don't check ramdisk or recovery variants. Only check core, vendor or product variants.
- if m.InRamdisk() || m.InVendorRamdisk() || m.InRecovery() {
- return false
- }
- // Don't create ABI dump for prebuilts.
- if m.Prebuilt() != nil || m.IsSnapshotPrebuilt() {
- return false
- }
- // Coverage builds have extra symbols.
- if m.isCoverageVariant() {
- return false
- }
- // Some sanitizer variants may have different ABI.
- if m.sanitize != nil && !m.sanitize.isVariantOnProductionDevice() {
- return false
- }
- // Don't create ABI dump for stubs.
- if m.isNDKStubLibrary() || m.IsLlndk() || m.IsStubs() {
- return false
- }
- isPlatformVariant := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
- if isPlatformVariant {
- // Bionic libraries that are installed to the bootstrap directory are not ABI checked.
- // Only the runtime APEX variants, which are the implementation libraries of bionic NDK stubs,
- // are checked.
- if InstallToBootstrap(m.BaseModuleName(), ctx.Config()) {
- return false
- }
- } else {
- // Don't create ABI dump if this library is for APEX but isn't exported.
- if !m.HasStubsVariants() {
- return false
- }
- }
- return classifySourceAbiDump(ctx) != ""
- }
- // Mark the direct and transitive dependencies of libraries that need ABI check, so that ABI dumps
- // of their dependencies would be generated.
- func sabiDepsMutator(mctx android.TopDownMutatorContext) {
- // Escape hatch to not check any ABI dump.
- if mctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") {
- return
- }
- // Only create ABI dump for native shared libraries and their static library dependencies.
- if m, ok := mctx.Module().(*Module); ok && m.sabi != nil {
- if shouldCreateSourceAbiDumpForLibrary(mctx) {
- // Mark this module so that .sdump / .lsdump for this library can be generated.
- m.sabi.Properties.ShouldCreateSourceAbiDump = true
- // Mark all of its static library dependencies.
- mctx.VisitDirectDeps(func(child android.Module) {
- depTag := mctx.OtherModuleDependencyTag(child)
- if IsStaticDepTag(depTag) || depTag == reuseObjTag {
- if c, ok := child.(*Module); ok && c.sabi != nil {
- // Mark this module so that .sdump for this static library can be generated.
- c.sabi.Properties.ShouldCreateSourceAbiDump = true
- }
- }
- })
- }
- }
- }
- // Add an entry to the global list of lsdump. The list is exported to a Make variable by
- // `cc.makeVarsProvider`.
- func addLsdumpPath(lsdumpPath string) {
- lsdumpPathsLock.Lock()
- defer lsdumpPathsLock.Unlock()
- lsdumpPaths = append(lsdumpPaths, lsdumpPath)
- }
|