blob: d9c46ea11695a2e00b76c0802ea908b3d5155cb3 [file] [log] [blame]
Inseob Kimde5744a2020-12-02 13:14:28 +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 defines snapshot prebuilt modules, e.g. vendor snapshot and recovery snapshot. Such
17// snapshot modules will override original source modules with setting BOARD_VNDK_VERSION, with
18// snapshot mutators and snapshot information maps which are also defined in this file.
19
20import (
21 "strings"
22 "sync"
23
24 "android/soong/android"
Jose Galmes6f843bc2020-12-11 13:36:29 -080025
26 "github.com/google/blueprint/proptools"
Inseob Kimde5744a2020-12-02 13:14:28 +090027)
28
29// Defines the specifics of different images to which the snapshot process is applicable, e.g.,
30// vendor, recovery, ramdisk.
31type snapshotImage interface {
32 // Used to register callbacks with the build system.
33 init()
34
Jose Galmes6f843bc2020-12-11 13:36:29 -080035 // Returns true if a snapshot should be generated for this image.
36 shouldGenerateSnapshot(ctx android.SingletonContext) bool
37
Inseob Kimde5744a2020-12-02 13:14:28 +090038 // Function that returns true if the module is included in this image.
39 // Using a function return instead of a value to prevent early
40 // evalution of a function that may be not be defined.
41 inImage(m *Module) func() bool
42
43 // Returns the value of the "available" property for a given module for
44 // and snapshot, e.g., "vendor_available", "recovery_available", etc.
45 // or nil if the property is not defined.
46 available(m *Module) *bool
47
48 // Returns true if a dir under source tree is an SoC-owned proprietary
49 // directory, such as device/, vendor/, etc.
50 //
51 // For a given snapshot (e.g., vendor, recovery, etc.) if
52 // isProprietaryPath(dir) returns true, then the module in dir will be
53 // built from sources.
54 isProprietaryPath(dir string) bool
55
56 // Whether to include VNDK in the snapshot for this image.
57 includeVndk() bool
58
59 // Whether a given module has been explicitly excluded from the
60 // snapshot, e.g., using the exclude_from_vendor_snapshot or
61 // exclude_from_recovery_snapshot properties.
62 excludeFromSnapshot(m *Module) bool
Jose Galmes6f843bc2020-12-11 13:36:29 -080063
64 // Returns the snapshotMap to be used for a given module and config, or nil if the
65 // module is not included in this image.
66 getSnapshotMap(m *Module, cfg android.Config) *snapshotMap
67
68 // Returns mutex used for mutual exclusion when updating the snapshot maps.
69 getMutex() *sync.Mutex
70
71 // For a given arch, a maps of which modules are included in this image.
72 suffixModules(config android.Config) map[string]bool
73
74 // Whether to add a given module to the suffix map.
75 shouldBeAddedToSuffixModules(m *Module) bool
76
77 // Returns true if the build is using a snapshot for this image.
78 isUsingSnapshot(cfg android.DeviceConfig) bool
79
80 // Whether to skip the module mutator for a module in a given context.
81 skipModuleMutator(ctx android.BottomUpMutatorContext) bool
82
83 // Whether to skip the source mutator for a given module.
84 skipSourceMutator(ctx android.BottomUpMutatorContext) bool
Inseob Kim7cf14652021-01-06 23:06:52 +090085
86 // Whether to exclude a given module from the directed snapshot or not.
87 // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on,
88 // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured.
89 excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool
Inseob Kimde5744a2020-12-02 13:14:28 +090090}
91
92type vendorSnapshotImage struct{}
93type recoverySnapshotImage struct{}
94
95func (vendorSnapshotImage) init() {
96 android.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
97 android.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
98 android.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
99 android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
100 android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
101 android.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory)
Inseob Kime9aec6a2021-01-05 20:03:22 +0900102
103 android.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
Inseob Kimde5744a2020-12-02 13:14:28 +0900104}
105
Jose Galmes6f843bc2020-12-11 13:36:29 -0800106func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
107 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot.
108 return ctx.DeviceConfig().VndkVersion() == "current"
109}
110
Inseob Kimde5744a2020-12-02 13:14:28 +0900111func (vendorSnapshotImage) inImage(m *Module) func() bool {
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500112 return m.InVendor
Inseob Kimde5744a2020-12-02 13:14:28 +0900113}
114
115func (vendorSnapshotImage) available(m *Module) *bool {
116 return m.VendorProperties.Vendor_available
117}
118
119func (vendorSnapshotImage) isProprietaryPath(dir string) bool {
120 return isVendorProprietaryPath(dir)
121}
122
123// vendor snapshot includes static/header libraries with vndk: {enabled: true}.
124func (vendorSnapshotImage) includeVndk() bool {
125 return true
126}
127
128func (vendorSnapshotImage) excludeFromSnapshot(m *Module) bool {
129 return m.ExcludeFromVendorSnapshot()
130}
131
Jose Galmes6f843bc2020-12-11 13:36:29 -0800132func (vendorSnapshotImage) getSnapshotMap(m *Module, cfg android.Config) *snapshotMap {
133 if lib, ok := m.linker.(libraryInterface); ok {
134 if lib.static() {
135 return vendorSnapshotStaticLibs(cfg)
136 } else if lib.shared() {
137 return vendorSnapshotSharedLibs(cfg)
138 } else {
139 // header
140 return vendorSnapshotHeaderLibs(cfg)
141 }
142 } else if m.binary() {
143 return vendorSnapshotBinaries(cfg)
144 } else if m.object() {
145 return vendorSnapshotObjects(cfg)
146 } else {
147 return nil
148 }
149}
150
151func (vendorSnapshotImage) getMutex() *sync.Mutex {
152 return &vendorSnapshotsLock
153}
154
155func (vendorSnapshotImage) suffixModules(config android.Config) map[string]bool {
156 return vendorSuffixModules(config)
157}
158
159func (vendorSnapshotImage) shouldBeAddedToSuffixModules(module *Module) bool {
160 // vendor suffix should be added to snapshots if the source module isn't vendor: true.
161 if module.SocSpecific() {
162 return false
163 }
164
165 // But we can't just check SocSpecific() since we already passed the image mutator.
166 // Check ramdisk and recovery to see if we are real "vendor: true" module.
167 ramdiskAvailable := module.InRamdisk() && !module.OnlyInRamdisk()
168 vendorRamdiskAvailable := module.InVendorRamdisk() && !module.OnlyInVendorRamdisk()
169 recoveryAvailable := module.InRecovery() && !module.OnlyInRecovery()
170
171 return !ramdiskAvailable && !recoveryAvailable && !vendorRamdiskAvailable
172}
173
174func (vendorSnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
175 vndkVersion := cfg.VndkVersion()
176 return vndkVersion != "current" && vndkVersion != ""
177}
178
179func (vendorSnapshotImage) skipModuleMutator(ctx android.BottomUpMutatorContext) bool {
180 vndkVersion := ctx.DeviceConfig().VndkVersion()
181 module, ok := ctx.Module().(*Module)
182 return !ok || module.VndkVersion() != vndkVersion
183}
184
185func (vendorSnapshotImage) skipSourceMutator(ctx android.BottomUpMutatorContext) bool {
186 vndkVersion := ctx.DeviceConfig().VndkVersion()
187 module, ok := ctx.Module().(*Module)
188 if !ok {
189 return true
190 }
191 if module.VndkVersion() != vndkVersion {
192 return true
193 }
194 // .. and also filter out llndk library
195 if module.IsLlndk() {
196 return true
197 }
198 return false
199}
200
Inseob Kim7cf14652021-01-06 23:06:52 +0900201// returns true iff a given module SHOULD BE EXCLUDED, false if included
202func (vendorSnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
203 // If we're using full snapshot, not directed snapshot, capture every module
204 if !cfg.DirectedVendorSnapshot() {
205 return false
206 }
207 // Else, checks if name is in VENDOR_SNAPSHOT_MODULES.
208 return !cfg.VendorSnapshotModules()[name]
209}
210
Inseob Kimde5744a2020-12-02 13:14:28 +0900211func (recoverySnapshotImage) init() {
212 android.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton)
213 android.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory)
214 android.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory)
215 android.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory)
216 android.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory)
217 android.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory)
218}
219
Jose Galmes6f843bc2020-12-11 13:36:29 -0800220func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
221 // RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a
222 // snapshot.
223 return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
224}
225
Inseob Kimde5744a2020-12-02 13:14:28 +0900226func (recoverySnapshotImage) inImage(m *Module) func() bool {
227 return m.InRecovery
228}
229
230func (recoverySnapshotImage) available(m *Module) *bool {
231 return m.Properties.Recovery_available
232}
233
234func (recoverySnapshotImage) isProprietaryPath(dir string) bool {
235 return isRecoveryProprietaryPath(dir)
236}
237
238// recovery snapshot does NOT treat vndk specially.
239func (recoverySnapshotImage) includeVndk() bool {
240 return false
241}
242
243func (recoverySnapshotImage) excludeFromSnapshot(m *Module) bool {
244 return m.ExcludeFromRecoverySnapshot()
245}
246
Jose Galmes6f843bc2020-12-11 13:36:29 -0800247func (recoverySnapshotImage) getSnapshotMap(m *Module, cfg android.Config) *snapshotMap {
248 if lib, ok := m.linker.(libraryInterface); ok {
249 if lib.static() {
250 return recoverySnapshotStaticLibs(cfg)
251 } else if lib.shared() {
252 return recoverySnapshotSharedLibs(cfg)
253 } else {
254 // header
255 return recoverySnapshotHeaderLibs(cfg)
256 }
257 } else if m.binary() {
258 return recoverySnapshotBinaries(cfg)
259 } else if m.object() {
260 return recoverySnapshotObjects(cfg)
261 } else {
262 return nil
263 }
264}
265
266func (recoverySnapshotImage) getMutex() *sync.Mutex {
267 return &recoverySnapshotsLock
268}
269
270func (recoverySnapshotImage) suffixModules(config android.Config) map[string]bool {
271 return recoverySuffixModules(config)
272}
273
274func (recoverySnapshotImage) shouldBeAddedToSuffixModules(module *Module) bool {
275 return proptools.BoolDefault(module.Properties.Recovery_available, false)
276}
277
278func (recoverySnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
279 recoverySnapshotVersion := cfg.RecoverySnapshotVersion()
280 return recoverySnapshotVersion != "current" && recoverySnapshotVersion != ""
281}
282
283func (recoverySnapshotImage) skipModuleMutator(ctx android.BottomUpMutatorContext) bool {
284 module, ok := ctx.Module().(*Module)
285 return !ok || !module.InRecovery()
286}
287
288func (recoverySnapshotImage) skipSourceMutator(ctx android.BottomUpMutatorContext) bool {
289 module, ok := ctx.Module().(*Module)
290 return !ok || !module.InRecovery()
291}
292
Inseob Kim7cf14652021-01-06 23:06:52 +0900293func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
294 // directed recovery snapshot is not implemented yet
295 return false
296}
297
Inseob Kimde5744a2020-12-02 13:14:28 +0900298var vendorSnapshotImageSingleton vendorSnapshotImage
299var recoverySnapshotImageSingleton recoverySnapshotImage
300
301func init() {
302 vendorSnapshotImageSingleton.init()
303 recoverySnapshotImageSingleton.init()
304}
305
306const (
307 vendorSnapshotHeaderSuffix = ".vendor_header."
308 vendorSnapshotSharedSuffix = ".vendor_shared."
309 vendorSnapshotStaticSuffix = ".vendor_static."
310 vendorSnapshotBinarySuffix = ".vendor_binary."
311 vendorSnapshotObjectSuffix = ".vendor_object."
312)
313
314const (
315 recoverySnapshotHeaderSuffix = ".recovery_header."
316 recoverySnapshotSharedSuffix = ".recovery_shared."
317 recoverySnapshotStaticSuffix = ".recovery_static."
318 recoverySnapshotBinarySuffix = ".recovery_binary."
319 recoverySnapshotObjectSuffix = ".recovery_object."
320)
321
322var (
323 vendorSnapshotsLock sync.Mutex
324 vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules")
325 vendorSnapshotHeaderLibsKey = android.NewOnceKey("vendorSnapshotHeaderLibs")
326 vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs")
327 vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs")
328 vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries")
329 vendorSnapshotObjectsKey = android.NewOnceKey("vendorSnapshotObjects")
330)
331
Jose Galmes6f843bc2020-12-11 13:36:29 -0800332var (
333 recoverySnapshotsLock sync.Mutex
334 recoverySuffixModulesKey = android.NewOnceKey("recoverySuffixModules")
335 recoverySnapshotHeaderLibsKey = android.NewOnceKey("recoverySnapshotHeaderLibs")
336 recoverySnapshotStaticLibsKey = android.NewOnceKey("recoverySnapshotStaticLibs")
337 recoverySnapshotSharedLibsKey = android.NewOnceKey("recoverySnapshotSharedLibs")
338 recoverySnapshotBinariesKey = android.NewOnceKey("recoverySnapshotBinaries")
339 recoverySnapshotObjectsKey = android.NewOnceKey("recoverySnapshotObjects")
340)
341
Inseob Kimde5744a2020-12-02 13:14:28 +0900342// vendorSuffixModules holds names of modules whose vendor variants should have the vendor suffix.
343// This is determined by source modules, and then this will be used when exporting snapshot modules
344// to Makefile.
345//
346// For example, if libbase has "vendor_available: true", the name of core variant will be "libbase"
347// while the name of vendor variant will be "libbase.vendor". In such cases, the vendor snapshot of
348// "libbase" should be exported with the name "libbase.vendor".
349//
350// Refer to VendorSnapshotSourceMutator and makeLibName which use this.
351func vendorSuffixModules(config android.Config) map[string]bool {
352 return config.Once(vendorSuffixModulesKey, func() interface{} {
353 return make(map[string]bool)
354 }).(map[string]bool)
355}
356
357// these are vendor snapshot maps holding names of vendor snapshot modules
358func vendorSnapshotHeaderLibs(config android.Config) *snapshotMap {
359 return config.Once(vendorSnapshotHeaderLibsKey, func() interface{} {
360 return newSnapshotMap()
361 }).(*snapshotMap)
362}
363
364func vendorSnapshotSharedLibs(config android.Config) *snapshotMap {
365 return config.Once(vendorSnapshotSharedLibsKey, func() interface{} {
366 return newSnapshotMap()
367 }).(*snapshotMap)
368}
369
370func vendorSnapshotStaticLibs(config android.Config) *snapshotMap {
371 return config.Once(vendorSnapshotStaticLibsKey, func() interface{} {
372 return newSnapshotMap()
373 }).(*snapshotMap)
374}
375
376func vendorSnapshotBinaries(config android.Config) *snapshotMap {
377 return config.Once(vendorSnapshotBinariesKey, func() interface{} {
378 return newSnapshotMap()
379 }).(*snapshotMap)
380}
381
382func vendorSnapshotObjects(config android.Config) *snapshotMap {
383 return config.Once(vendorSnapshotObjectsKey, func() interface{} {
384 return newSnapshotMap()
385 }).(*snapshotMap)
386}
387
Jose Galmes6f843bc2020-12-11 13:36:29 -0800388func recoverySuffixModules(config android.Config) map[string]bool {
389 return config.Once(recoverySuffixModulesKey, func() interface{} {
390 return make(map[string]bool)
391 }).(map[string]bool)
392}
393
394func recoverySnapshotHeaderLibs(config android.Config) *snapshotMap {
395 return config.Once(recoverySnapshotHeaderLibsKey, func() interface{} {
396 return newSnapshotMap()
397 }).(*snapshotMap)
398}
399
400func recoverySnapshotSharedLibs(config android.Config) *snapshotMap {
401 return config.Once(recoverySnapshotSharedLibsKey, func() interface{} {
402 return newSnapshotMap()
403 }).(*snapshotMap)
404}
405
406func recoverySnapshotStaticLibs(config android.Config) *snapshotMap {
407 return config.Once(recoverySnapshotStaticLibsKey, func() interface{} {
408 return newSnapshotMap()
409 }).(*snapshotMap)
410}
411
412func recoverySnapshotBinaries(config android.Config) *snapshotMap {
413 return config.Once(recoverySnapshotBinariesKey, func() interface{} {
414 return newSnapshotMap()
415 }).(*snapshotMap)
416}
417
418func recoverySnapshotObjects(config android.Config) *snapshotMap {
419 return config.Once(recoverySnapshotObjectsKey, func() interface{} {
420 return newSnapshotMap()
421 }).(*snapshotMap)
422}
423
Inseob Kimde5744a2020-12-02 13:14:28 +0900424type baseSnapshotDecoratorProperties struct {
425 // snapshot version.
426 Version string
427
428 // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
429 Target_arch string
Jose Galmes6f843bc2020-12-11 13:36:29 -0800430
431 // Suffix to be added to the module name, e.g., vendor_shared,
432 // recovery_shared, etc.
433 Module_suffix string
Inseob Kimde5744a2020-12-02 13:14:28 +0900434}
435
436// baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
437// version, snapshot arch, etc. It also adds a special suffix to Soong module name, so it doesn't
438// collide with source modules. e.g. the following example module,
439//
440// vendor_snapshot_static {
441// name: "libbase",
442// arch: "arm64",
443// version: 30,
444// ...
445// }
446//
447// will be seen as "libbase.vendor_static.30.arm64" by Soong.
448type baseSnapshotDecorator struct {
449 baseProperties baseSnapshotDecoratorProperties
Inseob Kimde5744a2020-12-02 13:14:28 +0900450}
451
452func (p *baseSnapshotDecorator) Name(name string) string {
453 return name + p.NameSuffix()
454}
455
456func (p *baseSnapshotDecorator) NameSuffix() string {
457 versionSuffix := p.version()
458 if p.arch() != "" {
459 versionSuffix += "." + p.arch()
460 }
461
Jose Galmes6f843bc2020-12-11 13:36:29 -0800462 return p.baseProperties.Module_suffix + versionSuffix
Inseob Kimde5744a2020-12-02 13:14:28 +0900463}
464
465func (p *baseSnapshotDecorator) version() string {
466 return p.baseProperties.Version
467}
468
469func (p *baseSnapshotDecorator) arch() string {
470 return p.baseProperties.Target_arch
471}
472
Jose Galmes6f843bc2020-12-11 13:36:29 -0800473func (p *baseSnapshotDecorator) module_suffix() string {
474 return p.baseProperties.Module_suffix
475}
476
Inseob Kimde5744a2020-12-02 13:14:28 +0900477func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool {
478 return true
479}
480
481// Call this with a module suffix after creating a snapshot module, such as
482// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc.
483func (p *baseSnapshotDecorator) init(m *Module, suffix string) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800484 p.baseProperties.Module_suffix = suffix
Inseob Kimde5744a2020-12-02 13:14:28 +0900485 m.AddProperties(&p.baseProperties)
486 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
487 vendorSnapshotLoadHook(ctx, p)
488 })
489}
490
491// vendorSnapshotLoadHook disables snapshots if it's not BOARD_VNDK_VERSION.
492// As vendor snapshot is only for vendor, such modules won't be used at all.
493func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *baseSnapshotDecorator) {
494 if p.version() != ctx.DeviceConfig().VndkVersion() {
495 ctx.Module().Disable()
496 return
497 }
498}
499
500//
501// Module definitions for snapshots of libraries (shared, static, header).
502//
503// Modules (vendor|recovery)_snapshot_(shared|static|header) are defined here. Shared libraries and
504// static libraries have their prebuilt library files (.so for shared, .a for static) as their src,
505// which can be installed or linked against. Also they export flags needed when linked, such as
506// include directories, c flags, sanitize dependency information, etc.
507//
508// These modules are auto-generated by development/vendor_snapshot/update.py.
509type snapshotLibraryProperties struct {
510 // Prebuilt file for each arch.
511 Src *string `android:"arch_variant"`
512
513 // list of directories that will be added to the include path (using -I).
514 Export_include_dirs []string `android:"arch_variant"`
515
516 // list of directories that will be added to the system path (using -isystem).
517 Export_system_include_dirs []string `android:"arch_variant"`
518
519 // list of flags that will be used for any module that links against this module.
520 Export_flags []string `android:"arch_variant"`
521
522 // Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
523 Sanitize_ubsan_dep *bool `android:"arch_variant"`
524
525 // Whether this prebuilt needs to depend on sanitize minimal runtime or not.
526 Sanitize_minimal_dep *bool `android:"arch_variant"`
527}
528
529type snapshotSanitizer interface {
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500530 isSanitizerEnabled(t SanitizerType) bool
531 setSanitizerVariation(t SanitizerType, enabled bool)
Inseob Kimde5744a2020-12-02 13:14:28 +0900532}
533
534type snapshotLibraryDecorator struct {
535 baseSnapshotDecorator
536 *libraryDecorator
537 properties snapshotLibraryProperties
538 sanitizerProperties struct {
539 CfiEnabled bool `blueprint:"mutated"`
540
541 // Library flags for cfi variant.
542 Cfi snapshotLibraryProperties `android:"arch_variant"`
543 }
Jose Galmes6f843bc2020-12-11 13:36:29 -0800544 androidMkSuffix string
Inseob Kimde5744a2020-12-02 13:14:28 +0900545}
546
547func (p *snapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
548 p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
549 return p.libraryDecorator.linkerFlags(ctx, flags)
550}
551
552func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
553 arches := config.Arches()
554 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
555 return false
556 }
557 if !p.header() && p.properties.Src == nil {
558 return false
559 }
560 return true
561}
562
563// cc modules' link functions are to link compiled objects into final binaries.
564// As snapshots are prebuilts, this just returns the prebuilt binary after doing things which are
565// done by normal library decorator, e.g. exporting flags.
566func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
567 m := ctx.Module().(*Module)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800568
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500569 if m.InVendor() && vendorSuffixModules(ctx.Config())[m.BaseModuleName()] {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800570 p.androidMkSuffix = vendorSuffix
571 } else if m.InRecovery() && recoverySuffixModules(ctx.Config())[m.BaseModuleName()] {
572 p.androidMkSuffix = recoverySuffix
573 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900574
575 if p.header() {
576 return p.libraryDecorator.link(ctx, flags, deps, objs)
577 }
578
579 if p.sanitizerProperties.CfiEnabled {
580 p.properties = p.sanitizerProperties.Cfi
581 }
582
583 if !p.matchesWithDevice(ctx.DeviceConfig()) {
584 return nil
585 }
586
587 p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
588 p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
589 p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
590
591 in := android.PathForModuleSrc(ctx, *p.properties.Src)
592 p.unstrippedOutputFile = in
593
594 if p.shared() {
595 libName := in.Base()
596 builderFlags := flagsToBuilderFlags(flags)
597
598 // Optimize out relinking against shared libraries whose interface hasn't changed by
599 // depending on a table of contents file instead of the library itself.
600 tocFile := android.PathForModuleOut(ctx, libName+".toc")
601 p.tocFile = android.OptionalPathForPath(tocFile)
602 transformSharedObjectToToc(ctx, in, tocFile, builderFlags)
603
604 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
605 SharedLibrary: in,
606 UnstrippedSharedLibrary: p.unstrippedOutputFile,
607
608 TableOfContents: p.tocFile,
609 })
610 }
611
612 if p.static() {
613 depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
614 ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
615 StaticLibrary: in,
616
617 TransitiveStaticLibrariesForOrdering: depSet,
618 })
619 }
620
621 p.libraryDecorator.flagExporter.setProvider(ctx)
622
623 return in
624}
625
626func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
627 if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
628 p.baseInstaller.install(ctx, file)
629 }
630}
631
632func (p *snapshotLibraryDecorator) nativeCoverage() bool {
633 return false
634}
635
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500636func (p *snapshotLibraryDecorator) isSanitizerEnabled(t SanitizerType) bool {
Inseob Kimde5744a2020-12-02 13:14:28 +0900637 switch t {
638 case cfi:
639 return p.sanitizerProperties.Cfi.Src != nil
640 default:
641 return false
642 }
643}
644
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500645func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enabled bool) {
Inseob Kimde5744a2020-12-02 13:14:28 +0900646 if !enabled {
647 return
648 }
649 switch t {
650 case cfi:
651 p.sanitizerProperties.CfiEnabled = true
652 default:
653 return
654 }
655}
656
657func snapshotLibraryFactory(suffix string) (*Module, *snapshotLibraryDecorator) {
658 module, library := NewLibrary(android.DeviceSupported)
659
660 module.stl = nil
661 module.sanitize = nil
662 library.disableStripping()
663
664 prebuilt := &snapshotLibraryDecorator{
665 libraryDecorator: library,
666 }
667
668 prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
669 prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
670
671 // Prevent default system libs (libc, libm, and libdl) from being linked
672 if prebuilt.baseLinker.Properties.System_shared_libs == nil {
673 prebuilt.baseLinker.Properties.System_shared_libs = []string{}
674 }
675
676 module.compiler = nil
677 module.linker = prebuilt
678 module.installer = prebuilt
679
680 prebuilt.init(module, suffix)
681 module.AddProperties(
682 &prebuilt.properties,
683 &prebuilt.sanitizerProperties,
684 )
685
686 return module, prebuilt
687}
688
689// vendor_snapshot_shared is a special prebuilt shared library which is auto-generated by
690// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_shared
691// overrides the vendor variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
692// is set.
693func VendorSnapshotSharedFactory() android.Module {
694 module, prebuilt := snapshotLibraryFactory(vendorSnapshotSharedSuffix)
695 prebuilt.libraryDecorator.BuildOnlyShared()
696 return module.Init()
697}
698
699// recovery_snapshot_shared is a special prebuilt shared library which is auto-generated by
700// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_shared
701// overrides the recovery variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
702// is set.
703func RecoverySnapshotSharedFactory() android.Module {
704 module, prebuilt := snapshotLibraryFactory(recoverySnapshotSharedSuffix)
705 prebuilt.libraryDecorator.BuildOnlyShared()
706 return module.Init()
707}
708
709// vendor_snapshot_static is a special prebuilt static library which is auto-generated by
710// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_static
711// overrides the vendor variant of the cc static library with the same name, if BOARD_VNDK_VERSION
712// is set.
713func VendorSnapshotStaticFactory() android.Module {
714 module, prebuilt := snapshotLibraryFactory(vendorSnapshotStaticSuffix)
715 prebuilt.libraryDecorator.BuildOnlyStatic()
716 return module.Init()
717}
718
719// recovery_snapshot_static is a special prebuilt static library which is auto-generated by
720// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_static
721// overrides the recovery variant of the cc static library with the same name, if BOARD_VNDK_VERSION
722// is set.
723func RecoverySnapshotStaticFactory() android.Module {
724 module, prebuilt := snapshotLibraryFactory(recoverySnapshotStaticSuffix)
725 prebuilt.libraryDecorator.BuildOnlyStatic()
726 return module.Init()
727}
728
729// vendor_snapshot_header is a special header library which is auto-generated by
730// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_header
731// overrides the vendor variant of the cc header library with the same name, if BOARD_VNDK_VERSION
732// is set.
733func VendorSnapshotHeaderFactory() android.Module {
734 module, prebuilt := snapshotLibraryFactory(vendorSnapshotHeaderSuffix)
735 prebuilt.libraryDecorator.HeaderOnly()
736 return module.Init()
737}
738
739// recovery_snapshot_header is a special header library which is auto-generated by
740// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_header
741// overrides the recovery variant of the cc header library with the same name, if BOARD_VNDK_VERSION
742// is set.
743func RecoverySnapshotHeaderFactory() android.Module {
744 module, prebuilt := snapshotLibraryFactory(recoverySnapshotHeaderSuffix)
745 prebuilt.libraryDecorator.HeaderOnly()
746 return module.Init()
747}
748
749var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil)
750
751//
752// Module definitions for snapshots of executable binaries.
753//
754// Modules (vendor|recovery)_snapshot_binary are defined here. They have their prebuilt executable
755// binaries (e.g. toybox, sh) as their src, which can be installed.
756//
757// These modules are auto-generated by development/vendor_snapshot/update.py.
758type snapshotBinaryProperties struct {
759 // Prebuilt file for each arch.
760 Src *string `android:"arch_variant"`
761}
762
763type snapshotBinaryDecorator struct {
764 baseSnapshotDecorator
765 *binaryDecorator
Jose Galmes6f843bc2020-12-11 13:36:29 -0800766 properties snapshotBinaryProperties
767 androidMkSuffix string
Inseob Kimde5744a2020-12-02 13:14:28 +0900768}
769
770func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
771 if config.DeviceArch() != p.arch() {
772 return false
773 }
774 if p.properties.Src == nil {
775 return false
776 }
777 return true
778}
779
780// cc modules' link functions are to link compiled objects into final binaries.
781// As snapshots are prebuilts, this just returns the prebuilt binary
782func (p *snapshotBinaryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
783 if !p.matchesWithDevice(ctx.DeviceConfig()) {
784 return nil
785 }
786
787 in := android.PathForModuleSrc(ctx, *p.properties.Src)
788 p.unstrippedOutputFile = in
789 binName := in.Base()
790
791 m := ctx.Module().(*Module)
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500792 if m.InVendor() && vendorSuffixModules(ctx.Config())[m.BaseModuleName()] {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800793 p.androidMkSuffix = vendorSuffix
794 } else if m.InRecovery() && recoverySuffixModules(ctx.Config())[m.BaseModuleName()] {
795 p.androidMkSuffix = recoverySuffix
796
797 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900798
799 // use cpExecutable to make it executable
800 outputFile := android.PathForModuleOut(ctx, binName)
801 ctx.Build(pctx, android.BuildParams{
802 Rule: android.CpExecutable,
803 Description: "prebuilt",
804 Output: outputFile,
805 Input: in,
806 })
807
808 return outputFile
809}
810
811func (p *snapshotBinaryDecorator) nativeCoverage() bool {
812 return false
813}
814
815// vendor_snapshot_binary is a special prebuilt executable binary which is auto-generated by
816// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_binary
817// overrides the vendor variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
818func VendorSnapshotBinaryFactory() android.Module {
819 return snapshotBinaryFactory(vendorSnapshotBinarySuffix)
820}
821
822// recovery_snapshot_binary is a special prebuilt executable binary which is auto-generated by
823// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_binary
824// overrides the recovery variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
825func RecoverySnapshotBinaryFactory() android.Module {
826 return snapshotBinaryFactory(recoverySnapshotBinarySuffix)
827}
828
829func snapshotBinaryFactory(suffix string) android.Module {
830 module, binary := NewBinary(android.DeviceSupported)
831 binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
832 binary.baseLinker.Properties.Nocrt = BoolPtr(true)
833
834 // Prevent default system libs (libc, libm, and libdl) from being linked
835 if binary.baseLinker.Properties.System_shared_libs == nil {
836 binary.baseLinker.Properties.System_shared_libs = []string{}
837 }
838
839 prebuilt := &snapshotBinaryDecorator{
840 binaryDecorator: binary,
841 }
842
843 module.compiler = nil
844 module.sanitize = nil
845 module.stl = nil
846 module.linker = prebuilt
847
848 prebuilt.init(module, suffix)
849 module.AddProperties(&prebuilt.properties)
850 return module.Init()
851}
852
853//
854// Module definitions for snapshots of object files (*.o).
855//
856// Modules (vendor|recovery)_snapshot_object are defined here. They have their prebuilt object
857// files (*.o) as their src.
858//
859// These modules are auto-generated by development/vendor_snapshot/update.py.
860type vendorSnapshotObjectProperties struct {
861 // Prebuilt file for each arch.
862 Src *string `android:"arch_variant"`
863}
864
865type snapshotObjectLinker struct {
866 baseSnapshotDecorator
867 objectLinker
Jose Galmes6f843bc2020-12-11 13:36:29 -0800868 properties vendorSnapshotObjectProperties
869 androidMkSuffix string
Inseob Kimde5744a2020-12-02 13:14:28 +0900870}
871
872func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
873 if config.DeviceArch() != p.arch() {
874 return false
875 }
876 if p.properties.Src == nil {
877 return false
878 }
879 return true
880}
881
882// cc modules' link functions are to link compiled objects into final binaries.
883// As snapshots are prebuilts, this just returns the prebuilt binary
884func (p *snapshotObjectLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
885 if !p.matchesWithDevice(ctx.DeviceConfig()) {
886 return nil
887 }
888
889 m := ctx.Module().(*Module)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800890
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500891 if m.InVendor() && vendorSuffixModules(ctx.Config())[m.BaseModuleName()] {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800892 p.androidMkSuffix = vendorSuffix
893 } else if m.InRecovery() && recoverySuffixModules(ctx.Config())[m.BaseModuleName()] {
894 p.androidMkSuffix = recoverySuffix
895 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900896
897 return android.PathForModuleSrc(ctx, *p.properties.Src)
898}
899
900func (p *snapshotObjectLinker) nativeCoverage() bool {
901 return false
902}
903
904// vendor_snapshot_object is a special prebuilt compiled object file which is auto-generated by
905// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_object
906// overrides the vendor variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
907func VendorSnapshotObjectFactory() android.Module {
908 module := newObject()
909
910 prebuilt := &snapshotObjectLinker{
911 objectLinker: objectLinker{
912 baseLinker: NewBaseLinker(nil),
913 },
914 }
915 module.linker = prebuilt
916
917 prebuilt.init(module, vendorSnapshotObjectSuffix)
918 module.AddProperties(&prebuilt.properties)
919 return module.Init()
920}
921
922// recovery_snapshot_object is a special prebuilt compiled object file which is auto-generated by
923// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_object
924// overrides the recovery variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
925func RecoverySnapshotObjectFactory() android.Module {
926 module := newObject()
927
928 prebuilt := &snapshotObjectLinker{
929 objectLinker: objectLinker{
930 baseLinker: NewBaseLinker(nil),
931 },
932 }
933 module.linker = prebuilt
934
935 prebuilt.init(module, recoverySnapshotObjectSuffix)
936 module.AddProperties(&prebuilt.properties)
937 return module.Init()
938}
939
940type snapshotInterface interface {
941 matchesWithDevice(config android.DeviceConfig) bool
942}
943
944var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
945var _ snapshotInterface = (*snapshotLibraryDecorator)(nil)
946var _ snapshotInterface = (*snapshotBinaryDecorator)(nil)
947var _ snapshotInterface = (*snapshotObjectLinker)(nil)
948
949//
950// Mutators that helps vendor snapshot modules override source modules.
951//
952
953// VendorSnapshotMutator gathers all snapshots for vendor, and disable all snapshots which don't
954// match with device, e.g.
955// - snapshot version is different with BOARD_VNDK_VERSION
956// - snapshot arch is different with device's arch (e.g. arm vs x86)
957//
958// This also handles vndk_prebuilt_shared, except for they won't be disabled in any cases, given
959// that any versions of VNDK might be packed into vndk APEX.
960//
961// TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules
962func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800963 snapshotMutator(ctx, vendorSnapshotImageSingleton)
964}
965
966func RecoverySnapshotMutator(ctx android.BottomUpMutatorContext) {
967 snapshotMutator(ctx, recoverySnapshotImageSingleton)
968}
969
970func snapshotMutator(ctx android.BottomUpMutatorContext, image snapshotImage) {
971 if !image.isUsingSnapshot(ctx.DeviceConfig()) {
Inseob Kimde5744a2020-12-02 13:14:28 +0900972 return
973 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900974 module, ok := ctx.Module().(*Module)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800975 if !ok || !module.Enabled() {
Inseob Kimde5744a2020-12-02 13:14:28 +0900976 return
977 }
Jose Galmes6f843bc2020-12-11 13:36:29 -0800978 if image.skipModuleMutator(ctx) {
979 return
980 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900981 if !module.isSnapshotPrebuilt() {
982 return
983 }
984
985 // isSnapshotPrebuilt ensures snapshotInterface
986 if !module.linker.(snapshotInterface).matchesWithDevice(ctx.DeviceConfig()) {
987 // Disable unnecessary snapshot module, but do not disable
988 // vndk_prebuilt_shared because they might be packed into vndk APEX
989 if !module.IsVndk() {
990 module.Disable()
991 }
992 return
993 }
994
Jose Galmes6f843bc2020-12-11 13:36:29 -0800995 var snapshotMap *snapshotMap = image.getSnapshotMap(module, ctx.Config())
996 if snapshotMap == nil {
Inseob Kimde5744a2020-12-02 13:14:28 +0900997 return
998 }
999
Jose Galmes6f843bc2020-12-11 13:36:29 -08001000 mutex := image.getMutex()
1001 mutex.Lock()
1002 defer mutex.Unlock()
Inseob Kimde5744a2020-12-02 13:14:28 +09001003 snapshotMap.add(module.BaseModuleName(), ctx.Arch().ArchType, ctx.ModuleName())
1004}
1005
1006// VendorSnapshotSourceMutator disables source modules which have corresponding snapshots.
1007func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -08001008 snapshotSourceMutator(ctx, vendorSnapshotImageSingleton)
1009}
1010
1011func RecoverySnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
1012 snapshotSourceMutator(ctx, recoverySnapshotImageSingleton)
1013}
1014
1015func snapshotSourceMutator(ctx android.BottomUpMutatorContext, image snapshotImage) {
Inseob Kimde5744a2020-12-02 13:14:28 +09001016 if !ctx.Device() {
1017 return
1018 }
Jose Galmes6f843bc2020-12-11 13:36:29 -08001019 if !image.isUsingSnapshot(ctx.DeviceConfig()) {
Inseob Kimde5744a2020-12-02 13:14:28 +09001020 return
1021 }
1022
1023 module, ok := ctx.Module().(*Module)
1024 if !ok {
1025 return
1026 }
1027
Jose Galmes6f843bc2020-12-11 13:36:29 -08001028 if image.shouldBeAddedToSuffixModules(module) {
1029 mutex := image.getMutex()
1030 mutex.Lock()
1031 defer mutex.Unlock()
Inseob Kimde5744a2020-12-02 13:14:28 +09001032
Jose Galmes6f843bc2020-12-11 13:36:29 -08001033 image.suffixModules(ctx.Config())[ctx.ModuleName()] = true
Inseob Kimde5744a2020-12-02 13:14:28 +09001034 }
1035
Jose Galmes6f843bc2020-12-11 13:36:29 -08001036 if module.isSnapshotPrebuilt() {
1037 return
1038 }
1039 if image.skipSourceMutator(ctx) {
Inseob Kimde5744a2020-12-02 13:14:28 +09001040 return
1041 }
1042
Jose Galmes6f843bc2020-12-11 13:36:29 -08001043 var snapshotMap *snapshotMap = image.getSnapshotMap(module, ctx.Config())
1044 if snapshotMap == nil {
Inseob Kimde5744a2020-12-02 13:14:28 +09001045 return
1046 }
1047
1048 if _, ok := snapshotMap.get(ctx.ModuleName(), ctx.Arch().ArchType); !ok {
1049 // Corresponding snapshot doesn't exist
1050 return
1051 }
1052
1053 // Disables source modules if corresponding snapshot exists.
1054 if lib, ok := module.linker.(libraryInterface); ok && lib.buildStatic() && lib.buildShared() {
1055 // But do not disable because the shared variant depends on the static variant.
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001056 module.HideFromMake()
Inseob Kimde5744a2020-12-02 13:14:28 +09001057 module.Properties.HideFromMake = true
1058 } else {
1059 module.Disable()
1060 }
1061}