• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 The Android Open Source Project
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.
14package cc
15
16// This file contains image variant related things, including image mutator functions, utility
17// functions to determine where a module is installed, etc.
18
19import (
20	"fmt"
21	"reflect"
22	"strings"
23
24	"android/soong/android"
25	"android/soong/snapshot"
26)
27
28var _ android.ImageInterface = (*Module)(nil)
29
30type ImageVariantType string
31
32const (
33	coreImageVariant          ImageVariantType = "core"
34	vendorImageVariant        ImageVariantType = "vendor"
35	productImageVariant       ImageVariantType = "product"
36	ramdiskImageVariant       ImageVariantType = "ramdisk"
37	vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk"
38	recoveryImageVariant      ImageVariantType = "recovery"
39	hostImageVariant          ImageVariantType = "host"
40)
41
42const (
43	// VendorVariationPrefix is the variant prefix used for /vendor code that compiles
44	// against the VNDK.
45	VendorVariationPrefix = "vendor."
46
47	// ProductVariationPrefix is the variant prefix used for /product code that compiles
48	// against the VNDK.
49	ProductVariationPrefix = "product."
50)
51
52func (ctx *moduleContext) ProductSpecific() bool {
53	return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext()
54}
55
56func (ctx *moduleContext) SocSpecific() bool {
57	return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext()
58}
59
60func (ctx *moduleContext) DeviceSpecific() bool {
61	return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext()
62}
63
64func (ctx *moduleContextImpl) inProduct() bool {
65	return ctx.mod.InProduct()
66}
67
68func (ctx *moduleContextImpl) inVendor() bool {
69	return ctx.mod.InVendor()
70}
71
72func (ctx *moduleContextImpl) inRamdisk() bool {
73	return ctx.mod.InRamdisk()
74}
75
76func (ctx *moduleContextImpl) inVendorRamdisk() bool {
77	return ctx.mod.InVendorRamdisk()
78}
79
80func (ctx *moduleContextImpl) inRecovery() bool {
81	return ctx.mod.InRecovery()
82}
83
84func (c *Module) productSpecificModuleContext() bool {
85	// Additionally check if this module is inProduct() that means it is a "product" variant of a
86	// module. As well as product specific modules, product variants must be installed to /product.
87	return c.InProduct()
88}
89
90func (c *Module) socSpecificModuleContext() bool {
91	// Additionally check if this module is inVendor() that means it is a "vendor" variant of a
92	// module. As well as SoC specific modules, vendor variants must be installed to /vendor
93	// unless they have "odm_available: true".
94	return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm()
95}
96
97func (c *Module) deviceSpecificModuleContext() bool {
98	// Some vendor variants want to be installed to /odm by setting "odm_available: true".
99	return c.InVendor() && c.VendorVariantToOdm()
100}
101
102// Returns true when this module is configured to have core and vendor variants.
103func (c *Module) HasVendorVariant() bool {
104	return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
105}
106
107// Returns true when this module creates a vendor variant and wants to install the vendor variant
108// to the odm partition.
109func (c *Module) VendorVariantToOdm() bool {
110	return Bool(c.VendorProperties.Odm_available)
111}
112
113// Returns true when this module is configured to have core and product variants.
114func (c *Module) HasProductVariant() bool {
115	return Bool(c.VendorProperties.Product_available)
116}
117
118// Returns true when this module is configured to have core and either product or vendor variants.
119func (c *Module) HasNonSystemVariants() bool {
120	return c.HasVendorVariant() || c.HasProductVariant()
121}
122
123// Returns true if the module is "product" variant. Usually these modules are installed in /product
124func (c *Module) InProduct() bool {
125	return c.Properties.ImageVariationPrefix == ProductVariationPrefix
126}
127
128// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
129func (c *Module) InVendor() bool {
130	return c.Properties.ImageVariationPrefix == VendorVariationPrefix
131}
132
133func (c *Module) InRamdisk() bool {
134	return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
135}
136
137func (c *Module) InVendorRamdisk() bool {
138	return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
139}
140
141func (c *Module) InRecovery() bool {
142	return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
143}
144
145func (c *Module) OnlyInRamdisk() bool {
146	return c.ModuleBase.InstallInRamdisk()
147}
148
149func (c *Module) OnlyInVendorRamdisk() bool {
150	return c.ModuleBase.InstallInVendorRamdisk()
151}
152
153func (c *Module) OnlyInRecovery() bool {
154	return c.ModuleBase.InstallInRecovery()
155}
156
157func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
158	if v.Kind() != reflect.Struct {
159		return true
160	}
161	for i := 0; i < v.NumField(); i++ {
162		prop := v.Field(i)
163		if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
164			vendor_prop := prop.FieldByName("Vendor")
165			product_prop := prop.FieldByName("Product")
166			if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
167				// Neither Target.Vendor nor Target.Product is defined
168				continue
169			}
170			if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
171				!reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
172				// If only one of either Target.Vendor or Target.Product is
173				// defined or they have different values, it fails the build
174				// since VNDK must have the same properties for both vendor
175				// and product variants.
176				return false
177			}
178		} else if !visitPropsAndCompareVendorAndProductProps(prop) {
179			// Visit the substructures to find Target.Vendor and Target.Product
180			return false
181		}
182	}
183	return true
184}
185
186// In the case of VNDK, vendor and product variants must have the same properties.
187// VNDK installs only one file and shares it for both vendor and product modules on
188// runtime. We may not define different versions of a VNDK lib for each partition.
189// This function is used only for the VNDK modules that is available to both vendor
190// and product partitions.
191func (c *Module) compareVendorAndProductProps() bool {
192	if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) {
193		panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
194	}
195	for _, properties := range c.GetProperties() {
196		if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
197			return false
198		}
199	}
200	return true
201}
202
203// ImageMutatableModule provides a common image mutation interface for  LinkableInterface modules.
204type ImageMutatableModule interface {
205	android.Module
206	LinkableInterface
207
208	// AndroidModuleBase returns the android.ModuleBase for this module
209	AndroidModuleBase() *android.ModuleBase
210
211	// VendorAvailable returns true if this module is available on the vendor image.
212	VendorAvailable() bool
213
214	// OdmAvailable returns true if this module is available on the odm image.
215	OdmAvailable() bool
216
217	// ProductAvailable returns true if this module is available on the product image.
218	ProductAvailable() bool
219
220	// RamdiskAvailable returns true if this module is available on the ramdisk image.
221	RamdiskAvailable() bool
222
223	// RecoveryAvailable returns true if this module is available on the recovery image.
224	RecoveryAvailable() bool
225
226	// VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
227	VendorRamdiskAvailable() bool
228
229	// IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
230	IsSnapshotPrebuilt() bool
231
232	// SnapshotVersion returns the snapshot version for this module.
233	SnapshotVersion(mctx android.BaseModuleContext) string
234
235	// SdkVersion returns the SDK version for this module.
236	SdkVersion() string
237
238	// ExtraVariants returns the list of extra variants this module requires.
239	ExtraVariants() []string
240
241	// AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
242	AppendExtraVariant(extraVariant string)
243
244	// SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
245	SetRamdiskVariantNeeded(b bool)
246
247	// SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
248	SetVendorRamdiskVariantNeeded(b bool)
249
250	// SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
251	SetRecoveryVariantNeeded(b bool)
252
253	// SetCoreVariantNeeded sets whether the Core Variant is needed.
254	SetCoreVariantNeeded(b bool)
255}
256
257var _ ImageMutatableModule = (*Module)(nil)
258
259func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
260	m.CheckVndkProperties(mctx)
261	MutateImage(mctx, m)
262}
263
264// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
265// If properties are not set correctly, results in a module context property error.
266func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
267	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
268	productSpecific := mctx.ProductSpecific()
269
270	if vndkdep := m.vndkdep; vndkdep != nil {
271		if vndkdep.isVndk() {
272			if vendorSpecific || productSpecific {
273				if !vndkdep.isVndkExt() {
274					mctx.PropertyErrorf("vndk",
275						"must set `extends: \"...\"` to vndk extension")
276				} else if Bool(m.VendorProperties.Vendor_available) {
277					mctx.PropertyErrorf("vendor_available",
278						"must not set at the same time as `vndk: {extends: \"...\"}`")
279				} else if Bool(m.VendorProperties.Product_available) {
280					mctx.PropertyErrorf("product_available",
281						"must not set at the same time as `vndk: {extends: \"...\"}`")
282				}
283			} else {
284				if vndkdep.isVndkExt() {
285					mctx.PropertyErrorf("vndk",
286						"must set `vendor: true` or `product_specific: true` to set `extends: %q`",
287						m.getVndkExtendsModuleName())
288				}
289				if !Bool(m.VendorProperties.Vendor_available) {
290					mctx.PropertyErrorf("vndk",
291						"vendor_available must be set to true when `vndk: {enabled: true}`")
292				}
293				if Bool(m.VendorProperties.Product_available) {
294					// If a VNDK module creates both product and vendor variants, they
295					// must have the same properties since they share a single VNDK
296					// library on runtime.
297					if !m.compareVendorAndProductProps() {
298						mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
299					}
300				}
301			}
302		} else {
303			if vndkdep.isVndkSp() {
304				mctx.PropertyErrorf("vndk",
305					"must set `enabled: true` to set `support_system_process: true`")
306			}
307			if vndkdep.isVndkExt() {
308				mctx.PropertyErrorf("vndk",
309					"must set `enabled: true` to set `extends: %q`",
310					m.getVndkExtendsModuleName())
311			}
312		}
313	}
314}
315
316func (m *Module) VendorAvailable() bool {
317	return Bool(m.VendorProperties.Vendor_available)
318}
319
320func (m *Module) OdmAvailable() bool {
321	return Bool(m.VendorProperties.Odm_available)
322}
323
324func (m *Module) ProductAvailable() bool {
325	return Bool(m.VendorProperties.Product_available)
326}
327
328func (m *Module) RamdiskAvailable() bool {
329	return Bool(m.Properties.Ramdisk_available)
330}
331
332func (m *Module) VendorRamdiskAvailable() bool {
333	return Bool(m.Properties.Vendor_ramdisk_available)
334}
335
336func (m *Module) AndroidModuleBase() *android.ModuleBase {
337	return &m.ModuleBase
338}
339
340func (m *Module) RecoveryAvailable() bool {
341	return Bool(m.Properties.Recovery_available)
342}
343
344func (m *Module) ExtraVariants() []string {
345	return m.Properties.ExtraVersionedImageVariations
346}
347
348func (m *Module) AppendExtraVariant(extraVariant string) {
349	m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant)
350}
351
352func (m *Module) SetRamdiskVariantNeeded(b bool) {
353	m.Properties.RamdiskVariantNeeded = b
354}
355
356func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
357	m.Properties.VendorRamdiskVariantNeeded = b
358}
359
360func (m *Module) SetRecoveryVariantNeeded(b bool) {
361	m.Properties.RecoveryVariantNeeded = b
362}
363
364func (m *Module) SetCoreVariantNeeded(b bool) {
365	m.Properties.CoreVariantNeeded = b
366}
367
368func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
369	if snapshot, ok := m.linker.(SnapshotInterface); ok {
370		return snapshot.Version()
371	} else {
372		mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
373		// Should we be panicking here instead?
374		return ""
375	}
376}
377
378func (m *Module) KernelHeadersDecorator() bool {
379	if _, ok := m.linker.(*kernelHeadersDecorator); ok {
380		return true
381	}
382	return false
383}
384
385// MutateImage handles common image mutations for ImageMutatableModule interfaces.
386func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
387	// Validation check
388	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
389	productSpecific := mctx.ProductSpecific()
390
391	if m.VendorAvailable() {
392		if vendorSpecific {
393			mctx.PropertyErrorf("vendor_available",
394				"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
395		}
396		if m.OdmAvailable() {
397			mctx.PropertyErrorf("vendor_available",
398				"doesn't make sense at the same time as `odm_available: true`")
399		}
400	}
401
402	if m.OdmAvailable() {
403		if vendorSpecific {
404			mctx.PropertyErrorf("odm_available",
405				"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
406		}
407	}
408
409	if m.ProductAvailable() {
410		if productSpecific {
411			mctx.PropertyErrorf("product_available",
412				"doesn't make sense at the same time as `product_specific: true`")
413		}
414		if vendorSpecific {
415			mctx.PropertyErrorf("product_available",
416				"cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
417		}
418	}
419
420	var coreVariantNeeded bool = false
421	var ramdiskVariantNeeded bool = false
422	var vendorRamdiskVariantNeeded bool = false
423	var recoveryVariantNeeded bool = false
424
425	var vendorVariants []string
426	var productVariants []string
427
428	platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
429	boardVndkVersion := mctx.DeviceConfig().VndkVersion()
430	productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
431	recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
432	usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
433		recoverySnapshotVersion != ""
434	needVndkVersionVendorVariantForLlndk := false
435	if boardVndkVersion != "" {
436		boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion)
437		if err == nil && !boardVndkApiLevel.IsPreview() {
438			// VNDK snapshot newer than v30 has LLNDK stub libraries.
439			// Only the VNDK version less than or equal to v30 requires generating the vendor
440			// variant of the VNDK version from the source tree.
441			needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
442		}
443	}
444	if boardVndkVersion == "current" {
445		boardVndkVersion = platformVndkVersion
446	}
447	if productVndkVersion == "current" {
448		productVndkVersion = platformVndkVersion
449	}
450
451	if m.NeedsLlndkVariants() {
452		// This is an LLNDK library.  The implementation of the library will be on /system,
453		// and vendor and product variants will be created with LLNDK stubs.
454		// The LLNDK libraries need vendor variants even if there is no VNDK.
455		coreVariantNeeded = true
456		if platformVndkVersion != "" {
457			vendorVariants = append(vendorVariants, platformVndkVersion)
458			productVariants = append(productVariants, platformVndkVersion)
459		}
460		// Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
461		// provide the LLNDK stub libraries.
462		if needVndkVersionVendorVariantForLlndk {
463			vendorVariants = append(vendorVariants, boardVndkVersion)
464		}
465		if productVndkVersion != "" {
466			productVariants = append(productVariants, productVndkVersion)
467		}
468	} else if m.NeedsVendorPublicLibraryVariants() {
469		// A vendor public library has the implementation on /vendor, with stub variants
470		// for system and product.
471		coreVariantNeeded = true
472		vendorVariants = append(vendorVariants, boardVndkVersion)
473		if platformVndkVersion != "" {
474			productVariants = append(productVariants, platformVndkVersion)
475		}
476		if productVndkVersion != "" {
477			productVariants = append(productVariants, productVndkVersion)
478		}
479	} else if boardVndkVersion == "" {
480		// If the device isn't compiling against the VNDK, we always
481		// use the core mode.
482		coreVariantNeeded = true
483	} else if m.IsSnapshotPrebuilt() {
484		// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
485		// PRODUCT_EXTRA_VNDK_VERSIONS.
486		if m.InstallInRecovery() {
487			recoveryVariantNeeded = true
488		} else {
489			vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
490		}
491	} else if m.HasNonSystemVariants() && !m.IsVndkExt() {
492		// This will be available to /system unless it is product_specific
493		// which will be handled later.
494		coreVariantNeeded = true
495
496		// We assume that modules under proprietary paths are compatible for
497		// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
498		// PLATFORM_VNDK_VERSION.
499		if m.HasVendorVariant() {
500			if snapshot.IsVendorProprietaryModule(mctx) {
501				vendorVariants = append(vendorVariants, boardVndkVersion)
502			} else {
503				vendorVariants = append(vendorVariants, platformVndkVersion)
504			}
505		}
506
507		// product_available modules are available to /product.
508		if m.HasProductVariant() {
509			productVariants = append(productVariants, platformVndkVersion)
510			// VNDK is always PLATFORM_VNDK_VERSION
511			if !m.IsVndk() {
512				productVariants = append(productVariants, productVndkVersion)
513			}
514		}
515	} else if vendorSpecific && m.SdkVersion() == "" {
516		// This will be available in /vendor (or /odm) only
517
518		// kernel_headers is a special module type whose exported headers
519		// are coming from DeviceKernelHeaders() which is always vendor
520		// dependent. They'll always have both vendor variants.
521		// For other modules, we assume that modules under proprietary
522		// paths are compatible for BOARD_VNDK_VERSION. The other modules
523		// are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
524		if m.KernelHeadersDecorator() {
525			vendorVariants = append(vendorVariants,
526				platformVndkVersion,
527				boardVndkVersion,
528			)
529		} else if snapshot.IsVendorProprietaryModule(mctx) {
530			vendorVariants = append(vendorVariants, boardVndkVersion)
531		} else {
532			vendorVariants = append(vendorVariants, platformVndkVersion)
533		}
534	} else {
535		// This is either in /system (or similar: /data), or is a
536		// modules built with the NDK. Modules built with the NDK
537		// will be restricted using the existing link type checks.
538		coreVariantNeeded = true
539	}
540
541	if boardVndkVersion != "" && productVndkVersion != "" {
542		if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
543			// The module has "product_specific: true" that does not create core variant.
544			coreVariantNeeded = false
545			productVariants = append(productVariants, productVndkVersion)
546		}
547	} else {
548		// Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
549		// restriction to use system libs.
550		// No product variants defined in this case.
551		productVariants = []string{}
552	}
553
554	if m.RamdiskAvailable() {
555		ramdiskVariantNeeded = true
556	}
557
558	if m.AndroidModuleBase().InstallInRamdisk() {
559		ramdiskVariantNeeded = true
560		coreVariantNeeded = false
561	}
562
563	if m.VendorRamdiskAvailable() {
564		vendorRamdiskVariantNeeded = true
565	}
566
567	if m.AndroidModuleBase().InstallInVendorRamdisk() {
568		vendorRamdiskVariantNeeded = true
569		coreVariantNeeded = false
570	}
571
572	if m.RecoveryAvailable() {
573		recoveryVariantNeeded = true
574	}
575
576	if m.AndroidModuleBase().InstallInRecovery() {
577		recoveryVariantNeeded = true
578		coreVariantNeeded = false
579	}
580
581	// If using a snapshot, the recovery variant under AOSP directories is not needed,
582	// except for kernel headers, which needs all variants.
583	if !m.KernelHeadersDecorator() &&
584		!m.IsSnapshotPrebuilt() &&
585		usingRecoverySnapshot &&
586		!snapshot.IsRecoveryProprietaryModule(mctx) {
587		recoveryVariantNeeded = false
588	}
589
590	for _, variant := range android.FirstUniqueStrings(vendorVariants) {
591		m.AppendExtraVariant(VendorVariationPrefix + variant)
592	}
593
594	for _, variant := range android.FirstUniqueStrings(productVariants) {
595		m.AppendExtraVariant(ProductVariationPrefix + variant)
596	}
597
598	m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
599	m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
600	m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
601	m.SetCoreVariantNeeded(coreVariantNeeded)
602
603	// Disable the module if no variants are needed.
604	if !ramdiskVariantNeeded &&
605		!recoveryVariantNeeded &&
606		!coreVariantNeeded &&
607		len(m.ExtraVariants()) == 0 {
608		m.Disable()
609	}
610}
611
612func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
613	return c.Properties.CoreVariantNeeded
614}
615
616func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
617	return c.Properties.RamdiskVariantNeeded
618}
619
620func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
621	return c.Properties.VendorRamdiskVariantNeeded
622}
623
624func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
625	return false
626}
627
628func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
629	return c.Properties.RecoveryVariantNeeded
630}
631
632func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
633	return c.Properties.ExtraVersionedImageVariations
634}
635
636func squashVendorSrcs(m *Module) {
637	if lib, ok := m.compiler.(*libraryDecorator); ok {
638		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
639			lib.baseCompiler.Properties.Target.Vendor.Srcs...)
640
641		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
642			lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
643
644		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
645			lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
646	}
647}
648
649func squashProductSrcs(m *Module) {
650	if lib, ok := m.compiler.(*libraryDecorator); ok {
651		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
652			lib.baseCompiler.Properties.Target.Product.Srcs...)
653
654		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
655			lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
656
657		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
658			lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
659	}
660}
661
662func squashRecoverySrcs(m *Module) {
663	if lib, ok := m.compiler.(*libraryDecorator); ok {
664		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
665			lib.baseCompiler.Properties.Target.Recovery.Srcs...)
666
667		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
668			lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
669
670		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
671			lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
672	}
673}
674
675func squashVendorRamdiskSrcs(m *Module) {
676	if lib, ok := m.compiler.(*libraryDecorator); ok {
677		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
678	}
679}
680
681func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
682	m := module.(*Module)
683	if variant == android.RamdiskVariation {
684		m.MakeAsPlatform()
685	} else if variant == android.VendorRamdiskVariation {
686		m.MakeAsPlatform()
687		squashVendorRamdiskSrcs(m)
688	} else if variant == android.RecoveryVariation {
689		m.MakeAsPlatform()
690		squashRecoverySrcs(m)
691	} else if strings.HasPrefix(variant, VendorVariationPrefix) {
692		m.Properties.ImageVariationPrefix = VendorVariationPrefix
693		m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
694		squashVendorSrcs(m)
695
696		// Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
697		// Hide other vendor variants to avoid collision.
698		vndkVersion := ctx.DeviceConfig().VndkVersion()
699		if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
700			m.Properties.HideFromMake = true
701			m.HideFromMake()
702		}
703	} else if strings.HasPrefix(variant, ProductVariationPrefix) {
704		m.Properties.ImageVariationPrefix = ProductVariationPrefix
705		m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
706		squashProductSrcs(m)
707	}
708
709	if c.NeedsVendorPublicLibraryVariants() &&
710		(variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) {
711		c.VendorProperties.IsVendorPublicLibrary = true
712	}
713}
714