blob: 18d3f210cc0c3dedf532c1cadb34a6e030e4f3b6 [file] [log] [blame]
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +090018 "regexp"
Kiyoung Kimee58c932022-10-25 22:59:41 +090019 "strings"
20
Inseob Kim5eb7ee92022-04-27 10:30:34 +090021 "android/soong/android"
22 "android/soong/multitree"
23)
24
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +090025var (
Kiyoung Kim76b06f32023-02-06 22:08:13 +090026 ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
27 stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)")
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +090028)
29
Inseob Kim5eb7ee92022-04-27 10:30:34 +090030func init() {
31 RegisterLibraryStubBuildComponents(android.InitRegistrationContext)
32}
33
34func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) {
Kiyoung Kim487689e2022-07-26 09:48:22 +090035 ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory)
Kiyoung Kim51279d32022-08-24 14:10:46 +090036 ctx.RegisterModuleType("cc_api_headers", CcApiHeadersFactory)
Kiyoung Kimee58c932022-10-25 22:59:41 +090037 ctx.RegisterModuleType("cc_api_variant", CcApiVariantFactory)
38}
39
40func updateImportedLibraryDependency(ctx android.BottomUpMutatorContext) {
41 m, ok := ctx.Module().(*Module)
42 if !ok {
43 return
44 }
45
46 apiLibrary, ok := m.linker.(*apiLibraryDecorator)
47 if !ok {
48 return
49 }
50
51 if m.UseVndk() && apiLibrary.hasLLNDKStubs() {
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +090052 // Add LLNDK variant dependency
53 if inList("llndk", apiLibrary.properties.Variants) {
54 variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
55 ctx.AddDependency(m, nil, variantName)
56 }
57 } else if m.IsSdkVariant() {
58 // Add NDK variant dependencies
59 targetVariant := "ndk." + m.StubsVersion()
60 if inList(targetVariant, apiLibrary.properties.Variants) {
61 variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
62 ctx.AddDependency(m, nil, variantName)
Kiyoung Kimee58c932022-10-25 22:59:41 +090063 }
Kiyoung Kim76b06f32023-02-06 22:08:13 +090064 } else if m.IsStubs() {
65 targetVariant := "apex." + m.StubsVersion()
66 if inList(targetVariant, apiLibrary.properties.Variants) {
67 variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
68 ctx.AddDependency(m, nil, variantName)
69 }
Kiyoung Kimee58c932022-10-25 22:59:41 +090070 }
Inseob Kim5eb7ee92022-04-27 10:30:34 +090071}
72
Kiyoung Kim487689e2022-07-26 09:48:22 +090073// 'cc_api_library' is a module type which is from the exported API surface
74// with C shared library type. The module will replace original module, and
75// offer a link to the module that generates shared library object from the
76// map file.
77type apiLibraryProperties struct {
Kiyoung Kimee58c932022-10-25 22:59:41 +090078 Src *string `android:"arch_variant"`
79 Variants []string
Kiyoung Kim487689e2022-07-26 09:48:22 +090080}
81
82type apiLibraryDecorator struct {
83 *libraryDecorator
84 properties apiLibraryProperties
85}
86
87func CcApiLibraryFactory() android.Module {
88 module, decorator := NewLibrary(android.DeviceSupported)
89 apiLibraryDecorator := &apiLibraryDecorator{
90 libraryDecorator: decorator,
91 }
92 apiLibraryDecorator.BuildOnlyShared()
93
94 module.stl = nil
95 module.sanitize = nil
96 decorator.disableStripping()
97
98 module.compiler = nil
99 module.linker = apiLibraryDecorator
100 module.installer = nil
Kiyoung Kimee58c932022-10-25 22:59:41 +0900101 module.library = apiLibraryDecorator
Kiyoung Kim487689e2022-07-26 09:48:22 +0900102 module.AddProperties(&module.Properties, &apiLibraryDecorator.properties)
103
Kiyoung Kim487689e2022-07-26 09:48:22 +0900104 // Prevent default system libs (libc, libm, and libdl) from being linked
105 if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil {
106 apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{}
107 }
108
Kiyoung Kim835c5892022-08-17 16:40:16 +0900109 apiLibraryDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
110 apiLibraryDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
111
Kiyoung Kim487689e2022-07-26 09:48:22 +0900112 module.Init()
113
114 return module
115}
116
117func (d *apiLibraryDecorator) Name(basename string) string {
118 return basename + multitree.GetApiImportSuffix()
119}
120
Spandan Dasf0beebc2022-10-18 18:23:28 +0000121// Export include dirs without checking for existence.
122// The directories are not guaranteed to exist during Soong analysis.
123func (d *apiLibraryDecorator) exportIncludes(ctx ModuleContext) {
124 exporterProps := d.flagExporter.Properties
125 for _, dir := range exporterProps.Export_include_dirs {
Spandan Dasc6c10fa2022-10-21 21:52:13 +0000126 d.dirs = append(d.dirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir))
Spandan Dasf0beebc2022-10-18 18:23:28 +0000127 }
128 // system headers
129 for _, dir := range exporterProps.Export_system_include_dirs {
Spandan Dasc6c10fa2022-10-21 21:52:13 +0000130 d.systemDirs = append(d.systemDirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir))
Spandan Dasf0beebc2022-10-18 18:23:28 +0000131 }
132}
133
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900134func (d *apiLibraryDecorator) linkerInit(ctx BaseModuleContext) {
135 d.baseLinker.linkerInit(ctx)
136
137 if d.hasNDKStubs() {
138 // Set SDK version of module as current
139 ctx.Module().(*Module).Properties.Sdk_version = StringPtr("current")
140
141 // Add NDK stub as NDK known libs
142 name := ctx.ModuleName()
143
144 ndkKnownLibsLock.Lock()
145 ndkKnownLibs := getNDKKnownLibs(ctx.Config())
146 if !inList(name, *ndkKnownLibs) {
147 *ndkKnownLibs = append(*ndkKnownLibs, name)
148 }
149 ndkKnownLibsLock.Unlock()
150 }
151}
152
Kiyoung Kim487689e2022-07-26 09:48:22 +0900153func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
Kiyoung Kimee58c932022-10-25 22:59:41 +0900154 m, _ := ctx.Module().(*Module)
155
156 var in android.Path
157
Spandan Das6830f6b2022-12-02 23:26:38 +0000158 // src might not exist during the beginning of soong analysis in Multi-tree
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900159 if src := String(d.properties.Src); src != "" {
Spandan Das6830f6b2022-12-02 23:26:38 +0000160 in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
Kiyoung Kimee58c932022-10-25 22:59:41 +0900161 }
162
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900163 libName := m.BaseModuleName() + multitree.GetApiImportSuffix()
Kiyoung Kimee58c932022-10-25 22:59:41 +0900164
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900165 load_cc_variant := func(apiVariantModule string) {
Kiyoung Kimee58c932022-10-25 22:59:41 +0900166 var mod android.Module
167
168 ctx.VisitDirectDeps(func(depMod android.Module) {
169 if depMod.Name() == apiVariantModule {
170 mod = depMod
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900171 libName = apiVariantModule
Kiyoung Kimee58c932022-10-25 22:59:41 +0900172 }
173 })
174
175 if mod != nil {
176 variantMod, ok := mod.(*CcApiVariant)
177 if ok {
178 in = variantMod.Src()
179
180 // Copy LLDNK properties to cc_api_library module
181 d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append(
182 d.libraryDecorator.flagExporter.Properties.Export_include_dirs,
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900183 variantMod.exportProperties.Export_include_dirs...)
Kiyoung Kimee58c932022-10-25 22:59:41 +0900184
185 // Export headers as system include dirs if specified. Mostly for libc
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900186 if Bool(variantMod.exportProperties.Export_headers_as_system) {
Kiyoung Kimee58c932022-10-25 22:59:41 +0900187 d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append(
188 d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs,
189 d.libraryDecorator.flagExporter.Properties.Export_include_dirs...)
190 d.libraryDecorator.flagExporter.Properties.Export_include_dirs = nil
191 }
192 }
193 }
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900194 }
195
196 if m.UseVndk() && d.hasLLNDKStubs() {
197 // LLNDK variant
198 load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", ""))
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900199 } else if m.IsSdkVariant() {
200 // NDK Variant
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900201 load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion()))
202 } else if m.IsStubs() {
203 // APEX Variant
204 load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion()))
Kiyoung Kim51279d32022-08-24 14:10:46 +0900205 }
206
Kiyoung Kim487689e2022-07-26 09:48:22 +0900207 // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
Spandan Dasf0beebc2022-10-18 18:23:28 +0000208 d.exportIncludes(ctx)
Kiyoung Kim487689e2022-07-26 09:48:22 +0900209 d.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
210 d.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
211 d.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
212 d.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
213 d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
Kiyoung Kim487689e2022-07-26 09:48:22 +0900214
Kiyoung Kimee58c932022-10-25 22:59:41 +0900215 if in == nil {
216 ctx.PropertyErrorf("src", "Unable to locate source property")
217 return nil
Spandan Dasf0beebc2022-10-18 18:23:28 +0000218 }
Kiyoung Kim487689e2022-07-26 09:48:22 +0900219
Spandan Dasa3c8a172022-10-26 20:54:32 +0000220 // Make the _compilation_ of rdeps have an order-only dep on cc_api_library.src (an .so file)
221 // The .so file itself has an order-only dependency on the headers contributed by this library.
222 // Creating this dependency ensures that the headers are assembled before compilation of rdeps begins.
223 d.libraryDecorator.reexportDeps(in)
224 d.libraryDecorator.flagExporter.setProvider(ctx)
225
Kiyoung Kim487689e2022-07-26 09:48:22 +0900226 d.unstrippedOutputFile = in
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900227 libName += flags.Toolchain.ShlibSuffix()
Kiyoung Kim487689e2022-07-26 09:48:22 +0900228
229 tocFile := android.PathForModuleOut(ctx, libName+".toc")
230 d.tocFile = android.OptionalPathForPath(tocFile)
231 TransformSharedObjectToToc(ctx, in, tocFile)
232
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900233 outputFile := android.PathForModuleOut(ctx, libName)
234
235 // TODO(b/270485584) This copies with a new name, just to avoid conflict with prebuilts.
236 // We can just use original input if there is any way to avoid name conflict without copy.
237 ctx.Build(pctx, android.BuildParams{
238 Rule: android.Cp,
239 Description: "API surface imported library",
240 Input: in,
241 Output: outputFile,
242 Args: map[string]string{
243 "cpFlags": "-L",
244 },
245 })
246
Kiyoung Kim487689e2022-07-26 09:48:22 +0900247 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900248 SharedLibrary: outputFile,
Kiyoung Kim487689e2022-07-26 09:48:22 +0900249 Target: ctx.Target(),
250
251 TableOfContents: d.tocFile,
252 })
253
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900254 d.shareStubs(ctx)
255
256 return outputFile
257}
258
259// Share additional information about stub libraries with provider
260func (d *apiLibraryDecorator) shareStubs(ctx ModuleContext) {
261 stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
262 if len(stubs) > 0 {
263 var stubsInfo []SharedStubLibrary
264 for _, stub := range stubs {
265 stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo)
266 flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo)
267 stubsInfo = append(stubsInfo, SharedStubLibrary{
268 Version: moduleLibraryInterface(stub).stubsVersion(),
269 SharedLibraryInfo: stubInfo,
270 FlagExporterInfo: flagInfo,
271 })
272 }
273 ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{
274 SharedStubLibraries: stubsInfo,
275
276 IsLLNDK: ctx.IsLlndk(),
277 })
278 }
Kiyoung Kim487689e2022-07-26 09:48:22 +0900279}
280
281func (d *apiLibraryDecorator) availableFor(what string) bool {
282 // Stub from API surface should be available for any APEX.
283 return true
284}
285
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900286func (d *apiLibraryDecorator) hasApexStubs() bool {
287 for _, variant := range d.properties.Variants {
288 if strings.HasPrefix(variant, "apex") {
289 return true
290 }
291 }
292 return false
293}
294
295func (d *apiLibraryDecorator) hasStubsVariants() bool {
296 return d.hasApexStubs()
297}
298
Kiyoung Kimee58c932022-10-25 22:59:41 +0900299func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
300 m, ok := ctx.Module().(*Module)
301
302 if !ok {
303 return nil
304 }
305
Kiyoung Kimee58c932022-10-25 22:59:41 +0900306 // TODO(b/244244438) Create more version information for NDK and APEX variations
307 // NDK variants
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900308 if m.IsSdkVariant() {
309 // TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant.
310 if d.hasNDKStubs() {
311 return d.getNdkVersions()
312 }
313 }
314
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900315 if d.hasLLNDKStubs() && m.UseVndk() {
316 // LLNDK libraries only need a single stubs variant.
317 return []string{android.FutureApiLevel.String()}
318 }
319
320 stubsVersions := d.getStubVersions()
321
322 if len(stubsVersions) != 0 {
323 return stubsVersions
324 }
325
Kiyoung Kimee58c932022-10-25 22:59:41 +0900326 if m.MinSdkVersion() == "" {
327 return nil
328 }
329
330 firstVersion, err := nativeApiLevelFromUser(ctx,
331 m.MinSdkVersion())
332
333 if err != nil {
334 return nil
335 }
336
337 return ndkLibraryVersions(ctx, firstVersion)
338}
339
340func (d *apiLibraryDecorator) hasLLNDKStubs() bool {
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900341 return inList("llndk", d.properties.Variants)
342}
343
344func (d *apiLibraryDecorator) hasNDKStubs() bool {
Kiyoung Kimee58c932022-10-25 22:59:41 +0900345 for _, variant := range d.properties.Variants {
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900346 if ndkVariantRegex.MatchString(variant) {
Kiyoung Kimee58c932022-10-25 22:59:41 +0900347 return true
348 }
349 }
350 return false
351}
352
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900353func (d *apiLibraryDecorator) getNdkVersions() []string {
354 ndkVersions := []string{}
355
356 for _, variant := range d.properties.Variants {
357 if match := ndkVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
358 ndkVersions = append(ndkVersions, match[1])
359 }
360 }
361
362 return ndkVersions
363}
364
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900365func (d *apiLibraryDecorator) getStubVersions() []string {
366 stubVersions := []string{}
367
368 for _, variant := range d.properties.Variants {
369 if match := stubVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
370 stubVersions = append(stubVersions, match[1])
371 }
372 }
373
374 return stubVersions
375}
376
Kiyoung Kim51279d32022-08-24 14:10:46 +0900377// 'cc_api_headers' is similar with 'cc_api_library', but which replaces
378// header libraries. The module will replace any dependencies to existing
379// original header libraries.
380type apiHeadersDecorator struct {
381 *libraryDecorator
382}
383
384func CcApiHeadersFactory() android.Module {
385 module, decorator := NewLibrary(android.DeviceSupported)
386 apiHeadersDecorator := &apiHeadersDecorator{
387 libraryDecorator: decorator,
388 }
389 apiHeadersDecorator.HeaderOnly()
390
391 module.stl = nil
392 module.sanitize = nil
393 decorator.disableStripping()
394
395 module.compiler = nil
396 module.linker = apiHeadersDecorator
397 module.installer = nil
398
Kiyoung Kim51279d32022-08-24 14:10:46 +0900399 // Prevent default system libs (libc, libm, and libdl) from being linked
400 if apiHeadersDecorator.baseLinker.Properties.System_shared_libs == nil {
401 apiHeadersDecorator.baseLinker.Properties.System_shared_libs = []string{}
402 }
403
404 apiHeadersDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
405 apiHeadersDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
406
407 module.Init()
408
409 return module
410}
411
412func (d *apiHeadersDecorator) Name(basename string) string {
413 return basename + multitree.GetApiImportSuffix()
414}
415
416func (d *apiHeadersDecorator) availableFor(what string) bool {
417 // Stub from API surface should be available for any APEX.
418 return true
Kiyoung Kim487689e2022-07-26 09:48:22 +0900419}
Kiyoung Kimee58c932022-10-25 22:59:41 +0900420
421type ccApiexportProperties struct {
422 Src *string `android:"arch_variant"`
423 Variant *string
424 Version *string
425}
426
427type variantExporterProperties struct {
Kiyoung Kim3d776f42022-11-11 12:35:01 +0900428 // Header directory to export
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900429 Export_include_dirs []string `android:"arch_variant"`
Kiyoung Kimee58c932022-10-25 22:59:41 +0900430
431 // Export all headers as system include
432 Export_headers_as_system *bool
433}
434
435type CcApiVariant struct {
436 android.ModuleBase
437
438 properties ccApiexportProperties
439 exportProperties variantExporterProperties
440
441 src android.Path
442}
443
444var _ android.Module = (*CcApiVariant)(nil)
445var _ android.ImageInterface = (*CcApiVariant)(nil)
446
447func CcApiVariantFactory() android.Module {
448 module := &CcApiVariant{}
449
450 module.AddProperties(&module.properties)
451 module.AddProperties(&module.exportProperties)
452
453 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
454 return module
455}
456
457func (v *CcApiVariant) GenerateAndroidBuildActions(ctx android.ModuleContext) {
458 // No need to build
459
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900460 if String(v.properties.Src) == "" {
Kiyoung Kimee58c932022-10-25 22:59:41 +0900461 ctx.PropertyErrorf("src", "src is a required property")
462 }
463
464 // Skip the existence check of the stub prebuilt file.
465 // The file is not guaranteed to exist during Soong analysis.
466 // Build orchestrator will be responsible for creating a connected ninja graph.
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900467 v.src = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), String(v.properties.Src))
Kiyoung Kimee58c932022-10-25 22:59:41 +0900468}
469
470func (v *CcApiVariant) Name() string {
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900471 version := String(v.properties.Version)
Kiyoung Kimee58c932022-10-25 22:59:41 +0900472 return BuildApiVariantName(v.BaseModuleName(), *v.properties.Variant, version)
473}
474
475func (v *CcApiVariant) Src() android.Path {
476 return v.src
477}
478
479func BuildApiVariantName(baseName string, variant string, version string) string {
480 names := []string{baseName, variant}
481 if version != "" {
482 names = append(names, version)
483 }
484
485 return strings.Join(names[:], ".") + multitree.GetApiImportSuffix()
486}
487
488// Implement ImageInterface to generate image variants
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900489func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
490func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900491 return inList(String(v.properties.Variant), []string{"ndk", "apex"})
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900492}
Kiyoung Kimee58c932022-10-25 22:59:41 +0900493func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
494func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
495func (v *CcApiVariant) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
496func (v *CcApiVariant) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { return false }
497func (v *CcApiVariant) ExtraImageVariations(ctx android.BaseModuleContext) []string {
498 var variations []string
499 platformVndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
500
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900501 if String(v.properties.Variant) == "llndk" {
Kiyoung Kimee58c932022-10-25 22:59:41 +0900502 variations = append(variations, VendorVariationPrefix+platformVndkVersion)
503 variations = append(variations, ProductVariationPrefix+platformVndkVersion)
504 }
505
506 return variations
507}
508func (v *CcApiVariant) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
509}