blob: ba35a5b7b1eec9193938f86eeaa7db9cd4ce755d [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
Inseob Kimeec88e12020-01-22 11:11:29 +090028const (
29 vendorSnapshotHeaderSuffix = ".vendor_header."
30 vendorSnapshotSharedSuffix = ".vendor_shared."
31 vendorSnapshotStaticSuffix = ".vendor_static."
32 vendorSnapshotBinarySuffix = ".vendor_binary."
Inseob Kim1042d292020-06-01 23:23:05 +090033 vendorSnapshotObjectSuffix = ".vendor_object."
Inseob Kimeec88e12020-01-22 11:11:29 +090034)
35
36var (
37 vendorSnapshotsLock sync.Mutex
38 vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules")
39 vendorSnapshotHeaderLibsKey = android.NewOnceKey("vendorSnapshotHeaderLibs")
40 vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs")
41 vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs")
42 vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries")
Inseob Kim1042d292020-06-01 23:23:05 +090043 vendorSnapshotObjectsKey = android.NewOnceKey("vendorSnapshotObjects")
Inseob Kimeec88e12020-01-22 11:11:29 +090044)
45
Inseob Kim5f64aec2020-02-18 17:27:19 +090046// vendor snapshot maps hold names of vendor snapshot modules per arch
Inseob Kimeec88e12020-01-22 11:11:29 +090047func vendorSuffixModules(config android.Config) map[string]bool {
48 return config.Once(vendorSuffixModulesKey, func() interface{} {
49 return make(map[string]bool)
50 }).(map[string]bool)
51}
52
53func vendorSnapshotHeaderLibs(config android.Config) *snapshotMap {
54 return config.Once(vendorSnapshotHeaderLibsKey, func() interface{} {
55 return newSnapshotMap()
56 }).(*snapshotMap)
57}
58
59func vendorSnapshotSharedLibs(config android.Config) *snapshotMap {
60 return config.Once(vendorSnapshotSharedLibsKey, func() interface{} {
61 return newSnapshotMap()
62 }).(*snapshotMap)
63}
64
65func vendorSnapshotStaticLibs(config android.Config) *snapshotMap {
66 return config.Once(vendorSnapshotStaticLibsKey, func() interface{} {
67 return newSnapshotMap()
68 }).(*snapshotMap)
69}
70
71func vendorSnapshotBinaries(config android.Config) *snapshotMap {
72 return config.Once(vendorSnapshotBinariesKey, func() interface{} {
73 return newSnapshotMap()
74 }).(*snapshotMap)
75}
76
Inseob Kim1042d292020-06-01 23:23:05 +090077func vendorSnapshotObjects(config android.Config) *snapshotMap {
78 return config.Once(vendorSnapshotObjectsKey, func() interface{} {
79 return newSnapshotMap()
80 }).(*snapshotMap)
81}
82
Inseob Kim2d34ad92020-07-30 21:04:09 +090083type vendorSnapshotBaseProperties struct {
Inseob Kimeec88e12020-01-22 11:11:29 +090084 // snapshot version.
85 Version string
86
87 // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
88 Target_arch string
Inseob Kim2d34ad92020-07-30 21:04:09 +090089}
Inseob Kimeec88e12020-01-22 11:11:29 +090090
Inseob Kim2d34ad92020-07-30 21:04:09 +090091// vendorSnapshotModuleBase provides common basic functions for all snapshot modules.
92type vendorSnapshotModuleBase struct {
93 baseProperties vendorSnapshotBaseProperties
94 moduleSuffix string
95}
96
97func (p *vendorSnapshotModuleBase) Name(name string) string {
98 return name + p.NameSuffix()
99}
100
101func (p *vendorSnapshotModuleBase) NameSuffix() string {
102 versionSuffix := p.version()
103 if p.arch() != "" {
104 versionSuffix += "." + p.arch()
105 }
106
107 return p.moduleSuffix + versionSuffix
108}
109
110func (p *vendorSnapshotModuleBase) version() string {
111 return p.baseProperties.Version
112}
113
114func (p *vendorSnapshotModuleBase) arch() string {
115 return p.baseProperties.Target_arch
116}
117
118func (p *vendorSnapshotModuleBase) isSnapshotPrebuilt() bool {
119 return true
120}
121
122// Call this after creating a snapshot module with module suffix
123// such as vendorSnapshotSharedSuffix
124func (p *vendorSnapshotModuleBase) init(m *Module, suffix string) {
125 p.moduleSuffix = suffix
126 m.AddProperties(&p.baseProperties)
127 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
128 vendorSnapshotLoadHook(ctx, p)
129 })
130}
131
132func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *vendorSnapshotModuleBase) {
133 if p.version() != ctx.DeviceConfig().VndkVersion() {
134 ctx.Module().Disable()
135 return
136 }
137}
138
139type vendorSnapshotLibraryProperties struct {
Inseob Kimeec88e12020-01-22 11:11:29 +0900140 // Prebuilt file for each arch.
141 Src *string `android:"arch_variant"`
142
143 // list of flags that will be used for any module that links against this module.
144 Export_flags []string `android:"arch_variant"`
145
146 // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
147 // etc).
148 Check_elf_files *bool
149
150 // Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
151 Sanitize_ubsan_dep *bool `android:"arch_variant"`
152
153 // Whether this prebuilt needs to depend on sanitize minimal runtime or not.
154 Sanitize_minimal_dep *bool `android:"arch_variant"`
155}
156
157type vendorSnapshotLibraryDecorator struct {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900158 vendorSnapshotModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +0900159 *libraryDecorator
160 properties vendorSnapshotLibraryProperties
161 androidMkVendorSuffix bool
162}
163
Inseob Kimeec88e12020-01-22 11:11:29 +0900164func (p *vendorSnapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
165 p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
166 return p.libraryDecorator.linkerFlags(ctx, flags)
167}
168
169func (p *vendorSnapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
170 arches := config.Arches()
171 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
172 return false
173 }
174 if !p.header() && p.properties.Src == nil {
175 return false
176 }
177 return true
178}
179
180func (p *vendorSnapshotLibraryDecorator) link(ctx ModuleContext,
181 flags Flags, deps PathDeps, objs Objects) android.Path {
182 m := ctx.Module().(*Module)
183 p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
184
185 if p.header() {
186 return p.libraryDecorator.link(ctx, flags, deps, objs)
187 }
188
189 if !p.matchesWithDevice(ctx.DeviceConfig()) {
190 return nil
191 }
192
193 p.libraryDecorator.exportIncludes(ctx)
194 p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
195
196 in := android.PathForModuleSrc(ctx, *p.properties.Src)
197 p.unstrippedOutputFile = in
198
199 if p.shared() {
200 libName := in.Base()
201 builderFlags := flagsToBuilderFlags(flags)
202
203 // Optimize out relinking against shared libraries whose interface hasn't changed by
204 // depending on a table of contents file instead of the library itself.
205 tocFile := android.PathForModuleOut(ctx, libName+".toc")
206 p.tocFile = android.OptionalPathForPath(tocFile)
207 TransformSharedObjectToToc(ctx, in, tocFile, builderFlags)
208 }
209
210 return in
211}
212
Inseob Kimeec88e12020-01-22 11:11:29 +0900213func (p *vendorSnapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
214 if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
215 p.baseInstaller.install(ctx, file)
216 }
217}
218
Inseob Kim2d34ad92020-07-30 21:04:09 +0900219func (p *vendorSnapshotLibraryDecorator) nativeCoverage() bool {
220 return false
Inseob Kimeec88e12020-01-22 11:11:29 +0900221}
222
Inseob Kim2d34ad92020-07-30 21:04:09 +0900223func vendorSnapshotLibrary(suffix string) (*Module, *vendorSnapshotLibraryDecorator) {
Inseob Kimeec88e12020-01-22 11:11:29 +0900224 module, library := NewLibrary(android.DeviceSupported)
225
226 module.stl = nil
227 module.sanitize = nil
228 library.StripProperties.Strip.None = BoolPtr(true)
229
230 prebuilt := &vendorSnapshotLibraryDecorator{
231 libraryDecorator: library,
232 }
233
234 prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
235 prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
236
237 // Prevent default system libs (libc, libm, and libdl) from being linked
238 if prebuilt.baseLinker.Properties.System_shared_libs == nil {
239 prebuilt.baseLinker.Properties.System_shared_libs = []string{}
240 }
241
242 module.compiler = nil
243 module.linker = prebuilt
244 module.installer = prebuilt
245
Inseob Kim2d34ad92020-07-30 21:04:09 +0900246 prebuilt.init(module, suffix)
247 module.AddProperties(&prebuilt.properties)
Inseob Kimeec88e12020-01-22 11:11:29 +0900248
249 return module, prebuilt
250}
251
252func VendorSnapshotSharedFactory() android.Module {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900253 module, prebuilt := vendorSnapshotLibrary(vendorSnapshotSharedSuffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900254 prebuilt.libraryDecorator.BuildOnlyShared()
Inseob Kimeec88e12020-01-22 11:11:29 +0900255 return module.Init()
256}
257
258func VendorSnapshotStaticFactory() android.Module {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900259 module, prebuilt := vendorSnapshotLibrary(vendorSnapshotStaticSuffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900260 prebuilt.libraryDecorator.BuildOnlyStatic()
Inseob Kimeec88e12020-01-22 11:11:29 +0900261 return module.Init()
262}
263
264func VendorSnapshotHeaderFactory() android.Module {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900265 module, prebuilt := vendorSnapshotLibrary(vendorSnapshotHeaderSuffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900266 prebuilt.libraryDecorator.HeaderOnly()
Inseob Kimeec88e12020-01-22 11:11:29 +0900267 return module.Init()
268}
269
270type vendorSnapshotBinaryProperties struct {
Inseob Kimeec88e12020-01-22 11:11:29 +0900271 // Prebuilt file for each arch.
272 Src *string `android:"arch_variant"`
273}
274
275type vendorSnapshotBinaryDecorator struct {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900276 vendorSnapshotModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +0900277 *binaryDecorator
278 properties vendorSnapshotBinaryProperties
279 androidMkVendorSuffix bool
280}
281
Inseob Kimeec88e12020-01-22 11:11:29 +0900282func (p *vendorSnapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
283 if config.DeviceArch() != p.arch() {
284 return false
285 }
286 if p.properties.Src == nil {
287 return false
288 }
289 return true
290}
291
292func (p *vendorSnapshotBinaryDecorator) link(ctx ModuleContext,
293 flags Flags, deps PathDeps, objs Objects) android.Path {
294 if !p.matchesWithDevice(ctx.DeviceConfig()) {
295 return nil
296 }
297
298 in := android.PathForModuleSrc(ctx, *p.properties.Src)
299 builderFlags := flagsToBuilderFlags(flags)
300 p.unstrippedOutputFile = in
301 binName := in.Base()
302 if p.needsStrip(ctx) {
303 stripped := android.PathForModuleOut(ctx, "stripped", binName)
304 p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
305 in = stripped
306 }
307
308 m := ctx.Module().(*Module)
309 p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
310
311 // use cpExecutable to make it executable
312 outputFile := android.PathForModuleOut(ctx, binName)
313 ctx.Build(pctx, android.BuildParams{
314 Rule: android.CpExecutable,
315 Description: "prebuilt",
316 Output: outputFile,
317 Input: in,
318 })
319
320 return outputFile
321}
322
Inseob Kim2d34ad92020-07-30 21:04:09 +0900323func (p *vendorSnapshotBinaryDecorator) nativeCoverage() bool {
324 return false
Inseob Kim1042d292020-06-01 23:23:05 +0900325}
326
Inseob Kimeec88e12020-01-22 11:11:29 +0900327func VendorSnapshotBinaryFactory() android.Module {
328 module, binary := NewBinary(android.DeviceSupported)
329 binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
330 binary.baseLinker.Properties.Nocrt = BoolPtr(true)
331
332 // Prevent default system libs (libc, libm, and libdl) from being linked
333 if binary.baseLinker.Properties.System_shared_libs == nil {
334 binary.baseLinker.Properties.System_shared_libs = []string{}
335 }
336
337 prebuilt := &vendorSnapshotBinaryDecorator{
338 binaryDecorator: binary,
339 }
340
341 module.compiler = nil
342 module.sanitize = nil
343 module.stl = nil
344 module.linker = prebuilt
345
Inseob Kim2d34ad92020-07-30 21:04:09 +0900346 prebuilt.init(module, vendorSnapshotBinarySuffix)
Inseob Kimeec88e12020-01-22 11:11:29 +0900347 module.AddProperties(&prebuilt.properties)
348 return module.Init()
349}
350
Inseob Kim1042d292020-06-01 23:23:05 +0900351type vendorSnapshotObjectProperties struct {
Inseob Kim1042d292020-06-01 23:23:05 +0900352 // Prebuilt file for each arch.
353 Src *string `android:"arch_variant"`
354}
355
356type vendorSnapshotObjectLinker struct {
Inseob Kim2d34ad92020-07-30 21:04:09 +0900357 vendorSnapshotModuleBase
Inseob Kim1042d292020-06-01 23:23:05 +0900358 objectLinker
359 properties vendorSnapshotObjectProperties
360 androidMkVendorSuffix bool
361}
362
Inseob Kim1042d292020-06-01 23:23:05 +0900363func (p *vendorSnapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
364 if config.DeviceArch() != p.arch() {
365 return false
366 }
367 if p.properties.Src == nil {
368 return false
369 }
370 return true
371}
372
373func (p *vendorSnapshotObjectLinker) link(ctx ModuleContext,
374 flags Flags, deps PathDeps, objs Objects) android.Path {
375 if !p.matchesWithDevice(ctx.DeviceConfig()) {
376 return nil
377 }
378
379 m := ctx.Module().(*Module)
380 p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
381
382 return android.PathForModuleSrc(ctx, *p.properties.Src)
383}
384
385func (p *vendorSnapshotObjectLinker) nativeCoverage() bool {
386 return false
387}
388
Inseob Kim1042d292020-06-01 23:23:05 +0900389func VendorSnapshotObjectFactory() android.Module {
390 module := newObject()
391
392 prebuilt := &vendorSnapshotObjectLinker{
393 objectLinker: objectLinker{
394 baseLinker: NewBaseLinker(nil),
395 },
396 }
397 module.linker = prebuilt
398
Inseob Kim2d34ad92020-07-30 21:04:09 +0900399 prebuilt.init(module, vendorSnapshotObjectSuffix)
Inseob Kim1042d292020-06-01 23:23:05 +0900400 module.AddProperties(&prebuilt.properties)
401 return module.Init()
402}
403
Inseob Kim8471cda2019-11-15 09:59:12 +0900404func init() {
405 android.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
Inseob Kimeec88e12020-01-22 11:11:29 +0900406 android.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
407 android.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
408 android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
409 android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
Inseob Kim1042d292020-06-01 23:23:05 +0900410 android.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory)
Inseob Kim8471cda2019-11-15 09:59:12 +0900411}
412
413func VendorSnapshotSingleton() android.Singleton {
414 return &vendorSnapshotSingleton{}
415}
416
417type vendorSnapshotSingleton struct {
418 vendorSnapshotZipFile android.OptionalPath
419}
420
421var (
422 // Modules under following directories are ignored. They are OEM's and vendor's
Daniel Norman713387d2020-07-28 16:04:38 -0700423 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Inseob Kim8471cda2019-11-15 09:59:12 +0900424 // TODO(b/65377115): Clean up these with more maintainable way
425 vendorProprietaryDirs = []string{
426 "device",
Daniel Norman713387d2020-07-28 16:04:38 -0700427 "kernel",
Inseob Kim8471cda2019-11-15 09:59:12 +0900428 "vendor",
429 "hardware",
430 }
431
432 // Modules under following directories are included as they are in AOSP,
Daniel Norman713387d2020-07-28 16:04:38 -0700433 // although hardware/ and kernel/ are normally for vendor's own.
Inseob Kim8471cda2019-11-15 09:59:12 +0900434 // TODO(b/65377115): Clean up these with more maintainable way
435 aospDirsUnderProprietary = []string{
Daniel Norman713387d2020-07-28 16:04:38 -0700436 "kernel/configs",
437 "kernel/prebuilts",
438 "kernel/tests",
Inseob Kim8471cda2019-11-15 09:59:12 +0900439 "hardware/interfaces",
440 "hardware/libhardware",
441 "hardware/libhardware_legacy",
442 "hardware/ril",
443 }
444)
445
446// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
447// device/, vendor/, etc.
448func isVendorProprietaryPath(dir string) bool {
449 for _, p := range vendorProprietaryDirs {
450 if strings.HasPrefix(dir, p) {
451 // filter out AOSP defined directories, e.g. hardware/interfaces/
452 aosp := false
453 for _, p := range aospDirsUnderProprietary {
454 if strings.HasPrefix(dir, p) {
455 aosp = true
456 break
457 }
458 }
459 if !aosp {
460 return true
461 }
462 }
463 }
464 return false
465}
466
467// Determine if a module is going to be included in vendor snapshot or not.
468//
469// Targets of vendor snapshot are "vendor: true" or "vendor_available: true" modules in
470// AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might
471// depend on newer VNDK) So they are captured as vendor snapshot To build older vendor
472// image and newer system image altogether.
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900473func isVendorSnapshotModule(m *Module, moduleDir string) bool {
Inseob Kim7f283f42020-06-01 21:53:49 +0900474 if !m.Enabled() || m.Properties.HideFromMake {
Inseob Kim8471cda2019-11-15 09:59:12 +0900475 return false
476 }
477 // skip proprietary modules, but include all VNDK (static)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900478 if isVendorProprietaryPath(moduleDir) && !m.IsVndk() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900479 return false
480 }
481 if m.Target().Os.Class != android.Device {
482 return false
483 }
484 if m.Target().NativeBridge == android.NativeBridgeEnabled {
485 return false
486 }
487 // the module must be installed in /vendor
Inseob Kim7f283f42020-06-01 21:53:49 +0900488 if !m.IsForPlatform() || m.isSnapshotPrebuilt() || !m.inVendor() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900489 return false
490 }
Inseob Kim65ca36a2020-06-11 13:55:45 +0900491 // skip kernel_headers which always depend on vendor
492 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
493 return false
494 }
Justin Yunf2664c62020-07-30 18:57:54 +0900495 // skip llndk_library and llndk_headers which are backward compatible
496 if _, ok := m.linker.(*llndkStubDecorator); ok {
497 return false
498 }
499 if _, ok := m.linker.(*llndkHeadersDecorator); ok {
500 return false
501 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900502
503 // Libraries
504 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim7f283f42020-06-01 21:53:49 +0900505 // TODO(b/65377115): add full support for sanitizer
506 if m.sanitize != nil {
507 // cfi, scs and hwasan export both sanitized and unsanitized variants for static and header
508 // Always use unsanitized variants of them.
509 for _, t := range []sanitizerType{cfi, scs, hwasan} {
510 if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
511 return false
512 }
513 }
514 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900515 if l.static() {
Inseob Kim7f283f42020-06-01 21:53:49 +0900516 return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900517 }
518 if l.shared() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700519 if !m.outputFile.Valid() {
520 return false
521 }
522 if !m.IsVndk() {
523 return true
524 }
525 return m.isVndkExt()
Inseob Kim8471cda2019-11-15 09:59:12 +0900526 }
527 return true
528 }
529
Inseob Kim1042d292020-06-01 23:23:05 +0900530 // Binaries and Objects
531 if m.binary() || m.object() {
Inseob Kim7f283f42020-06-01 21:53:49 +0900532 return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900533 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900534
535 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900536}
537
538func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
539 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a vendor snapshot.
540 if ctx.DeviceConfig().VndkVersion() != "current" {
541 return
542 }
543
544 var snapshotOutputs android.Paths
545
546 /*
547 Vendor snapshot zipped artifacts directory structure:
548 {SNAPSHOT_ARCH}/
549 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
550 shared/
551 (.so shared libraries)
552 static/
553 (.a static libraries)
554 header/
555 (header only libraries)
556 binary/
557 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900558 object/
559 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900560 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
561 shared/
562 (.so shared libraries)
563 static/
564 (.a static libraries)
565 header/
566 (header only libraries)
567 binary/
568 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900569 object/
570 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900571 NOTICE_FILES/
572 (notice files, e.g. libbase.txt)
573 configs/
574 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
575 include/
576 (header files of same directory structure with source tree)
577 */
578
579 snapshotDir := "vendor-snapshot"
580 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
581
582 includeDir := filepath.Join(snapshotArchDir, "include")
583 configsDir := filepath.Join(snapshotArchDir, "configs")
584 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
585
586 installedNotices := make(map[string]bool)
587 installedConfigs := make(map[string]bool)
588
589 var headers android.Paths
590
Inseob Kim8471cda2019-11-15 09:59:12 +0900591 installSnapshot := func(m *Module) android.Paths {
592 targetArch := "arch-" + m.Target().Arch.ArchType.String()
593 if m.Target().Arch.ArchVariant != "" {
594 targetArch += "-" + m.Target().Arch.ArchVariant
595 }
596
597 var ret android.Paths
598
599 prop := struct {
600 ModuleName string `json:",omitempty"`
601 RelativeInstallPath string `json:",omitempty"`
602
603 // library flags
604 ExportedDirs []string `json:",omitempty"`
605 ExportedSystemDirs []string `json:",omitempty"`
606 ExportedFlags []string `json:",omitempty"`
607 SanitizeMinimalDep bool `json:",omitempty"`
608 SanitizeUbsanDep bool `json:",omitempty"`
609
610 // binary flags
611 Symlinks []string `json:",omitempty"`
612
613 // dependencies
614 SharedLibs []string `json:",omitempty"`
615 RuntimeLibs []string `json:",omitempty"`
616 Required []string `json:",omitempty"`
617
618 // extra config files
619 InitRc []string `json:",omitempty"`
620 VintfFragments []string `json:",omitempty"`
621 }{}
622
623 // Common properties among snapshots.
624 prop.ModuleName = ctx.ModuleName(m)
Bill Peckham7d3f0962020-06-29 16:49:15 -0700625 if m.isVndkExt() {
626 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
627 if m.isVndkSp() {
628 prop.RelativeInstallPath = "vndk-sp"
629 } else {
630 prop.RelativeInstallPath = "vndk"
631 }
632 } else {
633 prop.RelativeInstallPath = m.RelativeInstallPath()
634 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900635 prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
636 prop.Required = m.RequiredModuleNames()
637 for _, path := range m.InitRc() {
638 prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
639 }
640 for _, path := range m.VintfFragments() {
641 prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
642 }
643
644 // install config files. ignores any duplicates.
645 for _, path := range append(m.InitRc(), m.VintfFragments()...) {
646 out := filepath.Join(configsDir, path.Base())
647 if !installedConfigs[out] {
648 installedConfigs[out] = true
649 ret = append(ret, copyFile(ctx, path, out))
650 }
651 }
652
653 var propOut string
654
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900655 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim8471cda2019-11-15 09:59:12 +0900656 // library flags
657 prop.ExportedFlags = l.exportedFlags()
658 for _, dir := range l.exportedDirs() {
659 prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
660 }
661 for _, dir := range l.exportedSystemDirs() {
662 prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
663 }
664 // shared libs dependencies aren't meaningful on static or header libs
665 if l.shared() {
666 prop.SharedLibs = m.Properties.SnapshotSharedLibs
667 }
668 if l.static() && m.sanitize != nil {
669 prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
670 prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
671 }
672
673 var libType string
674 if l.static() {
675 libType = "static"
676 } else if l.shared() {
677 libType = "shared"
678 } else {
679 libType = "header"
680 }
681
682 var stem string
683
684 // install .a or .so
685 if libType != "header" {
686 libPath := m.outputFile.Path()
687 stem = libPath.Base()
688 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
689 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
690 } else {
691 stem = ctx.ModuleName(m)
692 }
693
694 propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
Inseob Kim7f283f42020-06-01 21:53:49 +0900695 } else if m.binary() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900696 // binary flags
697 prop.Symlinks = m.Symlinks()
698 prop.SharedLibs = m.Properties.SnapshotSharedLibs
699
700 // install bin
701 binPath := m.outputFile.Path()
702 snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
703 ret = append(ret, copyFile(ctx, binPath, snapshotBinOut))
704 propOut = snapshotBinOut + ".json"
Inseob Kim1042d292020-06-01 23:23:05 +0900705 } else if m.object() {
706 // object files aren't installed to the device, so their names can conflict.
707 // Use module name as stem.
708 objPath := m.outputFile.Path()
709 snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
710 ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
711 ret = append(ret, copyFile(ctx, objPath, snapshotObjOut))
712 propOut = snapshotObjOut + ".json"
Inseob Kim7f283f42020-06-01 21:53:49 +0900713 } else {
714 ctx.Errorf("unknown module %q in vendor snapshot", m.String())
715 return nil
Inseob Kim8471cda2019-11-15 09:59:12 +0900716 }
717
718 j, err := json.Marshal(prop)
719 if err != nil {
720 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
721 return nil
722 }
723 ret = append(ret, writeStringToFile(ctx, string(j), propOut))
724
725 return ret
726 }
727
728 ctx.VisitAllModules(func(module android.Module) {
729 m, ok := module.(*Module)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900730 if !ok {
731 return
732 }
733
734 moduleDir := ctx.ModuleDir(module)
735 if !isVendorSnapshotModule(m, moduleDir) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900736 return
737 }
738
739 snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900740 if l, ok := m.linker.(snapshotLibraryInterface); ok {
741 headers = append(headers, l.snapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +0900742 }
743
Bob Badoura75b0572020-02-18 20:21:55 -0800744 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900745 noticeName := ctx.ModuleName(m) + ".txt"
746 noticeOut := filepath.Join(noticeDir, noticeName)
747 // skip already copied notice file
748 if !installedNotices[noticeOut] {
749 installedNotices[noticeOut] = true
Bob Badoura75b0572020-02-18 20:21:55 -0800750 snapshotOutputs = append(snapshotOutputs, combineNotices(
751 ctx, m.NoticeFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900752 }
753 }
754 })
755
756 // install all headers after removing duplicates
757 for _, header := range android.FirstUniquePaths(headers) {
758 snapshotOutputs = append(snapshotOutputs, copyFile(
759 ctx, header, filepath.Join(includeDir, header.String())))
760 }
761
762 // All artifacts are ready. Sort them to normalize ninja and then zip.
763 sort.Slice(snapshotOutputs, func(i, j int) bool {
764 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
765 })
766
767 zipPath := android.PathForOutput(ctx, snapshotDir, "vendor-"+ctx.Config().DeviceName()+".zip")
768 zipRule := android.NewRuleBuilder()
769
770 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
771 snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "vendor-"+ctx.Config().DeviceName()+"_list")
772 zipRule.Command().
773 Text("tr").
774 FlagWithArg("-d ", "\\'").
775 FlagWithRspFileInputList("< ", snapshotOutputs).
776 FlagWithOutput("> ", snapshotOutputList)
777
778 zipRule.Temporary(snapshotOutputList)
779
780 zipRule.Command().
781 BuiltTool(ctx, "soong_zip").
782 FlagWithOutput("-o ", zipPath).
783 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
784 FlagWithInput("-l ", snapshotOutputList)
785
786 zipRule.Build(pctx, ctx, zipPath.String(), "vendor snapshot "+zipPath.String())
787 zipRule.DeleteTemporaryFiles()
788 c.vendorSnapshotZipFile = android.OptionalPathForPath(zipPath)
789}
790
791func (c *vendorSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
792 ctx.Strict("SOONG_VENDOR_SNAPSHOT_ZIP", c.vendorSnapshotZipFile.String())
793}
Inseob Kimeec88e12020-01-22 11:11:29 +0900794
795type snapshotInterface interface {
796 matchesWithDevice(config android.DeviceConfig) bool
797}
798
799var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
800var _ snapshotInterface = (*vendorSnapshotLibraryDecorator)(nil)
801var _ snapshotInterface = (*vendorSnapshotBinaryDecorator)(nil)
Inseob Kim1042d292020-06-01 23:23:05 +0900802var _ snapshotInterface = (*vendorSnapshotObjectLinker)(nil)
Inseob Kimeec88e12020-01-22 11:11:29 +0900803
804// gathers all snapshot modules for vendor, and disable unnecessary snapshots
805// TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules
806func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) {
807 vndkVersion := ctx.DeviceConfig().VndkVersion()
808 // don't need snapshot if current
809 if vndkVersion == "current" || vndkVersion == "" {
810 return
811 }
812
813 module, ok := ctx.Module().(*Module)
814 if !ok || !module.Enabled() || module.VndkVersion() != vndkVersion {
815 return
816 }
817
Inseob Kim1042d292020-06-01 23:23:05 +0900818 if !module.isSnapshotPrebuilt() {
Inseob Kimeec88e12020-01-22 11:11:29 +0900819 return
820 }
821
Inseob Kim1042d292020-06-01 23:23:05 +0900822 // isSnapshotPrebuilt ensures snapshotInterface
823 if !module.linker.(snapshotInterface).matchesWithDevice(ctx.DeviceConfig()) {
Inseob Kimeec88e12020-01-22 11:11:29 +0900824 // Disable unnecessary snapshot module, but do not disable
825 // vndk_prebuilt_shared because they might be packed into vndk APEX
826 if !module.IsVndk() {
827 module.Disable()
828 }
829 return
830 }
831
832 var snapshotMap *snapshotMap
833
834 if lib, ok := module.linker.(libraryInterface); ok {
835 if lib.static() {
836 snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
837 } else if lib.shared() {
838 snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
839 } else {
840 // header
841 snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
842 }
843 } else if _, ok := module.linker.(*vendorSnapshotBinaryDecorator); ok {
844 snapshotMap = vendorSnapshotBinaries(ctx.Config())
Inseob Kim1042d292020-06-01 23:23:05 +0900845 } else if _, ok := module.linker.(*vendorSnapshotObjectLinker); ok {
846 snapshotMap = vendorSnapshotObjects(ctx.Config())
Inseob Kimeec88e12020-01-22 11:11:29 +0900847 } else {
848 return
849 }
850
851 vendorSnapshotsLock.Lock()
852 defer vendorSnapshotsLock.Unlock()
853 snapshotMap.add(module.BaseModuleName(), ctx.Arch().ArchType, ctx.ModuleName())
854}
855
856// Disables source modules which have snapshots
857func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
Inseob Kim5f64aec2020-02-18 17:27:19 +0900858 if !ctx.Device() {
859 return
860 }
861
Inseob Kimeec88e12020-01-22 11:11:29 +0900862 vndkVersion := ctx.DeviceConfig().VndkVersion()
863 // don't need snapshot if current
864 if vndkVersion == "current" || vndkVersion == "" {
865 return
866 }
867
868 module, ok := ctx.Module().(*Module)
869 if !ok {
870 return
871 }
872
Inseob Kim5f64aec2020-02-18 17:27:19 +0900873 // vendor suffix should be added to snapshots if the source module isn't vendor: true.
874 if !module.SocSpecific() {
875 // But we can't just check SocSpecific() since we already passed the image mutator.
876 // Check ramdisk and recovery to see if we are real "vendor: true" module.
877 ramdisk_available := module.InRamdisk() && !module.OnlyInRamdisk()
878 recovery_available := module.InRecovery() && !module.OnlyInRecovery()
Inseob Kimeec88e12020-01-22 11:11:29 +0900879
Inseob Kim5f64aec2020-02-18 17:27:19 +0900880 if !ramdisk_available && !recovery_available {
881 vendorSnapshotsLock.Lock()
882 defer vendorSnapshotsLock.Unlock()
883
884 vendorSuffixModules(ctx.Config())[ctx.ModuleName()] = true
885 }
Inseob Kimeec88e12020-01-22 11:11:29 +0900886 }
887
888 if module.isSnapshotPrebuilt() || module.VndkVersion() != ctx.DeviceConfig().VndkVersion() {
889 // only non-snapshot modules with BOARD_VNDK_VERSION
890 return
891 }
892
Inseob Kim206665c2020-06-02 23:48:32 +0900893 // .. and also filter out llndk library
894 if module.isLlndk(ctx.Config()) {
895 return
896 }
897
Inseob Kimeec88e12020-01-22 11:11:29 +0900898 var snapshotMap *snapshotMap
899
900 if lib, ok := module.linker.(libraryInterface); ok {
901 if lib.static() {
902 snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
903 } else if lib.shared() {
904 snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
905 } else {
906 // header
907 snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
908 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900909 } else if module.binary() {
Inseob Kimeec88e12020-01-22 11:11:29 +0900910 snapshotMap = vendorSnapshotBinaries(ctx.Config())
Inseob Kim1042d292020-06-01 23:23:05 +0900911 } else if module.object() {
912 snapshotMap = vendorSnapshotObjects(ctx.Config())
Inseob Kimeec88e12020-01-22 11:11:29 +0900913 } else {
914 return
915 }
916
917 if _, ok := snapshotMap.get(ctx.ModuleName(), ctx.Arch().ArchType); !ok {
918 // Corresponding snapshot doesn't exist
919 return
920 }
921
922 // Disables source modules if corresponding snapshot exists.
923 if lib, ok := module.linker.(libraryInterface); ok && lib.buildStatic() && lib.buildShared() {
924 // But do not disable because the shared variant depends on the static variant.
925 module.SkipInstall()
926 module.Properties.HideFromMake = true
927 } else {
928 module.Disable()
929 }
930}