blob: 64eab4160508703d7123a8abbf48c5059570f7f5 [file] [log] [blame]
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
Jayant Chowdharydcd33b62018-02-23 16:43:23 -080018 "sync"
Jayant Chowdhary9677e8c2017-06-15 14:45:18 -070019
Colin Cross36242852017-06-23 15:06:31 -070020 "android/soong/android"
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -080021 "android/soong/cc/config"
22)
23
Jayant Chowdharydcd33b62018-02-23 16:43:23 -080024var (
Yo Chiang8aa4e3f2020-11-19 16:30:49 +080025 lsdumpPaths []string
26 lsdumpPathsLock sync.Mutex
Jayant Chowdharydcd33b62018-02-23 16:43:23 -080027)
28
Hsin-Yi Chen362c1882024-02-06 15:43:17 +080029type lsdumpTag string
30
31const (
Hsin-Yi Chen98da0212024-04-14 19:08:17 +080032 apexLsdumpTag lsdumpTag = "APEX"
Hsin-Yi Chen362c1882024-02-06 15:43:17 +080033 llndkLsdumpTag lsdumpTag = "LLNDK"
Hsin-Yi Chen362c1882024-02-06 15:43:17 +080034 platformLsdumpTag lsdumpTag = "PLATFORM"
35 productLsdumpTag lsdumpTag = "PRODUCT"
36 vendorLsdumpTag lsdumpTag = "VENDOR"
37)
38
39// Return the prebuilt ABI dump directory for a tag; an empty string for an opt-in dump.
40func (tag *lsdumpTag) dirName() string {
41 switch *tag {
Hsin-Yi Chen98da0212024-04-14 19:08:17 +080042 case apexLsdumpTag:
43 return "platform"
Hsin-Yi Chen362c1882024-02-06 15:43:17 +080044 case llndkLsdumpTag:
45 return "vndk"
Hsin-Yi Chen362c1882024-02-06 15:43:17 +080046 default:
47 return ""
48 }
49}
50
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +080051// Properties for ABI compatibility checker in Android.bp.
52type headerAbiCheckerProperties struct {
53 // Enable ABI checks (even if this is not an LLNDK/VNDK lib)
54 Enabled *bool
55
56 // Path to a symbol file that specifies the symbols to be included in the generated
57 // ABI dump file
58 Symbol_file *string `android:"path"`
59
60 // Symbol versions that should be ignored from the symbol file
61 Exclude_symbol_versions []string
62
63 // Symbol tags that should be ignored from the symbol file
64 Exclude_symbol_tags []string
65
66 // Run checks on all APIs (in addition to the ones referred by
67 // one of exported ELF symbols.)
68 Check_all_apis *bool
69
70 // Extra flags passed to header-abi-diff
71 Diff_flags []string
72
73 // Opt-in reference dump directories
74 Ref_dump_dirs []string
75}
76
77func (props *headerAbiCheckerProperties) enabled() bool {
78 return Bool(props.Enabled)
79}
80
81func (props *headerAbiCheckerProperties) explicitlyDisabled() bool {
82 return !BoolDefault(props.Enabled, true)
83}
84
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -080085type SAbiProperties struct {
Yo Chiang2bbadfa2020-12-14 11:42:16 +080086 // Whether ABI dump should be created for this module.
87 // Set by `sabiDepsMutator` if this module is a shared library that needs ABI check, or a static
88 // library that is depended on by an ABI checked library.
89 ShouldCreateSourceAbiDump bool `blueprint:"mutated"`
Yo Chiang8aa4e3f2020-11-19 16:30:49 +080090
91 // Include directories that may contain ABI information exported by a library.
92 // These directories are passed to the header-abi-dumper.
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +080093 ReexportedIncludes []string `blueprint:"mutated"`
94 ReexportedSystemIncludes []string `blueprint:"mutated"`
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -080095}
96
97type sabi struct {
98 Properties SAbiProperties
99}
100
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800101func (sabi *sabi) props() []interface{} {
102 return []interface{}{&sabi.Properties}
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -0800103}
104
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800105func (sabi *sabi) flags(ctx ModuleContext, flags Flags) Flags {
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800106 // Filter out flags which libTooling don't understand.
107 // This is here for legacy reasons and future-proof, in case the version of libTooling and clang
108 // diverge.
109 flags.Local.ToolingCFlags = config.ClangLibToolingFilterUnknownCflags(flags.Local.CFlags)
110 flags.Global.ToolingCFlags = config.ClangLibToolingFilterUnknownCflags(flags.Global.CFlags)
111 flags.Local.ToolingCppFlags = config.ClangLibToolingFilterUnknownCflags(flags.Local.CppFlags)
112 flags.Global.ToolingCppFlags = config.ClangLibToolingFilterUnknownCflags(flags.Global.CppFlags)
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -0800113 return flags
114}
115
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800116// Returns true if ABI dump should be created for this library, either because library is ABI
117// checked or is depended on by an ABI checked library.
118// Could be called as a nil receiver.
119func (sabi *sabi) shouldCreateSourceAbiDump() bool {
120 return sabi != nil && sabi.Properties.ShouldCreateSourceAbiDump
121}
122
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800123// Returns a slice of strings that represent the ABI dumps generated for this module.
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800124func classifySourceAbiDump(ctx android.BaseModuleContext) []lsdumpTag {
125 result := []lsdumpTag{}
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800126 m := ctx.Module().(*Module)
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800127 headerAbiChecker := m.library.getHeaderAbiCheckerProperties(ctx)
128 if headerAbiChecker.explicitlyDisabled() {
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800129 return result
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800130 }
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800131 if !m.InProduct() && !m.InVendor() {
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800132 if m.isImplementationForLLNDKPublic() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800133 result = append(result, llndkLsdumpTag)
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800134 }
Hsin-Yi Chen98da0212024-04-14 19:08:17 +0800135 if m.library.hasStubsVariants() {
136 result = append(result, apexLsdumpTag)
Hsin-Yi Chen3d5c6792024-04-22 11:47:57 +0800137 }
138 if headerAbiChecker.enabled() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800139 result = append(result, platformLsdumpTag)
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800140 }
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800141 } else if headerAbiChecker.enabled() {
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800142 if m.InProduct() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800143 result = append(result, productLsdumpTag)
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800144 }
145 if m.InVendor() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800146 result = append(result, vendorLsdumpTag)
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800147 }
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800148 }
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800149 return result
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800150}
151
152// Called from sabiDepsMutator to check whether ABI dumps should be created for this module.
153// ctx should be wrapping a native library type module.
154func shouldCreateSourceAbiDumpForLibrary(ctx android.BaseModuleContext) bool {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800155 // Only generate ABI dump for device modules.
156 if !ctx.Device() {
157 return false
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800158 }
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800159
160 m := ctx.Module().(*Module)
161
162 // Only create ABI dump for native library module types.
163 if m.library == nil {
164 return false
165 }
166
167 // Create ABI dump for static libraries only if they are dependencies of ABI checked libraries.
168 if m.library.static() {
169 return m.sabi.shouldCreateSourceAbiDump()
170 }
171
172 // Module is shared library type.
173
Yo Chiangd737d3f2020-11-30 20:00:42 +0800174 // Don't check uninstallable modules.
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800175 if m.IsHideFromMake() {
Yo Chiangd737d3f2020-11-30 20:00:42 +0800176 return false
177 }
178
179 // Don't check ramdisk or recovery variants. Only check core, vendor or product variants.
180 if m.InRamdisk() || m.InVendorRamdisk() || m.InRecovery() {
181 return false
182 }
183
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800184 // Don't create ABI dump for prebuilts.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400185 if m.Prebuilt() != nil || m.IsSnapshotPrebuilt() {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800186 return false
187 }
188
189 // Coverage builds have extra symbols.
190 if m.isCoverageVariant() {
191 return false
192 }
193
194 // Some sanitizer variants may have different ABI.
195 if m.sanitize != nil && !m.sanitize.isVariantOnProductionDevice() {
196 return false
197 }
198
199 // Don't create ABI dump for stubs.
Colin Cross127bb8b2020-12-16 16:46:01 -0800200 if m.isNDKStubLibrary() || m.IsLlndk() || m.IsStubs() {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800201 return false
202 }
203
Colin Crossff694a82023-12-13 15:54:49 -0800204 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
205 if apexInfo.IsForPlatform() {
Yo Chiangd737d3f2020-11-30 20:00:42 +0800206 // Bionic libraries that are installed to the bootstrap directory are not ABI checked.
207 // Only the runtime APEX variants, which are the implementation libraries of bionic NDK stubs,
208 // are checked.
209 if InstallToBootstrap(m.BaseModuleName(), ctx.Config()) {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800210 return false
211 }
Yo Chiangd737d3f2020-11-30 20:00:42 +0800212 } else {
213 // Don't create ABI dump if this library is for APEX but isn't exported.
214 if !m.HasStubsVariants() {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800215 return false
216 }
217 }
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800218 return len(classifySourceAbiDump(ctx)) > 0
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800219}
220
221// Mark the direct and transitive dependencies of libraries that need ABI check, so that ABI dumps
222// of their dependencies would be generated.
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -0800223func sabiDepsMutator(mctx android.TopDownMutatorContext) {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800224 // Escape hatch to not check any ABI dump.
225 if mctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") {
226 return
227 }
228 // Only create ABI dump for native shared libraries and their static library dependencies.
229 if m, ok := mctx.Module().(*Module); ok && m.sabi != nil {
230 if shouldCreateSourceAbiDumpForLibrary(mctx) {
231 // Mark this module so that .sdump / .lsdump for this library can be generated.
232 m.sabi.Properties.ShouldCreateSourceAbiDump = true
233 // Mark all of its static library dependencies.
234 mctx.VisitDirectDeps(func(child android.Module) {
235 depTag := mctx.OtherModuleDependencyTag(child)
Yi-Yo Chiang21d1c6d2021-06-07 20:22:35 +0800236 if IsStaticDepTag(depTag) || depTag == reuseObjTag {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800237 if c, ok := child.(*Module); ok && c.sabi != nil {
238 // Mark this module so that .sdump for this static library can be generated.
239 c.sabi.Properties.ShouldCreateSourceAbiDump = true
240 }
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -0800241 }
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800242 })
243 }
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -0800244 }
245}
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800246
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800247// Add an entry to the global list of lsdump. The list is exported to a Make variable by
248// `cc.makeVarsProvider`.
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800249func addLsdumpPath(lsdumpPath string) {
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800250 lsdumpPathsLock.Lock()
251 defer lsdumpPathsLock.Unlock()
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800252 lsdumpPaths = append(lsdumpPaths, lsdumpPath)
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800253}