blob: 2caf0d4704e6955957fd0b60fd8be2c54d37b922 [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.
Colin Cross91ae5ec2024-10-01 14:03:40 -070087 // Set by `sabiTransitionMutator` if this module is a shared library that needs ABI check,
88 // or a static library that is depended on by an ABI checked library.
Yo Chiang2bbadfa2020-12-14 11:42:16 +080089 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.
Colin Cross91ae5ec2024-10-01 14:03:40 -0700124func classifySourceAbiDump(m *Module) []lsdumpTag {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800125 result := []lsdumpTag{}
Colin Cross91ae5ec2024-10-01 14:03:40 -0700126 headerAbiChecker := m.library.getHeaderAbiCheckerProperties(m)
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800127 if headerAbiChecker.explicitlyDisabled() {
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800128 return result
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800129 }
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800130 if !m.InProduct() && !m.InVendor() {
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800131 if m.isImplementationForLLNDKPublic() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800132 result = append(result, llndkLsdumpTag)
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800133 }
Hsin-Yi Chen98da0212024-04-14 19:08:17 +0800134 if m.library.hasStubsVariants() {
135 result = append(result, apexLsdumpTag)
Hsin-Yi Chen3d5c6792024-04-22 11:47:57 +0800136 }
137 if headerAbiChecker.enabled() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800138 result = append(result, platformLsdumpTag)
Hsin-Yi Chen27bafd02024-01-08 18:38:42 +0800139 }
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800140 } else if headerAbiChecker.enabled() {
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800141 if m.InProduct() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800142 result = append(result, productLsdumpTag)
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800143 }
144 if m.InVendor() {
Hsin-Yi Chen362c1882024-02-06 15:43:17 +0800145 result = append(result, vendorLsdumpTag)
Hsin-Yi Chen8feb4132022-12-26 15:54:36 +0800146 }
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800147 }
Hsin-Yi Chen50884dc2024-01-05 14:41:06 +0800148 return result
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800149}
150
Colin Cross91ae5ec2024-10-01 14:03:40 -0700151type shouldCreateAbiDumpContext interface {
152 android.ModuleProviderContext
153 Module() android.Module
154 Config() android.Config
155}
156
157var _ shouldCreateAbiDumpContext = android.ModuleContext(nil)
158var _ shouldCreateAbiDumpContext = android.OutgoingTransitionContext(nil)
159
160// Called from sabiTransitionMutator to check whether ABI dumps should be created for this module.
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800161// ctx should be wrapping a native library type module.
Colin Cross91ae5ec2024-10-01 14:03:40 -0700162func shouldCreateSourceAbiDumpForLibrary(ctx shouldCreateAbiDumpContext) bool {
163 m, ok := ctx.Module().(*Module)
164 if !ok {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800165 return false
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800166 }
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800167
Colin Cross91ae5ec2024-10-01 14:03:40 -0700168 // Only generate ABI dump for device modules.
169 if !m.Device() {
170 return false
171 }
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800172
173 // Only create ABI dump for native library module types.
174 if m.library == nil {
175 return false
176 }
177
Colin Cross91ae5ec2024-10-01 14:03:40 -0700178 // Don't create ABI dump for static libraries
179 // The sabi variant will be propagated to dependencies of ABI checked libraries.
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800180 if m.library.static() {
Colin Cross91ae5ec2024-10-01 14:03:40 -0700181 return false
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800182 }
183
184 // Module is shared library type.
185
Yo Chiangd737d3f2020-11-30 20:00:42 +0800186 // Don't check uninstallable modules.
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800187 if m.IsHideFromMake() {
Yo Chiangd737d3f2020-11-30 20:00:42 +0800188 return false
189 }
190
191 // Don't check ramdisk or recovery variants. Only check core, vendor or product variants.
192 if m.InRamdisk() || m.InVendorRamdisk() || m.InRecovery() {
193 return false
194 }
195
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800196 // Don't create ABI dump for prebuilts.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400197 if m.Prebuilt() != nil || m.IsSnapshotPrebuilt() {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800198 return false
199 }
200
201 // Coverage builds have extra symbols.
202 if m.isCoverageVariant() {
203 return false
204 }
205
206 // Some sanitizer variants may have different ABI.
207 if m.sanitize != nil && !m.sanitize.isVariantOnProductionDevice() {
208 return false
209 }
210
211 // Don't create ABI dump for stubs.
Colin Cross127bb8b2020-12-16 16:46:01 -0800212 if m.isNDKStubLibrary() || m.IsLlndk() || m.IsStubs() {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800213 return false
214 }
215
Colin Crossff694a82023-12-13 15:54:49 -0800216 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
217 if apexInfo.IsForPlatform() {
Yo Chiangd737d3f2020-11-30 20:00:42 +0800218 // Bionic libraries that are installed to the bootstrap directory are not ABI checked.
219 // Only the runtime APEX variants, which are the implementation libraries of bionic NDK stubs,
220 // are checked.
221 if InstallToBootstrap(m.BaseModuleName(), ctx.Config()) {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800222 return false
223 }
Yo Chiangd737d3f2020-11-30 20:00:42 +0800224 } else {
225 // Don't create ABI dump if this library is for APEX but isn't exported.
226 if !m.HasStubsVariants() {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800227 return false
228 }
229 }
Colin Cross91ae5ec2024-10-01 14:03:40 -0700230 return len(classifySourceAbiDump(m)) > 0
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800231}
232
233// Mark the direct and transitive dependencies of libraries that need ABI check, so that ABI dumps
234// of their dependencies would be generated.
Colin Cross91ae5ec2024-10-01 14:03:40 -0700235type sabiTransitionMutator struct{}
236
237func (s *sabiTransitionMutator) Split(ctx android.BaseModuleContext) []string {
238 return []string{""}
239}
240
241func (s *sabiTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800242 // Escape hatch to not check any ABI dump.
Colin Cross91ae5ec2024-10-01 14:03:40 -0700243 if ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") {
244 return ""
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800245 }
Colin Cross91ae5ec2024-10-01 14:03:40 -0700246
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800247 // Only create ABI dump for native shared libraries and their static library dependencies.
Colin Cross91ae5ec2024-10-01 14:03:40 -0700248 if m, ok := ctx.Module().(*Module); ok && m.sabi != nil {
249 if shouldCreateSourceAbiDumpForLibrary(ctx) {
250 if IsStaticDepTag(ctx.DepTag()) || ctx.DepTag() == reuseObjTag {
251 return "sabi"
252 }
253 } else if sourceVariation == "sabi" {
254 if IsWholeStaticLib(ctx.DepTag()) || ctx.DepTag() == reuseObjTag {
255 return "sabi"
256 }
257 }
258 }
259
260 return ""
261}
262
263func (s *sabiTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
264 if incomingVariation == "" {
265 return ""
266 }
267
268 if incomingVariation == "sabi" {
269 if m, ok := ctx.Module().(*Module); ok && m.sabi != nil {
270 return "sabi"
271 }
272 }
273
274 return ""
275}
276
277func (s *sabiTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
278 if m, ok := ctx.Module().(*Module); ok && m.sabi != nil {
279 if variation == "sabi" {
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800280 m.sabi.Properties.ShouldCreateSourceAbiDump = true
Colin Cross91ae5ec2024-10-01 14:03:40 -0700281 m.HideFromMake()
282 m.Properties.PreventInstall = true
283 } else if shouldCreateSourceAbiDumpForLibrary(ctx) {
284 // Escape hatch to not check any ABI dump.
285 if !ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") {
286 m.sabi.Properties.ShouldCreateSourceAbiDump = true
287 }
Yo Chiang2bbadfa2020-12-14 11:42:16 +0800288 }
Jayant Chowdhary3e231fd2017-02-08 13:45:53 -0800289 }
290}
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800291
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800292// Add an entry to the global list of lsdump. The list is exported to a Make variable by
293// `cc.makeVarsProvider`.
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800294func addLsdumpPath(lsdumpPath string) {
Yo Chiang8aa4e3f2020-11-19 16:30:49 +0800295 lsdumpPathsLock.Lock()
296 defer lsdumpPathsLock.Unlock()
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800297 lsdumpPaths = append(lsdumpPaths, lsdumpPath)
Hsin-Yi Chen53489642019-07-31 17:10:45 +0800298}