blob: 4524f24250344e3e3e4f4c8b7066e9ee9b0c9a57 [file] [log] [blame]
Inseob Kim8471cda2019-11-15 09:59:12 +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
16import (
17 "encoding/json"
18 "path/filepath"
19 "sort"
20 "strings"
Inseob Kimeec88e12020-01-22 11:11:29 +090021 "sync"
Inseob Kim8471cda2019-11-15 09:59:12 +090022
23 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
26)
27
Jose Galmesf7294582020-11-13 12:07:36 -080028// Defines the specifics of different images to which the snapshot process is
29// applicable, e.g., vendor, recovery, ramdisk.
30type image interface {
31 // Used to register callbacks with the build system.
32 init()
33
34 // Function that returns true if the module is included in this image.
35 // Using a function return instead of a value to prevent early
36 // evalution of a function that may be not be defined.
37 inImage(m *Module) func() bool
38
39 // Returns the value of the "available" property for a given module for
40 // and snapshot, e.g., "vendor_available", "recovery_available", etc.
41 // or nil if the property is not defined.
42 available(m *Module) *bool
43
44 // Returns true if a dir under source tree is an SoC-owned proprietary
45 // directory, such as device/, vendor/, etc.
46 //
47 // For a given snapshot (e.g., vendor, recovery, etc.) if
48 // isProprietaryPath(dir) returns true, then the module in dir will be
49 // built from sources.
50 isProprietaryPath(dir string) bool
51
52 // Whether to include VNDK in the snapshot for this image.
53 includeVndk() bool
54
55 // Whether a given module has been explicitly excluded from the
56 // snapshot, e.g., using the exclude_from_vendor_snapshot or
57 // exclude_from_recovery_snapshot properties.
58 excludeFromSnapshot(m *Module) bool
59}
60
61type vendorImage struct{}
62type recoveryImage struct{}
63
64func (vendorImage) init() {
65 android.RegisterSingletonType(
66 "vendor-snapshot", VendorSnapshotSingleton)
67 android.RegisterModuleType(
68 "vendor_snapshot_shared", VendorSnapshotSharedFactory)
69 android.RegisterModuleType(
70 "vendor_snapshot_static", VendorSnapshotStaticFactory)
71 android.RegisterModuleType(
72 "vendor_snapshot_header", VendorSnapshotHeaderFactory)
73 android.RegisterModuleType(
74 "vendor_snapshot_binary", VendorSnapshotBinaryFactory)
75 android.RegisterModuleType(
76 "vendor_snapshot_object", VendorSnapshotObjectFactory)
77}
78
79func (vendorImage) inImage(m *Module) func() bool {
80 return m.inVendor
81}
82
83func (vendorImage) available(m *Module) *bool {
84 return m.VendorProperties.Vendor_available
85}
86
87func (vendorImage) isProprietaryPath(dir string) bool {
88 return isVendorProprietaryPath(dir)
89}
90
91func (vendorImage) includeVndk() bool {
92 return true
93}
94
95func (vendorImage) excludeFromSnapshot(m *Module) bool {
96 return m.ExcludeFromVendorSnapshot()
97}
98
99func (recoveryImage) init() {
100 android.RegisterSingletonType(
101 "recovery-snapshot", RecoverySnapshotSingleton)
102 android.RegisterModuleType(
103 "recovery_snapshot_shared", RecoverySnapshotSharedFactory)
104 android.RegisterModuleType(
105 "recovery_snapshot_static", RecoverySnapshotStaticFactory)
106 android.RegisterModuleType(
107 "recovery_snapshot_header", RecoverySnapshotHeaderFactory)
108 android.RegisterModuleType(
109 "recovery_snapshot_binary", RecoverySnapshotBinaryFactory)
110 android.RegisterModuleType(
111 "recovery_snapshot_object", RecoverySnapshotObjectFactory)
112}
113
114func (recoveryImage) inImage(m *Module) func() bool {
115 return m.InRecovery
116}
117
118func (recoveryImage) available(m *Module) *bool {
119 return m.Properties.Recovery_available
120}
121
122func (recoveryImage) isProprietaryPath(dir string) bool {
123 return isRecoveryProprietaryPath(dir)
124}
125
126func (recoveryImage) includeVndk() bool {
127 return false
128}
129
130func (recoveryImage) excludeFromSnapshot(m *Module) bool {
131 return m.ExcludeFromRecoverySnapshot()
132}
133
134var vendorImageSingleton vendorImage
135var recoveryImageSingleton recoveryImage
136
Inseob Kimeec88e12020-01-22 11:11:29 +0900137const (
138 vendorSnapshotHeaderSuffix = ".vendor_header."
139 vendorSnapshotSharedSuffix = ".vendor_shared."
140 vendorSnapshotStaticSuffix = ".vendor_static."
141 vendorSnapshotBinarySuffix = ".vendor_binary."
Inseob Kim1042d292020-06-01 23:23:05 +0900142 vendorSnapshotObjectSuffix = ".vendor_object."
Inseob Kimeec88e12020-01-22 11:11:29 +0900143)
144
Jose Galmesf7294582020-11-13 12:07:36 -0800145const (
146 recoverySnapshotHeaderSuffix = ".recovery_header."
147 recoverySnapshotSharedSuffix = ".recovery_shared."
148 recoverySnapshotStaticSuffix = ".recovery_static."
149 recoverySnapshotBinarySuffix = ".recovery_binary."
150 recoverySnapshotObjectSuffix = ".recovery_object."
151)
152
Inseob Kimeec88e12020-01-22 11:11:29 +0900153var (
154 vendorSnapshotsLock sync.Mutex
155 vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules")
156 vendorSnapshotHeaderLibsKey = android.NewOnceKey("vendorSnapshotHeaderLibs")
157 vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs")
158 vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs")
159 vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries")
Inseob Kim1042d292020-06-01 23:23:05 +0900160 vendorSnapshotObjectsKey = android.NewOnceKey("vendorSnapshotObjects")
Inseob Kimeec88e12020-01-22 11:11:29 +0900161)
162
Inseob Kim5f64aec2020-02-18 17:27:19 +0900163// vendor snapshot maps hold names of vendor snapshot modules per arch
Inseob Kimeec88e12020-01-22 11:11:29 +0900164func vendorSuffixModules(config android.Config) map[string]bool {
165 return config.Once(vendorSuffixModulesKey, func() interface{} {
166 return make(map[string]bool)
167 }).(map[string]bool)
168}
169
170func vendorSnapshotHeaderLibs(config android.Config) *snapshotMap {
171 return config.Once(vendorSnapshotHeaderLibsKey, func() interface{} {
172 return newSnapshotMap()
173 }).(*snapshotMap)
174}
175
176func vendorSnapshotSharedLibs(config android.Config) *snapshotMap {
177 return config.Once(vendorSnapshotSharedLibsKey, func() interface{} {
178 return newSnapshotMap()
179 }).(*snapshotMap)
180}
181
182func vendorSnapshotStaticLibs(config android.Config) *snapshotMap {
183 return config.Once(vendorSnapshotStaticLibsKey, func() interface{} {
184 return newSnapshotMap()
185 }).(*snapshotMap)
186}
187
188func vendorSnapshotBinaries(config android.Config) *snapshotMap {
189 return config.Once(vendorSnapshotBinariesKey, func() interface{} {
190 return newSnapshotMap()
191 }).(*snapshotMap)
192}
193
Inseob Kim1042d292020-06-01 23:23:05 +0900194func vendorSnapshotObjects(config android.Config) *snapshotMap {
195 return config.Once(vendorSnapshotObjectsKey, func() interface{} {
196 return newSnapshotMap()
197 }).(*snapshotMap)
198}
199
Inseob Kim2d34ad92020-07-30 21:04:09 +0900200type vendorSnapshotBaseProperties struct {
Inseob Kimeec88e12020-01-22 11:11:29 +0900201 // snapshot version.
202 Version string
203
204 // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
205 Target_arch string
Inseob Kim2d34ad92020-07-30 21:04:09 +0900206}
Inseob Kimeec88e12020-01-22 11:11:29 +0900207
Inseob Kim2d34ad92020-07-30 21:04:09 +0900208// vendorSnapshotModuleBase provides common basic functions for all snapshot modules.
209type vendorSnapshotModuleBase struct {
210 baseProperties vendorSnapshotBaseProperties
211 moduleSuffix string
212}
213
214func (p *vendorSnapshotModuleBase) Name(name string) string {
215 return name + p.NameSuffix()
216}
217
218func (p *vendorSnapshotModuleBase) NameSuffix() string {
219 versionSuffix := p.version()
220 if p.arch() != "" {
221 versionSuffix += "." + p.arch()
222 }
223
224 return p.moduleSuffix + versionSuffix
225}
226
227func (p *vendorSnapshotModuleBase) version() string {
228 return p.baseProperties.Version
229}
230
231func (p *vendorSnapshotModuleBase) arch() string {
232 return p.baseProperties.Target_arch
233}
234
235func (p *vendorSnapshotModuleBase) isSnapshotPrebuilt() bool {
236 return true
237}
238
239// Call this after creating a snapshot module with module suffix
240// such as vendorSnapshotSharedSuffix
241func (p *vendorSnapshotModuleBase) init(m *Module, suffix string) {
242 p.moduleSuffix = suffix
243 m.AddProperties(&p.baseProperties)
244 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
245 vendorSnapshotLoadHook(ctx, p)
246 })
247}
248
249func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *vendorSnapshotModuleBase) {
250 if p.version() != ctx.DeviceConfig().VndkVersion() {
251 ctx.Module().Disable()
252 return
253 }
254}
255
Jose Galmesf7294582020-11-13 12:07:36 -0800256type snapshotLibraryProperties struct {
Inseob Kimeec88e12020-01-22 11:11:29 +0900257 // Prebuilt file for each arch.
258 Src *string `android:"arch_variant"`
259
Inseob Kimc42f2f22020-07-29 20:32:10 +0900260 // list of directories that will be added to the include path (using -I).
261 Export_include_dirs []string `android:"arch_variant"`
262
263 // list of directories that will be added to the system path (using -isystem).
264 Export_system_include_dirs []string `android:"arch_variant"`
265
Inseob Kimeec88e12020-01-22 11:11:29 +0900266 // list of flags that will be used for any module that links against this module.
267 Export_flags []string `android:"arch_variant"`
268
Inseob Kimeec88e12020-01-22 11:11:29 +0900269 // Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
270 Sanitize_ubsan_dep *bool `android:"arch_variant"`
271
272 // Whether this prebuilt needs to depend on sanitize minimal runtime or not.
273 Sanitize_minimal_dep *bool `android:"arch_variant"`
274}
275
Inseob Kimc42f2f22020-07-29 20:32:10 +0900276type snapshotSanitizer interface {
277 isSanitizerEnabled(t sanitizerType) bool
278 setSanitizerVariation(t sanitizerType, enabled bool)
279}
280
Jose Galmesf7294582020-11-13 12:07:36 -0800281type snapshotLibraryDecorator struct {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900282 vendorSnapshotModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +0900283 *libraryDecorator
Jose Galmesf7294582020-11-13 12:07:36 -0800284 properties snapshotLibraryProperties
Inseob Kimc42f2f22020-07-29 20:32:10 +0900285 sanitizerProperties struct {
286 CfiEnabled bool `blueprint:"mutated"`
287
288 // Library flags for cfi variant.
Jose Galmesf7294582020-11-13 12:07:36 -0800289 Cfi snapshotLibraryProperties `android:"arch_variant"`
Inseob Kimc42f2f22020-07-29 20:32:10 +0900290 }
Inseob Kimeec88e12020-01-22 11:11:29 +0900291 androidMkVendorSuffix bool
292}
293
Jose Galmesf7294582020-11-13 12:07:36 -0800294func (p *snapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
Inseob Kimeec88e12020-01-22 11:11:29 +0900295 p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
296 return p.libraryDecorator.linkerFlags(ctx, flags)
297}
298
Jose Galmesf7294582020-11-13 12:07:36 -0800299func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
Inseob Kimeec88e12020-01-22 11:11:29 +0900300 arches := config.Arches()
301 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
302 return false
303 }
304 if !p.header() && p.properties.Src == nil {
305 return false
306 }
307 return true
308}
309
Jose Galmesf7294582020-11-13 12:07:36 -0800310func (p *snapshotLibraryDecorator) link(ctx ModuleContext,
Inseob Kimeec88e12020-01-22 11:11:29 +0900311 flags Flags, deps PathDeps, objs Objects) android.Path {
312 m := ctx.Module().(*Module)
313 p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
314
315 if p.header() {
316 return p.libraryDecorator.link(ctx, flags, deps, objs)
317 }
318
Inseob Kimc42f2f22020-07-29 20:32:10 +0900319 if p.sanitizerProperties.CfiEnabled {
320 p.properties = p.sanitizerProperties.Cfi
321 }
322
Inseob Kimeec88e12020-01-22 11:11:29 +0900323 if !p.matchesWithDevice(ctx.DeviceConfig()) {
324 return nil
325 }
326
Inseob Kimc42f2f22020-07-29 20:32:10 +0900327 p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
328 p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
Inseob Kimeec88e12020-01-22 11:11:29 +0900329 p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
330
331 in := android.PathForModuleSrc(ctx, *p.properties.Src)
332 p.unstrippedOutputFile = in
333
334 if p.shared() {
335 libName := in.Base()
336 builderFlags := flagsToBuilderFlags(flags)
337
338 // Optimize out relinking against shared libraries whose interface hasn't changed by
339 // depending on a table of contents file instead of the library itself.
340 tocFile := android.PathForModuleOut(ctx, libName+".toc")
341 p.tocFile = android.OptionalPathForPath(tocFile)
342 TransformSharedObjectToToc(ctx, in, tocFile, builderFlags)
Colin Cross0de8a1e2020-09-18 14:15:30 -0700343
344 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
345 SharedLibrary: in,
346 UnstrippedSharedLibrary: p.unstrippedOutputFile,
347
348 TableOfContents: p.tocFile,
349 })
350 }
351
352 if p.static() {
353 depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
354 ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
355 StaticLibrary: in,
356
357 TransitiveStaticLibrariesForOrdering: depSet,
358 })
Inseob Kimeec88e12020-01-22 11:11:29 +0900359 }
360
Inseob Kim67be7322020-10-19 10:15:28 +0900361 p.libraryDecorator.flagExporter.setProvider(ctx)
362
Inseob Kimeec88e12020-01-22 11:11:29 +0900363 return in
364}
365
Jose Galmesf7294582020-11-13 12:07:36 -0800366func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
Inseob Kimeec88e12020-01-22 11:11:29 +0900367 if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
368 p.baseInstaller.install(ctx, file)
369 }
370}
371
Jose Galmesf7294582020-11-13 12:07:36 -0800372func (p *snapshotLibraryDecorator) nativeCoverage() bool {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900373 return false
Inseob Kimeec88e12020-01-22 11:11:29 +0900374}
375
Jose Galmesf7294582020-11-13 12:07:36 -0800376func (p *snapshotLibraryDecorator) isSanitizerEnabled(t sanitizerType) bool {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900377 switch t {
378 case cfi:
379 return p.sanitizerProperties.Cfi.Src != nil
380 default:
381 return false
382 }
383}
384
Jose Galmesf7294582020-11-13 12:07:36 -0800385func (p *snapshotLibraryDecorator) setSanitizerVariation(t sanitizerType, enabled bool) {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900386 if !enabled {
387 return
388 }
389 switch t {
390 case cfi:
391 p.sanitizerProperties.CfiEnabled = true
392 default:
393 return
394 }
395}
396
Jose Galmesf7294582020-11-13 12:07:36 -0800397func snapshotLibrary(suffix string) (*Module, *snapshotLibraryDecorator) {
Inseob Kimeec88e12020-01-22 11:11:29 +0900398 module, library := NewLibrary(android.DeviceSupported)
399
400 module.stl = nil
401 module.sanitize = nil
Thiébaud Weksteend4587452020-08-19 14:53:01 +0200402 library.disableStripping()
Inseob Kimeec88e12020-01-22 11:11:29 +0900403
Jose Galmesf7294582020-11-13 12:07:36 -0800404 prebuilt := &snapshotLibraryDecorator{
Inseob Kimeec88e12020-01-22 11:11:29 +0900405 libraryDecorator: library,
406 }
407
408 prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
409 prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
410
411 // Prevent default system libs (libc, libm, and libdl) from being linked
412 if prebuilt.baseLinker.Properties.System_shared_libs == nil {
413 prebuilt.baseLinker.Properties.System_shared_libs = []string{}
414 }
415
416 module.compiler = nil
417 module.linker = prebuilt
418 module.installer = prebuilt
419
Inseob Kim2d34ad92020-07-30 21:04:09 +0900420 prebuilt.init(module, suffix)
Inseob Kimc42f2f22020-07-29 20:32:10 +0900421 module.AddProperties(
422 &prebuilt.properties,
423 &prebuilt.sanitizerProperties,
424 )
Inseob Kimeec88e12020-01-22 11:11:29 +0900425
426 return module, prebuilt
427}
428
429func VendorSnapshotSharedFactory() android.Module {
Jose Galmesf7294582020-11-13 12:07:36 -0800430 module, prebuilt := snapshotLibrary(vendorSnapshotSharedSuffix)
431 prebuilt.libraryDecorator.BuildOnlyShared()
432 return module.Init()
433}
434
435func RecoverySnapshotSharedFactory() android.Module {
436 module, prebuilt := snapshotLibrary(recoverySnapshotSharedSuffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900437 prebuilt.libraryDecorator.BuildOnlyShared()
Inseob Kimeec88e12020-01-22 11:11:29 +0900438 return module.Init()
439}
440
441func VendorSnapshotStaticFactory() android.Module {
Jose Galmesf7294582020-11-13 12:07:36 -0800442 module, prebuilt := snapshotLibrary(vendorSnapshotStaticSuffix)
443 prebuilt.libraryDecorator.BuildOnlyStatic()
444 return module.Init()
445}
446
447func RecoverySnapshotStaticFactory() android.Module {
448 module, prebuilt := snapshotLibrary(recoverySnapshotStaticSuffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900449 prebuilt.libraryDecorator.BuildOnlyStatic()
Inseob Kimeec88e12020-01-22 11:11:29 +0900450 return module.Init()
451}
452
453func VendorSnapshotHeaderFactory() android.Module {
Jose Galmesf7294582020-11-13 12:07:36 -0800454 module, prebuilt := snapshotLibrary(vendorSnapshotHeaderSuffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900455 prebuilt.libraryDecorator.HeaderOnly()
Inseob Kimeec88e12020-01-22 11:11:29 +0900456 return module.Init()
457}
458
Jose Galmesf7294582020-11-13 12:07:36 -0800459func RecoverySnapshotHeaderFactory() android.Module {
460 module, prebuilt := snapshotLibrary(recoverySnapshotHeaderSuffix)
461 prebuilt.libraryDecorator.HeaderOnly()
462 return module.Init()
463}
Inseob Kimc42f2f22020-07-29 20:32:10 +0900464
Jose Galmesf7294582020-11-13 12:07:36 -0800465var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil)
466
467type snapshotBinaryProperties struct {
Inseob Kimeec88e12020-01-22 11:11:29 +0900468 // Prebuilt file for each arch.
469 Src *string `android:"arch_variant"`
470}
471
Jose Galmesf7294582020-11-13 12:07:36 -0800472type snapshotBinaryDecorator struct {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900473 vendorSnapshotModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +0900474 *binaryDecorator
Jose Galmesf7294582020-11-13 12:07:36 -0800475 properties snapshotBinaryProperties
Inseob Kimeec88e12020-01-22 11:11:29 +0900476 androidMkVendorSuffix bool
477}
478
Jose Galmesf7294582020-11-13 12:07:36 -0800479func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
Inseob Kimeec88e12020-01-22 11:11:29 +0900480 if config.DeviceArch() != p.arch() {
481 return false
482 }
483 if p.properties.Src == nil {
484 return false
485 }
486 return true
487}
488
Jose Galmesf7294582020-11-13 12:07:36 -0800489func (p *snapshotBinaryDecorator) link(ctx ModuleContext,
Inseob Kimeec88e12020-01-22 11:11:29 +0900490 flags Flags, deps PathDeps, objs Objects) android.Path {
491 if !p.matchesWithDevice(ctx.DeviceConfig()) {
492 return nil
493 }
494
495 in := android.PathForModuleSrc(ctx, *p.properties.Src)
Thiébaud Weksteend4587452020-08-19 14:53:01 +0200496 stripFlags := flagsToStripFlags(flags)
Inseob Kimeec88e12020-01-22 11:11:29 +0900497 p.unstrippedOutputFile = in
498 binName := in.Base()
Thiébaud Weksteend4587452020-08-19 14:53:01 +0200499 if p.stripper.NeedsStrip(ctx) {
Inseob Kimeec88e12020-01-22 11:11:29 +0900500 stripped := android.PathForModuleOut(ctx, "stripped", binName)
Thiébaud Weksteend4587452020-08-19 14:53:01 +0200501 p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
Inseob Kimeec88e12020-01-22 11:11:29 +0900502 in = stripped
503 }
504
505 m := ctx.Module().(*Module)
506 p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
507
508 // use cpExecutable to make it executable
509 outputFile := android.PathForModuleOut(ctx, binName)
510 ctx.Build(pctx, android.BuildParams{
511 Rule: android.CpExecutable,
512 Description: "prebuilt",
513 Output: outputFile,
514 Input: in,
515 })
516
517 return outputFile
518}
519
Jose Galmesf7294582020-11-13 12:07:36 -0800520func (p *snapshotBinaryDecorator) nativeCoverage() bool {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900521 return false
Inseob Kim1042d292020-06-01 23:23:05 +0900522}
523
Inseob Kimeec88e12020-01-22 11:11:29 +0900524func VendorSnapshotBinaryFactory() android.Module {
Jose Galmesf7294582020-11-13 12:07:36 -0800525 return snapshotBinaryFactory(vendorSnapshotBinarySuffix)
526}
527
528func RecoverySnapshotBinaryFactory() android.Module {
529 return snapshotBinaryFactory(recoverySnapshotBinarySuffix)
530}
531
532func snapshotBinaryFactory(suffix string) android.Module {
Inseob Kimeec88e12020-01-22 11:11:29 +0900533 module, binary := NewBinary(android.DeviceSupported)
534 binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
535 binary.baseLinker.Properties.Nocrt = BoolPtr(true)
536
537 // Prevent default system libs (libc, libm, and libdl) from being linked
538 if binary.baseLinker.Properties.System_shared_libs == nil {
539 binary.baseLinker.Properties.System_shared_libs = []string{}
540 }
541
Jose Galmesf7294582020-11-13 12:07:36 -0800542 prebuilt := &snapshotBinaryDecorator{
Inseob Kimeec88e12020-01-22 11:11:29 +0900543 binaryDecorator: binary,
544 }
545
546 module.compiler = nil
547 module.sanitize = nil
548 module.stl = nil
549 module.linker = prebuilt
550
Jose Galmesf7294582020-11-13 12:07:36 -0800551 prebuilt.init(module, suffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900552 module.AddProperties(&prebuilt.properties)
553 return module.Init()
554}
555
Inseob Kim1042d292020-06-01 23:23:05 +0900556type vendorSnapshotObjectProperties struct {
Inseob Kim1042d292020-06-01 23:23:05 +0900557 // Prebuilt file for each arch.
558 Src *string `android:"arch_variant"`
559}
560
Jose Galmesf7294582020-11-13 12:07:36 -0800561type snapshotObjectLinker struct {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900562 vendorSnapshotModuleBase
Inseob Kim1042d292020-06-01 23:23:05 +0900563 objectLinker
564 properties vendorSnapshotObjectProperties
565 androidMkVendorSuffix bool
566}
567
Jose Galmesf7294582020-11-13 12:07:36 -0800568func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
Inseob Kim1042d292020-06-01 23:23:05 +0900569 if config.DeviceArch() != p.arch() {
570 return false
571 }
572 if p.properties.Src == nil {
573 return false
574 }
575 return true
576}
577
Jose Galmesf7294582020-11-13 12:07:36 -0800578func (p *snapshotObjectLinker) link(ctx ModuleContext,
Inseob Kim1042d292020-06-01 23:23:05 +0900579 flags Flags, deps PathDeps, objs Objects) android.Path {
580 if !p.matchesWithDevice(ctx.DeviceConfig()) {
581 return nil
582 }
583
584 m := ctx.Module().(*Module)
585 p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
586
587 return android.PathForModuleSrc(ctx, *p.properties.Src)
588}
589
Jose Galmesf7294582020-11-13 12:07:36 -0800590func (p *snapshotObjectLinker) nativeCoverage() bool {
Inseob Kim1042d292020-06-01 23:23:05 +0900591 return false
592}
593
Inseob Kim1042d292020-06-01 23:23:05 +0900594func VendorSnapshotObjectFactory() android.Module {
595 module := newObject()
596
Jose Galmesf7294582020-11-13 12:07:36 -0800597 prebuilt := &snapshotObjectLinker{
Inseob Kim1042d292020-06-01 23:23:05 +0900598 objectLinker: objectLinker{
599 baseLinker: NewBaseLinker(nil),
600 },
601 }
602 module.linker = prebuilt
603
Inseob Kim2d34ad92020-07-30 21:04:09 +0900604 prebuilt.init(module, vendorSnapshotObjectSuffix)
Inseob Kim1042d292020-06-01 23:23:05 +0900605 module.AddProperties(&prebuilt.properties)
606 return module.Init()
607}
608
Jose Galmesf7294582020-11-13 12:07:36 -0800609func RecoverySnapshotObjectFactory() android.Module {
610 module := newObject()
611
612 prebuilt := &snapshotObjectLinker{
613 objectLinker: objectLinker{
614 baseLinker: NewBaseLinker(nil),
615 },
616 }
617 module.linker = prebuilt
618
619 prebuilt.init(module, recoverySnapshotObjectSuffix)
620 module.AddProperties(&prebuilt.properties)
621 return module.Init()
622}
623
Inseob Kim8471cda2019-11-15 09:59:12 +0900624func init() {
Jose Galmesf7294582020-11-13 12:07:36 -0800625 vendorImageSingleton.init()
626 recoveryImageSingleton.init()
627}
628
629var vendorSnapshotSingleton = snapshotSingleton{
630 "vendor",
631 "SOONG_VENDOR_SNAPSHOT_ZIP",
632 android.OptionalPath{},
633 true,
634 vendorImageSingleton,
635}
636
637var recoverySnapshotSingleton = snapshotSingleton{
638 "recovery",
639 "SOONG_RECOVERY_SNAPSHOT_ZIP",
640 android.OptionalPath{},
641 false,
642 recoveryImageSingleton,
Inseob Kim8471cda2019-11-15 09:59:12 +0900643}
644
645func VendorSnapshotSingleton() android.Singleton {
Jose Galmesf7294582020-11-13 12:07:36 -0800646 return &vendorSnapshotSingleton
Inseob Kim8471cda2019-11-15 09:59:12 +0900647}
648
Jose Galmesf7294582020-11-13 12:07:36 -0800649func RecoverySnapshotSingleton() android.Singleton {
650 return &recoverySnapshotSingleton
651}
652
653type snapshotSingleton struct {
654 // Name, e.g., "vendor", "recovery", "ramdisk".
655 name string
656
657 // Make variable that points to the snapshot file, e.g.,
658 // "SOONG_RECOVERY_SNAPSHOT_ZIP".
659 makeVar string
660
661 // Path to the snapshot zip file.
662 snapshotZipFile android.OptionalPath
663
664 // Whether the image supports VNDK extension modules.
665 supportsVndkExt bool
666
667 // Implementation of the image interface specific to the image
668 // associated with this snapshot (e.g., specific to the vendor image,
669 // recovery image, etc.).
670 image image
Inseob Kim8471cda2019-11-15 09:59:12 +0900671}
672
673var (
674 // Modules under following directories are ignored. They are OEM's and vendor's
Daniel Norman713387d2020-07-28 16:04:38 -0700675 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Inseob Kim8471cda2019-11-15 09:59:12 +0900676 // TODO(b/65377115): Clean up these with more maintainable way
677 vendorProprietaryDirs = []string{
678 "device",
Daniel Norman713387d2020-07-28 16:04:38 -0700679 "kernel",
Inseob Kim8471cda2019-11-15 09:59:12 +0900680 "vendor",
681 "hardware",
682 }
683
Jose Galmesf7294582020-11-13 12:07:36 -0800684 // Modules under following directories are ignored. They are OEM's and vendor's
685 // proprietary modules(device/, kernel/, vendor/, and hardware/).
686 // TODO(b/65377115): Clean up these with more maintainable way
687 recoveryProprietaryDirs = []string{
688 "bootable/recovery",
689 "device",
690 "hardware",
691 "kernel",
692 "vendor",
693 }
694
Inseob Kim8471cda2019-11-15 09:59:12 +0900695 // Modules under following directories are included as they are in AOSP,
Daniel Norman713387d2020-07-28 16:04:38 -0700696 // although hardware/ and kernel/ are normally for vendor's own.
Inseob Kim8471cda2019-11-15 09:59:12 +0900697 // TODO(b/65377115): Clean up these with more maintainable way
698 aospDirsUnderProprietary = []string{
Daniel Norman713387d2020-07-28 16:04:38 -0700699 "kernel/configs",
700 "kernel/prebuilts",
701 "kernel/tests",
Inseob Kim8471cda2019-11-15 09:59:12 +0900702 "hardware/interfaces",
703 "hardware/libhardware",
704 "hardware/libhardware_legacy",
705 "hardware/ril",
706 }
707)
708
709// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
710// device/, vendor/, etc.
711func isVendorProprietaryPath(dir string) bool {
Jose Galmesf7294582020-11-13 12:07:36 -0800712 return isProprietaryPath(dir, vendorProprietaryDirs)
713}
714
715func isRecoveryProprietaryPath(dir string) bool {
716 return isProprietaryPath(dir, recoveryProprietaryDirs)
717}
718
719// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
720// device/, vendor/, etc.
721func isProprietaryPath(dir string, proprietaryDirs []string) bool {
722 for _, p := range proprietaryDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900723 if strings.HasPrefix(dir, p) {
724 // filter out AOSP defined directories, e.g. hardware/interfaces/
725 aosp := false
726 for _, p := range aospDirsUnderProprietary {
727 if strings.HasPrefix(dir, p) {
728 aosp = true
729 break
730 }
731 }
732 if !aosp {
733 return true
734 }
735 }
736 }
737 return false
738}
739
Bill Peckham945441c2020-08-31 16:07:58 -0700740func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
741
742 // Any module in a vendor proprietary path is a vendor proprietary
743 // module.
744
745 if isVendorProprietaryPath(ctx.ModuleDir()) {
746 return true
747 }
748
749 // However if the module is not in a vendor proprietary path, it may
750 // still be a vendor proprietary module. This happens for cc modules
751 // that are excluded from the vendor snapshot, and it means that the
752 // vendor has assumed control of the framework-provided module.
753
754 if c, ok := ctx.Module().(*Module); ok {
755 if c.ExcludeFromVendorSnapshot() {
756 return true
757 }
758 }
759
760 return false
761}
762
Inseob Kim8471cda2019-11-15 09:59:12 +0900763// Determine if a module is going to be included in vendor snapshot or not.
764//
765// Targets of vendor snapshot are "vendor: true" or "vendor_available: true" modules in
766// AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might
767// depend on newer VNDK) So they are captured as vendor snapshot To build older vendor
768// image and newer system image altogether.
Colin Cross56a83212020-09-15 18:30:11 -0700769func isVendorSnapshotModule(m *Module, inVendorProprietaryPath bool, apexInfo android.ApexInfo) bool {
Jose Galmesf7294582020-11-13 12:07:36 -0800770 return isSnapshotModule(m, inVendorProprietaryPath, apexInfo, vendorImageSingleton)
771}
772
773func isRecoverySnapshotModule(m *Module, inRecoveryProprietaryPath bool, apexInfo android.ApexInfo) bool {
774 return isSnapshotModule(m, inRecoveryProprietaryPath, apexInfo, recoveryImageSingleton)
775}
776
777func isSnapshotModule(m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image image) bool {
Inseob Kim7f283f42020-06-01 21:53:49 +0900778 if !m.Enabled() || m.Properties.HideFromMake {
Inseob Kim8471cda2019-11-15 09:59:12 +0900779 return false
780 }
Martin Stjernholm809d5182020-09-10 01:46:05 +0100781 // When android/prebuilt.go selects between source and prebuilt, it sets
782 // SkipInstall on the other one to avoid duplicate install rules in make.
783 if m.IsSkipInstall() {
784 return false
785 }
Jose Galmesf7294582020-11-13 12:07:36 -0800786 // skip proprietary modules, but (for the vendor snapshot only)
787 // include all VNDK (static)
788 if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) {
Bill Peckham945441c2020-08-31 16:07:58 -0700789 return false
790 }
791 // If the module would be included based on its path, check to see if
792 // the module is marked to be excluded. If so, skip it.
793 if m.ExcludeFromVendorSnapshot() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900794 return false
795 }
796 if m.Target().Os.Class != android.Device {
797 return false
798 }
799 if m.Target().NativeBridge == android.NativeBridgeEnabled {
800 return false
801 }
802 // the module must be installed in /vendor
Jose Galmesf7294582020-11-13 12:07:36 -0800803 if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !image.inImage(m)() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900804 return false
805 }
Inseob Kim65ca36a2020-06-11 13:55:45 +0900806 // skip kernel_headers which always depend on vendor
807 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
808 return false
809 }
Justin Yunf2664c62020-07-30 18:57:54 +0900810 // skip llndk_library and llndk_headers which are backward compatible
811 if _, ok := m.linker.(*llndkStubDecorator); ok {
812 return false
813 }
814 if _, ok := m.linker.(*llndkHeadersDecorator); ok {
815 return false
816 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900817
818 // Libraries
819 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim7f283f42020-06-01 21:53:49 +0900820 // TODO(b/65377115): add full support for sanitizer
821 if m.sanitize != nil {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900822 // scs and hwasan export both sanitized and unsanitized variants for static and header
Inseob Kim7f283f42020-06-01 21:53:49 +0900823 // Always use unsanitized variants of them.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900824 for _, t := range []sanitizerType{scs, hwasan} {
Inseob Kim7f283f42020-06-01 21:53:49 +0900825 if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
826 return false
827 }
828 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900829 // cfi also exports both variants. But for static, we capture both.
830 if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
831 return false
832 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900833 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900834 if l.static() {
Jose Galmesf7294582020-11-13 12:07:36 -0800835 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900836 }
837 if l.shared() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700838 if !m.outputFile.Valid() {
839 return false
840 }
Jose Galmesf7294582020-11-13 12:07:36 -0800841 if image.includeVndk() {
842 if !m.IsVndk() {
843 return true
844 }
845 return m.isVndkExt()
Bill Peckham7d3f0962020-06-29 16:49:15 -0700846 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900847 }
848 return true
849 }
850
Inseob Kim1042d292020-06-01 23:23:05 +0900851 // Binaries and Objects
852 if m.binary() || m.object() {
Jose Galmesf7294582020-11-13 12:07:36 -0800853 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900854 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900855
856 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900857}
858
Jose Galmesf7294582020-11-13 12:07:36 -0800859func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900860 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a vendor snapshot.
861 if ctx.DeviceConfig().VndkVersion() != "current" {
862 return
863 }
864
865 var snapshotOutputs android.Paths
866
867 /*
868 Vendor snapshot zipped artifacts directory structure:
869 {SNAPSHOT_ARCH}/
870 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
871 shared/
872 (.so shared libraries)
873 static/
874 (.a static libraries)
875 header/
876 (header only libraries)
877 binary/
878 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900879 object/
880 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900881 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
882 shared/
883 (.so shared libraries)
884 static/
885 (.a static libraries)
886 header/
887 (header only libraries)
888 binary/
889 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900890 object/
891 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900892 NOTICE_FILES/
893 (notice files, e.g. libbase.txt)
894 configs/
895 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
896 include/
897 (header files of same directory structure with source tree)
898 */
899
Jose Galmesf7294582020-11-13 12:07:36 -0800900 snapshotDir := c.name + "-snapshot"
Inseob Kim8471cda2019-11-15 09:59:12 +0900901 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
902
903 includeDir := filepath.Join(snapshotArchDir, "include")
904 configsDir := filepath.Join(snapshotArchDir, "configs")
905 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
906
907 installedNotices := make(map[string]bool)
908 installedConfigs := make(map[string]bool)
909
910 var headers android.Paths
911
Inseob Kim8471cda2019-11-15 09:59:12 +0900912 installSnapshot := func(m *Module) android.Paths {
913 targetArch := "arch-" + m.Target().Arch.ArchType.String()
914 if m.Target().Arch.ArchVariant != "" {
915 targetArch += "-" + m.Target().Arch.ArchVariant
916 }
917
918 var ret android.Paths
919
920 prop := struct {
921 ModuleName string `json:",omitempty"`
922 RelativeInstallPath string `json:",omitempty"`
923
924 // library flags
925 ExportedDirs []string `json:",omitempty"`
926 ExportedSystemDirs []string `json:",omitempty"`
927 ExportedFlags []string `json:",omitempty"`
Inseob Kimc42f2f22020-07-29 20:32:10 +0900928 Sanitize string `json:",omitempty"`
Inseob Kim8471cda2019-11-15 09:59:12 +0900929 SanitizeMinimalDep bool `json:",omitempty"`
930 SanitizeUbsanDep bool `json:",omitempty"`
931
932 // binary flags
933 Symlinks []string `json:",omitempty"`
934
935 // dependencies
936 SharedLibs []string `json:",omitempty"`
937 RuntimeLibs []string `json:",omitempty"`
938 Required []string `json:",omitempty"`
939
940 // extra config files
941 InitRc []string `json:",omitempty"`
942 VintfFragments []string `json:",omitempty"`
943 }{}
944
945 // Common properties among snapshots.
946 prop.ModuleName = ctx.ModuleName(m)
Jose Galmesf7294582020-11-13 12:07:36 -0800947 if c.supportsVndkExt && m.isVndkExt() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700948 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
949 if m.isVndkSp() {
950 prop.RelativeInstallPath = "vndk-sp"
951 } else {
952 prop.RelativeInstallPath = "vndk"
953 }
954 } else {
955 prop.RelativeInstallPath = m.RelativeInstallPath()
956 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900957 prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
958 prop.Required = m.RequiredModuleNames()
959 for _, path := range m.InitRc() {
960 prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
961 }
962 for _, path := range m.VintfFragments() {
963 prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
964 }
965
966 // install config files. ignores any duplicates.
967 for _, path := range append(m.InitRc(), m.VintfFragments()...) {
968 out := filepath.Join(configsDir, path.Base())
969 if !installedConfigs[out] {
970 installedConfigs[out] = true
971 ret = append(ret, copyFile(ctx, path, out))
972 }
973 }
974
975 var propOut string
976
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900977 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Colin Cross0de8a1e2020-09-18 14:15:30 -0700978 exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
Inseob Kimc42f2f22020-07-29 20:32:10 +0900979
Inseob Kim8471cda2019-11-15 09:59:12 +0900980 // library flags
Colin Cross0de8a1e2020-09-18 14:15:30 -0700981 prop.ExportedFlags = exporterInfo.Flags
982 for _, dir := range exporterInfo.IncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900983 prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
984 }
Colin Cross0de8a1e2020-09-18 14:15:30 -0700985 for _, dir := range exporterInfo.SystemIncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900986 prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
987 }
988 // shared libs dependencies aren't meaningful on static or header libs
989 if l.shared() {
990 prop.SharedLibs = m.Properties.SnapshotSharedLibs
991 }
992 if l.static() && m.sanitize != nil {
993 prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
994 prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
995 }
996
997 var libType string
998 if l.static() {
999 libType = "static"
1000 } else if l.shared() {
1001 libType = "shared"
1002 } else {
1003 libType = "header"
1004 }
1005
1006 var stem string
1007
1008 // install .a or .so
1009 if libType != "header" {
1010 libPath := m.outputFile.Path()
1011 stem = libPath.Base()
Inseob Kimc42f2f22020-07-29 20:32:10 +09001012 if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(cfi) {
1013 // both cfi and non-cfi variant for static libraries can exist.
1014 // attach .cfi to distinguish between cfi and non-cfi.
1015 // e.g. libbase.a -> libbase.cfi.a
1016 ext := filepath.Ext(stem)
1017 stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
1018 prop.Sanitize = "cfi"
1019 prop.ModuleName += ".cfi"
1020 }
Inseob Kim8471cda2019-11-15 09:59:12 +09001021 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
1022 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
1023 } else {
1024 stem = ctx.ModuleName(m)
1025 }
1026
1027 propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
Inseob Kim7f283f42020-06-01 21:53:49 +09001028 } else if m.binary() {
Inseob Kim8471cda2019-11-15 09:59:12 +09001029 // binary flags
1030 prop.Symlinks = m.Symlinks()
1031 prop.SharedLibs = m.Properties.SnapshotSharedLibs
1032
1033 // install bin
1034 binPath := m.outputFile.Path()
1035 snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
1036 ret = append(ret, copyFile(ctx, binPath, snapshotBinOut))
1037 propOut = snapshotBinOut + ".json"
Inseob Kim1042d292020-06-01 23:23:05 +09001038 } else if m.object() {
1039 // object files aren't installed to the device, so their names can conflict.
1040 // Use module name as stem.
1041 objPath := m.outputFile.Path()
1042 snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
1043 ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
1044 ret = append(ret, copyFile(ctx, objPath, snapshotObjOut))
1045 propOut = snapshotObjOut + ".json"
Inseob Kim7f283f42020-06-01 21:53:49 +09001046 } else {
1047 ctx.Errorf("unknown module %q in vendor snapshot", m.String())
1048 return nil
Inseob Kim8471cda2019-11-15 09:59:12 +09001049 }
1050
1051 j, err := json.Marshal(prop)
1052 if err != nil {
1053 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
1054 return nil
1055 }
1056 ret = append(ret, writeStringToFile(ctx, string(j), propOut))
1057
1058 return ret
1059 }
1060
1061 ctx.VisitAllModules(func(module android.Module) {
1062 m, ok := module.(*Module)
Inseob Kimeda2e9c2020-03-03 22:06:32 +09001063 if !ok {
1064 return
1065 }
1066
1067 moduleDir := ctx.ModuleDir(module)
Jose Galmesf7294582020-11-13 12:07:36 -08001068 inProprietaryPath := c.image.isProprietaryPath(moduleDir)
Colin Cross56a83212020-09-15 18:30:11 -07001069 apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
Bill Peckham945441c2020-08-31 16:07:58 -07001070
1071 if m.ExcludeFromVendorSnapshot() {
Jose Galmesf7294582020-11-13 12:07:36 -08001072 if inProprietaryPath {
Bill Peckham945441c2020-08-31 16:07:58 -07001073 // Error: exclude_from_vendor_snapshot applies
1074 // to framework-path modules only.
1075 ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
1076 return
1077 }
Jose Galmesf7294582020-11-13 12:07:36 -08001078 if Bool(c.image.available(m)) {
Bill Peckham945441c2020-08-31 16:07:58 -07001079 // Error: may not combine "vendor_available:
1080 // true" with "exclude_from_vendor_snapshot:
1081 // true".
Jose Galmesf7294582020-11-13 12:07:36 -08001082 ctx.Errorf(
1083 "module %q may not use both \""+
1084 c.name+
1085 "_available: true\" and \"exclude_from_vendor_snapshot: true\"",
1086 m.String())
Bill Peckham945441c2020-08-31 16:07:58 -07001087 return
1088 }
1089 }
1090
Jose Galmesf7294582020-11-13 12:07:36 -08001091 if !isSnapshotModule(m, inProprietaryPath, apexInfo, c.image) {
Inseob Kim8471cda2019-11-15 09:59:12 +09001092 return
1093 }
1094
1095 snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
Inseob Kimeda2e9c2020-03-03 22:06:32 +09001096 if l, ok := m.linker.(snapshotLibraryInterface); ok {
1097 headers = append(headers, l.snapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +09001098 }
1099
Bob Badoura75b0572020-02-18 20:21:55 -08001100 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +09001101 noticeName := ctx.ModuleName(m) + ".txt"
1102 noticeOut := filepath.Join(noticeDir, noticeName)
1103 // skip already copied notice file
1104 if !installedNotices[noticeOut] {
1105 installedNotices[noticeOut] = true
Bob Badoura75b0572020-02-18 20:21:55 -08001106 snapshotOutputs = append(snapshotOutputs, combineNotices(
1107 ctx, m.NoticeFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +09001108 }
1109 }
1110 })
1111
1112 // install all headers after removing duplicates
1113 for _, header := range android.FirstUniquePaths(headers) {
1114 snapshotOutputs = append(snapshotOutputs, copyFile(
1115 ctx, header, filepath.Join(includeDir, header.String())))
1116 }
1117
1118 // All artifacts are ready. Sort them to normalize ninja and then zip.
1119 sort.Slice(snapshotOutputs, func(i, j int) bool {
1120 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
1121 })
1122
Jose Galmesf7294582020-11-13 12:07:36 -08001123 zipPath := android.PathForOutput(
1124 ctx,
1125 snapshotDir,
1126 c.name+"-"+ctx.Config().DeviceName()+".zip")
Colin Crossf1a035e2020-11-16 17:32:30 -08001127 zipRule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim8471cda2019-11-15 09:59:12 +09001128
1129 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
Jose Galmesf7294582020-11-13 12:07:36 -08001130 snapshotOutputList := android.PathForOutput(
1131 ctx,
1132 snapshotDir,
1133 c.name+"-"+ctx.Config().DeviceName()+"_list")
Inseob Kim8471cda2019-11-15 09:59:12 +09001134 zipRule.Command().
1135 Text("tr").
1136 FlagWithArg("-d ", "\\'").
1137 FlagWithRspFileInputList("< ", snapshotOutputs).
1138 FlagWithOutput("> ", snapshotOutputList)
1139
1140 zipRule.Temporary(snapshotOutputList)
1141
1142 zipRule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -08001143 BuiltTool("soong_zip").
Inseob Kim8471cda2019-11-15 09:59:12 +09001144 FlagWithOutput("-o ", zipPath).
1145 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
1146 FlagWithInput("-l ", snapshotOutputList)
1147
Colin Crossf1a035e2020-11-16 17:32:30 -08001148 zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +09001149 zipRule.DeleteTemporaryFiles()
Jose Galmesf7294582020-11-13 12:07:36 -08001150 c.snapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim8471cda2019-11-15 09:59:12 +09001151}
1152
Jose Galmesf7294582020-11-13 12:07:36 -08001153func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
1154 ctx.Strict(
1155 c.makeVar,
1156 c.snapshotZipFile.String())
Inseob Kim8471cda2019-11-15 09:59:12 +09001157}
Inseob Kimeec88e12020-01-22 11:11:29 +09001158
1159type snapshotInterface interface {
1160 matchesWithDevice(config android.DeviceConfig) bool
1161}
1162
1163var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
Jose Galmesf7294582020-11-13 12:07:36 -08001164var _ snapshotInterface = (*snapshotLibraryDecorator)(nil)
1165var _ snapshotInterface = (*snapshotBinaryDecorator)(nil)
1166var _ snapshotInterface = (*snapshotObjectLinker)(nil)
Inseob Kimeec88e12020-01-22 11:11:29 +09001167
1168// gathers all snapshot modules for vendor, and disable unnecessary snapshots
1169// TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules
1170func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) {
1171 vndkVersion := ctx.DeviceConfig().VndkVersion()
1172 // don't need snapshot if current
1173 if vndkVersion == "current" || vndkVersion == "" {
1174 return
1175 }
1176
1177 module, ok := ctx.Module().(*Module)
1178 if !ok || !module.Enabled() || module.VndkVersion() != vndkVersion {
1179 return
1180 }
1181
Inseob Kim1042d292020-06-01 23:23:05 +09001182 if !module.isSnapshotPrebuilt() {
Inseob Kimeec88e12020-01-22 11:11:29 +09001183 return
1184 }
1185
Inseob Kim1042d292020-06-01 23:23:05 +09001186 // isSnapshotPrebuilt ensures snapshotInterface
1187 if !module.linker.(snapshotInterface).matchesWithDevice(ctx.DeviceConfig()) {
Inseob Kimeec88e12020-01-22 11:11:29 +09001188 // Disable unnecessary snapshot module, but do not disable
1189 // vndk_prebuilt_shared because they might be packed into vndk APEX
1190 if !module.IsVndk() {
1191 module.Disable()
1192 }
1193 return
1194 }
1195
1196 var snapshotMap *snapshotMap
1197
1198 if lib, ok := module.linker.(libraryInterface); ok {
1199 if lib.static() {
1200 snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
1201 } else if lib.shared() {
1202 snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
1203 } else {
1204 // header
1205 snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
1206 }
Jose Galmesf7294582020-11-13 12:07:36 -08001207 } else if _, ok := module.linker.(*snapshotBinaryDecorator); ok {
Inseob Kimeec88e12020-01-22 11:11:29 +09001208 snapshotMap = vendorSnapshotBinaries(ctx.Config())
Jose Galmesf7294582020-11-13 12:07:36 -08001209 } else if _, ok := module.linker.(*snapshotObjectLinker); ok {
Inseob Kim1042d292020-06-01 23:23:05 +09001210 snapshotMap = vendorSnapshotObjects(ctx.Config())
Inseob Kimeec88e12020-01-22 11:11:29 +09001211 } else {
1212 return
1213 }
1214
1215 vendorSnapshotsLock.Lock()
1216 defer vendorSnapshotsLock.Unlock()
1217 snapshotMap.add(module.BaseModuleName(), ctx.Arch().ArchType, ctx.ModuleName())
1218}
1219
1220// Disables source modules which have snapshots
1221func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
Inseob Kim5f64aec2020-02-18 17:27:19 +09001222 if !ctx.Device() {
1223 return
1224 }
1225
Inseob Kimeec88e12020-01-22 11:11:29 +09001226 vndkVersion := ctx.DeviceConfig().VndkVersion()
1227 // don't need snapshot if current
1228 if vndkVersion == "current" || vndkVersion == "" {
1229 return
1230 }
1231
1232 module, ok := ctx.Module().(*Module)
1233 if !ok {
1234 return
1235 }
1236
Inseob Kim5f64aec2020-02-18 17:27:19 +09001237 // vendor suffix should be added to snapshots if the source module isn't vendor: true.
1238 if !module.SocSpecific() {
1239 // But we can't just check SocSpecific() since we already passed the image mutator.
1240 // Check ramdisk and recovery to see if we are real "vendor: true" module.
1241 ramdisk_available := module.InRamdisk() && !module.OnlyInRamdisk()
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001242 vendor_ramdisk_available := module.InVendorRamdisk() && !module.OnlyInVendorRamdisk()
Inseob Kim5f64aec2020-02-18 17:27:19 +09001243 recovery_available := module.InRecovery() && !module.OnlyInRecovery()
Inseob Kimeec88e12020-01-22 11:11:29 +09001244
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001245 if !ramdisk_available && !recovery_available && !vendor_ramdisk_available {
Inseob Kim5f64aec2020-02-18 17:27:19 +09001246 vendorSnapshotsLock.Lock()
1247 defer vendorSnapshotsLock.Unlock()
1248
1249 vendorSuffixModules(ctx.Config())[ctx.ModuleName()] = true
1250 }
Inseob Kimeec88e12020-01-22 11:11:29 +09001251 }
1252
1253 if module.isSnapshotPrebuilt() || module.VndkVersion() != ctx.DeviceConfig().VndkVersion() {
1254 // only non-snapshot modules with BOARD_VNDK_VERSION
1255 return
1256 }
1257
Inseob Kim206665c2020-06-02 23:48:32 +09001258 // .. and also filter out llndk library
1259 if module.isLlndk(ctx.Config()) {
1260 return
1261 }
1262
Inseob Kimeec88e12020-01-22 11:11:29 +09001263 var snapshotMap *snapshotMap
1264
1265 if lib, ok := module.linker.(libraryInterface); ok {
1266 if lib.static() {
1267 snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
1268 } else if lib.shared() {
1269 snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
1270 } else {
1271 // header
1272 snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
1273 }
Inseob Kim7f283f42020-06-01 21:53:49 +09001274 } else if module.binary() {
Inseob Kimeec88e12020-01-22 11:11:29 +09001275 snapshotMap = vendorSnapshotBinaries(ctx.Config())
Inseob Kim1042d292020-06-01 23:23:05 +09001276 } else if module.object() {
1277 snapshotMap = vendorSnapshotObjects(ctx.Config())
Inseob Kimeec88e12020-01-22 11:11:29 +09001278 } else {
1279 return
1280 }
1281
1282 if _, ok := snapshotMap.get(ctx.ModuleName(), ctx.Arch().ArchType); !ok {
1283 // Corresponding snapshot doesn't exist
1284 return
1285 }
1286
1287 // Disables source modules if corresponding snapshot exists.
1288 if lib, ok := module.linker.(libraryInterface); ok && lib.buildStatic() && lib.buildShared() {
1289 // But do not disable because the shared variant depends on the static variant.
1290 module.SkipInstall()
1291 module.Properties.HideFromMake = true
1292 } else {
1293 module.Disable()
1294 }
1295}