xref: /aosp_15_r20/build/soong/cc/library.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage cc
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"io"
20*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
21*333d2b36SAndroid Build Coastguard Worker	"regexp"
22*333d2b36SAndroid Build Coastguard Worker	"slices"
23*333d2b36SAndroid Build Coastguard Worker	"strconv"
24*333d2b36SAndroid Build Coastguard Worker	"strings"
25*333d2b36SAndroid Build Coastguard Worker	"sync"
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
28*333d2b36SAndroid Build Coastguard Worker
29*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
30*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/depset"
31*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/pathtools"
32*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
33*333d2b36SAndroid Build Coastguard Worker)
34*333d2b36SAndroid Build Coastguard Worker
35*333d2b36SAndroid Build Coastguard Worker// LibraryProperties is a collection of properties shared by cc library rules/cc.
36*333d2b36SAndroid Build Coastguard Workertype LibraryProperties struct {
37*333d2b36SAndroid Build Coastguard Worker	// local file name to pass to the linker as -unexported_symbols_list
38*333d2b36SAndroid Build Coastguard Worker	Unexported_symbols_list *string `android:"path,arch_variant"`
39*333d2b36SAndroid Build Coastguard Worker	// local file name to pass to the linker as -force_symbols_not_weak_list
40*333d2b36SAndroid Build Coastguard Worker	Force_symbols_not_weak_list *string `android:"path,arch_variant"`
41*333d2b36SAndroid Build Coastguard Worker	// local file name to pass to the linker as -force_symbols_weak_list
42*333d2b36SAndroid Build Coastguard Worker	Force_symbols_weak_list *string `android:"path,arch_variant"`
43*333d2b36SAndroid Build Coastguard Worker
44*333d2b36SAndroid Build Coastguard Worker	// rename host libraries to prevent overlap with system installed libraries
45*333d2b36SAndroid Build Coastguard Worker	Unique_host_soname *bool
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Worker	Aidl struct {
48*333d2b36SAndroid Build Coastguard Worker		// export headers generated from .aidl sources
49*333d2b36SAndroid Build Coastguard Worker		Export_aidl_headers *bool
50*333d2b36SAndroid Build Coastguard Worker	}
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Worker	Proto struct {
53*333d2b36SAndroid Build Coastguard Worker		// export headers generated from .proto sources
54*333d2b36SAndroid Build Coastguard Worker		Export_proto_headers *bool
55*333d2b36SAndroid Build Coastguard Worker	}
56*333d2b36SAndroid Build Coastguard Worker
57*333d2b36SAndroid Build Coastguard Worker	Sysprop struct {
58*333d2b36SAndroid Build Coastguard Worker		// Whether platform owns this sysprop library.
59*333d2b36SAndroid Build Coastguard Worker		Platform *bool
60*333d2b36SAndroid Build Coastguard Worker	} `blueprint:"mutated"`
61*333d2b36SAndroid Build Coastguard Worker
62*333d2b36SAndroid Build Coastguard Worker	Static_ndk_lib *bool
63*333d2b36SAndroid Build Coastguard Worker
64*333d2b36SAndroid Build Coastguard Worker	// Generate stubs to make this library accessible to APEXes.
65*333d2b36SAndroid Build Coastguard Worker	Stubs struct {
66*333d2b36SAndroid Build Coastguard Worker		// Relative path to the symbol map. The symbol map provides the list of
67*333d2b36SAndroid Build Coastguard Worker		// symbols that are exported for stubs variant of this library.
68*333d2b36SAndroid Build Coastguard Worker		Symbol_file *string `android:"path,arch_variant"`
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard Worker		// List versions to generate stubs libs for. The version name "current" is always
71*333d2b36SAndroid Build Coastguard Worker		// implicitly added.
72*333d2b36SAndroid Build Coastguard Worker		Versions []string
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker		// Whether to not require the implementation of the library to be installed if a
75*333d2b36SAndroid Build Coastguard Worker		// client of the stubs is installed. Defaults to true; set to false if the
76*333d2b36SAndroid Build Coastguard Worker		// implementation is made available by some other means, e.g. in a Microdroid
77*333d2b36SAndroid Build Coastguard Worker		// virtual machine.
78*333d2b36SAndroid Build Coastguard Worker		Implementation_installable *bool
79*333d2b36SAndroid Build Coastguard Worker	} `android:"arch_variant"`
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Worker	// set the name of the output
82*333d2b36SAndroid Build Coastguard Worker	Stem *string `android:"arch_variant"`
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Worker	// set suffix of the name of the output
85*333d2b36SAndroid Build Coastguard Worker	Suffix *string `android:"arch_variant"`
86*333d2b36SAndroid Build Coastguard Worker
87*333d2b36SAndroid Build Coastguard Worker	// Properties for ABI compatibility checker.
88*333d2b36SAndroid Build Coastguard Worker	Header_abi_checker headerAbiCheckerProperties
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Worker	Target struct {
91*333d2b36SAndroid Build Coastguard Worker		Vendor, Product struct {
92*333d2b36SAndroid Build Coastguard Worker			// set suffix of the name of the output
93*333d2b36SAndroid Build Coastguard Worker			Suffix *string `android:"arch_variant"`
94*333d2b36SAndroid Build Coastguard Worker
95*333d2b36SAndroid Build Coastguard Worker			Header_abi_checker headerAbiCheckerProperties
96*333d2b36SAndroid Build Coastguard Worker
97*333d2b36SAndroid Build Coastguard Worker			// Disable stubs for vendor/product variants
98*333d2b36SAndroid Build Coastguard Worker			// This is a workaround to keep `stubs` only for "core" variant (not product/vendor).
99*333d2b36SAndroid Build Coastguard Worker			// It would be nice if we could put `stubs` into a `target: { core: {} }`
100*333d2b36SAndroid Build Coastguard Worker			// block but it's not supported in soong yet. This could be removed/simplified once we have
101*333d2b36SAndroid Build Coastguard Worker			// a better syntax.
102*333d2b36SAndroid Build Coastguard Worker			No_stubs bool
103*333d2b36SAndroid Build Coastguard Worker		}
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Worker		Platform struct {
106*333d2b36SAndroid Build Coastguard Worker			Header_abi_checker headerAbiCheckerProperties
107*333d2b36SAndroid Build Coastguard Worker		}
108*333d2b36SAndroid Build Coastguard Worker	}
109*333d2b36SAndroid Build Coastguard Worker
110*333d2b36SAndroid Build Coastguard Worker	// Names of modules to be overridden. Listed modules can only be other shared libraries
111*333d2b36SAndroid Build Coastguard Worker	// (in Make or Soong).
112*333d2b36SAndroid Build Coastguard Worker	// This does not completely prevent installation of the overridden libraries, but if both
113*333d2b36SAndroid Build Coastguard Worker	// binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed
114*333d2b36SAndroid Build Coastguard Worker	// from PRODUCT_PACKAGES.
115*333d2b36SAndroid Build Coastguard Worker	Overrides []string
116*333d2b36SAndroid Build Coastguard Worker
117*333d2b36SAndroid Build Coastguard Worker	// Inject boringssl hash into the shared library.  This is only intended for use by external/boringssl.
118*333d2b36SAndroid Build Coastguard Worker	Inject_bssl_hash *bool `android:"arch_variant"`
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Worker	// If this is an LLNDK library, properties to describe the LLNDK stubs.  Will be copied from
121*333d2b36SAndroid Build Coastguard Worker	// the module pointed to by llndk_stubs if it is set.
122*333d2b36SAndroid Build Coastguard Worker	Llndk llndkLibraryProperties `android:"arch_variant"`
123*333d2b36SAndroid Build Coastguard Worker
124*333d2b36SAndroid Build Coastguard Worker	// If this is a vendor public library, properties to describe the vendor public library stubs.
125*333d2b36SAndroid Build Coastguard Worker	Vendor_public_library vendorPublicLibraryProperties
126*333d2b36SAndroid Build Coastguard Worker}
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Worker// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a
129*333d2b36SAndroid Build Coastguard Worker// library module.
130*333d2b36SAndroid Build Coastguard Workertype StaticProperties struct {
131*333d2b36SAndroid Build Coastguard Worker	Static StaticOrSharedProperties `android:"arch_variant"`
132*333d2b36SAndroid Build Coastguard Worker}
133*333d2b36SAndroid Build Coastguard Worker
134*333d2b36SAndroid Build Coastguard Worker// SharedProperties is a properties stanza to affect only attributes of the "shared" variants of a
135*333d2b36SAndroid Build Coastguard Worker// library module.
136*333d2b36SAndroid Build Coastguard Workertype SharedProperties struct {
137*333d2b36SAndroid Build Coastguard Worker	Shared StaticOrSharedProperties `android:"arch_variant"`
138*333d2b36SAndroid Build Coastguard Worker}
139*333d2b36SAndroid Build Coastguard Worker
140*333d2b36SAndroid Build Coastguard Worker// StaticOrSharedProperties is an embedded struct representing properties to affect attributes of
141*333d2b36SAndroid Build Coastguard Worker// either only the "static" variants or only the "shared" variants of a library module. These override
142*333d2b36SAndroid Build Coastguard Worker// the base properties of the same name.
143*333d2b36SAndroid Build Coastguard Worker// Use `StaticProperties` or `SharedProperties`, depending on which variant is needed.
144*333d2b36SAndroid Build Coastguard Worker// `StaticOrSharedProperties` exists only to avoid duplication.
145*333d2b36SAndroid Build Coastguard Workertype StaticOrSharedProperties struct {
146*333d2b36SAndroid Build Coastguard Worker	Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
147*333d2b36SAndroid Build Coastguard Worker
148*333d2b36SAndroid Build Coastguard Worker	Tidy_disabled_srcs []string `android:"path,arch_variant"`
149*333d2b36SAndroid Build Coastguard Worker
150*333d2b36SAndroid Build Coastguard Worker	Tidy_timeout_srcs []string `android:"path,arch_variant"`
151*333d2b36SAndroid Build Coastguard Worker
152*333d2b36SAndroid Build Coastguard Worker	Sanitized Sanitized `android:"arch_variant"`
153*333d2b36SAndroid Build Coastguard Worker
154*333d2b36SAndroid Build Coastguard Worker	Cflags proptools.Configurable[[]string] `android:"arch_variant"`
155*333d2b36SAndroid Build Coastguard Worker
156*333d2b36SAndroid Build Coastguard Worker	Enabled            *bool                            `android:"arch_variant"`
157*333d2b36SAndroid Build Coastguard Worker	Whole_static_libs  proptools.Configurable[[]string] `android:"arch_variant"`
158*333d2b36SAndroid Build Coastguard Worker	Static_libs        proptools.Configurable[[]string] `android:"arch_variant"`
159*333d2b36SAndroid Build Coastguard Worker	Shared_libs        proptools.Configurable[[]string] `android:"arch_variant"`
160*333d2b36SAndroid Build Coastguard Worker	System_shared_libs []string                         `android:"arch_variant"`
161*333d2b36SAndroid Build Coastguard Worker
162*333d2b36SAndroid Build Coastguard Worker	Export_shared_lib_headers []string `android:"arch_variant"`
163*333d2b36SAndroid Build Coastguard Worker	Export_static_lib_headers []string `android:"arch_variant"`
164*333d2b36SAndroid Build Coastguard Worker
165*333d2b36SAndroid Build Coastguard Worker	Apex_available []string `android:"arch_variant"`
166*333d2b36SAndroid Build Coastguard Worker
167*333d2b36SAndroid Build Coastguard Worker	Installable *bool `android:"arch_variant"`
168*333d2b36SAndroid Build Coastguard Worker}
169*333d2b36SAndroid Build Coastguard Worker
170*333d2b36SAndroid Build Coastguard Workertype LibraryMutatedProperties struct {
171*333d2b36SAndroid Build Coastguard Worker	// Build a static variant
172*333d2b36SAndroid Build Coastguard Worker	BuildStatic bool `blueprint:"mutated"`
173*333d2b36SAndroid Build Coastguard Worker	// Build a shared variant
174*333d2b36SAndroid Build Coastguard Worker	BuildShared bool `blueprint:"mutated"`
175*333d2b36SAndroid Build Coastguard Worker	// This variant is shared
176*333d2b36SAndroid Build Coastguard Worker	VariantIsShared bool `blueprint:"mutated"`
177*333d2b36SAndroid Build Coastguard Worker	// This variant is static
178*333d2b36SAndroid Build Coastguard Worker	VariantIsStatic bool `blueprint:"mutated"`
179*333d2b36SAndroid Build Coastguard Worker
180*333d2b36SAndroid Build Coastguard Worker	// This variant is a stubs lib
181*333d2b36SAndroid Build Coastguard Worker	BuildStubs bool `blueprint:"mutated"`
182*333d2b36SAndroid Build Coastguard Worker	// This variant is the latest version
183*333d2b36SAndroid Build Coastguard Worker	IsLatestVersion bool `blueprint:"mutated"`
184*333d2b36SAndroid Build Coastguard Worker	// Version of the stubs lib
185*333d2b36SAndroid Build Coastguard Worker	StubsVersion string `blueprint:"mutated"`
186*333d2b36SAndroid Build Coastguard Worker	// List of all stubs versions associated with an implementation lib
187*333d2b36SAndroid Build Coastguard Worker	AllStubsVersions []string `blueprint:"mutated"`
188*333d2b36SAndroid Build Coastguard Worker}
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Workertype FlagExporterProperties struct {
191*333d2b36SAndroid Build Coastguard Worker	// list of directories relative to the Blueprints file that will
192*333d2b36SAndroid Build Coastguard Worker	// be added to the include path (using -I) for this module and any module that links
193*333d2b36SAndroid Build Coastguard Worker	// against this module.  Directories listed in export_include_dirs do not need to be
194*333d2b36SAndroid Build Coastguard Worker	// listed in local_include_dirs.
195*333d2b36SAndroid Build Coastguard Worker	Export_include_dirs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
196*333d2b36SAndroid Build Coastguard Worker
197*333d2b36SAndroid Build Coastguard Worker	// list of directories that will be added to the system include path
198*333d2b36SAndroid Build Coastguard Worker	// using -isystem for this module and any module that links against this module.
199*333d2b36SAndroid Build Coastguard Worker	Export_system_include_dirs []string `android:"arch_variant,variant_prepend"`
200*333d2b36SAndroid Build Coastguard Worker
201*333d2b36SAndroid Build Coastguard Worker	Target struct {
202*333d2b36SAndroid Build Coastguard Worker		Vendor, Product struct {
203*333d2b36SAndroid Build Coastguard Worker			// list of exported include directories, like
204*333d2b36SAndroid Build Coastguard Worker			// export_include_dirs, that will be applied to
205*333d2b36SAndroid Build Coastguard Worker			// vendor or product variant of this library.
206*333d2b36SAndroid Build Coastguard Worker			// This will overwrite any other declarations.
207*333d2b36SAndroid Build Coastguard Worker			Override_export_include_dirs []string
208*333d2b36SAndroid Build Coastguard Worker		}
209*333d2b36SAndroid Build Coastguard Worker	}
210*333d2b36SAndroid Build Coastguard Worker}
211*333d2b36SAndroid Build Coastguard Worker
212*333d2b36SAndroid Build Coastguard Workerfunc init() {
213*333d2b36SAndroid Build Coastguard Worker	RegisterLibraryBuildComponents(android.InitRegistrationContext)
214*333d2b36SAndroid Build Coastguard Worker}
215*333d2b36SAndroid Build Coastguard Worker
216*333d2b36SAndroid Build Coastguard Workerfunc RegisterLibraryBuildComponents(ctx android.RegistrationContext) {
217*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory)
218*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory)
219*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("cc_library", LibraryFactory)
220*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory)
221*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory)
222*333d2b36SAndroid Build Coastguard Worker}
223*333d2b36SAndroid Build Coastguard Worker
224*333d2b36SAndroid Build Coastguard Worker// cc_library creates both static and/or shared libraries for a device and/or
225*333d2b36SAndroid Build Coastguard Worker// host. By default, a cc_library has a single variant that targets the device.
226*333d2b36SAndroid Build Coastguard Worker// Specifying `host_supported: true` also creates a library that targets the
227*333d2b36SAndroid Build Coastguard Worker// host.
228*333d2b36SAndroid Build Coastguard Workerfunc LibraryFactory() android.Module {
229*333d2b36SAndroid Build Coastguard Worker	module, _ := NewLibrary(android.HostAndDeviceSupported)
230*333d2b36SAndroid Build Coastguard Worker	// Can be used as both a static and a shared library.
231*333d2b36SAndroid Build Coastguard Worker	module.sdkMemberTypes = []android.SdkMemberType{
232*333d2b36SAndroid Build Coastguard Worker		sharedLibrarySdkMemberType,
233*333d2b36SAndroid Build Coastguard Worker		staticLibrarySdkMemberType,
234*333d2b36SAndroid Build Coastguard Worker		staticAndSharedLibrarySdkMemberType,
235*333d2b36SAndroid Build Coastguard Worker	}
236*333d2b36SAndroid Build Coastguard Worker	return module.Init()
237*333d2b36SAndroid Build Coastguard Worker}
238*333d2b36SAndroid Build Coastguard Worker
239*333d2b36SAndroid Build Coastguard Worker// cc_library_static creates a static library for a device and/or host binary.
240*333d2b36SAndroid Build Coastguard Workerfunc LibraryStaticFactory() android.Module {
241*333d2b36SAndroid Build Coastguard Worker	module, library := NewLibrary(android.HostAndDeviceSupported)
242*333d2b36SAndroid Build Coastguard Worker	library.BuildOnlyStatic()
243*333d2b36SAndroid Build Coastguard Worker	module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
244*333d2b36SAndroid Build Coastguard Worker	return module.Init()
245*333d2b36SAndroid Build Coastguard Worker}
246*333d2b36SAndroid Build Coastguard Worker
247*333d2b36SAndroid Build Coastguard Worker// cc_library_shared creates a shared library for a device and/or host.
248*333d2b36SAndroid Build Coastguard Workerfunc LibrarySharedFactory() android.Module {
249*333d2b36SAndroid Build Coastguard Worker	module, library := NewLibrary(android.HostAndDeviceSupported)
250*333d2b36SAndroid Build Coastguard Worker	library.BuildOnlyShared()
251*333d2b36SAndroid Build Coastguard Worker	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
252*333d2b36SAndroid Build Coastguard Worker	return module.Init()
253*333d2b36SAndroid Build Coastguard Worker}
254*333d2b36SAndroid Build Coastguard Worker
255*333d2b36SAndroid Build Coastguard Worker// cc_library_host_static creates a static library that is linkable to a host
256*333d2b36SAndroid Build Coastguard Worker// binary.
257*333d2b36SAndroid Build Coastguard Workerfunc LibraryHostStaticFactory() android.Module {
258*333d2b36SAndroid Build Coastguard Worker	module, library := NewLibrary(android.HostSupported)
259*333d2b36SAndroid Build Coastguard Worker	library.BuildOnlyStatic()
260*333d2b36SAndroid Build Coastguard Worker	module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
261*333d2b36SAndroid Build Coastguard Worker	return module.Init()
262*333d2b36SAndroid Build Coastguard Worker}
263*333d2b36SAndroid Build Coastguard Worker
264*333d2b36SAndroid Build Coastguard Worker// cc_library_host_shared creates a shared library that is usable on a host.
265*333d2b36SAndroid Build Coastguard Workerfunc LibraryHostSharedFactory() android.Module {
266*333d2b36SAndroid Build Coastguard Worker	module, library := NewLibrary(android.HostSupported)
267*333d2b36SAndroid Build Coastguard Worker	library.BuildOnlyShared()
268*333d2b36SAndroid Build Coastguard Worker	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
269*333d2b36SAndroid Build Coastguard Worker	return module.Init()
270*333d2b36SAndroid Build Coastguard Worker}
271*333d2b36SAndroid Build Coastguard Worker
272*333d2b36SAndroid Build Coastguard Worker// flagExporter is a separated portion of libraryDecorator pertaining to exported
273*333d2b36SAndroid Build Coastguard Worker// include paths and flags. Keeping this dependency-related information separate
274*333d2b36SAndroid Build Coastguard Worker// from the rest of library information is helpful in keeping data more structured
275*333d2b36SAndroid Build Coastguard Worker// and explicit.
276*333d2b36SAndroid Build Coastguard Workertype flagExporter struct {
277*333d2b36SAndroid Build Coastguard Worker	Properties FlagExporterProperties
278*333d2b36SAndroid Build Coastguard Worker
279*333d2b36SAndroid Build Coastguard Worker	dirs         android.Paths // Include directories to be included with -I
280*333d2b36SAndroid Build Coastguard Worker	systemDirs   android.Paths // System include directories to be included with -isystem
281*333d2b36SAndroid Build Coastguard Worker	flags        []string      // Exported raw flags.
282*333d2b36SAndroid Build Coastguard Worker	deps         android.Paths
283*333d2b36SAndroid Build Coastguard Worker	headers      android.Paths
284*333d2b36SAndroid Build Coastguard Worker	rustRlibDeps []RustRlibDep
285*333d2b36SAndroid Build Coastguard Worker}
286*333d2b36SAndroid Build Coastguard Worker
287*333d2b36SAndroid Build Coastguard Worker// exportedIncludes returns the effective include paths for this module and
288*333d2b36SAndroid Build Coastguard Worker// any module that links against this module. This is obtained from
289*333d2b36SAndroid Build Coastguard Worker// the export_include_dirs property in the appropriate target stanza.
290*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
291*333d2b36SAndroid Build Coastguard Worker	if ctx.inVendor() && f.Properties.Target.Vendor.Override_export_include_dirs != nil {
292*333d2b36SAndroid Build Coastguard Worker		return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs)
293*333d2b36SAndroid Build Coastguard Worker	}
294*333d2b36SAndroid Build Coastguard Worker	if ctx.inProduct() && f.Properties.Target.Product.Override_export_include_dirs != nil {
295*333d2b36SAndroid Build Coastguard Worker		return android.PathsForModuleSrc(ctx, f.Properties.Target.Product.Override_export_include_dirs)
296*333d2b36SAndroid Build Coastguard Worker	}
297*333d2b36SAndroid Build Coastguard Worker	return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs.GetOrDefault(ctx, nil))
298*333d2b36SAndroid Build Coastguard Worker}
299*333d2b36SAndroid Build Coastguard Worker
300*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) exportedSystemIncludes(ctx ModuleContext) android.Paths {
301*333d2b36SAndroid Build Coastguard Worker	return android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)
302*333d2b36SAndroid Build Coastguard Worker}
303*333d2b36SAndroid Build Coastguard Worker
304*333d2b36SAndroid Build Coastguard Worker// exportIncludes registers the include directories and system include directories to be exported
305*333d2b36SAndroid Build Coastguard Worker// transitively to modules depending on this module.
306*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) exportIncludes(ctx ModuleContext) {
307*333d2b36SAndroid Build Coastguard Worker	f.dirs = append(f.dirs, f.exportedIncludes(ctx)...)
308*333d2b36SAndroid Build Coastguard Worker	f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
309*333d2b36SAndroid Build Coastguard Worker}
310*333d2b36SAndroid Build Coastguard Worker
311*333d2b36SAndroid Build Coastguard Worker// exportIncludesAsSystem registers the include directories and system include directories to be
312*333d2b36SAndroid Build Coastguard Worker// exported transitively both as system include directories to modules depending on this module.
313*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) {
314*333d2b36SAndroid Build Coastguard Worker	// all dirs are force exported as system
315*333d2b36SAndroid Build Coastguard Worker	f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...)
316*333d2b36SAndroid Build Coastguard Worker	f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
317*333d2b36SAndroid Build Coastguard Worker}
318*333d2b36SAndroid Build Coastguard Worker
319*333d2b36SAndroid Build Coastguard Worker// reexportDirs registers the given directories as include directories to be exported transitively
320*333d2b36SAndroid Build Coastguard Worker// to modules depending on this module.
321*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) reexportDirs(dirs ...android.Path) {
322*333d2b36SAndroid Build Coastguard Worker	f.dirs = append(f.dirs, dirs...)
323*333d2b36SAndroid Build Coastguard Worker}
324*333d2b36SAndroid Build Coastguard Worker
325*333d2b36SAndroid Build Coastguard Worker// reexportSystemDirs registers the given directories as system include directories
326*333d2b36SAndroid Build Coastguard Worker// to be exported transitively to modules depending on this module.
327*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) reexportSystemDirs(dirs ...android.Path) {
328*333d2b36SAndroid Build Coastguard Worker	f.systemDirs = append(f.systemDirs, dirs...)
329*333d2b36SAndroid Build Coastguard Worker}
330*333d2b36SAndroid Build Coastguard Worker
331*333d2b36SAndroid Build Coastguard Worker// reexportFlags registers the flags to be exported transitively to modules depending on this
332*333d2b36SAndroid Build Coastguard Worker// module.
333*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) reexportFlags(flags ...string) {
334*333d2b36SAndroid Build Coastguard Worker	if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") {
335*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("Exporting invalid flag %q: "+
336*333d2b36SAndroid Build Coastguard Worker			"use reexportDirs or reexportSystemDirs to export directories", flag))
337*333d2b36SAndroid Build Coastguard Worker	}
338*333d2b36SAndroid Build Coastguard Worker	f.flags = append(f.flags, flags...)
339*333d2b36SAndroid Build Coastguard Worker}
340*333d2b36SAndroid Build Coastguard Worker
341*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) reexportDeps(deps ...android.Path) {
342*333d2b36SAndroid Build Coastguard Worker	f.deps = append(f.deps, deps...)
343*333d2b36SAndroid Build Coastguard Worker}
344*333d2b36SAndroid Build Coastguard Worker
345*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) reexportRustStaticDeps(deps ...RustRlibDep) {
346*333d2b36SAndroid Build Coastguard Worker	f.rustRlibDeps = append(f.rustRlibDeps, deps...)
347*333d2b36SAndroid Build Coastguard Worker}
348*333d2b36SAndroid Build Coastguard Worker
349*333d2b36SAndroid Build Coastguard Worker// addExportedGeneratedHeaders does nothing but collects generated header files.
350*333d2b36SAndroid Build Coastguard Worker// This can be differ to exportedDeps which may contain phony files to minimize ninja.
351*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
352*333d2b36SAndroid Build Coastguard Worker	f.headers = append(f.headers, headers...)
353*333d2b36SAndroid Build Coastguard Worker}
354*333d2b36SAndroid Build Coastguard Worker
355*333d2b36SAndroid Build Coastguard Workerfunc (f *flagExporter) setProvider(ctx android.ModuleContext) {
356*333d2b36SAndroid Build Coastguard Worker	android.SetProvider(ctx, FlagExporterInfoProvider, FlagExporterInfo{
357*333d2b36SAndroid Build Coastguard Worker		// Comes from Export_include_dirs property, and those of exported transitive deps
358*333d2b36SAndroid Build Coastguard Worker		IncludeDirs: android.FirstUniquePaths(f.dirs),
359*333d2b36SAndroid Build Coastguard Worker		// Comes from Export_system_include_dirs property, and those of exported transitive deps
360*333d2b36SAndroid Build Coastguard Worker		SystemIncludeDirs: android.FirstUniquePaths(f.systemDirs),
361*333d2b36SAndroid Build Coastguard Worker		// Used in very few places as a one-off way of adding extra defines.
362*333d2b36SAndroid Build Coastguard Worker		Flags: f.flags,
363*333d2b36SAndroid Build Coastguard Worker		// Used sparingly, for extra files that need to be explicitly exported to dependers,
364*333d2b36SAndroid Build Coastguard Worker		// or for phony files to minimize ninja.
365*333d2b36SAndroid Build Coastguard Worker		Deps: f.deps,
366*333d2b36SAndroid Build Coastguard Worker		// Used for exporting rlib deps of static libraries to dependents.
367*333d2b36SAndroid Build Coastguard Worker		RustRlibDeps: f.rustRlibDeps,
368*333d2b36SAndroid Build Coastguard Worker		// For exported generated headers, such as exported aidl headers, proto headers, or
369*333d2b36SAndroid Build Coastguard Worker		// sysprop headers.
370*333d2b36SAndroid Build Coastguard Worker		GeneratedHeaders: f.headers,
371*333d2b36SAndroid Build Coastguard Worker	})
372*333d2b36SAndroid Build Coastguard Worker}
373*333d2b36SAndroid Build Coastguard Worker
374*333d2b36SAndroid Build Coastguard Worker// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific
375*333d2b36SAndroid Build Coastguard Worker// functionality: static vs. shared linkage, reusing object files for shared libraries
376*333d2b36SAndroid Build Coastguard Workertype libraryDecorator struct {
377*333d2b36SAndroid Build Coastguard Worker	Properties        LibraryProperties
378*333d2b36SAndroid Build Coastguard Worker	StaticProperties  StaticProperties
379*333d2b36SAndroid Build Coastguard Worker	SharedProperties  SharedProperties
380*333d2b36SAndroid Build Coastguard Worker	MutatedProperties LibraryMutatedProperties
381*333d2b36SAndroid Build Coastguard Worker
382*333d2b36SAndroid Build Coastguard Worker	// For reusing static library objects for shared library
383*333d2b36SAndroid Build Coastguard Worker	reuseObjects Objects
384*333d2b36SAndroid Build Coastguard Worker
385*333d2b36SAndroid Build Coastguard Worker	// table-of-contents file to optimize out relinking when possible
386*333d2b36SAndroid Build Coastguard Worker	tocFile android.OptionalPath
387*333d2b36SAndroid Build Coastguard Worker
388*333d2b36SAndroid Build Coastguard Worker	flagExporter
389*333d2b36SAndroid Build Coastguard Worker	flagExporterInfo *FlagExporterInfo
390*333d2b36SAndroid Build Coastguard Worker	stripper         Stripper
391*333d2b36SAndroid Build Coastguard Worker
392*333d2b36SAndroid Build Coastguard Worker	// For whole_static_libs
393*333d2b36SAndroid Build Coastguard Worker	objects                      Objects
394*333d2b36SAndroid Build Coastguard Worker	wholeStaticLibsFromPrebuilts android.Paths
395*333d2b36SAndroid Build Coastguard Worker
396*333d2b36SAndroid Build Coastguard Worker	// Uses the module's name if empty, but can be overridden. Does not include
397*333d2b36SAndroid Build Coastguard Worker	// shlib suffix.
398*333d2b36SAndroid Build Coastguard Worker	libName string
399*333d2b36SAndroid Build Coastguard Worker
400*333d2b36SAndroid Build Coastguard Worker	sabi *sabi
401*333d2b36SAndroid Build Coastguard Worker
402*333d2b36SAndroid Build Coastguard Worker	// Output archive of gcno coverage information files
403*333d2b36SAndroid Build Coastguard Worker	coverageOutputFile android.OptionalPath
404*333d2b36SAndroid Build Coastguard Worker
405*333d2b36SAndroid Build Coastguard Worker	// Source Abi Diff
406*333d2b36SAndroid Build Coastguard Worker	sAbiDiff android.Paths
407*333d2b36SAndroid Build Coastguard Worker
408*333d2b36SAndroid Build Coastguard Worker	// Location of the static library in the sysroot. Empty if the library is
409*333d2b36SAndroid Build Coastguard Worker	// not included in the NDK.
410*333d2b36SAndroid Build Coastguard Worker	ndkSysrootPath android.Path
411*333d2b36SAndroid Build Coastguard Worker
412*333d2b36SAndroid Build Coastguard Worker	// Location of the linked, unstripped library for shared libraries
413*333d2b36SAndroid Build Coastguard Worker	unstrippedOutputFile android.Path
414*333d2b36SAndroid Build Coastguard Worker	// Location of the linked, stripped library for shared libraries, strip: "all"
415*333d2b36SAndroid Build Coastguard Worker	strippedAllOutputFile android.Path
416*333d2b36SAndroid Build Coastguard Worker
417*333d2b36SAndroid Build Coastguard Worker	// Location of the file that should be copied to dist dir when requested
418*333d2b36SAndroid Build Coastguard Worker	distFile android.Path
419*333d2b36SAndroid Build Coastguard Worker
420*333d2b36SAndroid Build Coastguard Worker	versionScriptPath android.OptionalPath
421*333d2b36SAndroid Build Coastguard Worker
422*333d2b36SAndroid Build Coastguard Worker	postInstallCmds []string
423*333d2b36SAndroid Build Coastguard Worker
424*333d2b36SAndroid Build Coastguard Worker	skipAPIDefine bool
425*333d2b36SAndroid Build Coastguard Worker
426*333d2b36SAndroid Build Coastguard Worker	// Decorated interfaces
427*333d2b36SAndroid Build Coastguard Worker	*baseCompiler
428*333d2b36SAndroid Build Coastguard Worker	*baseLinker
429*333d2b36SAndroid Build Coastguard Worker	*baseInstaller
430*333d2b36SAndroid Build Coastguard Worker
431*333d2b36SAndroid Build Coastguard Worker	apiListCoverageXmlPath android.ModuleOutPath
432*333d2b36SAndroid Build Coastguard Worker
433*333d2b36SAndroid Build Coastguard Worker	// Path to the file containing the APIs exported by this library
434*333d2b36SAndroid Build Coastguard Worker	stubsSymbolFilePath android.Path
435*333d2b36SAndroid Build Coastguard Worker}
436*333d2b36SAndroid Build Coastguard Worker
437*333d2b36SAndroid Build Coastguard Worker// linkerProps returns the list of properties structs relevant for this library. (For example, if
438*333d2b36SAndroid Build Coastguard Worker// the library is cc_shared_library, then static-library properties are omitted.)
439*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkerProps() []interface{} {
440*333d2b36SAndroid Build Coastguard Worker	var props []interface{}
441*333d2b36SAndroid Build Coastguard Worker	props = append(props, library.baseLinker.linkerProps()...)
442*333d2b36SAndroid Build Coastguard Worker	props = append(props,
443*333d2b36SAndroid Build Coastguard Worker		&library.Properties,
444*333d2b36SAndroid Build Coastguard Worker		&library.MutatedProperties,
445*333d2b36SAndroid Build Coastguard Worker		&library.flagExporter.Properties,
446*333d2b36SAndroid Build Coastguard Worker		&library.stripper.StripProperties)
447*333d2b36SAndroid Build Coastguard Worker
448*333d2b36SAndroid Build Coastguard Worker	if library.MutatedProperties.BuildShared {
449*333d2b36SAndroid Build Coastguard Worker		props = append(props, &library.SharedProperties)
450*333d2b36SAndroid Build Coastguard Worker	}
451*333d2b36SAndroid Build Coastguard Worker	if library.MutatedProperties.BuildStatic {
452*333d2b36SAndroid Build Coastguard Worker		props = append(props, &library.StaticProperties)
453*333d2b36SAndroid Build Coastguard Worker	}
454*333d2b36SAndroid Build Coastguard Worker
455*333d2b36SAndroid Build Coastguard Worker	return props
456*333d2b36SAndroid Build Coastguard Worker}
457*333d2b36SAndroid Build Coastguard Worker
458*333d2b36SAndroid Build Coastguard Worker// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this
459*333d2b36SAndroid Build Coastguard Worker// library, or that are implied by attributes of this library (such as whether this library is a
460*333d2b36SAndroid Build Coastguard Worker// shared library).
461*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
462*333d2b36SAndroid Build Coastguard Worker	flags = library.baseLinker.linkerFlags(ctx, flags)
463*333d2b36SAndroid Build Coastguard Worker
464*333d2b36SAndroid Build Coastguard Worker	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
465*333d2b36SAndroid Build Coastguard Worker	// all code is position independent, and then those warnings get promoted to
466*333d2b36SAndroid Build Coastguard Worker	// errors.
467*333d2b36SAndroid Build Coastguard Worker	if !ctx.Windows() {
468*333d2b36SAndroid Build Coastguard Worker		flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC")
469*333d2b36SAndroid Build Coastguard Worker	}
470*333d2b36SAndroid Build Coastguard Worker
471*333d2b36SAndroid Build Coastguard Worker	if library.static() {
472*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...)
473*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
474*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)...)
475*333d2b36SAndroid Build Coastguard Worker	}
476*333d2b36SAndroid Build Coastguard Worker
477*333d2b36SAndroid Build Coastguard Worker	if library.shared() {
478*333d2b36SAndroid Build Coastguard Worker		libName := library.getLibName(ctx)
479*333d2b36SAndroid Build Coastguard Worker		var f []string
480*333d2b36SAndroid Build Coastguard Worker		if ctx.toolchain().Bionic() {
481*333d2b36SAndroid Build Coastguard Worker			f = append(f,
482*333d2b36SAndroid Build Coastguard Worker				"-nostdlib",
483*333d2b36SAndroid Build Coastguard Worker				"-Wl,--gc-sections",
484*333d2b36SAndroid Build Coastguard Worker			)
485*333d2b36SAndroid Build Coastguard Worker		}
486*333d2b36SAndroid Build Coastguard Worker
487*333d2b36SAndroid Build Coastguard Worker		if ctx.Darwin() {
488*333d2b36SAndroid Build Coastguard Worker			f = append(f,
489*333d2b36SAndroid Build Coastguard Worker				"-dynamiclib",
490*333d2b36SAndroid Build Coastguard Worker				"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
491*333d2b36SAndroid Build Coastguard Worker			)
492*333d2b36SAndroid Build Coastguard Worker			if ctx.Arch().ArchType == android.X86 {
493*333d2b36SAndroid Build Coastguard Worker				f = append(f,
494*333d2b36SAndroid Build Coastguard Worker					"-read_only_relocs suppress",
495*333d2b36SAndroid Build Coastguard Worker				)
496*333d2b36SAndroid Build Coastguard Worker			}
497*333d2b36SAndroid Build Coastguard Worker		} else {
498*333d2b36SAndroid Build Coastguard Worker			f = append(f, "-shared")
499*333d2b36SAndroid Build Coastguard Worker			if !ctx.Windows() {
500*333d2b36SAndroid Build Coastguard Worker				f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
501*333d2b36SAndroid Build Coastguard Worker			}
502*333d2b36SAndroid Build Coastguard Worker		}
503*333d2b36SAndroid Build Coastguard Worker
504*333d2b36SAndroid Build Coastguard Worker		flags.Global.LdFlags = append(flags.Global.LdFlags, f...)
505*333d2b36SAndroid Build Coastguard Worker	}
506*333d2b36SAndroid Build Coastguard Worker
507*333d2b36SAndroid Build Coastguard Worker	return flags
508*333d2b36SAndroid Build Coastguard Worker}
509*333d2b36SAndroid Build Coastguard Worker
510*333d2b36SAndroid Build Coastguard Worker// compilerFlags takes a Flags and augments it to contain compile flags from global values,
511*333d2b36SAndroid Build Coastguard Worker// per-target values, module type values, per-module Blueprints properties, extra flags from
512*333d2b36SAndroid Build Coastguard Worker// `flags`, and generated sources from `deps`.
513*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
514*333d2b36SAndroid Build Coastguard Worker	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
515*333d2b36SAndroid Build Coastguard Worker	if len(exportIncludeDirs) > 0 {
516*333d2b36SAndroid Build Coastguard Worker		f := includeDirsToFlags(exportIncludeDirs)
517*333d2b36SAndroid Build Coastguard Worker		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
518*333d2b36SAndroid Build Coastguard Worker		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
519*333d2b36SAndroid Build Coastguard Worker	}
520*333d2b36SAndroid Build Coastguard Worker
521*333d2b36SAndroid Build Coastguard Worker	flags = library.baseCompiler.compilerFlags(ctx, flags, deps)
522*333d2b36SAndroid Build Coastguard Worker	if ctx.IsLlndk() {
523*333d2b36SAndroid Build Coastguard Worker		// LLNDK libraries ignore most of the properties on the cc_library and use the
524*333d2b36SAndroid Build Coastguard Worker		// LLNDK-specific properties instead.
525*333d2b36SAndroid Build Coastguard Worker		// Wipe all the module-local properties, leaving only the global properties.
526*333d2b36SAndroid Build Coastguard Worker		flags.Local = LocalOrGlobalFlags{}
527*333d2b36SAndroid Build Coastguard Worker	}
528*333d2b36SAndroid Build Coastguard Worker	if library.buildStubs() {
529*333d2b36SAndroid Build Coastguard Worker		// Remove -include <file> when compiling stubs. Otherwise, the force included
530*333d2b36SAndroid Build Coastguard Worker		// headers might cause conflicting types error with the symbols in the
531*333d2b36SAndroid Build Coastguard Worker		// generated stubs source code. e.g.
532*333d2b36SAndroid Build Coastguard Worker		// double acos(double); // in header
533*333d2b36SAndroid Build Coastguard Worker		// void acos() {} // in the generated source code
534*333d2b36SAndroid Build Coastguard Worker		removeInclude := func(flags []string) []string {
535*333d2b36SAndroid Build Coastguard Worker			ret := flags[:0]
536*333d2b36SAndroid Build Coastguard Worker			for _, f := range flags {
537*333d2b36SAndroid Build Coastguard Worker				if strings.HasPrefix(f, "-include ") {
538*333d2b36SAndroid Build Coastguard Worker					continue
539*333d2b36SAndroid Build Coastguard Worker				}
540*333d2b36SAndroid Build Coastguard Worker				ret = append(ret, f)
541*333d2b36SAndroid Build Coastguard Worker			}
542*333d2b36SAndroid Build Coastguard Worker			return ret
543*333d2b36SAndroid Build Coastguard Worker		}
544*333d2b36SAndroid Build Coastguard Worker		flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags)
545*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = removeInclude(flags.Local.CFlags)
546*333d2b36SAndroid Build Coastguard Worker
547*333d2b36SAndroid Build Coastguard Worker		flags = addStubLibraryCompilerFlags(flags)
548*333d2b36SAndroid Build Coastguard Worker	}
549*333d2b36SAndroid Build Coastguard Worker	return flags
550*333d2b36SAndroid Build Coastguard Worker}
551*333d2b36SAndroid Build Coastguard Worker
552*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) getHeaderAbiCheckerProperties(m *Module) headerAbiCheckerProperties {
553*333d2b36SAndroid Build Coastguard Worker	variantProps := &library.Properties.Target.Platform.Header_abi_checker
554*333d2b36SAndroid Build Coastguard Worker	if m.InVendor() {
555*333d2b36SAndroid Build Coastguard Worker		variantProps = &library.Properties.Target.Vendor.Header_abi_checker
556*333d2b36SAndroid Build Coastguard Worker	} else if m.InProduct() {
557*333d2b36SAndroid Build Coastguard Worker		variantProps = &library.Properties.Target.Product.Header_abi_checker
558*333d2b36SAndroid Build Coastguard Worker	}
559*333d2b36SAndroid Build Coastguard Worker	props := library.Properties.Header_abi_checker
560*333d2b36SAndroid Build Coastguard Worker	err := proptools.AppendProperties(&props, variantProps, nil)
561*333d2b36SAndroid Build Coastguard Worker	if err != nil {
562*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("Cannot merge headerAbiCheckerProperties: %s", err.Error()))
563*333d2b36SAndroid Build Coastguard Worker	}
564*333d2b36SAndroid Build Coastguard Worker	return props
565*333d2b36SAndroid Build Coastguard Worker}
566*333d2b36SAndroid Build Coastguard Worker
567*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
568*333d2b36SAndroid Build Coastguard Worker	if ctx.IsLlndk() {
569*333d2b36SAndroid Build Coastguard Worker		// Get the matching SDK version for the vendor API level.
570*333d2b36SAndroid Build Coastguard Worker		version, err := android.GetSdkVersionForVendorApiLevel(ctx.Config().VendorApiLevel())
571*333d2b36SAndroid Build Coastguard Worker		if err != nil {
572*333d2b36SAndroid Build Coastguard Worker			panic(err)
573*333d2b36SAndroid Build Coastguard Worker		}
574*333d2b36SAndroid Build Coastguard Worker
575*333d2b36SAndroid Build Coastguard Worker		// This is the vendor variant of an LLNDK library, build the LLNDK stubs.
576*333d2b36SAndroid Build Coastguard Worker		nativeAbiResult := parseNativeAbiDefinition(ctx,
577*333d2b36SAndroid Build Coastguard Worker			String(library.Properties.Llndk.Symbol_file),
578*333d2b36SAndroid Build Coastguard Worker			nativeClampedApiLevel(ctx, version), "--llndk")
579*333d2b36SAndroid Build Coastguard Worker		objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
580*333d2b36SAndroid Build Coastguard Worker		if !Bool(library.Properties.Llndk.Unversioned) {
581*333d2b36SAndroid Build Coastguard Worker			library.versionScriptPath = android.OptionalPathForPath(
582*333d2b36SAndroid Build Coastguard Worker				nativeAbiResult.versionScript)
583*333d2b36SAndroid Build Coastguard Worker		}
584*333d2b36SAndroid Build Coastguard Worker		return objs
585*333d2b36SAndroid Build Coastguard Worker	}
586*333d2b36SAndroid Build Coastguard Worker	if ctx.IsVendorPublicLibrary() {
587*333d2b36SAndroid Build Coastguard Worker		nativeAbiResult := parseNativeAbiDefinition(ctx,
588*333d2b36SAndroid Build Coastguard Worker			String(library.Properties.Vendor_public_library.Symbol_file),
589*333d2b36SAndroid Build Coastguard Worker			android.FutureApiLevel, "")
590*333d2b36SAndroid Build Coastguard Worker		objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
591*333d2b36SAndroid Build Coastguard Worker		if !Bool(library.Properties.Vendor_public_library.Unversioned) {
592*333d2b36SAndroid Build Coastguard Worker			library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.versionScript)
593*333d2b36SAndroid Build Coastguard Worker		}
594*333d2b36SAndroid Build Coastguard Worker		return objs
595*333d2b36SAndroid Build Coastguard Worker	}
596*333d2b36SAndroid Build Coastguard Worker	if library.buildStubs() {
597*333d2b36SAndroid Build Coastguard Worker		return library.compileModuleLibApiStubs(ctx, flags, deps)
598*333d2b36SAndroid Build Coastguard Worker	}
599*333d2b36SAndroid Build Coastguard Worker
600*333d2b36SAndroid Build Coastguard Worker	srcs := library.baseCompiler.Properties.Srcs.GetOrDefault(ctx, nil)
601*333d2b36SAndroid Build Coastguard Worker	staticSrcs := library.StaticProperties.Static.Srcs.GetOrDefault(ctx, nil)
602*333d2b36SAndroid Build Coastguard Worker	sharedSrcs := library.SharedProperties.Shared.Srcs.GetOrDefault(ctx, nil)
603*333d2b36SAndroid Build Coastguard Worker	if !library.buildShared() && !library.buildStatic() {
604*333d2b36SAndroid Build Coastguard Worker		if len(srcs) > 0 {
605*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs")
606*333d2b36SAndroid Build Coastguard Worker		}
607*333d2b36SAndroid Build Coastguard Worker		if len(staticSrcs) > 0 {
608*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs")
609*333d2b36SAndroid Build Coastguard Worker		}
610*333d2b36SAndroid Build Coastguard Worker		if len(sharedSrcs) > 0 {
611*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs")
612*333d2b36SAndroid Build Coastguard Worker		}
613*333d2b36SAndroid Build Coastguard Worker		return Objects{}
614*333d2b36SAndroid Build Coastguard Worker	}
615*333d2b36SAndroid Build Coastguard Worker	if library.sabi.shouldCreateSourceAbiDump() {
616*333d2b36SAndroid Build Coastguard Worker		dirs := library.exportedIncludeDirsForAbiCheck(ctx)
617*333d2b36SAndroid Build Coastguard Worker		flags.SAbiFlags = make([]string, 0, len(dirs))
618*333d2b36SAndroid Build Coastguard Worker		for _, dir := range dirs {
619*333d2b36SAndroid Build Coastguard Worker			flags.SAbiFlags = append(flags.SAbiFlags, "-I"+dir)
620*333d2b36SAndroid Build Coastguard Worker		}
621*333d2b36SAndroid Build Coastguard Worker		totalLength := len(srcs) + len(deps.GeneratedSources) +
622*333d2b36SAndroid Build Coastguard Worker			len(sharedSrcs) + len(staticSrcs)
623*333d2b36SAndroid Build Coastguard Worker		if totalLength > 0 {
624*333d2b36SAndroid Build Coastguard Worker			flags.SAbiDump = true
625*333d2b36SAndroid Build Coastguard Worker		}
626*333d2b36SAndroid Build Coastguard Worker	}
627*333d2b36SAndroid Build Coastguard Worker	objs := library.baseCompiler.compile(ctx, flags, deps)
628*333d2b36SAndroid Build Coastguard Worker	library.reuseObjects = objs
629*333d2b36SAndroid Build Coastguard Worker	buildFlags := flagsToBuilderFlags(flags)
630*333d2b36SAndroid Build Coastguard Worker
631*333d2b36SAndroid Build Coastguard Worker	if library.static() {
632*333d2b36SAndroid Build Coastguard Worker		srcs := android.PathsForModuleSrc(ctx, staticSrcs)
633*333d2b36SAndroid Build Coastguard Worker		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, srcs,
634*333d2b36SAndroid Build Coastguard Worker			android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_disabled_srcs),
635*333d2b36SAndroid Build Coastguard Worker			android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_timeout_srcs),
636*333d2b36SAndroid Build Coastguard Worker			library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
637*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
638*333d2b36SAndroid Build Coastguard Worker		srcs := android.PathsForModuleSrc(ctx, sharedSrcs)
639*333d2b36SAndroid Build Coastguard Worker		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, srcs,
640*333d2b36SAndroid Build Coastguard Worker			android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_disabled_srcs),
641*333d2b36SAndroid Build Coastguard Worker			android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_timeout_srcs),
642*333d2b36SAndroid Build Coastguard Worker			library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
643*333d2b36SAndroid Build Coastguard Worker	}
644*333d2b36SAndroid Build Coastguard Worker
645*333d2b36SAndroid Build Coastguard Worker	return objs
646*333d2b36SAndroid Build Coastguard Worker}
647*333d2b36SAndroid Build Coastguard Worker
648*333d2b36SAndroid Build Coastguard Worker// Compile stubs for the API surface between platform and apex
649*333d2b36SAndroid Build Coastguard Worker// This method will be used by source and prebuilt cc module types.
650*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
651*333d2b36SAndroid Build Coastguard Worker	// TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk.
652*333d2b36SAndroid Build Coastguard Worker	if library.Properties.Stubs.Symbol_file == nil {
653*333d2b36SAndroid Build Coastguard Worker		return Objects{}
654*333d2b36SAndroid Build Coastguard Worker	}
655*333d2b36SAndroid Build Coastguard Worker	symbolFile := String(library.Properties.Stubs.Symbol_file)
656*333d2b36SAndroid Build Coastguard Worker	library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
657*333d2b36SAndroid Build Coastguard Worker	// b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
658*333d2b36SAndroid Build Coastguard Worker	// systemapi, respectively. The former is for symbols defined in platform libraries
659*333d2b36SAndroid Build Coastguard Worker	// and the latter is for symbols defined in APEXes.
660*333d2b36SAndroid Build Coastguard Worker	// A single library can contain either # apex or # systemapi, but not both.
661*333d2b36SAndroid Build Coastguard Worker	// The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
662*333d2b36SAndroid Build Coastguard Worker	// However, having this distinction helps guard accidental
663*333d2b36SAndroid Build Coastguard Worker	// promotion or demotion of API and also helps the API review process b/191371676
664*333d2b36SAndroid Build Coastguard Worker	var flag string
665*333d2b36SAndroid Build Coastguard Worker	if ctx.notInPlatform() {
666*333d2b36SAndroid Build Coastguard Worker		flag = "--apex"
667*333d2b36SAndroid Build Coastguard Worker	} else {
668*333d2b36SAndroid Build Coastguard Worker		flag = "--systemapi"
669*333d2b36SAndroid Build Coastguard Worker	}
670*333d2b36SAndroid Build Coastguard Worker	// b/184712170, unless the lib is an NDK library, exclude all public symbols from
671*333d2b36SAndroid Build Coastguard Worker	// the stub so that it is mandated that all symbols are explicitly marked with
672*333d2b36SAndroid Build Coastguard Worker	// either apex or systemapi.
673*333d2b36SAndroid Build Coastguard Worker	if !ctx.Module().(*Module).IsNdk(ctx.Config()) &&
674*333d2b36SAndroid Build Coastguard Worker		// the symbol files of libclang libs are autogenerated and do not contain systemapi tags
675*333d2b36SAndroid Build Coastguard Worker		// TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols
676*333d2b36SAndroid Build Coastguard Worker		!strings.Contains(ctx.ModuleName(), "libclang_rt") {
677*333d2b36SAndroid Build Coastguard Worker		flag = flag + " --no-ndk"
678*333d2b36SAndroid Build Coastguard Worker	}
679*333d2b36SAndroid Build Coastguard Worker	// TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches.
680*333d2b36SAndroid Build Coastguard Worker	if isBionic(ctx.baseModuleName()) {
681*333d2b36SAndroid Build Coastguard Worker		// set the flags explicitly for bionic libs.
682*333d2b36SAndroid Build Coastguard Worker		// this is necessary for development in minimal branches which does not contain bionic/*.
683*333d2b36SAndroid Build Coastguard Worker		// In such minimal branches, e.g. on the prebuilt libc stubs
684*333d2b36SAndroid Build Coastguard Worker		// 1. IsNdk will return false (since the ndk_library definition for libc does not exist)
685*333d2b36SAndroid Build Coastguard Worker		// 2. NotInPlatform will return true (since the source com.android.runtime does not exist)
686*333d2b36SAndroid Build Coastguard Worker		flag = "--apex"
687*333d2b36SAndroid Build Coastguard Worker	}
688*333d2b36SAndroid Build Coastguard Worker	nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
689*333d2b36SAndroid Build Coastguard Worker		android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
690*333d2b36SAndroid Build Coastguard Worker	objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
691*333d2b36SAndroid Build Coastguard Worker
692*333d2b36SAndroid Build Coastguard Worker	library.versionScriptPath = android.OptionalPathForPath(
693*333d2b36SAndroid Build Coastguard Worker		nativeAbiResult.versionScript)
694*333d2b36SAndroid Build Coastguard Worker
695*333d2b36SAndroid Build Coastguard Worker	// Parse symbol file to get API list for coverage
696*333d2b36SAndroid Build Coastguard Worker	if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
697*333d2b36SAndroid Build Coastguard Worker		library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
698*333d2b36SAndroid Build Coastguard Worker	}
699*333d2b36SAndroid Build Coastguard Worker
700*333d2b36SAndroid Build Coastguard Worker	return objs
701*333d2b36SAndroid Build Coastguard Worker}
702*333d2b36SAndroid Build Coastguard Worker
703*333d2b36SAndroid Build Coastguard Workertype libraryInterface interface {
704*333d2b36SAndroid Build Coastguard Worker	versionedInterface
705*333d2b36SAndroid Build Coastguard Worker
706*333d2b36SAndroid Build Coastguard Worker	static() bool
707*333d2b36SAndroid Build Coastguard Worker	shared() bool
708*333d2b36SAndroid Build Coastguard Worker	objs() Objects
709*333d2b36SAndroid Build Coastguard Worker	reuseObjs() Objects
710*333d2b36SAndroid Build Coastguard Worker	toc() android.OptionalPath
711*333d2b36SAndroid Build Coastguard Worker
712*333d2b36SAndroid Build Coastguard Worker	// Returns true if the build options for the module have selected a static or shared build
713*333d2b36SAndroid Build Coastguard Worker	buildStatic() bool
714*333d2b36SAndroid Build Coastguard Worker	buildShared() bool
715*333d2b36SAndroid Build Coastguard Worker
716*333d2b36SAndroid Build Coastguard Worker	// Sets whether a specific variant is static or shared
717*333d2b36SAndroid Build Coastguard Worker	setStatic()
718*333d2b36SAndroid Build Coastguard Worker	setShared()
719*333d2b36SAndroid Build Coastguard Worker
720*333d2b36SAndroid Build Coastguard Worker	// Gets the ABI properties for vendor, product, or platform variant
721*333d2b36SAndroid Build Coastguard Worker	getHeaderAbiCheckerProperties(m *Module) headerAbiCheckerProperties
722*333d2b36SAndroid Build Coastguard Worker
723*333d2b36SAndroid Build Coastguard Worker	// Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff
724*333d2b36SAndroid Build Coastguard Worker	androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer)
725*333d2b36SAndroid Build Coastguard Worker
726*333d2b36SAndroid Build Coastguard Worker	availableFor(string) bool
727*333d2b36SAndroid Build Coastguard Worker
728*333d2b36SAndroid Build Coastguard Worker	getAPIListCoverageXMLPath() android.ModuleOutPath
729*333d2b36SAndroid Build Coastguard Worker
730*333d2b36SAndroid Build Coastguard Worker	installable() *bool
731*333d2b36SAndroid Build Coastguard Worker}
732*333d2b36SAndroid Build Coastguard Worker
733*333d2b36SAndroid Build Coastguard Workertype versionedInterface interface {
734*333d2b36SAndroid Build Coastguard Worker	buildStubs() bool
735*333d2b36SAndroid Build Coastguard Worker	setBuildStubs(isLatest bool)
736*333d2b36SAndroid Build Coastguard Worker	hasStubsVariants() bool
737*333d2b36SAndroid Build Coastguard Worker	isStubsImplementationRequired() bool
738*333d2b36SAndroid Build Coastguard Worker	setStubsVersion(string)
739*333d2b36SAndroid Build Coastguard Worker	stubsVersion() string
740*333d2b36SAndroid Build Coastguard Worker
741*333d2b36SAndroid Build Coastguard Worker	stubsVersions(ctx android.BaseModuleContext) []string
742*333d2b36SAndroid Build Coastguard Worker	setAllStubsVersions([]string)
743*333d2b36SAndroid Build Coastguard Worker	allStubsVersions() []string
744*333d2b36SAndroid Build Coastguard Worker
745*333d2b36SAndroid Build Coastguard Worker	implementationModuleName(name string) string
746*333d2b36SAndroid Build Coastguard Worker	hasLLNDKStubs() bool
747*333d2b36SAndroid Build Coastguard Worker	hasLLNDKHeaders() bool
748*333d2b36SAndroid Build Coastguard Worker	hasVendorPublicLibrary() bool
749*333d2b36SAndroid Build Coastguard Worker	isLLNDKMovedToApex() bool
750*333d2b36SAndroid Build Coastguard Worker}
751*333d2b36SAndroid Build Coastguard Worker
752*333d2b36SAndroid Build Coastguard Workervar _ libraryInterface = (*libraryDecorator)(nil)
753*333d2b36SAndroid Build Coastguard Workervar _ versionedInterface = (*libraryDecorator)(nil)
754*333d2b36SAndroid Build Coastguard Worker
755*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendor bool, inProduct bool) string {
756*333d2b36SAndroid Build Coastguard Worker	name := library.libName
757*333d2b36SAndroid Build Coastguard Worker	if name == "" {
758*333d2b36SAndroid Build Coastguard Worker		name = String(library.Properties.Stem)
759*333d2b36SAndroid Build Coastguard Worker		if name == "" {
760*333d2b36SAndroid Build Coastguard Worker			name = baseModuleName
761*333d2b36SAndroid Build Coastguard Worker		}
762*333d2b36SAndroid Build Coastguard Worker	}
763*333d2b36SAndroid Build Coastguard Worker
764*333d2b36SAndroid Build Coastguard Worker	suffix := ""
765*333d2b36SAndroid Build Coastguard Worker	if inVendor {
766*333d2b36SAndroid Build Coastguard Worker		suffix = String(library.Properties.Target.Vendor.Suffix)
767*333d2b36SAndroid Build Coastguard Worker	} else if inProduct {
768*333d2b36SAndroid Build Coastguard Worker		suffix = String(library.Properties.Target.Product.Suffix)
769*333d2b36SAndroid Build Coastguard Worker	}
770*333d2b36SAndroid Build Coastguard Worker	if suffix == "" {
771*333d2b36SAndroid Build Coastguard Worker		suffix = String(library.Properties.Suffix)
772*333d2b36SAndroid Build Coastguard Worker	}
773*333d2b36SAndroid Build Coastguard Worker
774*333d2b36SAndroid Build Coastguard Worker	return name + suffix
775*333d2b36SAndroid Build Coastguard Worker}
776*333d2b36SAndroid Build Coastguard Worker
777*333d2b36SAndroid Build Coastguard Worker// getLibName returns the actual canonical name of the library (the name which
778*333d2b36SAndroid Build Coastguard Worker// should be passed to the linker via linker flags).
779*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) getLibName(ctx BaseModuleContext) string {
780*333d2b36SAndroid Build Coastguard Worker	name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct())
781*333d2b36SAndroid Build Coastguard Worker
782*333d2b36SAndroid Build Coastguard Worker	if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
783*333d2b36SAndroid Build Coastguard Worker		if !strings.HasSuffix(name, "-host") {
784*333d2b36SAndroid Build Coastguard Worker			name = name + "-host"
785*333d2b36SAndroid Build Coastguard Worker		}
786*333d2b36SAndroid Build Coastguard Worker	}
787*333d2b36SAndroid Build Coastguard Worker
788*333d2b36SAndroid Build Coastguard Worker	return name
789*333d2b36SAndroid Build Coastguard Worker}
790*333d2b36SAndroid Build Coastguard Worker
791*333d2b36SAndroid Build Coastguard Workervar versioningMacroNamesListMutex sync.Mutex
792*333d2b36SAndroid Build Coastguard Worker
793*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
794*333d2b36SAndroid Build Coastguard Worker	location := InstallInSystem
795*333d2b36SAndroid Build Coastguard Worker	if library.baseLinker.sanitize.inSanitizerDir() {
796*333d2b36SAndroid Build Coastguard Worker		location = InstallInSanitizerDir
797*333d2b36SAndroid Build Coastguard Worker	}
798*333d2b36SAndroid Build Coastguard Worker	library.baseInstaller.location = location
799*333d2b36SAndroid Build Coastguard Worker	library.baseLinker.linkerInit(ctx)
800*333d2b36SAndroid Build Coastguard Worker	// Let baseLinker know whether this variant is for stubs or not, so that
801*333d2b36SAndroid Build Coastguard Worker	// it can omit things that are not required for linking stubs.
802*333d2b36SAndroid Build Coastguard Worker	library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs()
803*333d2b36SAndroid Build Coastguard Worker
804*333d2b36SAndroid Build Coastguard Worker	if library.buildStubs() {
805*333d2b36SAndroid Build Coastguard Worker		macroNames := versioningMacroNamesList(ctx.Config())
806*333d2b36SAndroid Build Coastguard Worker		myName := versioningMacroName(ctx.ModuleName())
807*333d2b36SAndroid Build Coastguard Worker		versioningMacroNamesListMutex.Lock()
808*333d2b36SAndroid Build Coastguard Worker		defer versioningMacroNamesListMutex.Unlock()
809*333d2b36SAndroid Build Coastguard Worker		if (*macroNames)[myName] == "" {
810*333d2b36SAndroid Build Coastguard Worker			(*macroNames)[myName] = ctx.ModuleName()
811*333d2b36SAndroid Build Coastguard Worker		} else if (*macroNames)[myName] != ctx.ModuleName() {
812*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("Macro name %q for versioning conflicts with macro name from module %q ", myName, (*macroNames)[myName])
813*333d2b36SAndroid Build Coastguard Worker		}
814*333d2b36SAndroid Build Coastguard Worker	}
815*333d2b36SAndroid Build Coastguard Worker}
816*333d2b36SAndroid Build Coastguard Worker
817*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
818*333d2b36SAndroid Build Coastguard Worker	if ctx.IsLlndk() {
819*333d2b36SAndroid Build Coastguard Worker		// LLNDK libraries ignore most of the properties on the cc_library and use the
820*333d2b36SAndroid Build Coastguard Worker		// LLNDK-specific properties instead.
821*333d2b36SAndroid Build Coastguard Worker		return deps
822*333d2b36SAndroid Build Coastguard Worker	}
823*333d2b36SAndroid Build Coastguard Worker
824*333d2b36SAndroid Build Coastguard Worker	deps = library.baseCompiler.compilerDeps(ctx, deps)
825*333d2b36SAndroid Build Coastguard Worker
826*333d2b36SAndroid Build Coastguard Worker	return deps
827*333d2b36SAndroid Build Coastguard Worker}
828*333d2b36SAndroid Build Coastguard Worker
829*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
830*333d2b36SAndroid Build Coastguard Worker	if ctx.IsLlndk() {
831*333d2b36SAndroid Build Coastguard Worker		// LLNDK libraries ignore most of the properties on the cc_library and use the
832*333d2b36SAndroid Build Coastguard Worker		// LLNDK-specific properties instead.
833*333d2b36SAndroid Build Coastguard Worker		deps.HeaderLibs = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
834*333d2b36SAndroid Build Coastguard Worker		deps.ReexportHeaderLibHeaders = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
835*333d2b36SAndroid Build Coastguard Worker		return deps
836*333d2b36SAndroid Build Coastguard Worker	}
837*333d2b36SAndroid Build Coastguard Worker	if ctx.IsVendorPublicLibrary() {
838*333d2b36SAndroid Build Coastguard Worker		headers := library.Properties.Vendor_public_library.Export_public_headers
839*333d2b36SAndroid Build Coastguard Worker		deps.HeaderLibs = append([]string(nil), headers...)
840*333d2b36SAndroid Build Coastguard Worker		deps.ReexportHeaderLibHeaders = append([]string(nil), headers...)
841*333d2b36SAndroid Build Coastguard Worker		return deps
842*333d2b36SAndroid Build Coastguard Worker	}
843*333d2b36SAndroid Build Coastguard Worker
844*333d2b36SAndroid Build Coastguard Worker	if library.static() {
845*333d2b36SAndroid Build Coastguard Worker		// Compare with nil because an empty list needs to be propagated.
846*333d2b36SAndroid Build Coastguard Worker		if library.StaticProperties.Static.System_shared_libs != nil {
847*333d2b36SAndroid Build Coastguard Worker			library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs
848*333d2b36SAndroid Build Coastguard Worker		}
849*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
850*333d2b36SAndroid Build Coastguard Worker		// Compare with nil because an empty list needs to be propagated.
851*333d2b36SAndroid Build Coastguard Worker		if library.SharedProperties.Shared.System_shared_libs != nil {
852*333d2b36SAndroid Build Coastguard Worker			library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs
853*333d2b36SAndroid Build Coastguard Worker		}
854*333d2b36SAndroid Build Coastguard Worker	}
855*333d2b36SAndroid Build Coastguard Worker
856*333d2b36SAndroid Build Coastguard Worker	deps = library.baseLinker.linkerDeps(ctx, deps)
857*333d2b36SAndroid Build Coastguard Worker
858*333d2b36SAndroid Build Coastguard Worker	if library.static() {
859*333d2b36SAndroid Build Coastguard Worker		deps.WholeStaticLibs = append(deps.WholeStaticLibs,
860*333d2b36SAndroid Build Coastguard Worker			library.StaticProperties.Static.Whole_static_libs.GetOrDefault(ctx, nil)...)
861*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = append(deps.StaticLibs, library.StaticProperties.Static.Static_libs.GetOrDefault(ctx, nil)...)
862*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = append(deps.SharedLibs, library.StaticProperties.Static.Shared_libs.GetOrDefault(ctx, nil)...)
863*333d2b36SAndroid Build Coastguard Worker
864*333d2b36SAndroid Build Coastguard Worker		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...)
865*333d2b36SAndroid Build Coastguard Worker		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...)
866*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
867*333d2b36SAndroid Build Coastguard Worker		if library.baseLinker.Properties.crt() {
868*333d2b36SAndroid Build Coastguard Worker			deps.CrtBegin = append(deps.CrtBegin, ctx.toolchain().CrtBeginSharedLibrary()...)
869*333d2b36SAndroid Build Coastguard Worker			deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtEndSharedLibrary()...)
870*333d2b36SAndroid Build Coastguard Worker
871*333d2b36SAndroid Build Coastguard Worker		}
872*333d2b36SAndroid Build Coastguard Worker		if library.baseLinker.Properties.crtPadSegment() {
873*333d2b36SAndroid Build Coastguard Worker			deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtPadSegmentSharedLibrary()...)
874*333d2b36SAndroid Build Coastguard Worker		}
875*333d2b36SAndroid Build Coastguard Worker		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs.GetOrDefault(ctx, nil)...)
876*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs.GetOrDefault(ctx, nil)...)
877*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = append(deps.SharedLibs, library.SharedProperties.Shared.Shared_libs.GetOrDefault(ctx, nil)...)
878*333d2b36SAndroid Build Coastguard Worker
879*333d2b36SAndroid Build Coastguard Worker		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...)
880*333d2b36SAndroid Build Coastguard Worker		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...)
881*333d2b36SAndroid Build Coastguard Worker
882*333d2b36SAndroid Build Coastguard Worker		deps.LlndkHeaderLibs = append(deps.LlndkHeaderLibs, library.Properties.Llndk.Export_llndk_headers...)
883*333d2b36SAndroid Build Coastguard Worker	}
884*333d2b36SAndroid Build Coastguard Worker	if ctx.inVendor() {
885*333d2b36SAndroid Build Coastguard Worker		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
886*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
887*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
888*333d2b36SAndroid Build Coastguard Worker		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
889*333d2b36SAndroid Build Coastguard Worker		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
890*333d2b36SAndroid Build Coastguard Worker	}
891*333d2b36SAndroid Build Coastguard Worker	if ctx.inProduct() {
892*333d2b36SAndroid Build Coastguard Worker		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
893*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Product.Exclude_shared_libs)
894*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
895*333d2b36SAndroid Build Coastguard Worker		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_shared_libs)
896*333d2b36SAndroid Build Coastguard Worker		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
897*333d2b36SAndroid Build Coastguard Worker	}
898*333d2b36SAndroid Build Coastguard Worker	if ctx.inRecovery() {
899*333d2b36SAndroid Build Coastguard Worker		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
900*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs)
901*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
902*333d2b36SAndroid Build Coastguard Worker		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs)
903*333d2b36SAndroid Build Coastguard Worker		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
904*333d2b36SAndroid Build Coastguard Worker	}
905*333d2b36SAndroid Build Coastguard Worker	if ctx.inRamdisk() {
906*333d2b36SAndroid Build Coastguard Worker		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
907*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs)
908*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
909*333d2b36SAndroid Build Coastguard Worker		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs)
910*333d2b36SAndroid Build Coastguard Worker		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
911*333d2b36SAndroid Build Coastguard Worker	}
912*333d2b36SAndroid Build Coastguard Worker	if ctx.inVendorRamdisk() {
913*333d2b36SAndroid Build Coastguard Worker		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
914*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
915*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
916*333d2b36SAndroid Build Coastguard Worker		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
917*333d2b36SAndroid Build Coastguard Worker		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
918*333d2b36SAndroid Build Coastguard Worker	}
919*333d2b36SAndroid Build Coastguard Worker
920*333d2b36SAndroid Build Coastguard Worker	return deps
921*333d2b36SAndroid Build Coastguard Worker}
922*333d2b36SAndroid Build Coastguard Worker
923*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
924*333d2b36SAndroid Build Coastguard Worker	specifiedDeps = library.baseLinker.linkerSpecifiedDeps(ctx, module, specifiedDeps)
925*333d2b36SAndroid Build Coastguard Worker	var properties StaticOrSharedProperties
926*333d2b36SAndroid Build Coastguard Worker	if library.static() {
927*333d2b36SAndroid Build Coastguard Worker		properties = library.StaticProperties.Static
928*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
929*333d2b36SAndroid Build Coastguard Worker		properties = library.SharedProperties.Shared
930*333d2b36SAndroid Build Coastguard Worker	}
931*333d2b36SAndroid Build Coastguard Worker
932*333d2b36SAndroid Build Coastguard Worker	eval := module.ConfigurableEvaluator(ctx)
933*333d2b36SAndroid Build Coastguard Worker	specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs.GetOrDefault(eval, nil)...)
934*333d2b36SAndroid Build Coastguard Worker
935*333d2b36SAndroid Build Coastguard Worker	// Must distinguish nil and [] in system_shared_libs - ensure that [] in
936*333d2b36SAndroid Build Coastguard Worker	// either input list doesn't come out as nil.
937*333d2b36SAndroid Build Coastguard Worker	if specifiedDeps.systemSharedLibs == nil {
938*333d2b36SAndroid Build Coastguard Worker		specifiedDeps.systemSharedLibs = properties.System_shared_libs
939*333d2b36SAndroid Build Coastguard Worker	} else {
940*333d2b36SAndroid Build Coastguard Worker		specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...)
941*333d2b36SAndroid Build Coastguard Worker	}
942*333d2b36SAndroid Build Coastguard Worker
943*333d2b36SAndroid Build Coastguard Worker	specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs)
944*333d2b36SAndroid Build Coastguard Worker	if len(specifiedDeps.systemSharedLibs) > 0 {
945*333d2b36SAndroid Build Coastguard Worker		// Skip this if systemSharedLibs is either nil or [], to ensure they are
946*333d2b36SAndroid Build Coastguard Worker		// retained.
947*333d2b36SAndroid Build Coastguard Worker		specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs)
948*333d2b36SAndroid Build Coastguard Worker	}
949*333d2b36SAndroid Build Coastguard Worker	return specifiedDeps
950*333d2b36SAndroid Build Coastguard Worker}
951*333d2b36SAndroid Build Coastguard Worker
952*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
953*333d2b36SAndroid Build Coastguard Worker	if library.static() {
954*333d2b36SAndroid Build Coastguard Worker		moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
955*333d2b36SAndroid Build Coastguard Worker		moduleInfoJSON.Uninstallable = true
956*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
957*333d2b36SAndroid Build Coastguard Worker		moduleInfoJSON.Class = []string{"SHARED_LIBRARIES"}
958*333d2b36SAndroid Build Coastguard Worker	} else if library.header() {
959*333d2b36SAndroid Build Coastguard Worker		moduleInfoJSON.Class = []string{"HEADER_LIBRARIES"}
960*333d2b36SAndroid Build Coastguard Worker		moduleInfoJSON.Uninstallable = true
961*333d2b36SAndroid Build Coastguard Worker	}
962*333d2b36SAndroid Build Coastguard Worker
963*333d2b36SAndroid Build Coastguard Worker	if library.buildStubs() && library.stubsVersion() != "" {
964*333d2b36SAndroid Build Coastguard Worker		moduleInfoJSON.SubName += "." + library.stubsVersion()
965*333d2b36SAndroid Build Coastguard Worker	}
966*333d2b36SAndroid Build Coastguard Worker
967*333d2b36SAndroid Build Coastguard Worker	// If a library providing a stub is included in an APEX, the private APIs of the library
968*333d2b36SAndroid Build Coastguard Worker	// is accessible only inside the APEX. From outside of the APEX, clients can only use the
969*333d2b36SAndroid Build Coastguard Worker	// public APIs via the stub. To enforce this, the (latest version of the) stub gets the
970*333d2b36SAndroid Build Coastguard Worker	// name of the library. The impl library instead gets the `.bootstrap` suffix to so that
971*333d2b36SAndroid Build Coastguard Worker	// they can be exceptionally used directly when APEXes are not available (e.g. during the
972*333d2b36SAndroid Build Coastguard Worker	// very early stage in the boot process).
973*333d2b36SAndroid Build Coastguard Worker	if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.notInPlatform() &&
974*333d2b36SAndroid Build Coastguard Worker		!ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && !ctx.useVndk() && !ctx.static() {
975*333d2b36SAndroid Build Coastguard Worker		if library.buildStubs() && library.isLatestStubVersion() {
976*333d2b36SAndroid Build Coastguard Worker			moduleInfoJSON.SubName = ""
977*333d2b36SAndroid Build Coastguard Worker		}
978*333d2b36SAndroid Build Coastguard Worker		if !library.buildStubs() {
979*333d2b36SAndroid Build Coastguard Worker			moduleInfoJSON.SubName = ".bootstrap"
980*333d2b36SAndroid Build Coastguard Worker		}
981*333d2b36SAndroid Build Coastguard Worker	}
982*333d2b36SAndroid Build Coastguard Worker
983*333d2b36SAndroid Build Coastguard Worker	library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
984*333d2b36SAndroid Build Coastguard Worker}
985*333d2b36SAndroid Build Coastguard Worker
986*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkStatic(ctx ModuleContext,
987*333d2b36SAndroid Build Coastguard Worker	flags Flags, deps PathDeps, objs Objects) android.Path {
988*333d2b36SAndroid Build Coastguard Worker
989*333d2b36SAndroid Build Coastguard Worker	library.objects = deps.WholeStaticLibObjs.Copy()
990*333d2b36SAndroid Build Coastguard Worker	library.objects = library.objects.Append(objs)
991*333d2b36SAndroid Build Coastguard Worker	library.wholeStaticLibsFromPrebuilts = android.CopyOfPaths(deps.WholeStaticLibsFromPrebuilts)
992*333d2b36SAndroid Build Coastguard Worker
993*333d2b36SAndroid Build Coastguard Worker	fileName := ctx.ModuleName() + staticLibraryExtension
994*333d2b36SAndroid Build Coastguard Worker	outputFile := android.PathForModuleOut(ctx, fileName)
995*333d2b36SAndroid Build Coastguard Worker	builderFlags := flagsToBuilderFlags(flags)
996*333d2b36SAndroid Build Coastguard Worker
997*333d2b36SAndroid Build Coastguard Worker	if Bool(library.baseLinker.Properties.Use_version_lib) {
998*333d2b36SAndroid Build Coastguard Worker		if ctx.Host() {
999*333d2b36SAndroid Build Coastguard Worker			versionedOutputFile := outputFile
1000*333d2b36SAndroid Build Coastguard Worker			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
1001*333d2b36SAndroid Build Coastguard Worker			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
1002*333d2b36SAndroid Build Coastguard Worker		} else {
1003*333d2b36SAndroid Build Coastguard Worker			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
1004*333d2b36SAndroid Build Coastguard Worker			library.distFile = versionedOutputFile
1005*333d2b36SAndroid Build Coastguard Worker			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
1006*333d2b36SAndroid Build Coastguard Worker		}
1007*333d2b36SAndroid Build Coastguard Worker	}
1008*333d2b36SAndroid Build Coastguard Worker
1009*333d2b36SAndroid Build Coastguard Worker	transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, nil, objs.tidyDepFiles)
1010*333d2b36SAndroid Build Coastguard Worker
1011*333d2b36SAndroid Build Coastguard Worker	library.coverageOutputFile = transformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName())
1012*333d2b36SAndroid Build Coastguard Worker
1013*333d2b36SAndroid Build Coastguard Worker	ctx.CheckbuildFile(outputFile)
1014*333d2b36SAndroid Build Coastguard Worker
1015*333d2b36SAndroid Build Coastguard Worker	if library.static() {
1016*333d2b36SAndroid Build Coastguard Worker		android.SetProvider(ctx, StaticLibraryInfoProvider, StaticLibraryInfo{
1017*333d2b36SAndroid Build Coastguard Worker			StaticLibrary:                outputFile,
1018*333d2b36SAndroid Build Coastguard Worker			ReuseObjects:                 library.reuseObjects,
1019*333d2b36SAndroid Build Coastguard Worker			Objects:                      library.objects,
1020*333d2b36SAndroid Build Coastguard Worker			WholeStaticLibsFromPrebuilts: library.wholeStaticLibsFromPrebuilts,
1021*333d2b36SAndroid Build Coastguard Worker
1022*333d2b36SAndroid Build Coastguard Worker			TransitiveStaticLibrariesForOrdering: depset.NewBuilder[android.Path](depset.TOPOLOGICAL).
1023*333d2b36SAndroid Build Coastguard Worker				Direct(outputFile).
1024*333d2b36SAndroid Build Coastguard Worker				Transitive(deps.TranstiveStaticLibrariesForOrdering).
1025*333d2b36SAndroid Build Coastguard Worker				Build(),
1026*333d2b36SAndroid Build Coastguard Worker		})
1027*333d2b36SAndroid Build Coastguard Worker	}
1028*333d2b36SAndroid Build Coastguard Worker
1029*333d2b36SAndroid Build Coastguard Worker	if library.header() {
1030*333d2b36SAndroid Build Coastguard Worker		android.SetProvider(ctx, HeaderLibraryInfoProvider, HeaderLibraryInfo{})
1031*333d2b36SAndroid Build Coastguard Worker	}
1032*333d2b36SAndroid Build Coastguard Worker
1033*333d2b36SAndroid Build Coastguard Worker	return outputFile
1034*333d2b36SAndroid Build Coastguard Worker}
1035*333d2b36SAndroid Build Coastguard Worker
1036*333d2b36SAndroid Build Coastguard Workerfunc ndkSharedLibDeps(ctx ModuleContext) android.Paths {
1037*333d2b36SAndroid Build Coastguard Worker	if ctx.Module().(*Module).IsSdkVariant() {
1038*333d2b36SAndroid Build Coastguard Worker		// The NDK sysroot timestamp file depends on all the NDK
1039*333d2b36SAndroid Build Coastguard Worker		// sysroot header and shared library files.
1040*333d2b36SAndroid Build Coastguard Worker		return android.Paths{getNdkBaseTimestampFile(ctx)}
1041*333d2b36SAndroid Build Coastguard Worker	}
1042*333d2b36SAndroid Build Coastguard Worker	return nil
1043*333d2b36SAndroid Build Coastguard Worker}
1044*333d2b36SAndroid Build Coastguard Worker
1045*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkShared(ctx ModuleContext,
1046*333d2b36SAndroid Build Coastguard Worker	flags Flags, deps PathDeps, objs Objects) android.Path {
1047*333d2b36SAndroid Build Coastguard Worker
1048*333d2b36SAndroid Build Coastguard Worker	var linkerDeps android.Paths
1049*333d2b36SAndroid Build Coastguard Worker	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
1050*333d2b36SAndroid Build Coastguard Worker	linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
1051*333d2b36SAndroid Build Coastguard Worker
1052*333d2b36SAndroid Build Coastguard Worker	unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list")
1053*333d2b36SAndroid Build Coastguard Worker	forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list")
1054*333d2b36SAndroid Build Coastguard Worker	forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list")
1055*333d2b36SAndroid Build Coastguard Worker	if !ctx.Darwin() {
1056*333d2b36SAndroid Build Coastguard Worker		if unexportedSymbols.Valid() {
1057*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1058*333d2b36SAndroid Build Coastguard Worker		}
1059*333d2b36SAndroid Build Coastguard Worker		if forceNotWeakSymbols.Valid() {
1060*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1061*333d2b36SAndroid Build Coastguard Worker		}
1062*333d2b36SAndroid Build Coastguard Worker		if forceWeakSymbols.Valid() {
1063*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1064*333d2b36SAndroid Build Coastguard Worker		}
1065*333d2b36SAndroid Build Coastguard Worker	} else {
1066*333d2b36SAndroid Build Coastguard Worker		if unexportedSymbols.Valid() {
1067*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
1068*333d2b36SAndroid Build Coastguard Worker			linkerDeps = append(linkerDeps, unexportedSymbols.Path())
1069*333d2b36SAndroid Build Coastguard Worker		}
1070*333d2b36SAndroid Build Coastguard Worker		if forceNotWeakSymbols.Valid() {
1071*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
1072*333d2b36SAndroid Build Coastguard Worker			linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
1073*333d2b36SAndroid Build Coastguard Worker		}
1074*333d2b36SAndroid Build Coastguard Worker		if forceWeakSymbols.Valid() {
1075*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
1076*333d2b36SAndroid Build Coastguard Worker			linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
1077*333d2b36SAndroid Build Coastguard Worker		}
1078*333d2b36SAndroid Build Coastguard Worker	}
1079*333d2b36SAndroid Build Coastguard Worker	if library.versionScriptPath.Valid() {
1080*333d2b36SAndroid Build Coastguard Worker		linkerScriptFlags := "-Wl,--version-script," + library.versionScriptPath.String()
1081*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlags)
1082*333d2b36SAndroid Build Coastguard Worker		linkerDeps = append(linkerDeps, library.versionScriptPath.Path())
1083*333d2b36SAndroid Build Coastguard Worker	}
1084*333d2b36SAndroid Build Coastguard Worker
1085*333d2b36SAndroid Build Coastguard Worker	fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
1086*333d2b36SAndroid Build Coastguard Worker	outputFile := android.PathForModuleOut(ctx, fileName)
1087*333d2b36SAndroid Build Coastguard Worker	unstrippedOutputFile := outputFile
1088*333d2b36SAndroid Build Coastguard Worker
1089*333d2b36SAndroid Build Coastguard Worker	var implicitOutputs android.WritablePaths
1090*333d2b36SAndroid Build Coastguard Worker	if ctx.Windows() {
1091*333d2b36SAndroid Build Coastguard Worker		importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib"))
1092*333d2b36SAndroid Build Coastguard Worker
1093*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--out-implib="+importLibraryPath.String())
1094*333d2b36SAndroid Build Coastguard Worker		implicitOutputs = append(implicitOutputs, importLibraryPath)
1095*333d2b36SAndroid Build Coastguard Worker	}
1096*333d2b36SAndroid Build Coastguard Worker
1097*333d2b36SAndroid Build Coastguard Worker	builderFlags := flagsToBuilderFlags(flags)
1098*333d2b36SAndroid Build Coastguard Worker
1099*333d2b36SAndroid Build Coastguard Worker	if ctx.Darwin() && deps.DarwinSecondArchOutput.Valid() {
1100*333d2b36SAndroid Build Coastguard Worker		fatOutputFile := outputFile
1101*333d2b36SAndroid Build Coastguard Worker		outputFile = android.PathForModuleOut(ctx, "pre-fat", fileName)
1102*333d2b36SAndroid Build Coastguard Worker		transformDarwinUniversalBinary(ctx, fatOutputFile, outputFile, deps.DarwinSecondArchOutput.Path())
1103*333d2b36SAndroid Build Coastguard Worker	}
1104*333d2b36SAndroid Build Coastguard Worker
1105*333d2b36SAndroid Build Coastguard Worker	// Optimize out relinking against shared libraries whose interface hasn't changed by
1106*333d2b36SAndroid Build Coastguard Worker	// depending on a table of contents file instead of the library itself.
1107*333d2b36SAndroid Build Coastguard Worker	tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc")
1108*333d2b36SAndroid Build Coastguard Worker	library.tocFile = android.OptionalPathForPath(tocFile)
1109*333d2b36SAndroid Build Coastguard Worker	TransformSharedObjectToToc(ctx, outputFile, tocFile)
1110*333d2b36SAndroid Build Coastguard Worker
1111*333d2b36SAndroid Build Coastguard Worker	stripFlags := flagsToStripFlags(flags)
1112*333d2b36SAndroid Build Coastguard Worker	needsStrip := library.stripper.NeedsStrip(ctx)
1113*333d2b36SAndroid Build Coastguard Worker	if library.buildStubs() {
1114*333d2b36SAndroid Build Coastguard Worker		// No need to strip stubs libraries
1115*333d2b36SAndroid Build Coastguard Worker		needsStrip = false
1116*333d2b36SAndroid Build Coastguard Worker	}
1117*333d2b36SAndroid Build Coastguard Worker	if needsStrip {
1118*333d2b36SAndroid Build Coastguard Worker		if ctx.Darwin() {
1119*333d2b36SAndroid Build Coastguard Worker			stripFlags.StripUseGnuStrip = true
1120*333d2b36SAndroid Build Coastguard Worker		}
1121*333d2b36SAndroid Build Coastguard Worker		strippedOutputFile := outputFile
1122*333d2b36SAndroid Build Coastguard Worker		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
1123*333d2b36SAndroid Build Coastguard Worker		library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags)
1124*333d2b36SAndroid Build Coastguard Worker	}
1125*333d2b36SAndroid Build Coastguard Worker	library.unstrippedOutputFile = outputFile
1126*333d2b36SAndroid Build Coastguard Worker
1127*333d2b36SAndroid Build Coastguard Worker	outputFile = maybeInjectBoringSSLHash(ctx, outputFile, library.Properties.Inject_bssl_hash, fileName)
1128*333d2b36SAndroid Build Coastguard Worker
1129*333d2b36SAndroid Build Coastguard Worker	if Bool(library.baseLinker.Properties.Use_version_lib) {
1130*333d2b36SAndroid Build Coastguard Worker		if ctx.Host() {
1131*333d2b36SAndroid Build Coastguard Worker			versionedOutputFile := outputFile
1132*333d2b36SAndroid Build Coastguard Worker			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
1133*333d2b36SAndroid Build Coastguard Worker			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
1134*333d2b36SAndroid Build Coastguard Worker		} else {
1135*333d2b36SAndroid Build Coastguard Worker			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
1136*333d2b36SAndroid Build Coastguard Worker			library.distFile = versionedOutputFile
1137*333d2b36SAndroid Build Coastguard Worker
1138*333d2b36SAndroid Build Coastguard Worker			if library.stripper.NeedsStrip(ctx) {
1139*333d2b36SAndroid Build Coastguard Worker				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
1140*333d2b36SAndroid Build Coastguard Worker				library.distFile = out
1141*333d2b36SAndroid Build Coastguard Worker				library.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
1142*333d2b36SAndroid Build Coastguard Worker			}
1143*333d2b36SAndroid Build Coastguard Worker
1144*333d2b36SAndroid Build Coastguard Worker			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
1145*333d2b36SAndroid Build Coastguard Worker		}
1146*333d2b36SAndroid Build Coastguard Worker	}
1147*333d2b36SAndroid Build Coastguard Worker
1148*333d2b36SAndroid Build Coastguard Worker	// Generate an output file for dist as if strip: "all" is set on the module.
1149*333d2b36SAndroid Build Coastguard Worker	// Currently this is for layoutlib release process only.
1150*333d2b36SAndroid Build Coastguard Worker	for _, dist := range ctx.Module().(*Module).Dists() {
1151*333d2b36SAndroid Build Coastguard Worker		if dist.Tag != nil && *dist.Tag == "stripped_all" {
1152*333d2b36SAndroid Build Coastguard Worker			strippedAllOutputFile := android.PathForModuleOut(ctx, "stripped_all", fileName)
1153*333d2b36SAndroid Build Coastguard Worker			transformStrip(ctx, outputFile, strippedAllOutputFile, StripFlags{Toolchain: flags.Toolchain})
1154*333d2b36SAndroid Build Coastguard Worker			library.strippedAllOutputFile = strippedAllOutputFile
1155*333d2b36SAndroid Build Coastguard Worker			break
1156*333d2b36SAndroid Build Coastguard Worker		}
1157*333d2b36SAndroid Build Coastguard Worker	}
1158*333d2b36SAndroid Build Coastguard Worker
1159*333d2b36SAndroid Build Coastguard Worker	sharedLibs := deps.EarlySharedLibs
1160*333d2b36SAndroid Build Coastguard Worker	sharedLibs = append(sharedLibs, deps.SharedLibs...)
1161*333d2b36SAndroid Build Coastguard Worker	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1162*333d2b36SAndroid Build Coastguard Worker
1163*333d2b36SAndroid Build Coastguard Worker	linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
1164*333d2b36SAndroid Build Coastguard Worker	linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
1165*333d2b36SAndroid Build Coastguard Worker	linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
1166*333d2b36SAndroid Build Coastguard Worker
1167*333d2b36SAndroid Build Coastguard Worker	if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil && !library.buildStubs() {
1168*333d2b36SAndroid Build Coastguard Worker		if ctx.Module().(*Module).WholeRustStaticlib {
1169*333d2b36SAndroid Build Coastguard Worker			deps.WholeStaticLibs = append(deps.WholeStaticLibs, generatedLib)
1170*333d2b36SAndroid Build Coastguard Worker		} else {
1171*333d2b36SAndroid Build Coastguard Worker			deps.StaticLibs = append(deps.StaticLibs, generatedLib)
1172*333d2b36SAndroid Build Coastguard Worker		}
1173*333d2b36SAndroid Build Coastguard Worker	}
1174*333d2b36SAndroid Build Coastguard Worker
1175*333d2b36SAndroid Build Coastguard Worker	transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
1176*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin,
1177*333d2b36SAndroid Build Coastguard Worker		deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles)
1178*333d2b36SAndroid Build Coastguard Worker
1179*333d2b36SAndroid Build Coastguard Worker	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
1180*333d2b36SAndroid Build Coastguard Worker	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
1181*333d2b36SAndroid Build Coastguard Worker	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...)
1182*333d2b36SAndroid Build Coastguard Worker	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
1183*333d2b36SAndroid Build Coastguard Worker
1184*333d2b36SAndroid Build Coastguard Worker	library.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
1185*333d2b36SAndroid Build Coastguard Worker	library.linkSAbiDumpFiles(ctx, deps, objs, fileName, unstrippedOutputFile)
1186*333d2b36SAndroid Build Coastguard Worker
1187*333d2b36SAndroid Build Coastguard Worker	var transitiveStaticLibrariesForOrdering depset.DepSet[android.Path]
1188*333d2b36SAndroid Build Coastguard Worker	if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
1189*333d2b36SAndroid Build Coastguard Worker		s, _ := android.OtherModuleProvider(ctx, static[0], StaticLibraryInfoProvider)
1190*333d2b36SAndroid Build Coastguard Worker		transitiveStaticLibrariesForOrdering = s.TransitiveStaticLibrariesForOrdering
1191*333d2b36SAndroid Build Coastguard Worker	}
1192*333d2b36SAndroid Build Coastguard Worker
1193*333d2b36SAndroid Build Coastguard Worker	android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
1194*333d2b36SAndroid Build Coastguard Worker		TableOfContents:                      android.OptionalPathForPath(tocFile),
1195*333d2b36SAndroid Build Coastguard Worker		SharedLibrary:                        unstrippedOutputFile,
1196*333d2b36SAndroid Build Coastguard Worker		TransitiveStaticLibrariesForOrdering: transitiveStaticLibrariesForOrdering,
1197*333d2b36SAndroid Build Coastguard Worker		Target:                               ctx.Target(),
1198*333d2b36SAndroid Build Coastguard Worker		IsStubs:                              library.buildStubs(),
1199*333d2b36SAndroid Build Coastguard Worker	})
1200*333d2b36SAndroid Build Coastguard Worker
1201*333d2b36SAndroid Build Coastguard Worker	addStubDependencyProviders(ctx)
1202*333d2b36SAndroid Build Coastguard Worker
1203*333d2b36SAndroid Build Coastguard Worker	return unstrippedOutputFile
1204*333d2b36SAndroid Build Coastguard Worker}
1205*333d2b36SAndroid Build Coastguard Worker
1206*333d2b36SAndroid Build Coastguard Worker// Visits the stub variants of the library and returns a struct containing the stub .so paths
1207*333d2b36SAndroid Build Coastguard Workerfunc addStubDependencyProviders(ctx ModuleContext) []SharedStubLibrary {
1208*333d2b36SAndroid Build Coastguard Worker	stubsInfo := []SharedStubLibrary{}
1209*333d2b36SAndroid Build Coastguard Worker	stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
1210*333d2b36SAndroid Build Coastguard Worker	if len(stubs) > 0 {
1211*333d2b36SAndroid Build Coastguard Worker		for _, stub := range stubs {
1212*333d2b36SAndroid Build Coastguard Worker			stubInfo, ok := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
1213*333d2b36SAndroid Build Coastguard Worker			// TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk.
1214*333d2b36SAndroid Build Coastguard Worker			if !ok {
1215*333d2b36SAndroid Build Coastguard Worker				continue
1216*333d2b36SAndroid Build Coastguard Worker			}
1217*333d2b36SAndroid Build Coastguard Worker			flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
1218*333d2b36SAndroid Build Coastguard Worker			stubsInfo = append(stubsInfo, SharedStubLibrary{
1219*333d2b36SAndroid Build Coastguard Worker				Version:           moduleLibraryInterface(stub).stubsVersion(),
1220*333d2b36SAndroid Build Coastguard Worker				SharedLibraryInfo: stubInfo,
1221*333d2b36SAndroid Build Coastguard Worker				FlagExporterInfo:  flagInfo,
1222*333d2b36SAndroid Build Coastguard Worker			})
1223*333d2b36SAndroid Build Coastguard Worker		}
1224*333d2b36SAndroid Build Coastguard Worker		if len(stubsInfo) > 0 {
1225*333d2b36SAndroid Build Coastguard Worker			android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
1226*333d2b36SAndroid Build Coastguard Worker				SharedStubLibraries: stubsInfo,
1227*333d2b36SAndroid Build Coastguard Worker				IsLLNDK:             ctx.IsLlndk(),
1228*333d2b36SAndroid Build Coastguard Worker			})
1229*333d2b36SAndroid Build Coastguard Worker		}
1230*333d2b36SAndroid Build Coastguard Worker	}
1231*333d2b36SAndroid Build Coastguard Worker	return stubsInfo
1232*333d2b36SAndroid Build Coastguard Worker}
1233*333d2b36SAndroid Build Coastguard Worker
1234*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) unstrippedOutputFilePath() android.Path {
1235*333d2b36SAndroid Build Coastguard Worker	return library.unstrippedOutputFile
1236*333d2b36SAndroid Build Coastguard Worker}
1237*333d2b36SAndroid Build Coastguard Worker
1238*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) strippedAllOutputFilePath() android.Path {
1239*333d2b36SAndroid Build Coastguard Worker	return library.strippedAllOutputFile
1240*333d2b36SAndroid Build Coastguard Worker}
1241*333d2b36SAndroid Build Coastguard Worker
1242*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) disableStripping() {
1243*333d2b36SAndroid Build Coastguard Worker	library.stripper.StripProperties.Strip.None = BoolPtr(true)
1244*333d2b36SAndroid Build Coastguard Worker}
1245*333d2b36SAndroid Build Coastguard Worker
1246*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) nativeCoverage() bool {
1247*333d2b36SAndroid Build Coastguard Worker	if library.header() || library.buildStubs() {
1248*333d2b36SAndroid Build Coastguard Worker		return false
1249*333d2b36SAndroid Build Coastguard Worker	}
1250*333d2b36SAndroid Build Coastguard Worker	return true
1251*333d2b36SAndroid Build Coastguard Worker}
1252*333d2b36SAndroid Build Coastguard Worker
1253*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath {
1254*333d2b36SAndroid Build Coastguard Worker	return library.coverageOutputFile
1255*333d2b36SAndroid Build Coastguard Worker}
1256*333d2b36SAndroid Build Coastguard Worker
1257*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) exportedIncludeDirsForAbiCheck(ctx ModuleContext) []string {
1258*333d2b36SAndroid Build Coastguard Worker	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx).Strings()
1259*333d2b36SAndroid Build Coastguard Worker	exportIncludeDirs = append(exportIncludeDirs, library.sabi.Properties.ReexportedIncludes...)
1260*333d2b36SAndroid Build Coastguard Worker	exportSystemIncludeDirs := library.flagExporter.exportedSystemIncludes(ctx).Strings()
1261*333d2b36SAndroid Build Coastguard Worker	exportSystemIncludeDirs = append(exportSystemIncludeDirs, library.sabi.Properties.ReexportedSystemIncludes...)
1262*333d2b36SAndroid Build Coastguard Worker	// The ABI checker does not distinguish normal and system headers.
1263*333d2b36SAndroid Build Coastguard Worker	return append(exportIncludeDirs, exportSystemIncludeDirs...)
1264*333d2b36SAndroid Build Coastguard Worker}
1265*333d2b36SAndroid Build Coastguard Worker
1266*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) llndkIncludeDirsForAbiCheck(ctx ModuleContext, deps PathDeps) []string {
1267*333d2b36SAndroid Build Coastguard Worker	var includeDirs, systemIncludeDirs []string
1268*333d2b36SAndroid Build Coastguard Worker
1269*333d2b36SAndroid Build Coastguard Worker	if library.Properties.Llndk.Override_export_include_dirs != nil {
1270*333d2b36SAndroid Build Coastguard Worker		includeDirs = append(includeDirs, android.PathsForModuleSrc(
1271*333d2b36SAndroid Build Coastguard Worker			ctx, library.Properties.Llndk.Override_export_include_dirs).Strings()...)
1272*333d2b36SAndroid Build Coastguard Worker	} else {
1273*333d2b36SAndroid Build Coastguard Worker		includeDirs = append(includeDirs, library.flagExporter.exportedIncludes(ctx).Strings()...)
1274*333d2b36SAndroid Build Coastguard Worker		// Ignore library.sabi.Properties.ReexportedIncludes because
1275*333d2b36SAndroid Build Coastguard Worker		// LLNDK does not reexport the implementation's dependencies, such as export_header_libs.
1276*333d2b36SAndroid Build Coastguard Worker	}
1277*333d2b36SAndroid Build Coastguard Worker
1278*333d2b36SAndroid Build Coastguard Worker	systemIncludeDirs = append(systemIncludeDirs,
1279*333d2b36SAndroid Build Coastguard Worker		library.flagExporter.exportedSystemIncludes(ctx).Strings()...)
1280*333d2b36SAndroid Build Coastguard Worker	if Bool(library.Properties.Llndk.Export_headers_as_system) {
1281*333d2b36SAndroid Build Coastguard Worker		systemIncludeDirs = append(systemIncludeDirs, includeDirs...)
1282*333d2b36SAndroid Build Coastguard Worker		includeDirs = nil
1283*333d2b36SAndroid Build Coastguard Worker	}
1284*333d2b36SAndroid Build Coastguard Worker	// Header libs.
1285*333d2b36SAndroid Build Coastguard Worker	includeDirs = append(includeDirs, deps.LlndkIncludeDirs.Strings()...)
1286*333d2b36SAndroid Build Coastguard Worker	systemIncludeDirs = append(systemIncludeDirs, deps.LlndkSystemIncludeDirs.Strings()...)
1287*333d2b36SAndroid Build Coastguard Worker	// The ABI checker does not distinguish normal and system headers.
1288*333d2b36SAndroid Build Coastguard Worker	return append(includeDirs, systemIncludeDirs...)
1289*333d2b36SAndroid Build Coastguard Worker}
1290*333d2b36SAndroid Build Coastguard Worker
1291*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkLlndkSAbiDumpFiles(ctx ModuleContext,
1292*333d2b36SAndroid Build Coastguard Worker	deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string,
1293*333d2b36SAndroid Build Coastguard Worker	excludeSymbolVersions, excludeSymbolTags []string,
1294*333d2b36SAndroid Build Coastguard Worker	sdkVersionForVendorApiLevel string) android.Path {
1295*333d2b36SAndroid Build Coastguard Worker	return transformDumpToLinkedDump(ctx,
1296*333d2b36SAndroid Build Coastguard Worker		sAbiDumpFiles, soFile, libFileName+".llndk",
1297*333d2b36SAndroid Build Coastguard Worker		library.llndkIncludeDirsForAbiCheck(ctx, deps),
1298*333d2b36SAndroid Build Coastguard Worker		android.OptionalPathForModuleSrc(ctx, library.Properties.Llndk.Symbol_file),
1299*333d2b36SAndroid Build Coastguard Worker		append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
1300*333d2b36SAndroid Build Coastguard Worker		append([]string{"platform-only"}, excludeSymbolTags...),
1301*333d2b36SAndroid Build Coastguard Worker		[]string{"llndk"}, sdkVersionForVendorApiLevel)
1302*333d2b36SAndroid Build Coastguard Worker}
1303*333d2b36SAndroid Build Coastguard Worker
1304*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkApexSAbiDumpFiles(ctx ModuleContext,
1305*333d2b36SAndroid Build Coastguard Worker	deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string,
1306*333d2b36SAndroid Build Coastguard Worker	excludeSymbolVersions, excludeSymbolTags []string,
1307*333d2b36SAndroid Build Coastguard Worker	sdkVersion string) android.Path {
1308*333d2b36SAndroid Build Coastguard Worker	return transformDumpToLinkedDump(ctx,
1309*333d2b36SAndroid Build Coastguard Worker		sAbiDumpFiles, soFile, libFileName+".apex",
1310*333d2b36SAndroid Build Coastguard Worker		library.exportedIncludeDirsForAbiCheck(ctx),
1311*333d2b36SAndroid Build Coastguard Worker		android.OptionalPathForModuleSrc(ctx, library.Properties.Stubs.Symbol_file),
1312*333d2b36SAndroid Build Coastguard Worker		append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
1313*333d2b36SAndroid Build Coastguard Worker		append([]string{"platform-only"}, excludeSymbolTags...),
1314*333d2b36SAndroid Build Coastguard Worker		[]string{"apex", "systemapi"}, sdkVersion)
1315*333d2b36SAndroid Build Coastguard Worker}
1316*333d2b36SAndroid Build Coastguard Worker
1317*333d2b36SAndroid Build Coastguard Workerfunc getRefAbiDumpFile(ctx android.ModuleInstallPathContext,
1318*333d2b36SAndroid Build Coastguard Worker	versionedDumpDir, fileName string) android.OptionalPath {
1319*333d2b36SAndroid Build Coastguard Worker
1320*333d2b36SAndroid Build Coastguard Worker	currentArchType := ctx.Arch().ArchType
1321*333d2b36SAndroid Build Coastguard Worker	primaryArchType := ctx.Config().DevicePrimaryArchType()
1322*333d2b36SAndroid Build Coastguard Worker	archName := currentArchType.String()
1323*333d2b36SAndroid Build Coastguard Worker	if currentArchType != primaryArchType {
1324*333d2b36SAndroid Build Coastguard Worker		archName += "_" + primaryArchType.String()
1325*333d2b36SAndroid Build Coastguard Worker	}
1326*333d2b36SAndroid Build Coastguard Worker
1327*333d2b36SAndroid Build Coastguard Worker	return android.ExistentPathForSource(ctx, versionedDumpDir, archName, "source-based",
1328*333d2b36SAndroid Build Coastguard Worker		fileName+".lsdump")
1329*333d2b36SAndroid Build Coastguard Worker}
1330*333d2b36SAndroid Build Coastguard Worker
1331*333d2b36SAndroid Build Coastguard Worker// Return the previous and current SDK versions for cross-version ABI diff.
1332*333d2b36SAndroid Build Coastguard Workerfunc crossVersionAbiDiffSdkVersions(ctx ModuleContext, dumpDir string) (int, int) {
1333*333d2b36SAndroid Build Coastguard Worker	sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt()
1334*333d2b36SAndroid Build Coastguard Worker
1335*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().PlatformSdkFinal() {
1336*333d2b36SAndroid Build Coastguard Worker		return sdkVersionInt - 1, sdkVersionInt
1337*333d2b36SAndroid Build Coastguard Worker	} else {
1338*333d2b36SAndroid Build Coastguard Worker		// The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't
1339*333d2b36SAndroid Build Coastguard Worker		// been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version.
1340*333d2b36SAndroid Build Coastguard Worker		// This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory.
1341*333d2b36SAndroid Build Coastguard Worker		versionedDumpDir := android.ExistentPathForSource(ctx,
1342*333d2b36SAndroid Build Coastguard Worker			dumpDir, ctx.Config().PlatformSdkVersion().String())
1343*333d2b36SAndroid Build Coastguard Worker		if versionedDumpDir.Valid() {
1344*333d2b36SAndroid Build Coastguard Worker			return sdkVersionInt, sdkVersionInt + 1
1345*333d2b36SAndroid Build Coastguard Worker		} else {
1346*333d2b36SAndroid Build Coastguard Worker			return sdkVersionInt - 1, sdkVersionInt
1347*333d2b36SAndroid Build Coastguard Worker		}
1348*333d2b36SAndroid Build Coastguard Worker	}
1349*333d2b36SAndroid Build Coastguard Worker}
1350*333d2b36SAndroid Build Coastguard Worker
1351*333d2b36SAndroid Build Coastguard Worker// Return the SDK version for same-version ABI diff.
1352*333d2b36SAndroid Build Coastguard Workerfunc currRefAbiDumpSdkVersion(ctx ModuleContext) string {
1353*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().PlatformSdkFinal() {
1354*333d2b36SAndroid Build Coastguard Worker		// After sdk finalization, the ABI of the latest API level must be consistent with the source code,
1355*333d2b36SAndroid Build Coastguard Worker		// so choose PLATFORM_SDK_VERSION as the current version.
1356*333d2b36SAndroid Build Coastguard Worker		return ctx.Config().PlatformSdkVersion().String()
1357*333d2b36SAndroid Build Coastguard Worker	} else {
1358*333d2b36SAndroid Build Coastguard Worker		return "current"
1359*333d2b36SAndroid Build Coastguard Worker	}
1360*333d2b36SAndroid Build Coastguard Worker}
1361*333d2b36SAndroid Build Coastguard Worker
1362*333d2b36SAndroid Build Coastguard Worker// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
1363*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext,
1364*333d2b36SAndroid Build Coastguard Worker	sourceDump, referenceDump android.Path,
1365*333d2b36SAndroid Build Coastguard Worker	baseName, nameExt string, isLlndk, allowExtensions bool,
1366*333d2b36SAndroid Build Coastguard Worker	sourceVersion, errorMessage string) {
1367*333d2b36SAndroid Build Coastguard Worker
1368*333d2b36SAndroid Build Coastguard Worker	extraFlags := []string{"-target-version", sourceVersion}
1369*333d2b36SAndroid Build Coastguard Worker	headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module))
1370*333d2b36SAndroid Build Coastguard Worker	if Bool(headerAbiChecker.Check_all_apis) {
1371*333d2b36SAndroid Build Coastguard Worker		extraFlags = append(extraFlags, "-check-all-apis")
1372*333d2b36SAndroid Build Coastguard Worker	} else {
1373*333d2b36SAndroid Build Coastguard Worker		extraFlags = append(extraFlags,
1374*333d2b36SAndroid Build Coastguard Worker			"-allow-unreferenced-changes",
1375*333d2b36SAndroid Build Coastguard Worker			"-allow-unreferenced-elf-symbol-changes")
1376*333d2b36SAndroid Build Coastguard Worker	}
1377*333d2b36SAndroid Build Coastguard Worker	if isLlndk {
1378*333d2b36SAndroid Build Coastguard Worker		extraFlags = append(extraFlags, "-consider-opaque-types-different")
1379*333d2b36SAndroid Build Coastguard Worker	}
1380*333d2b36SAndroid Build Coastguard Worker	if allowExtensions {
1381*333d2b36SAndroid Build Coastguard Worker		extraFlags = append(extraFlags, "-allow-extensions")
1382*333d2b36SAndroid Build Coastguard Worker	}
1383*333d2b36SAndroid Build Coastguard Worker	extraFlags = append(extraFlags, headerAbiChecker.Diff_flags...)
1384*333d2b36SAndroid Build Coastguard Worker
1385*333d2b36SAndroid Build Coastguard Worker	library.sAbiDiff = append(
1386*333d2b36SAndroid Build Coastguard Worker		library.sAbiDiff,
1387*333d2b36SAndroid Build Coastguard Worker		transformAbiDumpToAbiDiff(ctx, sourceDump, referenceDump,
1388*333d2b36SAndroid Build Coastguard Worker			baseName, nameExt, extraFlags, errorMessage))
1389*333d2b36SAndroid Build Coastguard Worker}
1390*333d2b36SAndroid Build Coastguard Worker
1391*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) crossVersionAbiDiff(ctx android.ModuleContext,
1392*333d2b36SAndroid Build Coastguard Worker	sourceDump, referenceDump android.Path,
1393*333d2b36SAndroid Build Coastguard Worker	baseName, nameExt string, isLlndk bool, sourceVersion, prevDumpDir string) {
1394*333d2b36SAndroid Build Coastguard Worker
1395*333d2b36SAndroid Build Coastguard Worker	errorMessage := "error: Please follow https://android.googlesource.com/platform/development/+/main/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the difference between your source code and the ABI dumps in " + prevDumpDir
1396*333d2b36SAndroid Build Coastguard Worker
1397*333d2b36SAndroid Build Coastguard Worker	library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
1398*333d2b36SAndroid Build Coastguard Worker		isLlndk, true /* allowExtensions */, sourceVersion, errorMessage)
1399*333d2b36SAndroid Build Coastguard Worker}
1400*333d2b36SAndroid Build Coastguard Worker
1401*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext,
1402*333d2b36SAndroid Build Coastguard Worker	sourceDump, referenceDump android.Path,
1403*333d2b36SAndroid Build Coastguard Worker	baseName, nameExt string, isLlndk bool, lsdumpTagName string) {
1404*333d2b36SAndroid Build Coastguard Worker
1405*333d2b36SAndroid Build Coastguard Worker	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
1406*333d2b36SAndroid Build Coastguard Worker	errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py --lib " + libName + " --lib-variant " + lsdumpTagName
1407*333d2b36SAndroid Build Coastguard Worker
1408*333d2b36SAndroid Build Coastguard Worker	targetRelease := ctx.Config().Getenv("TARGET_RELEASE")
1409*333d2b36SAndroid Build Coastguard Worker	if targetRelease != "" {
1410*333d2b36SAndroid Build Coastguard Worker		errorMessage += " --release " + targetRelease
1411*333d2b36SAndroid Build Coastguard Worker	}
1412*333d2b36SAndroid Build Coastguard Worker
1413*333d2b36SAndroid Build Coastguard Worker	library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
1414*333d2b36SAndroid Build Coastguard Worker		isLlndk, false /* allowExtensions */, "current", errorMessage)
1415*333d2b36SAndroid Build Coastguard Worker}
1416*333d2b36SAndroid Build Coastguard Worker
1417*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext,
1418*333d2b36SAndroid Build Coastguard Worker	sourceDump, referenceDump android.Path,
1419*333d2b36SAndroid Build Coastguard Worker	baseName, nameExt string, refDumpDir string, lsdumpTagName string) {
1420*333d2b36SAndroid Build Coastguard Worker
1421*333d2b36SAndroid Build Coastguard Worker	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
1422*333d2b36SAndroid Build Coastguard Worker	errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py --lib " + libName + " --lib-variant " + lsdumpTagName + " --ref-dump-dir $$ANDROID_BUILD_TOP/" + refDumpDir
1423*333d2b36SAndroid Build Coastguard Worker
1424*333d2b36SAndroid Build Coastguard Worker	targetRelease := ctx.Config().Getenv("TARGET_RELEASE")
1425*333d2b36SAndroid Build Coastguard Worker	if targetRelease != "" {
1426*333d2b36SAndroid Build Coastguard Worker		errorMessage += " --release " + targetRelease
1427*333d2b36SAndroid Build Coastguard Worker	}
1428*333d2b36SAndroid Build Coastguard Worker
1429*333d2b36SAndroid Build Coastguard Worker	// Most opt-in libraries do not have dumps for all default architectures.
1430*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().HasDeviceProduct() {
1431*333d2b36SAndroid Build Coastguard Worker		errorMessage += " --product " + ctx.Config().DeviceProduct()
1432*333d2b36SAndroid Build Coastguard Worker	}
1433*333d2b36SAndroid Build Coastguard Worker
1434*333d2b36SAndroid Build Coastguard Worker	library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
1435*333d2b36SAndroid Build Coastguard Worker		false /* isLlndk */, false /* allowExtensions */, "current", errorMessage)
1436*333d2b36SAndroid Build Coastguard Worker}
1437*333d2b36SAndroid Build Coastguard Worker
1438*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, deps PathDeps, objs Objects, fileName string, soFile android.Path) {
1439*333d2b36SAndroid Build Coastguard Worker	if library.sabi.shouldCreateSourceAbiDump() {
1440*333d2b36SAndroid Build Coastguard Worker		exportedIncludeDirs := library.exportedIncludeDirsForAbiCheck(ctx)
1441*333d2b36SAndroid Build Coastguard Worker		headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module))
1442*333d2b36SAndroid Build Coastguard Worker		currSdkVersion := currRefAbiDumpSdkVersion(ctx)
1443*333d2b36SAndroid Build Coastguard Worker		currVendorVersion := ctx.Config().VendorApiLevel()
1444*333d2b36SAndroid Build Coastguard Worker
1445*333d2b36SAndroid Build Coastguard Worker		// Generate source dumps.
1446*333d2b36SAndroid Build Coastguard Worker		implDump := transformDumpToLinkedDump(ctx,
1447*333d2b36SAndroid Build Coastguard Worker			objs.sAbiDumpFiles, soFile, fileName,
1448*333d2b36SAndroid Build Coastguard Worker			exportedIncludeDirs,
1449*333d2b36SAndroid Build Coastguard Worker			android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
1450*333d2b36SAndroid Build Coastguard Worker			headerAbiChecker.Exclude_symbol_versions,
1451*333d2b36SAndroid Build Coastguard Worker			headerAbiChecker.Exclude_symbol_tags,
1452*333d2b36SAndroid Build Coastguard Worker			[]string{} /* includeSymbolTags */, currSdkVersion)
1453*333d2b36SAndroid Build Coastguard Worker
1454*333d2b36SAndroid Build Coastguard Worker		var llndkDump, apexVariantDump android.Path
1455*333d2b36SAndroid Build Coastguard Worker		tags := classifySourceAbiDump(ctx.Module().(*Module))
1456*333d2b36SAndroid Build Coastguard Worker		optInTags := []lsdumpTag{}
1457*333d2b36SAndroid Build Coastguard Worker		for _, tag := range tags {
1458*333d2b36SAndroid Build Coastguard Worker			if tag == llndkLsdumpTag && currVendorVersion != "" {
1459*333d2b36SAndroid Build Coastguard Worker				if llndkDump == nil {
1460*333d2b36SAndroid Build Coastguard Worker					sdkVersion, err := android.GetSdkVersionForVendorApiLevel(currVendorVersion)
1461*333d2b36SAndroid Build Coastguard Worker					if err != nil {
1462*333d2b36SAndroid Build Coastguard Worker						ctx.ModuleErrorf("Cannot create %s llndk dump: %s", fileName, err)
1463*333d2b36SAndroid Build Coastguard Worker						return
1464*333d2b36SAndroid Build Coastguard Worker					}
1465*333d2b36SAndroid Build Coastguard Worker					// TODO(b/323447559): Evaluate if replacing sAbiDumpFiles with implDump is faster
1466*333d2b36SAndroid Build Coastguard Worker					llndkDump = library.linkLlndkSAbiDumpFiles(ctx,
1467*333d2b36SAndroid Build Coastguard Worker						deps, objs.sAbiDumpFiles, soFile, fileName,
1468*333d2b36SAndroid Build Coastguard Worker						headerAbiChecker.Exclude_symbol_versions,
1469*333d2b36SAndroid Build Coastguard Worker						headerAbiChecker.Exclude_symbol_tags,
1470*333d2b36SAndroid Build Coastguard Worker						nativeClampedApiLevel(ctx, sdkVersion).String())
1471*333d2b36SAndroid Build Coastguard Worker				}
1472*333d2b36SAndroid Build Coastguard Worker				addLsdumpPath(ctx.Config(), string(tag)+":"+llndkDump.String())
1473*333d2b36SAndroid Build Coastguard Worker			} else if tag == apexLsdumpTag {
1474*333d2b36SAndroid Build Coastguard Worker				if apexVariantDump == nil {
1475*333d2b36SAndroid Build Coastguard Worker					apexVariantDump = library.linkApexSAbiDumpFiles(ctx,
1476*333d2b36SAndroid Build Coastguard Worker						deps, objs.sAbiDumpFiles, soFile, fileName,
1477*333d2b36SAndroid Build Coastguard Worker						headerAbiChecker.Exclude_symbol_versions,
1478*333d2b36SAndroid Build Coastguard Worker						headerAbiChecker.Exclude_symbol_tags,
1479*333d2b36SAndroid Build Coastguard Worker						currSdkVersion)
1480*333d2b36SAndroid Build Coastguard Worker				}
1481*333d2b36SAndroid Build Coastguard Worker				addLsdumpPath(ctx.Config(), string(tag)+":"+apexVariantDump.String())
1482*333d2b36SAndroid Build Coastguard Worker			} else {
1483*333d2b36SAndroid Build Coastguard Worker				if tag.dirName() == "" {
1484*333d2b36SAndroid Build Coastguard Worker					optInTags = append(optInTags, tag)
1485*333d2b36SAndroid Build Coastguard Worker				}
1486*333d2b36SAndroid Build Coastguard Worker				addLsdumpPath(ctx.Config(), string(tag)+":"+implDump.String())
1487*333d2b36SAndroid Build Coastguard Worker			}
1488*333d2b36SAndroid Build Coastguard Worker		}
1489*333d2b36SAndroid Build Coastguard Worker
1490*333d2b36SAndroid Build Coastguard Worker		// Diff source dumps and reference dumps.
1491*333d2b36SAndroid Build Coastguard Worker		for _, tag := range tags {
1492*333d2b36SAndroid Build Coastguard Worker			dumpDirName := tag.dirName()
1493*333d2b36SAndroid Build Coastguard Worker			if dumpDirName == "" {
1494*333d2b36SAndroid Build Coastguard Worker				continue
1495*333d2b36SAndroid Build Coastguard Worker			}
1496*333d2b36SAndroid Build Coastguard Worker			dumpDir := filepath.Join("prebuilts", "abi-dumps", dumpDirName)
1497*333d2b36SAndroid Build Coastguard Worker			isLlndk := (tag == llndkLsdumpTag)
1498*333d2b36SAndroid Build Coastguard Worker			isApex := (tag == apexLsdumpTag)
1499*333d2b36SAndroid Build Coastguard Worker			binderBitness := ctx.DeviceConfig().BinderBitness()
1500*333d2b36SAndroid Build Coastguard Worker			nameExt := ""
1501*333d2b36SAndroid Build Coastguard Worker			if isLlndk {
1502*333d2b36SAndroid Build Coastguard Worker				nameExt = "llndk"
1503*333d2b36SAndroid Build Coastguard Worker			} else if isApex {
1504*333d2b36SAndroid Build Coastguard Worker				nameExt = "apex"
1505*333d2b36SAndroid Build Coastguard Worker			}
1506*333d2b36SAndroid Build Coastguard Worker			// Check against the previous version.
1507*333d2b36SAndroid Build Coastguard Worker			var prevVersion, currVersion string
1508*333d2b36SAndroid Build Coastguard Worker			sourceDump := implDump
1509*333d2b36SAndroid Build Coastguard Worker			// If this release config does not define VendorApiLevel, fall back to the old policy.
1510*333d2b36SAndroid Build Coastguard Worker			if isLlndk && currVendorVersion != "" {
1511*333d2b36SAndroid Build Coastguard Worker				prevVersion = ctx.Config().PrevVendorApiLevel()
1512*333d2b36SAndroid Build Coastguard Worker				currVersion = currVendorVersion
1513*333d2b36SAndroid Build Coastguard Worker				// LLNDK dumps are generated by different rules after trunk stable.
1514*333d2b36SAndroid Build Coastguard Worker				if android.IsTrunkStableVendorApiLevel(prevVersion) {
1515*333d2b36SAndroid Build Coastguard Worker					sourceDump = llndkDump
1516*333d2b36SAndroid Build Coastguard Worker				}
1517*333d2b36SAndroid Build Coastguard Worker			} else {
1518*333d2b36SAndroid Build Coastguard Worker				prevVersionInt, currVersionInt := crossVersionAbiDiffSdkVersions(ctx, dumpDir)
1519*333d2b36SAndroid Build Coastguard Worker				prevVersion = strconv.Itoa(prevVersionInt)
1520*333d2b36SAndroid Build Coastguard Worker				currVersion = strconv.Itoa(currVersionInt)
1521*333d2b36SAndroid Build Coastguard Worker				// APEX dumps are generated by different rules after trunk stable.
1522*333d2b36SAndroid Build Coastguard Worker				if isApex && prevVersionInt > 34 {
1523*333d2b36SAndroid Build Coastguard Worker					sourceDump = apexVariantDump
1524*333d2b36SAndroid Build Coastguard Worker				}
1525*333d2b36SAndroid Build Coastguard Worker			}
1526*333d2b36SAndroid Build Coastguard Worker			prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness)
1527*333d2b36SAndroid Build Coastguard Worker			prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName)
1528*333d2b36SAndroid Build Coastguard Worker			if prevDumpFile.Valid() {
1529*333d2b36SAndroid Build Coastguard Worker				library.crossVersionAbiDiff(ctx, sourceDump, prevDumpFile.Path(),
1530*333d2b36SAndroid Build Coastguard Worker					fileName, nameExt+prevVersion, isLlndk, currVersion, prevDumpDir)
1531*333d2b36SAndroid Build Coastguard Worker			}
1532*333d2b36SAndroid Build Coastguard Worker			// Check against the current version.
1533*333d2b36SAndroid Build Coastguard Worker			sourceDump = implDump
1534*333d2b36SAndroid Build Coastguard Worker			if isLlndk && currVendorVersion != "" {
1535*333d2b36SAndroid Build Coastguard Worker				currVersion = currVendorVersion
1536*333d2b36SAndroid Build Coastguard Worker				if android.IsTrunkStableVendorApiLevel(currVersion) {
1537*333d2b36SAndroid Build Coastguard Worker					sourceDump = llndkDump
1538*333d2b36SAndroid Build Coastguard Worker				}
1539*333d2b36SAndroid Build Coastguard Worker			} else {
1540*333d2b36SAndroid Build Coastguard Worker				currVersion = currSdkVersion
1541*333d2b36SAndroid Build Coastguard Worker				if isApex && (!ctx.Config().PlatformSdkFinal() ||
1542*333d2b36SAndroid Build Coastguard Worker					ctx.Config().PlatformSdkVersion().FinalInt() > 34) {
1543*333d2b36SAndroid Build Coastguard Worker					sourceDump = apexVariantDump
1544*333d2b36SAndroid Build Coastguard Worker				}
1545*333d2b36SAndroid Build Coastguard Worker			}
1546*333d2b36SAndroid Build Coastguard Worker			currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness)
1547*333d2b36SAndroid Build Coastguard Worker			currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName)
1548*333d2b36SAndroid Build Coastguard Worker			if currDumpFile.Valid() {
1549*333d2b36SAndroid Build Coastguard Worker				library.sameVersionAbiDiff(ctx, sourceDump, currDumpFile.Path(),
1550*333d2b36SAndroid Build Coastguard Worker					fileName, nameExt, isLlndk, string(tag))
1551*333d2b36SAndroid Build Coastguard Worker			}
1552*333d2b36SAndroid Build Coastguard Worker		}
1553*333d2b36SAndroid Build Coastguard Worker
1554*333d2b36SAndroid Build Coastguard Worker		// Assert that a module is tagged with at most one of platformLsdumpTag, productLsdumpTag, or vendorLsdumpTag.
1555*333d2b36SAndroid Build Coastguard Worker		if len(headerAbiChecker.Ref_dump_dirs) > 0 && len(optInTags) != 1 {
1556*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("Expect exactly one opt-in lsdump tag when ref_dump_dirs are specified: %s", optInTags)
1557*333d2b36SAndroid Build Coastguard Worker			return
1558*333d2b36SAndroid Build Coastguard Worker		}
1559*333d2b36SAndroid Build Coastguard Worker		// Ensure that a module tagged with only platformLsdumpTag has ref_dump_dirs.
1560*333d2b36SAndroid Build Coastguard Worker		// Android.bp in vendor projects should be cleaned up before this is enforced for vendorLsdumpTag and productLsdumpTag.
1561*333d2b36SAndroid Build Coastguard Worker		if len(headerAbiChecker.Ref_dump_dirs) == 0 && len(tags) == 1 && tags[0] == platformLsdumpTag {
1562*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("header_abi_checker is explicitly enabled, but no ref_dump_dirs are specified.")
1563*333d2b36SAndroid Build Coastguard Worker		}
1564*333d2b36SAndroid Build Coastguard Worker		// Check against the opt-in reference dumps.
1565*333d2b36SAndroid Build Coastguard Worker		for i, optInDumpDir := range headerAbiChecker.Ref_dump_dirs {
1566*333d2b36SAndroid Build Coastguard Worker			optInDumpDirPath := android.PathForModuleSrc(ctx, optInDumpDir)
1567*333d2b36SAndroid Build Coastguard Worker			// Ref_dump_dirs are not versioned.
1568*333d2b36SAndroid Build Coastguard Worker			// They do not contain subdir for binder bitness because 64-bit binder has been mandatory.
1569*333d2b36SAndroid Build Coastguard Worker			optInDumpFile := getRefAbiDumpFile(ctx, optInDumpDirPath.String(), fileName)
1570*333d2b36SAndroid Build Coastguard Worker			if !optInDumpFile.Valid() {
1571*333d2b36SAndroid Build Coastguard Worker				continue
1572*333d2b36SAndroid Build Coastguard Worker			}
1573*333d2b36SAndroid Build Coastguard Worker			library.optInAbiDiff(ctx,
1574*333d2b36SAndroid Build Coastguard Worker				implDump, optInDumpFile.Path(),
1575*333d2b36SAndroid Build Coastguard Worker				fileName, "opt"+strconv.Itoa(i), optInDumpDirPath.String(), string(optInTags[0]))
1576*333d2b36SAndroid Build Coastguard Worker		}
1577*333d2b36SAndroid Build Coastguard Worker	}
1578*333d2b36SAndroid Build Coastguard Worker}
1579*333d2b36SAndroid Build Coastguard Worker
1580*333d2b36SAndroid Build Coastguard Worker// link registers actions to link this library, and sets various fields
1581*333d2b36SAndroid Build Coastguard Worker// on this library to reflect information that should be exported up the build
1582*333d2b36SAndroid Build Coastguard Worker// tree (for example, exported flags and include paths).
1583*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) link(ctx ModuleContext,
1584*333d2b36SAndroid Build Coastguard Worker	flags Flags, deps PathDeps, objs Objects) android.Path {
1585*333d2b36SAndroid Build Coastguard Worker
1586*333d2b36SAndroid Build Coastguard Worker	if ctx.IsLlndk() {
1587*333d2b36SAndroid Build Coastguard Worker		// override the module's export_include_dirs with llndk.override_export_include_dirs
1588*333d2b36SAndroid Build Coastguard Worker		// if it is set.
1589*333d2b36SAndroid Build Coastguard Worker		if override := library.Properties.Llndk.Override_export_include_dirs; override != nil {
1590*333d2b36SAndroid Build Coastguard Worker			library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](
1591*333d2b36SAndroid Build Coastguard Worker				nil,
1592*333d2b36SAndroid Build Coastguard Worker				[]proptools.ConfigurableCase[[]string]{
1593*333d2b36SAndroid Build Coastguard Worker					proptools.NewConfigurableCase[[]string](nil, &override),
1594*333d2b36SAndroid Build Coastguard Worker				},
1595*333d2b36SAndroid Build Coastguard Worker			)
1596*333d2b36SAndroid Build Coastguard Worker		}
1597*333d2b36SAndroid Build Coastguard Worker
1598*333d2b36SAndroid Build Coastguard Worker		if Bool(library.Properties.Llndk.Export_headers_as_system) {
1599*333d2b36SAndroid Build Coastguard Worker			library.flagExporter.Properties.Export_system_include_dirs = append(
1600*333d2b36SAndroid Build Coastguard Worker				library.flagExporter.Properties.Export_system_include_dirs,
1601*333d2b36SAndroid Build Coastguard Worker				library.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil)...)
1602*333d2b36SAndroid Build Coastguard Worker			library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](nil, nil)
1603*333d2b36SAndroid Build Coastguard Worker		}
1604*333d2b36SAndroid Build Coastguard Worker	}
1605*333d2b36SAndroid Build Coastguard Worker
1606*333d2b36SAndroid Build Coastguard Worker	if ctx.IsVendorPublicLibrary() {
1607*333d2b36SAndroid Build Coastguard Worker		// override the module's export_include_dirs with vendor_public_library.override_export_include_dirs
1608*333d2b36SAndroid Build Coastguard Worker		// if it is set.
1609*333d2b36SAndroid Build Coastguard Worker		if override := library.Properties.Vendor_public_library.Override_export_include_dirs; override != nil {
1610*333d2b36SAndroid Build Coastguard Worker			library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](
1611*333d2b36SAndroid Build Coastguard Worker				nil,
1612*333d2b36SAndroid Build Coastguard Worker				[]proptools.ConfigurableCase[[]string]{
1613*333d2b36SAndroid Build Coastguard Worker					proptools.NewConfigurableCase[[]string](nil, &override),
1614*333d2b36SAndroid Build Coastguard Worker				},
1615*333d2b36SAndroid Build Coastguard Worker			)
1616*333d2b36SAndroid Build Coastguard Worker		}
1617*333d2b36SAndroid Build Coastguard Worker	}
1618*333d2b36SAndroid Build Coastguard Worker
1619*333d2b36SAndroid Build Coastguard Worker	// Linking this library consists of linking `deps.Objs` (.o files in dependencies
1620*333d2b36SAndroid Build Coastguard Worker	// of this library), together with `objs` (.o files created by compiling this
1621*333d2b36SAndroid Build Coastguard Worker	// library).
1622*333d2b36SAndroid Build Coastguard Worker	objs = deps.Objs.Copy().Append(objs)
1623*333d2b36SAndroid Build Coastguard Worker	var out android.Path
1624*333d2b36SAndroid Build Coastguard Worker	if library.static() || library.header() {
1625*333d2b36SAndroid Build Coastguard Worker		out = library.linkStatic(ctx, flags, deps, objs)
1626*333d2b36SAndroid Build Coastguard Worker	} else {
1627*333d2b36SAndroid Build Coastguard Worker		out = library.linkShared(ctx, flags, deps, objs)
1628*333d2b36SAndroid Build Coastguard Worker	}
1629*333d2b36SAndroid Build Coastguard Worker
1630*333d2b36SAndroid Build Coastguard Worker	// Export include paths and flags to be propagated up the tree.
1631*333d2b36SAndroid Build Coastguard Worker	library.exportIncludes(ctx)
1632*333d2b36SAndroid Build Coastguard Worker	library.reexportDirs(deps.ReexportedDirs...)
1633*333d2b36SAndroid Build Coastguard Worker	library.reexportSystemDirs(deps.ReexportedSystemDirs...)
1634*333d2b36SAndroid Build Coastguard Worker	library.reexportFlags(deps.ReexportedFlags...)
1635*333d2b36SAndroid Build Coastguard Worker	library.reexportDeps(deps.ReexportedDeps...)
1636*333d2b36SAndroid Build Coastguard Worker	library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
1637*333d2b36SAndroid Build Coastguard Worker
1638*333d2b36SAndroid Build Coastguard Worker	if library.static() && len(deps.ReexportedRustRlibDeps) > 0 {
1639*333d2b36SAndroid Build Coastguard Worker		library.reexportRustStaticDeps(deps.ReexportedRustRlibDeps...)
1640*333d2b36SAndroid Build Coastguard Worker	}
1641*333d2b36SAndroid Build Coastguard Worker
1642*333d2b36SAndroid Build Coastguard Worker	// Optionally export aidl headers.
1643*333d2b36SAndroid Build Coastguard Worker	if Bool(library.Properties.Aidl.Export_aidl_headers) {
1644*333d2b36SAndroid Build Coastguard Worker		if library.baseCompiler.hasAidl(ctx, deps) {
1645*333d2b36SAndroid Build Coastguard Worker			if library.baseCompiler.hasSrcExt(ctx, ".aidl") {
1646*333d2b36SAndroid Build Coastguard Worker				dir := android.PathForModuleGen(ctx, "aidl")
1647*333d2b36SAndroid Build Coastguard Worker				library.reexportDirs(dir)
1648*333d2b36SAndroid Build Coastguard Worker			}
1649*333d2b36SAndroid Build Coastguard Worker			if len(deps.AidlLibraryInfos) > 0 {
1650*333d2b36SAndroid Build Coastguard Worker				dir := android.PathForModuleGen(ctx, "aidl_library")
1651*333d2b36SAndroid Build Coastguard Worker				library.reexportDirs(dir)
1652*333d2b36SAndroid Build Coastguard Worker			}
1653*333d2b36SAndroid Build Coastguard Worker
1654*333d2b36SAndroid Build Coastguard Worker			library.reexportDeps(library.baseCompiler.aidlOrderOnlyDeps...)
1655*333d2b36SAndroid Build Coastguard Worker			library.addExportedGeneratedHeaders(library.baseCompiler.aidlHeaders...)
1656*333d2b36SAndroid Build Coastguard Worker		}
1657*333d2b36SAndroid Build Coastguard Worker	}
1658*333d2b36SAndroid Build Coastguard Worker
1659*333d2b36SAndroid Build Coastguard Worker	// Optionally export proto headers.
1660*333d2b36SAndroid Build Coastguard Worker	if Bool(library.Properties.Proto.Export_proto_headers) {
1661*333d2b36SAndroid Build Coastguard Worker		if library.baseCompiler.hasSrcExt(ctx, ".proto") {
1662*333d2b36SAndroid Build Coastguard Worker			var includes android.Paths
1663*333d2b36SAndroid Build Coastguard Worker			if flags.proto.CanonicalPathFromRoot {
1664*333d2b36SAndroid Build Coastguard Worker				includes = append(includes, flags.proto.SubDir)
1665*333d2b36SAndroid Build Coastguard Worker			}
1666*333d2b36SAndroid Build Coastguard Worker			includes = append(includes, flags.proto.Dir)
1667*333d2b36SAndroid Build Coastguard Worker			library.reexportDirs(includes...)
1668*333d2b36SAndroid Build Coastguard Worker
1669*333d2b36SAndroid Build Coastguard Worker			library.reexportDeps(library.baseCompiler.protoOrderOnlyDeps...)
1670*333d2b36SAndroid Build Coastguard Worker			library.addExportedGeneratedHeaders(library.baseCompiler.protoHeaders...)
1671*333d2b36SAndroid Build Coastguard Worker		}
1672*333d2b36SAndroid Build Coastguard Worker	}
1673*333d2b36SAndroid Build Coastguard Worker
1674*333d2b36SAndroid Build Coastguard Worker	// If the library is sysprop_library, expose either public or internal header selectively.
1675*333d2b36SAndroid Build Coastguard Worker	if library.baseCompiler.hasSrcExt(ctx, ".sysprop") {
1676*333d2b36SAndroid Build Coastguard Worker		dir := android.PathForModuleGen(ctx, "sysprop", "include")
1677*333d2b36SAndroid Build Coastguard Worker		if library.Properties.Sysprop.Platform != nil {
1678*333d2b36SAndroid Build Coastguard Worker			isOwnerPlatform := Bool(library.Properties.Sysprop.Platform)
1679*333d2b36SAndroid Build Coastguard Worker
1680*333d2b36SAndroid Build Coastguard Worker			// If the owner is different from the user, expose public header. That is,
1681*333d2b36SAndroid Build Coastguard Worker			// 1) if the user is product (as owner can only be platform / vendor)
1682*333d2b36SAndroid Build Coastguard Worker			// 2) if the owner is platform and the client is vendor
1683*333d2b36SAndroid Build Coastguard Worker			// We don't care Platform -> Vendor dependency as it's already forbidden.
1684*333d2b36SAndroid Build Coastguard Worker			if ctx.Device() && (ctx.ProductSpecific() || (isOwnerPlatform && ctx.inVendor())) {
1685*333d2b36SAndroid Build Coastguard Worker				dir = android.PathForModuleGen(ctx, "sysprop/public", "include")
1686*333d2b36SAndroid Build Coastguard Worker			}
1687*333d2b36SAndroid Build Coastguard Worker		}
1688*333d2b36SAndroid Build Coastguard Worker
1689*333d2b36SAndroid Build Coastguard Worker		// Make sure to only export headers which are within the include directory.
1690*333d2b36SAndroid Build Coastguard Worker		_, headers := android.FilterPathListPredicate(library.baseCompiler.syspropHeaders, func(path android.Path) bool {
1691*333d2b36SAndroid Build Coastguard Worker			_, isRel := android.MaybeRel(ctx, dir.String(), path.String())
1692*333d2b36SAndroid Build Coastguard Worker			return isRel
1693*333d2b36SAndroid Build Coastguard Worker		})
1694*333d2b36SAndroid Build Coastguard Worker
1695*333d2b36SAndroid Build Coastguard Worker		// Add sysprop-related directories to the exported directories of this library.
1696*333d2b36SAndroid Build Coastguard Worker		library.reexportDirs(dir)
1697*333d2b36SAndroid Build Coastguard Worker		library.reexportDeps(library.baseCompiler.syspropOrderOnlyDeps...)
1698*333d2b36SAndroid Build Coastguard Worker		library.addExportedGeneratedHeaders(headers...)
1699*333d2b36SAndroid Build Coastguard Worker	}
1700*333d2b36SAndroid Build Coastguard Worker
1701*333d2b36SAndroid Build Coastguard Worker	// Add stub-related flags if this library is a stub library.
1702*333d2b36SAndroid Build Coastguard Worker	library.exportVersioningMacroIfNeeded(ctx)
1703*333d2b36SAndroid Build Coastguard Worker
1704*333d2b36SAndroid Build Coastguard Worker	// Propagate a Provider containing information about exported flags, deps, and include paths.
1705*333d2b36SAndroid Build Coastguard Worker	library.flagExporter.setProvider(ctx)
1706*333d2b36SAndroid Build Coastguard Worker
1707*333d2b36SAndroid Build Coastguard Worker	return out
1708*333d2b36SAndroid Build Coastguard Worker}
1709*333d2b36SAndroid Build Coastguard Worker
1710*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) {
1711*333d2b36SAndroid Build Coastguard Worker	if library.buildStubs() && library.stubsVersion() != "" && !library.skipAPIDefine {
1712*333d2b36SAndroid Build Coastguard Worker		name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx))
1713*333d2b36SAndroid Build Coastguard Worker		apiLevel, err := android.ApiLevelFromUser(ctx, library.stubsVersion())
1714*333d2b36SAndroid Build Coastguard Worker		if err != nil {
1715*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("Can't export version macro: %s", err.Error())
1716*333d2b36SAndroid Build Coastguard Worker		}
1717*333d2b36SAndroid Build Coastguard Worker		library.reexportFlags("-D" + name + "=" + strconv.Itoa(apiLevel.FinalOrPreviewInt()))
1718*333d2b36SAndroid Build Coastguard Worker	}
1719*333d2b36SAndroid Build Coastguard Worker}
1720*333d2b36SAndroid Build Coastguard Worker
1721*333d2b36SAndroid Build Coastguard Worker// buildStatic returns true if this library should be built as a static library.
1722*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) buildStatic() bool {
1723*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.BuildStatic &&
1724*333d2b36SAndroid Build Coastguard Worker		BoolDefault(library.StaticProperties.Static.Enabled, true)
1725*333d2b36SAndroid Build Coastguard Worker}
1726*333d2b36SAndroid Build Coastguard Worker
1727*333d2b36SAndroid Build Coastguard Worker// buildShared returns true if this library should be built as a shared library.
1728*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) buildShared() bool {
1729*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.BuildShared &&
1730*333d2b36SAndroid Build Coastguard Worker		BoolDefault(library.SharedProperties.Shared.Enabled, true)
1731*333d2b36SAndroid Build Coastguard Worker}
1732*333d2b36SAndroid Build Coastguard Worker
1733*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) objs() Objects {
1734*333d2b36SAndroid Build Coastguard Worker	return library.objects
1735*333d2b36SAndroid Build Coastguard Worker}
1736*333d2b36SAndroid Build Coastguard Worker
1737*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) reuseObjs() Objects {
1738*333d2b36SAndroid Build Coastguard Worker	return library.reuseObjects
1739*333d2b36SAndroid Build Coastguard Worker}
1740*333d2b36SAndroid Build Coastguard Worker
1741*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) toc() android.OptionalPath {
1742*333d2b36SAndroid Build Coastguard Worker	return library.tocFile
1743*333d2b36SAndroid Build Coastguard Worker}
1744*333d2b36SAndroid Build Coastguard Worker
1745*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
1746*333d2b36SAndroid Build Coastguard Worker	dir := library.baseInstaller.installDir(ctx)
1747*333d2b36SAndroid Build Coastguard Worker	dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir)
1748*333d2b36SAndroid Build Coastguard Worker	// libc_hwasan has relative_install_dir set, which would mess up the dir.Base() logic.
1749*333d2b36SAndroid Build Coastguard Worker	// hardcode here because it's the only target, if we have other targets that use this
1750*333d2b36SAndroid Build Coastguard Worker	// we can generalise this.
1751*333d2b36SAndroid Build Coastguard Worker	var target string
1752*333d2b36SAndroid Build Coastguard Worker	if ctx.baseModuleName() == "libc_hwasan" {
1753*333d2b36SAndroid Build Coastguard Worker		target = "/" + filepath.Join("apex", "com.android.runtime", "lib64", "bionic", "hwasan", file.Base())
1754*333d2b36SAndroid Build Coastguard Worker	} else {
1755*333d2b36SAndroid Build Coastguard Worker		base := dir.Base()
1756*333d2b36SAndroid Build Coastguard Worker		target = "/" + filepath.Join("apex", "com.android.runtime", base, "bionic", file.Base())
1757*333d2b36SAndroid Build Coastguard Worker	}
1758*333d2b36SAndroid Build Coastguard Worker	ctx.InstallAbsoluteSymlink(dir, file.Base(), target)
1759*333d2b36SAndroid Build Coastguard Worker	library.postInstallCmds = append(library.postInstallCmds, makeSymlinkCmd(dirOnDevice, file.Base(), target))
1760*333d2b36SAndroid Build Coastguard Worker}
1761*333d2b36SAndroid Build Coastguard Worker
1762*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
1763*333d2b36SAndroid Build Coastguard Worker	if library.shared() {
1764*333d2b36SAndroid Build Coastguard Worker		translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
1765*333d2b36SAndroid Build Coastguard Worker		if library.hasStubsVariants() && !ctx.Host() && !ctx.isSdkVariant() &&
1766*333d2b36SAndroid Build Coastguard Worker			InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() &&
1767*333d2b36SAndroid Build Coastguard Worker			!translatedArch && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() {
1768*333d2b36SAndroid Build Coastguard Worker			// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
1769*333d2b36SAndroid Build Coastguard Worker			// The original path becomes a symlink to the corresponding file in the
1770*333d2b36SAndroid Build Coastguard Worker			// runtime APEX.
1771*333d2b36SAndroid Build Coastguard Worker			if ctx.Device() {
1772*333d2b36SAndroid Build Coastguard Worker				library.installSymlinkToRuntimeApex(ctx, file)
1773*333d2b36SAndroid Build Coastguard Worker			}
1774*333d2b36SAndroid Build Coastguard Worker			library.baseInstaller.subDir = "bootstrap"
1775*333d2b36SAndroid Build Coastguard Worker		}
1776*333d2b36SAndroid Build Coastguard Worker
1777*333d2b36SAndroid Build Coastguard Worker		library.baseInstaller.install(ctx, file)
1778*333d2b36SAndroid Build Coastguard Worker	}
1779*333d2b36SAndroid Build Coastguard Worker
1780*333d2b36SAndroid Build Coastguard Worker	if Bool(library.Properties.Static_ndk_lib) && library.static() &&
1781*333d2b36SAndroid Build Coastguard Worker		!ctx.InVendorOrProduct() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() &&
1782*333d2b36SAndroid Build Coastguard Worker		library.baseLinker.sanitize.isUnsanitizedVariant() &&
1783*333d2b36SAndroid Build Coastguard Worker		ctx.isForPlatform() && !ctx.isPreventInstall() {
1784*333d2b36SAndroid Build Coastguard Worker		installPath := getUnversionedLibraryInstallPath(ctx).Join(ctx, file.Base())
1785*333d2b36SAndroid Build Coastguard Worker
1786*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleBuild(pctx, android.ModuleBuildParams{
1787*333d2b36SAndroid Build Coastguard Worker			Rule:        android.Cp,
1788*333d2b36SAndroid Build Coastguard Worker			Description: "install " + installPath.Base(),
1789*333d2b36SAndroid Build Coastguard Worker			Output:      installPath,
1790*333d2b36SAndroid Build Coastguard Worker			Input:       file,
1791*333d2b36SAndroid Build Coastguard Worker		})
1792*333d2b36SAndroid Build Coastguard Worker
1793*333d2b36SAndroid Build Coastguard Worker		library.ndkSysrootPath = installPath
1794*333d2b36SAndroid Build Coastguard Worker	}
1795*333d2b36SAndroid Build Coastguard Worker}
1796*333d2b36SAndroid Build Coastguard Worker
1797*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) everInstallable() bool {
1798*333d2b36SAndroid Build Coastguard Worker	// Only shared and static libraries are installed. Header libraries (which are
1799*333d2b36SAndroid Build Coastguard Worker	// neither static or shared) are not installed.
1800*333d2b36SAndroid Build Coastguard Worker	return library.shared() || library.static()
1801*333d2b36SAndroid Build Coastguard Worker}
1802*333d2b36SAndroid Build Coastguard Worker
1803*333d2b36SAndroid Build Coastguard Worker// static returns true if this library is for a "static' variant.
1804*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) static() bool {
1805*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.VariantIsStatic
1806*333d2b36SAndroid Build Coastguard Worker}
1807*333d2b36SAndroid Build Coastguard Worker
1808*333d2b36SAndroid Build Coastguard Worker// shared returns true if this library is for a "shared' variant.
1809*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) shared() bool {
1810*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.VariantIsShared
1811*333d2b36SAndroid Build Coastguard Worker}
1812*333d2b36SAndroid Build Coastguard Worker
1813*333d2b36SAndroid Build Coastguard Worker// header returns true if this library is for a header-only variant.
1814*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) header() bool {
1815*333d2b36SAndroid Build Coastguard Worker	// Neither "static" nor "shared" implies this library is header-only.
1816*333d2b36SAndroid Build Coastguard Worker	return !library.static() && !library.shared()
1817*333d2b36SAndroid Build Coastguard Worker}
1818*333d2b36SAndroid Build Coastguard Worker
1819*333d2b36SAndroid Build Coastguard Worker// setStatic marks the library variant as "static".
1820*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) setStatic() {
1821*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.VariantIsStatic = true
1822*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.VariantIsShared = false
1823*333d2b36SAndroid Build Coastguard Worker}
1824*333d2b36SAndroid Build Coastguard Worker
1825*333d2b36SAndroid Build Coastguard Worker// setShared marks the library variant as "shared".
1826*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) setShared() {
1827*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.VariantIsStatic = false
1828*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.VariantIsShared = true
1829*333d2b36SAndroid Build Coastguard Worker}
1830*333d2b36SAndroid Build Coastguard Worker
1831*333d2b36SAndroid Build Coastguard Worker// BuildOnlyStatic disables building this library as a shared library.
1832*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) BuildOnlyStatic() {
1833*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.BuildShared = false
1834*333d2b36SAndroid Build Coastguard Worker}
1835*333d2b36SAndroid Build Coastguard Worker
1836*333d2b36SAndroid Build Coastguard Worker// BuildOnlyShared disables building this library as a static library.
1837*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) BuildOnlyShared() {
1838*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.BuildStatic = false
1839*333d2b36SAndroid Build Coastguard Worker}
1840*333d2b36SAndroid Build Coastguard Worker
1841*333d2b36SAndroid Build Coastguard Worker// HeaderOnly disables building this library as a shared or static library;
1842*333d2b36SAndroid Build Coastguard Worker// the library only exists to propagate header file dependencies up the build graph.
1843*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) HeaderOnly() {
1844*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.BuildShared = false
1845*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.BuildStatic = false
1846*333d2b36SAndroid Build Coastguard Worker}
1847*333d2b36SAndroid Build Coastguard Worker
1848*333d2b36SAndroid Build Coastguard Worker// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
1849*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) hasLLNDKStubs() bool {
1850*333d2b36SAndroid Build Coastguard Worker	return String(library.Properties.Llndk.Symbol_file) != ""
1851*333d2b36SAndroid Build Coastguard Worker}
1852*333d2b36SAndroid Build Coastguard Worker
1853*333d2b36SAndroid Build Coastguard Worker// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
1854*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) hasLLNDKHeaders() bool {
1855*333d2b36SAndroid Build Coastguard Worker	return Bool(library.Properties.Llndk.Llndk_headers)
1856*333d2b36SAndroid Build Coastguard Worker}
1857*333d2b36SAndroid Build Coastguard Worker
1858*333d2b36SAndroid Build Coastguard Worker// isLLNDKMovedToApex returns true if this cc_library module sets the llndk.moved_to_apex property.
1859*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) isLLNDKMovedToApex() bool {
1860*333d2b36SAndroid Build Coastguard Worker	return Bool(library.Properties.Llndk.Moved_to_apex)
1861*333d2b36SAndroid Build Coastguard Worker}
1862*333d2b36SAndroid Build Coastguard Worker
1863*333d2b36SAndroid Build Coastguard Worker// hasVendorPublicLibrary returns true if this cc_library module has a variant that will build
1864*333d2b36SAndroid Build Coastguard Worker// vendor public library stubs.
1865*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) hasVendorPublicLibrary() bool {
1866*333d2b36SAndroid Build Coastguard Worker	return String(library.Properties.Vendor_public_library.Symbol_file) != ""
1867*333d2b36SAndroid Build Coastguard Worker}
1868*333d2b36SAndroid Build Coastguard Worker
1869*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) implementationModuleName(name string) string {
1870*333d2b36SAndroid Build Coastguard Worker	return name
1871*333d2b36SAndroid Build Coastguard Worker}
1872*333d2b36SAndroid Build Coastguard Worker
1873*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) buildStubs() bool {
1874*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.BuildStubs
1875*333d2b36SAndroid Build Coastguard Worker}
1876*333d2b36SAndroid Build Coastguard Worker
1877*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string {
1878*333d2b36SAndroid Build Coastguard Worker	if props := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module)); props.Symbol_file != nil {
1879*333d2b36SAndroid Build Coastguard Worker		return props.Symbol_file
1880*333d2b36SAndroid Build Coastguard Worker	}
1881*333d2b36SAndroid Build Coastguard Worker	if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
1882*333d2b36SAndroid Build Coastguard Worker		return library.Properties.Stubs.Symbol_file
1883*333d2b36SAndroid Build Coastguard Worker	}
1884*333d2b36SAndroid Build Coastguard Worker	// TODO(b/309880485): Distinguish platform, NDK, LLNDK, and APEX version scripts.
1885*333d2b36SAndroid Build Coastguard Worker	if library.baseLinker.Properties.Version_script != nil {
1886*333d2b36SAndroid Build Coastguard Worker		return library.baseLinker.Properties.Version_script
1887*333d2b36SAndroid Build Coastguard Worker	}
1888*333d2b36SAndroid Build Coastguard Worker	return nil
1889*333d2b36SAndroid Build Coastguard Worker}
1890*333d2b36SAndroid Build Coastguard Worker
1891*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) hasStubsVariants() bool {
1892*333d2b36SAndroid Build Coastguard Worker	// Just having stubs.symbol_file is enough to create a stub variant. In that case
1893*333d2b36SAndroid Build Coastguard Worker	// the stub for the future API level is created.
1894*333d2b36SAndroid Build Coastguard Worker	return library.Properties.Stubs.Symbol_file != nil ||
1895*333d2b36SAndroid Build Coastguard Worker		len(library.Properties.Stubs.Versions) > 0
1896*333d2b36SAndroid Build Coastguard Worker}
1897*333d2b36SAndroid Build Coastguard Worker
1898*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) isStubsImplementationRequired() bool {
1899*333d2b36SAndroid Build Coastguard Worker	return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
1900*333d2b36SAndroid Build Coastguard Worker}
1901*333d2b36SAndroid Build Coastguard Worker
1902*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) stubsVersions(ctx android.BaseModuleContext) []string {
1903*333d2b36SAndroid Build Coastguard Worker	if !library.hasStubsVariants() {
1904*333d2b36SAndroid Build Coastguard Worker		return nil
1905*333d2b36SAndroid Build Coastguard Worker	}
1906*333d2b36SAndroid Build Coastguard Worker
1907*333d2b36SAndroid Build Coastguard Worker	if library.hasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() {
1908*333d2b36SAndroid Build Coastguard Worker		// LLNDK libraries only need a single stubs variant (""), which is
1909*333d2b36SAndroid Build Coastguard Worker		// added automatically in createVersionVariations().
1910*333d2b36SAndroid Build Coastguard Worker		return nil
1911*333d2b36SAndroid Build Coastguard Worker	}
1912*333d2b36SAndroid Build Coastguard Worker
1913*333d2b36SAndroid Build Coastguard Worker	// Future API level is implicitly added if there isn't
1914*333d2b36SAndroid Build Coastguard Worker	versions := addCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
1915*333d2b36SAndroid Build Coastguard Worker	normalizeVersions(ctx, versions)
1916*333d2b36SAndroid Build Coastguard Worker	return versions
1917*333d2b36SAndroid Build Coastguard Worker}
1918*333d2b36SAndroid Build Coastguard Worker
1919*333d2b36SAndroid Build Coastguard Workerfunc addCurrentVersionIfNotPresent(vers []string) []string {
1920*333d2b36SAndroid Build Coastguard Worker	if inList(android.FutureApiLevel.String(), vers) {
1921*333d2b36SAndroid Build Coastguard Worker		return vers
1922*333d2b36SAndroid Build Coastguard Worker	}
1923*333d2b36SAndroid Build Coastguard Worker	// In some cases, people use the raw value "10000" in the versions property.
1924*333d2b36SAndroid Build Coastguard Worker	// We shouldn't add the future API level in that case, otherwise there will
1925*333d2b36SAndroid Build Coastguard Worker	// be two identical versions.
1926*333d2b36SAndroid Build Coastguard Worker	if inList(strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()), vers) {
1927*333d2b36SAndroid Build Coastguard Worker		return vers
1928*333d2b36SAndroid Build Coastguard Worker	}
1929*333d2b36SAndroid Build Coastguard Worker	return append(vers, android.FutureApiLevel.String())
1930*333d2b36SAndroid Build Coastguard Worker}
1931*333d2b36SAndroid Build Coastguard Worker
1932*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) setStubsVersion(version string) {
1933*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.StubsVersion = version
1934*333d2b36SAndroid Build Coastguard Worker}
1935*333d2b36SAndroid Build Coastguard Worker
1936*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) stubsVersion() string {
1937*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.StubsVersion
1938*333d2b36SAndroid Build Coastguard Worker}
1939*333d2b36SAndroid Build Coastguard Worker
1940*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) setBuildStubs(isLatest bool) {
1941*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.BuildStubs = true
1942*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.IsLatestVersion = isLatest
1943*333d2b36SAndroid Build Coastguard Worker}
1944*333d2b36SAndroid Build Coastguard Worker
1945*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) setAllStubsVersions(versions []string) {
1946*333d2b36SAndroid Build Coastguard Worker	library.MutatedProperties.AllStubsVersions = versions
1947*333d2b36SAndroid Build Coastguard Worker}
1948*333d2b36SAndroid Build Coastguard Worker
1949*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) allStubsVersions() []string {
1950*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.AllStubsVersions
1951*333d2b36SAndroid Build Coastguard Worker}
1952*333d2b36SAndroid Build Coastguard Worker
1953*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) isLatestStubVersion() bool {
1954*333d2b36SAndroid Build Coastguard Worker	return library.MutatedProperties.IsLatestVersion
1955*333d2b36SAndroid Build Coastguard Worker}
1956*333d2b36SAndroid Build Coastguard Worker
1957*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) availableFor(what string) bool {
1958*333d2b36SAndroid Build Coastguard Worker	var list []string
1959*333d2b36SAndroid Build Coastguard Worker	if library.static() {
1960*333d2b36SAndroid Build Coastguard Worker		list = library.StaticProperties.Static.Apex_available
1961*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
1962*333d2b36SAndroid Build Coastguard Worker		list = library.SharedProperties.Shared.Apex_available
1963*333d2b36SAndroid Build Coastguard Worker	}
1964*333d2b36SAndroid Build Coastguard Worker	if len(list) == 0 {
1965*333d2b36SAndroid Build Coastguard Worker		return false
1966*333d2b36SAndroid Build Coastguard Worker	}
1967*333d2b36SAndroid Build Coastguard Worker	return android.CheckAvailableForApex(what, list)
1968*333d2b36SAndroid Build Coastguard Worker}
1969*333d2b36SAndroid Build Coastguard Worker
1970*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) installable() *bool {
1971*333d2b36SAndroid Build Coastguard Worker	if library.static() {
1972*333d2b36SAndroid Build Coastguard Worker		return library.StaticProperties.Static.Installable
1973*333d2b36SAndroid Build Coastguard Worker	} else if library.shared() {
1974*333d2b36SAndroid Build Coastguard Worker		return library.SharedProperties.Shared.Installable
1975*333d2b36SAndroid Build Coastguard Worker	}
1976*333d2b36SAndroid Build Coastguard Worker	return nil
1977*333d2b36SAndroid Build Coastguard Worker}
1978*333d2b36SAndroid Build Coastguard Worker
1979*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) makeUninstallable(mod *Module) {
1980*333d2b36SAndroid Build Coastguard Worker	if library.static() && library.buildStatic() && !library.buildStubs() {
1981*333d2b36SAndroid Build Coastguard Worker		// If we're asked to make a static library uninstallable we don't do
1982*333d2b36SAndroid Build Coastguard Worker		// anything since AndroidMkEntries always sets LOCAL_UNINSTALLABLE_MODULE
1983*333d2b36SAndroid Build Coastguard Worker		// for these entries. This is done to still get the make targets for NOTICE
1984*333d2b36SAndroid Build Coastguard Worker		// files from notice_files.mk, which other libraries might depend on.
1985*333d2b36SAndroid Build Coastguard Worker		return
1986*333d2b36SAndroid Build Coastguard Worker	}
1987*333d2b36SAndroid Build Coastguard Worker	mod.ModuleBase.MakeUninstallable()
1988*333d2b36SAndroid Build Coastguard Worker}
1989*333d2b36SAndroid Build Coastguard Worker
1990*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) getPartition() string {
1991*333d2b36SAndroid Build Coastguard Worker	return library.path.Partition()
1992*333d2b36SAndroid Build Coastguard Worker}
1993*333d2b36SAndroid Build Coastguard Worker
1994*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPath {
1995*333d2b36SAndroid Build Coastguard Worker	return library.apiListCoverageXmlPath
1996*333d2b36SAndroid Build Coastguard Worker}
1997*333d2b36SAndroid Build Coastguard Worker
1998*333d2b36SAndroid Build Coastguard Workerfunc (library *libraryDecorator) overriddenModules() []string {
1999*333d2b36SAndroid Build Coastguard Worker	return library.Properties.Overrides
2000*333d2b36SAndroid Build Coastguard Worker}
2001*333d2b36SAndroid Build Coastguard Worker
2002*333d2b36SAndroid Build Coastguard Workervar _ overridable = (*libraryDecorator)(nil)
2003*333d2b36SAndroid Build Coastguard Worker
2004*333d2b36SAndroid Build Coastguard Workervar versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
2005*333d2b36SAndroid Build Coastguard Worker
2006*333d2b36SAndroid Build Coastguard Worker// versioningMacroNamesList returns a singleton map, where keys are "version macro names",
2007*333d2b36SAndroid Build Coastguard Worker// and values are the module name responsible for registering the version macro name.
2008*333d2b36SAndroid Build Coastguard Worker//
2009*333d2b36SAndroid Build Coastguard Worker// Version macros are used when building against stubs, to provide version information about
2010*333d2b36SAndroid Build Coastguard Worker// the stub. Only stub libraries should have an entry in this list.
2011*333d2b36SAndroid Build Coastguard Worker//
2012*333d2b36SAndroid Build Coastguard Worker// For example, when building against libFoo#ver, __LIBFOO_API__ macro is set to ver so
2013*333d2b36SAndroid Build Coastguard Worker// that headers from libFoo can be conditionally compiled (this may hide APIs
2014*333d2b36SAndroid Build Coastguard Worker// that are not available for the version).
2015*333d2b36SAndroid Build Coastguard Worker//
2016*333d2b36SAndroid Build Coastguard Worker// This map is used to ensure that there aren't conflicts between these version macro names.
2017*333d2b36SAndroid Build Coastguard Workerfunc versioningMacroNamesList(config android.Config) *map[string]string {
2018*333d2b36SAndroid Build Coastguard Worker	return config.Once(versioningMacroNamesListKey, func() interface{} {
2019*333d2b36SAndroid Build Coastguard Worker		m := make(map[string]string)
2020*333d2b36SAndroid Build Coastguard Worker		return &m
2021*333d2b36SAndroid Build Coastguard Worker	}).(*map[string]string)
2022*333d2b36SAndroid Build Coastguard Worker}
2023*333d2b36SAndroid Build Coastguard Worker
2024*333d2b36SAndroid Build Coastguard Worker// alphanumeric and _ characters are preserved.
2025*333d2b36SAndroid Build Coastguard Worker// other characters are all converted to _
2026*333d2b36SAndroid Build Coastguard Workervar charsNotForMacro = regexp.MustCompile("[^a-zA-Z0-9_]+")
2027*333d2b36SAndroid Build Coastguard Worker
2028*333d2b36SAndroid Build Coastguard Worker// versioningMacroName returns the canonical version macro name for the given module.
2029*333d2b36SAndroid Build Coastguard Workerfunc versioningMacroName(moduleName string) string {
2030*333d2b36SAndroid Build Coastguard Worker	macroName := charsNotForMacro.ReplaceAllString(moduleName, "_")
2031*333d2b36SAndroid Build Coastguard Worker	macroName = strings.ToUpper(macroName)
2032*333d2b36SAndroid Build Coastguard Worker	return "__" + macroName + "_API__"
2033*333d2b36SAndroid Build Coastguard Worker}
2034*333d2b36SAndroid Build Coastguard Worker
2035*333d2b36SAndroid Build Coastguard Worker// NewLibrary builds and returns a new Module corresponding to a C++ library.
2036*333d2b36SAndroid Build Coastguard Worker// Individual module implementations which comprise a C++ library (or something like
2037*333d2b36SAndroid Build Coastguard Worker// a C++ library) should call this function, set some fields on the result, and
2038*333d2b36SAndroid Build Coastguard Worker// then call the Init function.
2039*333d2b36SAndroid Build Coastguard Workerfunc NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
2040*333d2b36SAndroid Build Coastguard Worker	module := newModule(hod, android.MultilibBoth)
2041*333d2b36SAndroid Build Coastguard Worker
2042*333d2b36SAndroid Build Coastguard Worker	library := &libraryDecorator{
2043*333d2b36SAndroid Build Coastguard Worker		MutatedProperties: LibraryMutatedProperties{
2044*333d2b36SAndroid Build Coastguard Worker			BuildShared: true,
2045*333d2b36SAndroid Build Coastguard Worker			BuildStatic: true,
2046*333d2b36SAndroid Build Coastguard Worker		},
2047*333d2b36SAndroid Build Coastguard Worker		baseCompiler:  NewBaseCompiler(),
2048*333d2b36SAndroid Build Coastguard Worker		baseLinker:    NewBaseLinker(module.sanitize),
2049*333d2b36SAndroid Build Coastguard Worker		baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem),
2050*333d2b36SAndroid Build Coastguard Worker		sabi:          module.sabi,
2051*333d2b36SAndroid Build Coastguard Worker	}
2052*333d2b36SAndroid Build Coastguard Worker
2053*333d2b36SAndroid Build Coastguard Worker	module.compiler = library
2054*333d2b36SAndroid Build Coastguard Worker	module.linker = library
2055*333d2b36SAndroid Build Coastguard Worker	module.installer = library
2056*333d2b36SAndroid Build Coastguard Worker	module.library = library
2057*333d2b36SAndroid Build Coastguard Worker
2058*333d2b36SAndroid Build Coastguard Worker	return module, library
2059*333d2b36SAndroid Build Coastguard Worker}
2060*333d2b36SAndroid Build Coastguard Worker
2061*333d2b36SAndroid Build Coastguard Worker// connects a shared library to a static library in order to reuse its .o files to avoid
2062*333d2b36SAndroid Build Coastguard Worker// compiling source files twice.
2063*333d2b36SAndroid Build Coastguard Workerfunc reuseStaticLibrary(ctx android.BottomUpMutatorContext, shared *Module) {
2064*333d2b36SAndroid Build Coastguard Worker	if sharedCompiler, ok := shared.compiler.(*libraryDecorator); ok {
2065*333d2b36SAndroid Build Coastguard Worker
2066*333d2b36SAndroid Build Coastguard Worker		// Check libraries in addition to cflags, since libraries may be exporting different
2067*333d2b36SAndroid Build Coastguard Worker		// include directories.
2068*333d2b36SAndroid Build Coastguard Worker		if len(sharedCompiler.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)) == 0 &&
2069*333d2b36SAndroid Build Coastguard Worker			len(sharedCompiler.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)) == 0 &&
2070*333d2b36SAndroid Build Coastguard Worker			len(sharedCompiler.StaticProperties.Static.Whole_static_libs.GetOrDefault(ctx, nil)) == 0 &&
2071*333d2b36SAndroid Build Coastguard Worker			len(sharedCompiler.SharedProperties.Shared.Whole_static_libs.GetOrDefault(ctx, nil)) == 0 &&
2072*333d2b36SAndroid Build Coastguard Worker			len(sharedCompiler.StaticProperties.Static.Static_libs.GetOrDefault(ctx, nil)) == 0 &&
2073*333d2b36SAndroid Build Coastguard Worker			len(sharedCompiler.SharedProperties.Shared.Static_libs.GetOrDefault(ctx, nil)) == 0 &&
2074*333d2b36SAndroid Build Coastguard Worker			len(sharedCompiler.StaticProperties.Static.Shared_libs.GetOrDefault(ctx, nil)) == 0 &&
2075*333d2b36SAndroid Build Coastguard Worker			len(sharedCompiler.SharedProperties.Shared.Shared_libs.GetOrDefault(ctx, nil)) == 0 &&
2076*333d2b36SAndroid Build Coastguard Worker			// Compare System_shared_libs properties with nil because empty lists are
2077*333d2b36SAndroid Build Coastguard Worker			// semantically significant for them.
2078*333d2b36SAndroid Build Coastguard Worker			sharedCompiler.StaticProperties.Static.System_shared_libs == nil &&
2079*333d2b36SAndroid Build Coastguard Worker			sharedCompiler.SharedProperties.Shared.System_shared_libs == nil {
2080*333d2b36SAndroid Build Coastguard Worker
2081*333d2b36SAndroid Build Coastguard Worker			ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, reuseObjTag, ctx.ModuleName())
2082*333d2b36SAndroid Build Coastguard Worker		}
2083*333d2b36SAndroid Build Coastguard Worker
2084*333d2b36SAndroid Build Coastguard Worker		// This dep is just to reference static variant from shared variant
2085*333d2b36SAndroid Build Coastguard Worker		ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticVariantTag, ctx.ModuleName())
2086*333d2b36SAndroid Build Coastguard Worker	}
2087*333d2b36SAndroid Build Coastguard Worker}
2088*333d2b36SAndroid Build Coastguard Worker
2089*333d2b36SAndroid Build Coastguard Worker// linkageTransitionMutator adds "static" or "shared" variants for modules depending
2090*333d2b36SAndroid Build Coastguard Worker// on whether the module can be built as a static library or a shared library.
2091*333d2b36SAndroid Build Coastguard Workertype linkageTransitionMutator struct{}
2092*333d2b36SAndroid Build Coastguard Worker
2093*333d2b36SAndroid Build Coastguard Workerfunc (linkageTransitionMutator) Split(ctx android.BaseModuleContext) []string {
2094*333d2b36SAndroid Build Coastguard Worker	ccPrebuilt := false
2095*333d2b36SAndroid Build Coastguard Worker	if m, ok := ctx.Module().(*Module); ok && m.linker != nil {
2096*333d2b36SAndroid Build Coastguard Worker		_, ccPrebuilt = m.linker.(prebuiltLibraryInterface)
2097*333d2b36SAndroid Build Coastguard Worker	}
2098*333d2b36SAndroid Build Coastguard Worker	if ccPrebuilt {
2099*333d2b36SAndroid Build Coastguard Worker		library := ctx.Module().(*Module).linker.(prebuiltLibraryInterface)
2100*333d2b36SAndroid Build Coastguard Worker
2101*333d2b36SAndroid Build Coastguard Worker		// Differentiate between header only and building an actual static/shared library
2102*333d2b36SAndroid Build Coastguard Worker		buildStatic := library.buildStatic()
2103*333d2b36SAndroid Build Coastguard Worker		buildShared := library.buildShared()
2104*333d2b36SAndroid Build Coastguard Worker		if buildStatic || buildShared {
2105*333d2b36SAndroid Build Coastguard Worker			// Always create both the static and shared variants for prebuilt libraries, and then disable the one
2106*333d2b36SAndroid Build Coastguard Worker			// that is not being used.  This allows them to share the name of a cc_library module, which requires that
2107*333d2b36SAndroid Build Coastguard Worker			// all the variants of the cc_library also exist on the prebuilt.
2108*333d2b36SAndroid Build Coastguard Worker			return []string{"static", "shared"}
2109*333d2b36SAndroid Build Coastguard Worker		} else {
2110*333d2b36SAndroid Build Coastguard Worker			// Header only
2111*333d2b36SAndroid Build Coastguard Worker		}
2112*333d2b36SAndroid Build Coastguard Worker	} else if library, ok := ctx.Module().(LinkableInterface); ok && (library.CcLibraryInterface() || library.RustLibraryInterface()) {
2113*333d2b36SAndroid Build Coastguard Worker		// Non-cc.Modules may need an empty variant for their mutators.
2114*333d2b36SAndroid Build Coastguard Worker		variations := []string{}
2115*333d2b36SAndroid Build Coastguard Worker		if library.NonCcVariants() {
2116*333d2b36SAndroid Build Coastguard Worker			variations = append(variations, "")
2117*333d2b36SAndroid Build Coastguard Worker		}
2118*333d2b36SAndroid Build Coastguard Worker		isLLNDK := false
2119*333d2b36SAndroid Build Coastguard Worker		if m, ok := ctx.Module().(*Module); ok {
2120*333d2b36SAndroid Build Coastguard Worker			isLLNDK = m.IsLlndk()
2121*333d2b36SAndroid Build Coastguard Worker		}
2122*333d2b36SAndroid Build Coastguard Worker		buildStatic := library.BuildStaticVariant() && !isLLNDK
2123*333d2b36SAndroid Build Coastguard Worker		buildShared := library.BuildSharedVariant()
2124*333d2b36SAndroid Build Coastguard Worker		if buildStatic && buildShared {
2125*333d2b36SAndroid Build Coastguard Worker			variations = append([]string{"static", "shared"}, variations...)
2126*333d2b36SAndroid Build Coastguard Worker			return variations
2127*333d2b36SAndroid Build Coastguard Worker		} else if buildStatic {
2128*333d2b36SAndroid Build Coastguard Worker			variations = append([]string{"static"}, variations...)
2129*333d2b36SAndroid Build Coastguard Worker		} else if buildShared {
2130*333d2b36SAndroid Build Coastguard Worker			variations = append([]string{"shared"}, variations...)
2131*333d2b36SAndroid Build Coastguard Worker		}
2132*333d2b36SAndroid Build Coastguard Worker
2133*333d2b36SAndroid Build Coastguard Worker		if len(variations) > 0 {
2134*333d2b36SAndroid Build Coastguard Worker			return variations
2135*333d2b36SAndroid Build Coastguard Worker		}
2136*333d2b36SAndroid Build Coastguard Worker	}
2137*333d2b36SAndroid Build Coastguard Worker	return []string{""}
2138*333d2b36SAndroid Build Coastguard Worker}
2139*333d2b36SAndroid Build Coastguard Worker
2140*333d2b36SAndroid Build Coastguard Workerfunc (linkageTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
2141*333d2b36SAndroid Build Coastguard Worker	return ""
2142*333d2b36SAndroid Build Coastguard Worker}
2143*333d2b36SAndroid Build Coastguard Worker
2144*333d2b36SAndroid Build Coastguard Workerfunc (linkageTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
2145*333d2b36SAndroid Build Coastguard Worker	ccPrebuilt := false
2146*333d2b36SAndroid Build Coastguard Worker	if m, ok := ctx.Module().(*Module); ok && m.linker != nil {
2147*333d2b36SAndroid Build Coastguard Worker		_, ccPrebuilt = m.linker.(prebuiltLibraryInterface)
2148*333d2b36SAndroid Build Coastguard Worker	}
2149*333d2b36SAndroid Build Coastguard Worker	if ccPrebuilt {
2150*333d2b36SAndroid Build Coastguard Worker		if incomingVariation != "" {
2151*333d2b36SAndroid Build Coastguard Worker			return incomingVariation
2152*333d2b36SAndroid Build Coastguard Worker		}
2153*333d2b36SAndroid Build Coastguard Worker		library := ctx.Module().(*Module).linker.(prebuiltLibraryInterface)
2154*333d2b36SAndroid Build Coastguard Worker		if library.buildShared() {
2155*333d2b36SAndroid Build Coastguard Worker			return "shared"
2156*333d2b36SAndroid Build Coastguard Worker		} else if library.buildStatic() {
2157*333d2b36SAndroid Build Coastguard Worker			return "static"
2158*333d2b36SAndroid Build Coastguard Worker		}
2159*333d2b36SAndroid Build Coastguard Worker		return ""
2160*333d2b36SAndroid Build Coastguard Worker	} else if library, ok := ctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
2161*333d2b36SAndroid Build Coastguard Worker		isLLNDK := false
2162*333d2b36SAndroid Build Coastguard Worker		if m, ok := ctx.Module().(*Module); ok {
2163*333d2b36SAndroid Build Coastguard Worker			isLLNDK = m.IsLlndk()
2164*333d2b36SAndroid Build Coastguard Worker		}
2165*333d2b36SAndroid Build Coastguard Worker		buildStatic := library.BuildStaticVariant() && !isLLNDK
2166*333d2b36SAndroid Build Coastguard Worker		buildShared := library.BuildSharedVariant()
2167*333d2b36SAndroid Build Coastguard Worker		if library.BuildRlibVariant() && library.IsRustFFI() && !buildStatic && (incomingVariation == "static" || incomingVariation == "") {
2168*333d2b36SAndroid Build Coastguard Worker			// Rust modules do not build static libs, but rlibs are used as if they
2169*333d2b36SAndroid Build Coastguard Worker			// were via `static_libs`. Thus we need to alias the BuildRlibVariant
2170*333d2b36SAndroid Build Coastguard Worker			// to "static" for Rust FFI libraries.
2171*333d2b36SAndroid Build Coastguard Worker			return ""
2172*333d2b36SAndroid Build Coastguard Worker		}
2173*333d2b36SAndroid Build Coastguard Worker		if incomingVariation != "" {
2174*333d2b36SAndroid Build Coastguard Worker			return incomingVariation
2175*333d2b36SAndroid Build Coastguard Worker		}
2176*333d2b36SAndroid Build Coastguard Worker		if buildShared {
2177*333d2b36SAndroid Build Coastguard Worker			return "shared"
2178*333d2b36SAndroid Build Coastguard Worker		} else if buildStatic {
2179*333d2b36SAndroid Build Coastguard Worker			return "static"
2180*333d2b36SAndroid Build Coastguard Worker		}
2181*333d2b36SAndroid Build Coastguard Worker		return ""
2182*333d2b36SAndroid Build Coastguard Worker	}
2183*333d2b36SAndroid Build Coastguard Worker	return ""
2184*333d2b36SAndroid Build Coastguard Worker}
2185*333d2b36SAndroid Build Coastguard Worker
2186*333d2b36SAndroid Build Coastguard Workerfunc (linkageTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
2187*333d2b36SAndroid Build Coastguard Worker	ccPrebuilt := false
2188*333d2b36SAndroid Build Coastguard Worker	if m, ok := ctx.Module().(*Module); ok && m.linker != nil {
2189*333d2b36SAndroid Build Coastguard Worker		_, ccPrebuilt = m.linker.(prebuiltLibraryInterface)
2190*333d2b36SAndroid Build Coastguard Worker	}
2191*333d2b36SAndroid Build Coastguard Worker	if ccPrebuilt {
2192*333d2b36SAndroid Build Coastguard Worker		library := ctx.Module().(*Module).linker.(prebuiltLibraryInterface)
2193*333d2b36SAndroid Build Coastguard Worker		if variation == "static" {
2194*333d2b36SAndroid Build Coastguard Worker			library.setStatic()
2195*333d2b36SAndroid Build Coastguard Worker			if !library.buildStatic() {
2196*333d2b36SAndroid Build Coastguard Worker				library.disablePrebuilt()
2197*333d2b36SAndroid Build Coastguard Worker			}
2198*333d2b36SAndroid Build Coastguard Worker		} else if variation == "shared" {
2199*333d2b36SAndroid Build Coastguard Worker			library.setShared()
2200*333d2b36SAndroid Build Coastguard Worker			if !library.buildShared() {
2201*333d2b36SAndroid Build Coastguard Worker				library.disablePrebuilt()
2202*333d2b36SAndroid Build Coastguard Worker			}
2203*333d2b36SAndroid Build Coastguard Worker		}
2204*333d2b36SAndroid Build Coastguard Worker	} else if library, ok := ctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
2205*333d2b36SAndroid Build Coastguard Worker		if variation == "static" {
2206*333d2b36SAndroid Build Coastguard Worker			library.SetStatic()
2207*333d2b36SAndroid Build Coastguard Worker		} else if variation == "shared" {
2208*333d2b36SAndroid Build Coastguard Worker			library.SetShared()
2209*333d2b36SAndroid Build Coastguard Worker			var isLLNDK bool
2210*333d2b36SAndroid Build Coastguard Worker			if m, ok := ctx.Module().(*Module); ok {
2211*333d2b36SAndroid Build Coastguard Worker				isLLNDK = m.IsLlndk()
2212*333d2b36SAndroid Build Coastguard Worker			}
2213*333d2b36SAndroid Build Coastguard Worker			buildStatic := library.BuildStaticVariant() && !isLLNDK
2214*333d2b36SAndroid Build Coastguard Worker			buildShared := library.BuildSharedVariant()
2215*333d2b36SAndroid Build Coastguard Worker			if buildStatic && buildShared {
2216*333d2b36SAndroid Build Coastguard Worker				if _, ok := library.(*Module); ok {
2217*333d2b36SAndroid Build Coastguard Worker					reuseStaticLibrary(ctx, library.(*Module))
2218*333d2b36SAndroid Build Coastguard Worker				}
2219*333d2b36SAndroid Build Coastguard Worker			}
2220*333d2b36SAndroid Build Coastguard Worker		}
2221*333d2b36SAndroid Build Coastguard Worker	}
2222*333d2b36SAndroid Build Coastguard Worker}
2223*333d2b36SAndroid Build Coastguard Worker
2224*333d2b36SAndroid Build Coastguard Worker// normalizeVersions modifies `versions` in place, so that each raw version
2225*333d2b36SAndroid Build Coastguard Worker// string becomes its normalized canonical form.
2226*333d2b36SAndroid Build Coastguard Worker// Validates that the versions in `versions` are specified in least to greatest order.
2227*333d2b36SAndroid Build Coastguard Workerfunc normalizeVersions(ctx android.BaseModuleContext, versions []string) {
2228*333d2b36SAndroid Build Coastguard Worker	var previous android.ApiLevel
2229*333d2b36SAndroid Build Coastguard Worker	for i, v := range versions {
2230*333d2b36SAndroid Build Coastguard Worker		ver, err := android.ApiLevelFromUser(ctx, v)
2231*333d2b36SAndroid Build Coastguard Worker		if err != nil {
2232*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("versions", "%s", err.Error())
2233*333d2b36SAndroid Build Coastguard Worker			return
2234*333d2b36SAndroid Build Coastguard Worker		}
2235*333d2b36SAndroid Build Coastguard Worker		if i > 0 && ver.LessThanOrEqualTo(previous) {
2236*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("versions", "not sorted: %v", versions)
2237*333d2b36SAndroid Build Coastguard Worker		}
2238*333d2b36SAndroid Build Coastguard Worker		versions[i] = ver.String()
2239*333d2b36SAndroid Build Coastguard Worker		previous = ver
2240*333d2b36SAndroid Build Coastguard Worker	}
2241*333d2b36SAndroid Build Coastguard Worker}
2242*333d2b36SAndroid Build Coastguard Worker
2243*333d2b36SAndroid Build Coastguard Workerfunc perApiVersionVariations(mctx android.BaseModuleContext, minSdkVersion string) []string {
2244*333d2b36SAndroid Build Coastguard Worker	from, err := nativeApiLevelFromUser(mctx, minSdkVersion)
2245*333d2b36SAndroid Build Coastguard Worker	if err != nil {
2246*333d2b36SAndroid Build Coastguard Worker		mctx.PropertyErrorf("min_sdk_version", err.Error())
2247*333d2b36SAndroid Build Coastguard Worker		return []string{""}
2248*333d2b36SAndroid Build Coastguard Worker	}
2249*333d2b36SAndroid Build Coastguard Worker
2250*333d2b36SAndroid Build Coastguard Worker	return ndkLibraryVersions(mctx, from)
2251*333d2b36SAndroid Build Coastguard Worker}
2252*333d2b36SAndroid Build Coastguard Worker
2253*333d2b36SAndroid Build Coastguard Workerfunc canBeOrLinkAgainstVersionVariants(module interface {
2254*333d2b36SAndroid Build Coastguard Worker	Host() bool
2255*333d2b36SAndroid Build Coastguard Worker	InRamdisk() bool
2256*333d2b36SAndroid Build Coastguard Worker	InVendorRamdisk() bool
2257*333d2b36SAndroid Build Coastguard Worker}) bool {
2258*333d2b36SAndroid Build Coastguard Worker	return !module.Host() && !module.InRamdisk() && !module.InVendorRamdisk()
2259*333d2b36SAndroid Build Coastguard Worker}
2260*333d2b36SAndroid Build Coastguard Worker
2261*333d2b36SAndroid Build Coastguard Workerfunc canBeVersionVariant(module interface {
2262*333d2b36SAndroid Build Coastguard Worker	Host() bool
2263*333d2b36SAndroid Build Coastguard Worker	InRamdisk() bool
2264*333d2b36SAndroid Build Coastguard Worker	InVendorRamdisk() bool
2265*333d2b36SAndroid Build Coastguard Worker	CcLibraryInterface() bool
2266*333d2b36SAndroid Build Coastguard Worker	Shared() bool
2267*333d2b36SAndroid Build Coastguard Worker}) bool {
2268*333d2b36SAndroid Build Coastguard Worker	return canBeOrLinkAgainstVersionVariants(module) &&
2269*333d2b36SAndroid Build Coastguard Worker		module.CcLibraryInterface() && module.Shared()
2270*333d2b36SAndroid Build Coastguard Worker}
2271*333d2b36SAndroid Build Coastguard Worker
2272*333d2b36SAndroid Build Coastguard Workerfunc moduleLibraryInterface(module blueprint.Module) libraryInterface {
2273*333d2b36SAndroid Build Coastguard Worker	if m, ok := module.(*Module); ok {
2274*333d2b36SAndroid Build Coastguard Worker		return m.library
2275*333d2b36SAndroid Build Coastguard Worker	}
2276*333d2b36SAndroid Build Coastguard Worker	return nil
2277*333d2b36SAndroid Build Coastguard Worker}
2278*333d2b36SAndroid Build Coastguard Worker
2279*333d2b36SAndroid Build Coastguard Worker// setStubsVersions normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions.
2280*333d2b36SAndroid Build Coastguard Workerfunc setStubsVersions(mctx android.BaseModuleContext, library libraryInterface, module *Module) {
2281*333d2b36SAndroid Build Coastguard Worker	if !library.buildShared() || !canBeVersionVariant(module) {
2282*333d2b36SAndroid Build Coastguard Worker		return
2283*333d2b36SAndroid Build Coastguard Worker	}
2284*333d2b36SAndroid Build Coastguard Worker	versions := library.stubsVersions(mctx)
2285*333d2b36SAndroid Build Coastguard Worker	if mctx.Failed() {
2286*333d2b36SAndroid Build Coastguard Worker		return
2287*333d2b36SAndroid Build Coastguard Worker	}
2288*333d2b36SAndroid Build Coastguard Worker	// Set the versions on the pre-mutated module so they can be read by any llndk modules that
2289*333d2b36SAndroid Build Coastguard Worker	// depend on the implementation library and haven't been mutated yet.
2290*333d2b36SAndroid Build Coastguard Worker	library.setAllStubsVersions(versions)
2291*333d2b36SAndroid Build Coastguard Worker}
2292*333d2b36SAndroid Build Coastguard Worker
2293*333d2b36SAndroid Build Coastguard Worker// versionTransitionMutator splits a module into the mandatory non-stubs variant
2294*333d2b36SAndroid Build Coastguard Worker// (which is unnamed) and zero or more stubs variants.
2295*333d2b36SAndroid Build Coastguard Workertype versionTransitionMutator struct{}
2296*333d2b36SAndroid Build Coastguard Worker
2297*333d2b36SAndroid Build Coastguard Workerfunc (versionTransitionMutator) Split(ctx android.BaseModuleContext) []string {
2298*333d2b36SAndroid Build Coastguard Worker	if ctx.Os() != android.Android {
2299*333d2b36SAndroid Build Coastguard Worker		return []string{""}
2300*333d2b36SAndroid Build Coastguard Worker	}
2301*333d2b36SAndroid Build Coastguard Worker
2302*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(*Module)
2303*333d2b36SAndroid Build Coastguard Worker	if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
2304*333d2b36SAndroid Build Coastguard Worker		setStubsVersions(ctx, library, m)
2305*333d2b36SAndroid Build Coastguard Worker
2306*333d2b36SAndroid Build Coastguard Worker		return append(slices.Clone(library.allStubsVersions()), "")
2307*333d2b36SAndroid Build Coastguard Worker	} else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() {
2308*333d2b36SAndroid Build Coastguard Worker		return perApiVersionVariations(ctx, m.MinSdkVersion())
2309*333d2b36SAndroid Build Coastguard Worker	}
2310*333d2b36SAndroid Build Coastguard Worker
2311*333d2b36SAndroid Build Coastguard Worker	return []string{""}
2312*333d2b36SAndroid Build Coastguard Worker}
2313*333d2b36SAndroid Build Coastguard Worker
2314*333d2b36SAndroid Build Coastguard Workerfunc (versionTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
2315*333d2b36SAndroid Build Coastguard Worker	return ""
2316*333d2b36SAndroid Build Coastguard Worker}
2317*333d2b36SAndroid Build Coastguard Worker
2318*333d2b36SAndroid Build Coastguard Workerfunc (versionTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
2319*333d2b36SAndroid Build Coastguard Worker	if ctx.Os() != android.Android {
2320*333d2b36SAndroid Build Coastguard Worker		return ""
2321*333d2b36SAndroid Build Coastguard Worker	}
2322*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(*Module)
2323*333d2b36SAndroid Build Coastguard Worker	if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
2324*333d2b36SAndroid Build Coastguard Worker		if incomingVariation == "latest" {
2325*333d2b36SAndroid Build Coastguard Worker			latestVersion := ""
2326*333d2b36SAndroid Build Coastguard Worker			versions := library.allStubsVersions()
2327*333d2b36SAndroid Build Coastguard Worker			if len(versions) > 0 {
2328*333d2b36SAndroid Build Coastguard Worker				latestVersion = versions[len(versions)-1]
2329*333d2b36SAndroid Build Coastguard Worker			}
2330*333d2b36SAndroid Build Coastguard Worker			return latestVersion
2331*333d2b36SAndroid Build Coastguard Worker		}
2332*333d2b36SAndroid Build Coastguard Worker		return incomingVariation
2333*333d2b36SAndroid Build Coastguard Worker	} else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() {
2334*333d2b36SAndroid Build Coastguard Worker		// If this module only has variants with versions and the incoming dependency doesn't specify which one
2335*333d2b36SAndroid Build Coastguard Worker		// is needed then assume the latest version.
2336*333d2b36SAndroid Build Coastguard Worker		if incomingVariation == "" {
2337*333d2b36SAndroid Build Coastguard Worker			return android.FutureApiLevel.String()
2338*333d2b36SAndroid Build Coastguard Worker		}
2339*333d2b36SAndroid Build Coastguard Worker		return incomingVariation
2340*333d2b36SAndroid Build Coastguard Worker	}
2341*333d2b36SAndroid Build Coastguard Worker
2342*333d2b36SAndroid Build Coastguard Worker	return ""
2343*333d2b36SAndroid Build Coastguard Worker}
2344*333d2b36SAndroid Build Coastguard Worker
2345*333d2b36SAndroid Build Coastguard Workerfunc (versionTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
2346*333d2b36SAndroid Build Coastguard Worker	// Optimization: return early if this module can't be affected.
2347*333d2b36SAndroid Build Coastguard Worker	if ctx.Os() != android.Android {
2348*333d2b36SAndroid Build Coastguard Worker		return
2349*333d2b36SAndroid Build Coastguard Worker	}
2350*333d2b36SAndroid Build Coastguard Worker
2351*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(*Module)
2352*333d2b36SAndroid Build Coastguard Worker	if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
2353*333d2b36SAndroid Build Coastguard Worker		isLLNDK := m.IsLlndk()
2354*333d2b36SAndroid Build Coastguard Worker		isVendorPublicLibrary := m.IsVendorPublicLibrary()
2355*333d2b36SAndroid Build Coastguard Worker
2356*333d2b36SAndroid Build Coastguard Worker		if variation != "" || isLLNDK || isVendorPublicLibrary {
2357*333d2b36SAndroid Build Coastguard Worker			// A stubs or LLNDK stubs variant.
2358*333d2b36SAndroid Build Coastguard Worker			if m.sanitize != nil {
2359*333d2b36SAndroid Build Coastguard Worker				m.sanitize.Properties.ForceDisable = true
2360*333d2b36SAndroid Build Coastguard Worker			}
2361*333d2b36SAndroid Build Coastguard Worker			if m.stl != nil {
2362*333d2b36SAndroid Build Coastguard Worker				m.stl.Properties.Stl = StringPtr("none")
2363*333d2b36SAndroid Build Coastguard Worker			}
2364*333d2b36SAndroid Build Coastguard Worker			m.Properties.PreventInstall = true
2365*333d2b36SAndroid Build Coastguard Worker			lib := moduleLibraryInterface(m)
2366*333d2b36SAndroid Build Coastguard Worker			allStubsVersions := library.allStubsVersions()
2367*333d2b36SAndroid Build Coastguard Worker			isLatest := len(allStubsVersions) > 0 && variation == allStubsVersions[len(allStubsVersions)-1]
2368*333d2b36SAndroid Build Coastguard Worker			lib.setBuildStubs(isLatest)
2369*333d2b36SAndroid Build Coastguard Worker		}
2370*333d2b36SAndroid Build Coastguard Worker		if variation != "" {
2371*333d2b36SAndroid Build Coastguard Worker			// A non-LLNDK stubs module is hidden from make
2372*333d2b36SAndroid Build Coastguard Worker			library.setStubsVersion(variation)
2373*333d2b36SAndroid Build Coastguard Worker			m.Properties.HideFromMake = true
2374*333d2b36SAndroid Build Coastguard Worker		} else {
2375*333d2b36SAndroid Build Coastguard Worker			// A non-LLNDK implementation module has a dependency to all stubs versions
2376*333d2b36SAndroid Build Coastguard Worker			for _, version := range library.allStubsVersions() {
2377*333d2b36SAndroid Build Coastguard Worker				ctx.AddVariationDependencies([]blueprint.Variation{{"version", version}},
2378*333d2b36SAndroid Build Coastguard Worker					stubImplDepTag, ctx.ModuleName())
2379*333d2b36SAndroid Build Coastguard Worker			}
2380*333d2b36SAndroid Build Coastguard Worker		}
2381*333d2b36SAndroid Build Coastguard Worker	} else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() {
2382*333d2b36SAndroid Build Coastguard Worker		m.Properties.Sdk_version = StringPtr(variation)
2383*333d2b36SAndroid Build Coastguard Worker		m.Properties.Min_sdk_version = StringPtr(variation)
2384*333d2b36SAndroid Build Coastguard Worker	}
2385*333d2b36SAndroid Build Coastguard Worker}
2386*333d2b36SAndroid Build Coastguard Worker
2387*333d2b36SAndroid Build Coastguard Worker// maybeInjectBoringSSLHash adds a rule to run bssl_inject_hash on the output file if the module has the
2388*333d2b36SAndroid Build Coastguard Worker// inject_bssl_hash or if any static library dependencies have inject_bssl_hash set.  It returns the output path
2389*333d2b36SAndroid Build Coastguard Worker// that the linked output file should be written to.
2390*333d2b36SAndroid Build Coastguard Worker// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
2391*333d2b36SAndroid Build Coastguard Workerfunc maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.ModuleOutPath,
2392*333d2b36SAndroid Build Coastguard Worker	inject *bool, fileName string) android.ModuleOutPath {
2393*333d2b36SAndroid Build Coastguard Worker	// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
2394*333d2b36SAndroid Build Coastguard Worker	injectBoringSSLHash := Bool(inject)
2395*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDeps(func(dep android.Module) {
2396*333d2b36SAndroid Build Coastguard Worker		if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() {
2397*333d2b36SAndroid Build Coastguard Worker			if cc, ok := dep.(*Module); ok {
2398*333d2b36SAndroid Build Coastguard Worker				if library, ok := cc.linker.(*libraryDecorator); ok {
2399*333d2b36SAndroid Build Coastguard Worker					if Bool(library.Properties.Inject_bssl_hash) {
2400*333d2b36SAndroid Build Coastguard Worker						injectBoringSSLHash = true
2401*333d2b36SAndroid Build Coastguard Worker					}
2402*333d2b36SAndroid Build Coastguard Worker				}
2403*333d2b36SAndroid Build Coastguard Worker			}
2404*333d2b36SAndroid Build Coastguard Worker		}
2405*333d2b36SAndroid Build Coastguard Worker	})
2406*333d2b36SAndroid Build Coastguard Worker	if injectBoringSSLHash {
2407*333d2b36SAndroid Build Coastguard Worker		hashedOutputfile := outputFile
2408*333d2b36SAndroid Build Coastguard Worker		outputFile = android.PathForModuleOut(ctx, "unhashed", fileName)
2409*333d2b36SAndroid Build Coastguard Worker
2410*333d2b36SAndroid Build Coastguard Worker		rule := android.NewRuleBuilder(pctx, ctx)
2411*333d2b36SAndroid Build Coastguard Worker		rule.Command().
2412*333d2b36SAndroid Build Coastguard Worker			BuiltTool("bssl_inject_hash").
2413*333d2b36SAndroid Build Coastguard Worker			FlagWithInput("-in-object ", outputFile).
2414*333d2b36SAndroid Build Coastguard Worker			FlagWithOutput("-o ", hashedOutputfile)
2415*333d2b36SAndroid Build Coastguard Worker		rule.Build("injectCryptoHash", "inject crypto hash")
2416*333d2b36SAndroid Build Coastguard Worker	}
2417*333d2b36SAndroid Build Coastguard Worker
2418*333d2b36SAndroid Build Coastguard Worker	return outputFile
2419*333d2b36SAndroid Build Coastguard Worker}
2420