blob: 32325b9106f95fdca6c21a0b663817503a89231a [file] [log] [blame]
Inseob Kime498dd92020-08-04 09:24:04 +09001// 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 "strings"
21
22 "android/soong/android"
23)
24
25var _ android.ImageInterface = (*Module)(nil)
26
Inseob Kim74d25562020-08-04 00:41:38 +090027type imageVariantType string
28
29const (
Yifan Hong60e0cfb2020-10-21 15:17:56 -070030 coreImageVariant imageVariantType = "core"
31 vendorImageVariant imageVariantType = "vendor"
32 productImageVariant imageVariantType = "product"
33 ramdiskImageVariant imageVariantType = "ramdisk"
34 vendorRamdiskImageVariant imageVariantType = "vendor_ramdisk"
35 recoveryImageVariant imageVariantType = "recovery"
36 hostImageVariant imageVariantType = "host"
Inseob Kim74d25562020-08-04 00:41:38 +090037)
38
39func (c *Module) getImageVariantType() imageVariantType {
40 if c.Host() {
41 return hostImageVariant
42 } else if c.inVendor() {
43 return vendorImageVariant
Ivan Lozanof9e21722020-12-02 09:00:51 -050044 } else if c.InProduct() {
Inseob Kim74d25562020-08-04 00:41:38 +090045 return productImageVariant
46 } else if c.InRamdisk() {
47 return ramdiskImageVariant
Yifan Hong60e0cfb2020-10-21 15:17:56 -070048 } else if c.InVendorRamdisk() {
49 return vendorRamdiskImageVariant
Inseob Kim74d25562020-08-04 00:41:38 +090050 } else if c.InRecovery() {
51 return recoveryImageVariant
52 } else {
53 return coreImageVariant
54 }
55}
56
Inseob Kime498dd92020-08-04 09:24:04 +090057const (
58 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
59 // against the VNDK.
60 VendorVariationPrefix = "vendor."
61
62 // ProductVariationPrefix is the variant prefix used for /product code that compiles
63 // against the VNDK.
64 ProductVariationPrefix = "product."
65)
66
67func (ctx *moduleContext) ProductSpecific() bool {
Justin Yun63e9ec72020-10-29 16:49:43 +090068 //TODO(b/150902910): Replace HasNonSystemVariants() with HasProductVariant()
Inseob Kime498dd92020-08-04 09:24:04 +090069 return ctx.ModuleContext.ProductSpecific() ||
Ivan Lozanof9e21722020-12-02 09:00:51 -050070 (ctx.mod.HasNonSystemVariants() && ctx.mod.InProduct())
Inseob Kime498dd92020-08-04 09:24:04 +090071}
72
73func (ctx *moduleContext) SocSpecific() bool {
74 return ctx.ModuleContext.SocSpecific() ||
Justin Yun543f60b2020-10-18 10:54:31 +090075 (ctx.mod.HasVendorVariant() && ctx.mod.inVendor())
Inseob Kime498dd92020-08-04 09:24:04 +090076}
77
78func (ctx *moduleContextImpl) inProduct() bool {
Ivan Lozanof9e21722020-12-02 09:00:51 -050079 return ctx.mod.InProduct()
Inseob Kime498dd92020-08-04 09:24:04 +090080}
81
82func (ctx *moduleContextImpl) inVendor() bool {
83 return ctx.mod.inVendor()
84}
85
86func (ctx *moduleContextImpl) inRamdisk() bool {
87 return ctx.mod.InRamdisk()
88}
89
Yifan Hong60e0cfb2020-10-21 15:17:56 -070090func (ctx *moduleContextImpl) inVendorRamdisk() bool {
91 return ctx.mod.InVendorRamdisk()
92}
93
Inseob Kime498dd92020-08-04 09:24:04 +090094func (ctx *moduleContextImpl) inRecovery() bool {
95 return ctx.mod.InRecovery()
96}
97
Justin Yun63e9ec72020-10-29 16:49:43 +090098// Returns true when this module is configured to have core and vendor variants.
Inseob Kime498dd92020-08-04 09:24:04 +090099func (c *Module) HasVendorVariant() bool {
100 return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
101}
102
Justin Yun63e9ec72020-10-29 16:49:43 +0900103// Returns true when this module is configured to have core and product variants.
104func (c *Module) HasProductVariant() bool {
105 return c.IsVndk() || Bool(c.VendorProperties.Product_available)
106}
107
108// Returns true when this module is configured to have core and either product or vendor variants.
109func (c *Module) HasNonSystemVariants() bool {
110 return c.IsVndk() || Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Product_available)
111}
112
Inseob Kime498dd92020-08-04 09:24:04 +0900113// Returns true if the module is "product" variant. Usually these modules are installed in /product
Ivan Lozanof9e21722020-12-02 09:00:51 -0500114func (c *Module) InProduct() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900115 return c.Properties.ImageVariationPrefix == ProductVariationPrefix
116}
117
118// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
119func (c *Module) inVendor() bool {
120 return c.Properties.ImageVariationPrefix == VendorVariationPrefix
121}
122
123func (c *Module) InRamdisk() bool {
124 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
125}
126
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700127func (c *Module) InVendorRamdisk() bool {
128 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
129}
130
Inseob Kime498dd92020-08-04 09:24:04 +0900131func (c *Module) InRecovery() bool {
132 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
133}
134
135func (c *Module) OnlyInRamdisk() bool {
136 return c.ModuleBase.InstallInRamdisk()
137}
138
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700139func (c *Module) OnlyInVendorRamdisk() bool {
140 return c.ModuleBase.InstallInVendorRamdisk()
141}
142
Inseob Kime498dd92020-08-04 09:24:04 +0900143func (c *Module) OnlyInRecovery() bool {
144 return c.ModuleBase.InstallInRecovery()
145}
146
147func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
148 // Validation check
149 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
150 productSpecific := mctx.ProductSpecific()
151
Justin Yun63e9ec72020-10-29 16:49:43 +0900152 if m.VendorProperties.Vendor_available != nil {
153 if vendorSpecific {
154 mctx.PropertyErrorf("vendor_available",
155 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
156 }
157 // If defined, make sure vendor_available and product_available has the
158 // same value since `false` for these properties means the module is
159 // for system only but provides the variant.
160 if m.VendorProperties.Product_available != nil {
161 if Bool(m.VendorProperties.Vendor_available) != Bool(m.VendorProperties.Product_available) {
162 mctx.PropertyErrorf("product_available", "may not have different value than `vendor_available`")
163 }
164 }
165 }
166
167 if m.VendorProperties.Product_available != nil {
168 if productSpecific {
169 mctx.PropertyErrorf("product_available",
170 "doesn't make sense at the same time as `product_specific: true`")
171 }
172 if vendorSpecific {
173 mctx.PropertyErrorf("product_available",
174 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
175 }
Inseob Kime498dd92020-08-04 09:24:04 +0900176 }
177
178 if vndkdep := m.vndkdep; vndkdep != nil {
179 if vndkdep.isVndk() {
180 if vendorSpecific || productSpecific {
181 if !vndkdep.isVndkExt() {
182 mctx.PropertyErrorf("vndk",
183 "must set `extends: \"...\"` to vndk extension")
184 } else if m.VendorProperties.Vendor_available != nil {
185 mctx.PropertyErrorf("vendor_available",
186 "must not set at the same time as `vndk: {extends: \"...\"}`")
Justin Yun63e9ec72020-10-29 16:49:43 +0900187 } else if m.VendorProperties.Product_available != nil {
188 mctx.PropertyErrorf("product_available",
189 "must not set at the same time as `vndk: {extends: \"...\"}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900190 }
191 } else {
192 if vndkdep.isVndkExt() {
193 mctx.PropertyErrorf("vndk",
194 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
195 m.getVndkExtendsModuleName())
196 }
197 if m.VendorProperties.Vendor_available == nil {
198 mctx.PropertyErrorf("vndk",
199 "vendor_available must be set to either true or false when `vndk: {enabled: true}`")
200 }
201 }
202 } else {
203 if vndkdep.isVndkSp() {
204 mctx.PropertyErrorf("vndk",
205 "must set `enabled: true` to set `support_system_process: true`")
206 }
207 if vndkdep.isVndkExt() {
208 mctx.PropertyErrorf("vndk",
209 "must set `enabled: true` to set `extends: %q`",
210 m.getVndkExtendsModuleName())
211 }
212 }
213 }
214
215 var coreVariantNeeded bool = false
216 var ramdiskVariantNeeded bool = false
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700217 var vendorRamdiskVariantNeeded bool = false
Inseob Kime498dd92020-08-04 09:24:04 +0900218 var recoveryVariantNeeded bool = false
219
220 var vendorVariants []string
221 var productVariants []string
222
223 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
224 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
225 productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
226 if boardVndkVersion == "current" {
227 boardVndkVersion = platformVndkVersion
228 }
229 if productVndkVersion == "current" {
230 productVndkVersion = platformVndkVersion
231 }
232
233 if boardVndkVersion == "" {
234 // If the device isn't compiling against the VNDK, we always
235 // use the core mode.
236 coreVariantNeeded = true
237 } else if _, ok := m.linker.(*llndkStubDecorator); ok {
238 // LL-NDK stubs only exist in the vendor and product variants,
239 // since the real libraries will be used in the core variant.
240 vendorVariants = append(vendorVariants,
241 platformVndkVersion,
242 boardVndkVersion,
243 )
244 productVariants = append(productVariants,
245 platformVndkVersion,
246 productVndkVersion,
247 )
248 } else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
249 // ... and LL-NDK headers as well
250 vendorVariants = append(vendorVariants,
251 platformVndkVersion,
252 boardVndkVersion,
253 )
254 productVariants = append(productVariants,
255 platformVndkVersion,
256 productVndkVersion,
257 )
258 } else if m.isSnapshotPrebuilt() {
259 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
260 // PRODUCT_EXTRA_VNDK_VERSIONS.
261 if snapshot, ok := m.linker.(interface {
262 version() string
263 }); ok {
264 vendorVariants = append(vendorVariants, snapshot.version())
265 } else {
266 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
267 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500268 } else if m.HasNonSystemVariants() && !m.IsVndkExt() {
Justin Yun63e9ec72020-10-29 16:49:43 +0900269 // This will be available to /system unless it is product_specific
270 // which will be handled later.
Inseob Kime498dd92020-08-04 09:24:04 +0900271 coreVariantNeeded = true
272
273 // We assume that modules under proprietary paths are compatible for
274 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
275 // PLATFORM_VNDK_VERSION.
Justin Yun63e9ec72020-10-29 16:49:43 +0900276 if m.HasVendorVariant() {
277 if isVendorProprietaryModule(mctx) {
278 vendorVariants = append(vendorVariants, boardVndkVersion)
279 } else {
280 vendorVariants = append(vendorVariants, platformVndkVersion)
281 }
Inseob Kime498dd92020-08-04 09:24:04 +0900282 }
283
284 // vendor_available modules are also available to /product.
Justin Yun63e9ec72020-10-29 16:49:43 +0900285 // TODO(b/150902910): product variant will be created only if
286 // m.HasProductVariant() is true.
Inseob Kime498dd92020-08-04 09:24:04 +0900287 productVariants = append(productVariants, platformVndkVersion)
288 // VNDK is always PLATFORM_VNDK_VERSION
289 if !m.IsVndk() {
290 productVariants = append(productVariants, productVndkVersion)
291 }
292 } else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
293 // This will be available in /vendor (or /odm) only
294
295 // kernel_headers is a special module type whose exported headers
296 // are coming from DeviceKernelHeaders() which is always vendor
297 // dependent. They'll always have both vendor variants.
298 // For other modules, we assume that modules under proprietary
299 // paths are compatible for BOARD_VNDK_VERSION. The other modules
300 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
301 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
302 vendorVariants = append(vendorVariants,
303 platformVndkVersion,
304 boardVndkVersion,
305 )
Bill Peckham945441c2020-08-31 16:07:58 -0700306 } else if isVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900307 vendorVariants = append(vendorVariants, boardVndkVersion)
308 } else {
309 vendorVariants = append(vendorVariants, platformVndkVersion)
310 }
311 } else {
312 // This is either in /system (or similar: /data), or is a
313 // modules built with the NDK. Modules built with the NDK
314 // will be restricted using the existing link type checks.
315 coreVariantNeeded = true
316 }
317
318 if boardVndkVersion != "" && productVndkVersion != "" {
319 if coreVariantNeeded && productSpecific && String(m.Properties.Sdk_version) == "" {
320 // The module has "product_specific: true" that does not create core variant.
321 coreVariantNeeded = false
322 productVariants = append(productVariants, productVndkVersion)
323 }
324 } else {
325 // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
326 // restriction to use system libs.
327 // No product variants defined in this case.
328 productVariants = []string{}
329 }
330
331 if Bool(m.Properties.Ramdisk_available) {
332 ramdiskVariantNeeded = true
333 }
334
335 if m.ModuleBase.InstallInRamdisk() {
336 ramdiskVariantNeeded = true
337 coreVariantNeeded = false
338 }
339
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700340 if Bool(m.Properties.Vendor_ramdisk_available) {
341 vendorRamdiskVariantNeeded = true
342 }
343
344 if m.ModuleBase.InstallInVendorRamdisk() {
345 vendorRamdiskVariantNeeded = true
346 coreVariantNeeded = false
347 }
348
Inseob Kime498dd92020-08-04 09:24:04 +0900349 if Bool(m.Properties.Recovery_available) {
350 recoveryVariantNeeded = true
351 }
352
353 if m.ModuleBase.InstallInRecovery() {
354 recoveryVariantNeeded = true
355 coreVariantNeeded = false
356 }
357
358 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
359 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, VendorVariationPrefix+variant)
360 }
361
362 for _, variant := range android.FirstUniqueStrings(productVariants) {
363 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant)
364 }
365
366 m.Properties.RamdiskVariantNeeded = ramdiskVariantNeeded
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700367 m.Properties.VendorRamdiskVariantNeeded = vendorRamdiskVariantNeeded
Inseob Kime498dd92020-08-04 09:24:04 +0900368 m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded
369 m.Properties.CoreVariantNeeded = coreVariantNeeded
370}
371
372func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
373 return c.Properties.CoreVariantNeeded
374}
375
376func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
377 return c.Properties.RamdiskVariantNeeded
378}
379
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700380func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
381 return c.Properties.VendorRamdiskVariantNeeded
382}
383
Inseob Kime498dd92020-08-04 09:24:04 +0900384func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
385 return c.Properties.RecoveryVariantNeeded
386}
387
388func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
389 return c.Properties.ExtraVariants
390}
391
Justin Yun63e9ec72020-10-29 16:49:43 +0900392func squashVendorSrcs(m *Module) {
393 if lib, ok := m.compiler.(*libraryDecorator); ok {
394 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
395 lib.baseCompiler.Properties.Target.Vendor.Srcs...)
396
397 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
398 lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
399
400 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
401 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
402 }
403}
404
405func squashProductSrcs(m *Module) {
406 if lib, ok := m.compiler.(*libraryDecorator); ok {
407 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
408 lib.baseCompiler.Properties.Target.Product.Srcs...)
409
410 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
411 lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
412
413 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
414 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
415 }
416}
417
418func squashRecoverySrcs(m *Module) {
419 if lib, ok := m.compiler.(*libraryDecorator); ok {
420 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
421 lib.baseCompiler.Properties.Target.Recovery.Srcs...)
422
423 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
424 lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
425
426 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
427 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
428 }
429}
430
431func squashVendorRamdiskSrcs(m *Module) {
432 if lib, ok := m.compiler.(*libraryDecorator); ok {
433 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
434 }
435}
436
Inseob Kime498dd92020-08-04 09:24:04 +0900437func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
438 m := module.(*Module)
Yifan Hong6da33c22020-10-27 15:01:21 -0700439 if variant == android.RamdiskVariation {
Inseob Kime498dd92020-08-04 09:24:04 +0900440 m.MakeAsPlatform()
Yifan Hong6da33c22020-10-27 15:01:21 -0700441 } else if variant == android.VendorRamdiskVariation {
442 m.MakeAsPlatform()
443 squashVendorRamdiskSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900444 } else if variant == android.RecoveryVariation {
445 m.MakeAsPlatform()
446 squashRecoverySrcs(m)
447 } else if strings.HasPrefix(variant, VendorVariationPrefix) {
448 m.Properties.ImageVariationPrefix = VendorVariationPrefix
449 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
450 squashVendorSrcs(m)
451
452 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
453 // Hide other vendor variants to avoid collision.
454 vndkVersion := ctx.DeviceConfig().VndkVersion()
455 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
456 m.Properties.HideFromMake = true
457 m.SkipInstall()
458 }
459 } else if strings.HasPrefix(variant, ProductVariationPrefix) {
460 m.Properties.ImageVariationPrefix = ProductVariationPrefix
461 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
Justin Yun63e9ec72020-10-29 16:49:43 +0900462 // TODO (b/150902910): This will be replaced with squashProductSrcs(m).
Inseob Kime498dd92020-08-04 09:24:04 +0900463 squashVendorSrcs(m)
464 }
465}