blob: 6bd095fd6368e30aa8eb157b22d45f868124f0e0 [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
Inseob Kimde5744a2020-12-02 13:14:28 +090016// This file contains singletons to capture vendor and recovery snapshot. They consist of prebuilt
17// modules under AOSP so older vendor and recovery can be built with a newer system in a single
18// source tree.
19
Inseob Kim8471cda2019-11-15 09:59:12 +090020import (
21 "encoding/json"
22 "path/filepath"
23 "sort"
24 "strings"
25
26 "github.com/google/blueprint/proptools"
27
28 "android/soong/android"
29)
30
Jose Galmesf7294582020-11-13 12:07:36 -080031var vendorSnapshotSingleton = snapshotSingleton{
32 "vendor",
33 "SOONG_VENDOR_SNAPSHOT_ZIP",
34 android.OptionalPath{},
35 true,
Inseob Kimde5744a2020-12-02 13:14:28 +090036 vendorSnapshotImageSingleton,
Inseob Kime9aec6a2021-01-05 20:03:22 +090037 false, /* fake */
38}
39
40var vendorFakeSnapshotSingleton = snapshotSingleton{
41 "vendor",
42 "SOONG_VENDOR_FAKE_SNAPSHOT_ZIP",
43 android.OptionalPath{},
44 true,
45 vendorSnapshotImageSingleton,
46 true, /* fake */
Jose Galmesf7294582020-11-13 12:07:36 -080047}
48
49var recoverySnapshotSingleton = snapshotSingleton{
50 "recovery",
51 "SOONG_RECOVERY_SNAPSHOT_ZIP",
52 android.OptionalPath{},
53 false,
Inseob Kimde5744a2020-12-02 13:14:28 +090054 recoverySnapshotImageSingleton,
Inseob Kime9aec6a2021-01-05 20:03:22 +090055 false, /* fake */
Inseob Kim8471cda2019-11-15 09:59:12 +090056}
57
58func VendorSnapshotSingleton() android.Singleton {
Jose Galmesf7294582020-11-13 12:07:36 -080059 return &vendorSnapshotSingleton
Inseob Kim8471cda2019-11-15 09:59:12 +090060}
61
Inseob Kime9aec6a2021-01-05 20:03:22 +090062func VendorFakeSnapshotSingleton() android.Singleton {
63 return &vendorFakeSnapshotSingleton
64}
65
Jose Galmesf7294582020-11-13 12:07:36 -080066func RecoverySnapshotSingleton() android.Singleton {
67 return &recoverySnapshotSingleton
68}
69
70type snapshotSingleton struct {
71 // Name, e.g., "vendor", "recovery", "ramdisk".
72 name string
73
74 // Make variable that points to the snapshot file, e.g.,
75 // "SOONG_RECOVERY_SNAPSHOT_ZIP".
76 makeVar string
77
78 // Path to the snapshot zip file.
79 snapshotZipFile android.OptionalPath
80
81 // Whether the image supports VNDK extension modules.
82 supportsVndkExt bool
83
84 // Implementation of the image interface specific to the image
85 // associated with this snapshot (e.g., specific to the vendor image,
86 // recovery image, etc.).
Inseob Kimde5744a2020-12-02 13:14:28 +090087 image snapshotImage
Inseob Kime9aec6a2021-01-05 20:03:22 +090088
89 // Whether this singleton is for fake snapshot or not.
90 // Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
91 // It is much faster to generate, and can be used to inspect dependencies.
92 fake bool
Inseob Kim8471cda2019-11-15 09:59:12 +090093}
94
95var (
96 // Modules under following directories are ignored. They are OEM's and vendor's
Daniel Norman713387d2020-07-28 16:04:38 -070097 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Inseob Kim8471cda2019-11-15 09:59:12 +090098 vendorProprietaryDirs = []string{
99 "device",
Daniel Norman713387d2020-07-28 16:04:38 -0700100 "kernel",
Inseob Kim8471cda2019-11-15 09:59:12 +0900101 "vendor",
102 "hardware",
103 }
104
Jose Galmesf7294582020-11-13 12:07:36 -0800105 // Modules under following directories are ignored. They are OEM's and vendor's
106 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Jose Galmesf7294582020-11-13 12:07:36 -0800107 recoveryProprietaryDirs = []string{
Jose Galmesf7294582020-11-13 12:07:36 -0800108 "device",
109 "hardware",
110 "kernel",
111 "vendor",
112 }
113
Inseob Kim8471cda2019-11-15 09:59:12 +0900114 // Modules under following directories are included as they are in AOSP,
Daniel Norman713387d2020-07-28 16:04:38 -0700115 // although hardware/ and kernel/ are normally for vendor's own.
Inseob Kim8471cda2019-11-15 09:59:12 +0900116 aospDirsUnderProprietary = []string{
Daniel Norman713387d2020-07-28 16:04:38 -0700117 "kernel/configs",
118 "kernel/prebuilts",
119 "kernel/tests",
Inseob Kim8471cda2019-11-15 09:59:12 +0900120 "hardware/interfaces",
121 "hardware/libhardware",
122 "hardware/libhardware_legacy",
123 "hardware/ril",
124 }
125)
126
127// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
128// device/, vendor/, etc.
129func isVendorProprietaryPath(dir string) bool {
Jose Galmesf7294582020-11-13 12:07:36 -0800130 return isProprietaryPath(dir, vendorProprietaryDirs)
131}
132
133func isRecoveryProprietaryPath(dir string) bool {
134 return isProprietaryPath(dir, recoveryProprietaryDirs)
135}
136
137// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
138// device/, vendor/, etc.
139func isProprietaryPath(dir string, proprietaryDirs []string) bool {
140 for _, p := range proprietaryDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900141 if strings.HasPrefix(dir, p) {
142 // filter out AOSP defined directories, e.g. hardware/interfaces/
143 aosp := false
144 for _, p := range aospDirsUnderProprietary {
145 if strings.HasPrefix(dir, p) {
146 aosp = true
147 break
148 }
149 }
150 if !aosp {
151 return true
152 }
153 }
154 }
155 return false
156}
157
Bill Peckham945441c2020-08-31 16:07:58 -0700158func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
Bill Peckham945441c2020-08-31 16:07:58 -0700159 // Any module in a vendor proprietary path is a vendor proprietary
160 // module.
Bill Peckham945441c2020-08-31 16:07:58 -0700161 if isVendorProprietaryPath(ctx.ModuleDir()) {
162 return true
163 }
164
165 // However if the module is not in a vendor proprietary path, it may
166 // still be a vendor proprietary module. This happens for cc modules
167 // that are excluded from the vendor snapshot, and it means that the
168 // vendor has assumed control of the framework-provided module.
Bill Peckham945441c2020-08-31 16:07:58 -0700169 if c, ok := ctx.Module().(*Module); ok {
170 if c.ExcludeFromVendorSnapshot() {
171 return true
172 }
173 }
174
175 return false
176}
177
Jose Galmes6f843bc2020-12-11 13:36:29 -0800178func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
179
180 // Any module in a vendor proprietary path is a vendor proprietary
181 // module.
182 if isRecoveryProprietaryPath(ctx.ModuleDir()) {
183 return true
184 }
185
186 // However if the module is not in a vendor proprietary path, it may
187 // still be a vendor proprietary module. This happens for cc modules
188 // that are excluded from the vendor snapshot, and it means that the
189 // vendor has assumed control of the framework-provided module.
190
191 if c, ok := ctx.Module().(*Module); ok {
192 if c.ExcludeFromRecoverySnapshot() {
193 return true
194 }
195 }
196
197 return false
198}
199
Inseob Kimde5744a2020-12-02 13:14:28 +0900200// Determines if the module is a candidate for snapshot.
Inseob Kim7cf14652021-01-06 23:06:52 +0900201func isSnapshotAware(cfg android.DeviceConfig, m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
Inseob Kim7f283f42020-06-01 21:53:49 +0900202 if !m.Enabled() || m.Properties.HideFromMake {
Inseob Kim8471cda2019-11-15 09:59:12 +0900203 return false
204 }
Martin Stjernholm809d5182020-09-10 01:46:05 +0100205 // When android/prebuilt.go selects between source and prebuilt, it sets
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800206 // HideFromMake on the other one to avoid duplicate install rules in make.
207 if m.IsHideFromMake() {
Martin Stjernholm809d5182020-09-10 01:46:05 +0100208 return false
209 }
Jose Galmesf7294582020-11-13 12:07:36 -0800210 // skip proprietary modules, but (for the vendor snapshot only)
211 // include all VNDK (static)
212 if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) {
Bill Peckham945441c2020-08-31 16:07:58 -0700213 return false
214 }
215 // If the module would be included based on its path, check to see if
216 // the module is marked to be excluded. If so, skip it.
Jose Galmes6f843bc2020-12-11 13:36:29 -0800217 if image.excludeFromSnapshot(m) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900218 return false
219 }
220 if m.Target().Os.Class != android.Device {
221 return false
222 }
223 if m.Target().NativeBridge == android.NativeBridgeEnabled {
224 return false
225 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900226 // the module must be installed in target image
Jose Galmesf7294582020-11-13 12:07:36 -0800227 if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !image.inImage(m)() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900228 return false
229 }
Inseob Kim65ca36a2020-06-11 13:55:45 +0900230 // skip kernel_headers which always depend on vendor
231 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
232 return false
233 }
Justin Yunf2664c62020-07-30 18:57:54 +0900234 // skip llndk_library and llndk_headers which are backward compatible
Colin Cross127bb8b2020-12-16 16:46:01 -0800235 if m.IsLlndk() {
236 return false
237 }
Justin Yunf2664c62020-07-30 18:57:54 +0900238 if _, ok := m.linker.(*llndkStubDecorator); ok {
239 return false
240 }
241 if _, ok := m.linker.(*llndkHeadersDecorator); ok {
242 return false
243 }
Inseob Kim7cf14652021-01-06 23:06:52 +0900244 // If we are using directed snapshot AND we have to exclude this module, skip this
245 if image.excludeFromDirectedSnapshot(cfg, m.BaseModuleName()) {
246 return false
247 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900248
249 // Libraries
250 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim7f283f42020-06-01 21:53:49 +0900251 if m.sanitize != nil {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900252 // scs and hwasan export both sanitized and unsanitized variants for static and header
Inseob Kim7f283f42020-06-01 21:53:49 +0900253 // Always use unsanitized variants of them.
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500254 for _, t := range []SanitizerType{scs, hwasan} {
Inseob Kim7f283f42020-06-01 21:53:49 +0900255 if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
256 return false
257 }
258 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900259 // cfi also exports both variants. But for static, we capture both.
Inseob Kimde5744a2020-12-02 13:14:28 +0900260 // This is because cfi static libraries can't be linked from non-cfi modules,
261 // and vice versa. This isn't the case for scs and hwasan sanitizers.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900262 if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
263 return false
264 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900265 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900266 if l.static() {
Jose Galmesf7294582020-11-13 12:07:36 -0800267 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900268 }
269 if l.shared() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700270 if !m.outputFile.Valid() {
271 return false
272 }
Jose Galmesf7294582020-11-13 12:07:36 -0800273 if image.includeVndk() {
274 if !m.IsVndk() {
275 return true
276 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500277 return m.IsVndkExt()
Bill Peckham7d3f0962020-06-29 16:49:15 -0700278 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900279 }
280 return true
281 }
282
Inseob Kim1042d292020-06-01 23:23:05 +0900283 // Binaries and Objects
284 if m.binary() || m.object() {
Jose Galmesf7294582020-11-13 12:07:36 -0800285 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900286 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900287
288 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900289}
290
Inseob Kimde5744a2020-12-02 13:14:28 +0900291// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
292// These flags become Android.bp snapshot module properties.
293type snapshotJsonFlags struct {
294 ModuleName string `json:",omitempty"`
295 RelativeInstallPath string `json:",omitempty"`
296
297 // library flags
298 ExportedDirs []string `json:",omitempty"`
299 ExportedSystemDirs []string `json:",omitempty"`
300 ExportedFlags []string `json:",omitempty"`
301 Sanitize string `json:",omitempty"`
302 SanitizeMinimalDep bool `json:",omitempty"`
303 SanitizeUbsanDep bool `json:",omitempty"`
304
305 // binary flags
306 Symlinks []string `json:",omitempty"`
307
308 // dependencies
309 SharedLibs []string `json:",omitempty"`
310 RuntimeLibs []string `json:",omitempty"`
311 Required []string `json:",omitempty"`
312
313 // extra config files
314 InitRc []string `json:",omitempty"`
315 VintfFragments []string `json:",omitempty"`
316}
317
Jose Galmesf7294582020-11-13 12:07:36 -0800318func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800319 if !c.image.shouldGenerateSnapshot(ctx) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900320 return
321 }
322
323 var snapshotOutputs android.Paths
324
325 /*
326 Vendor snapshot zipped artifacts directory structure:
327 {SNAPSHOT_ARCH}/
328 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
329 shared/
330 (.so shared libraries)
331 static/
332 (.a static libraries)
333 header/
334 (header only libraries)
335 binary/
336 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900337 object/
338 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900339 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
340 shared/
341 (.so shared libraries)
342 static/
343 (.a static libraries)
344 header/
345 (header only libraries)
346 binary/
347 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900348 object/
349 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900350 NOTICE_FILES/
351 (notice files, e.g. libbase.txt)
352 configs/
353 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
354 include/
355 (header files of same directory structure with source tree)
356 */
357
Jose Galmesf7294582020-11-13 12:07:36 -0800358 snapshotDir := c.name + "-snapshot"
Inseob Kime9aec6a2021-01-05 20:03:22 +0900359 if c.fake {
360 // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
361 // collision with real snapshot files
362 snapshotDir = filepath.Join("fake", snapshotDir)
363 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900364 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
365
366 includeDir := filepath.Join(snapshotArchDir, "include")
367 configsDir := filepath.Join(snapshotArchDir, "configs")
368 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
369
370 installedNotices := make(map[string]bool)
371 installedConfigs := make(map[string]bool)
372
373 var headers android.Paths
374
Inseob Kime9aec6a2021-01-05 20:03:22 +0900375 copyFile := copyFileRule
376 if c.fake {
377 // All prebuilt binaries and headers are installed by copyFile function. This makes a fake
378 // snapshot just touch prebuilts and headers, rather than installing real files.
379 copyFile = func(ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
380 return writeStringToFileRule(ctx, "", out)
381 }
382 }
383
Inseob Kimde5744a2020-12-02 13:14:28 +0900384 // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
385 // For executables, init_rc and vintf_fragments files are also copied.
Inseob Kim8471cda2019-11-15 09:59:12 +0900386 installSnapshot := func(m *Module) android.Paths {
387 targetArch := "arch-" + m.Target().Arch.ArchType.String()
388 if m.Target().Arch.ArchVariant != "" {
389 targetArch += "-" + m.Target().Arch.ArchVariant
390 }
391
392 var ret android.Paths
393
Inseob Kimde5744a2020-12-02 13:14:28 +0900394 prop := snapshotJsonFlags{}
Inseob Kim8471cda2019-11-15 09:59:12 +0900395
396 // Common properties among snapshots.
397 prop.ModuleName = ctx.ModuleName(m)
Ivan Lozanof9e21722020-12-02 09:00:51 -0500398 if c.supportsVndkExt && m.IsVndkExt() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700399 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
400 if m.isVndkSp() {
401 prop.RelativeInstallPath = "vndk-sp"
402 } else {
403 prop.RelativeInstallPath = "vndk"
404 }
405 } else {
406 prop.RelativeInstallPath = m.RelativeInstallPath()
407 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900408 prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
409 prop.Required = m.RequiredModuleNames()
410 for _, path := range m.InitRc() {
411 prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
412 }
413 for _, path := range m.VintfFragments() {
414 prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
415 }
416
417 // install config files. ignores any duplicates.
418 for _, path := range append(m.InitRc(), m.VintfFragments()...) {
419 out := filepath.Join(configsDir, path.Base())
420 if !installedConfigs[out] {
421 installedConfigs[out] = true
Inseob Kime9aec6a2021-01-05 20:03:22 +0900422 ret = append(ret, copyFile(ctx, path, out))
Inseob Kim8471cda2019-11-15 09:59:12 +0900423 }
424 }
425
426 var propOut string
427
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900428 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Colin Cross0de8a1e2020-09-18 14:15:30 -0700429 exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
Inseob Kimc42f2f22020-07-29 20:32:10 +0900430
Inseob Kim8471cda2019-11-15 09:59:12 +0900431 // library flags
Colin Cross0de8a1e2020-09-18 14:15:30 -0700432 prop.ExportedFlags = exporterInfo.Flags
433 for _, dir := range exporterInfo.IncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900434 prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
435 }
Colin Cross0de8a1e2020-09-18 14:15:30 -0700436 for _, dir := range exporterInfo.SystemIncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900437 prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
438 }
439 // shared libs dependencies aren't meaningful on static or header libs
440 if l.shared() {
441 prop.SharedLibs = m.Properties.SnapshotSharedLibs
442 }
443 if l.static() && m.sanitize != nil {
444 prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
445 prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
446 }
447
448 var libType string
449 if l.static() {
450 libType = "static"
451 } else if l.shared() {
452 libType = "shared"
453 } else {
454 libType = "header"
455 }
456
457 var stem string
458
459 // install .a or .so
460 if libType != "header" {
461 libPath := m.outputFile.Path()
462 stem = libPath.Base()
Inseob Kimc42f2f22020-07-29 20:32:10 +0900463 if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(cfi) {
464 // both cfi and non-cfi variant for static libraries can exist.
465 // attach .cfi to distinguish between cfi and non-cfi.
466 // e.g. libbase.a -> libbase.cfi.a
467 ext := filepath.Ext(stem)
468 stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
469 prop.Sanitize = "cfi"
470 prop.ModuleName += ".cfi"
471 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900472 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
Inseob Kime9aec6a2021-01-05 20:03:22 +0900473 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900474 } else {
475 stem = ctx.ModuleName(m)
476 }
477
478 propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
Inseob Kim7f283f42020-06-01 21:53:49 +0900479 } else if m.binary() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900480 // binary flags
481 prop.Symlinks = m.Symlinks()
482 prop.SharedLibs = m.Properties.SnapshotSharedLibs
483
484 // install bin
485 binPath := m.outputFile.Path()
486 snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
Inseob Kime9aec6a2021-01-05 20:03:22 +0900487 ret = append(ret, copyFile(ctx, binPath, snapshotBinOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900488 propOut = snapshotBinOut + ".json"
Inseob Kim1042d292020-06-01 23:23:05 +0900489 } else if m.object() {
490 // object files aren't installed to the device, so their names can conflict.
491 // Use module name as stem.
492 objPath := m.outputFile.Path()
493 snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
494 ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
Inseob Kime9aec6a2021-01-05 20:03:22 +0900495 ret = append(ret, copyFile(ctx, objPath, snapshotObjOut))
Inseob Kim1042d292020-06-01 23:23:05 +0900496 propOut = snapshotObjOut + ".json"
Inseob Kim7f283f42020-06-01 21:53:49 +0900497 } else {
498 ctx.Errorf("unknown module %q in vendor snapshot", m.String())
499 return nil
Inseob Kim8471cda2019-11-15 09:59:12 +0900500 }
501
502 j, err := json.Marshal(prop)
503 if err != nil {
504 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
505 return nil
506 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900507 ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900508
509 return ret
510 }
511
512 ctx.VisitAllModules(func(module android.Module) {
513 m, ok := module.(*Module)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900514 if !ok {
515 return
516 }
517
518 moduleDir := ctx.ModuleDir(module)
Jose Galmesf7294582020-11-13 12:07:36 -0800519 inProprietaryPath := c.image.isProprietaryPath(moduleDir)
Colin Cross56a83212020-09-15 18:30:11 -0700520 apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
Bill Peckham945441c2020-08-31 16:07:58 -0700521
Jose Galmes6f843bc2020-12-11 13:36:29 -0800522 if c.image.excludeFromSnapshot(m) {
Jose Galmesf7294582020-11-13 12:07:36 -0800523 if inProprietaryPath {
Bill Peckham945441c2020-08-31 16:07:58 -0700524 // Error: exclude_from_vendor_snapshot applies
525 // to framework-path modules only.
526 ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
527 return
528 }
Jose Galmesf7294582020-11-13 12:07:36 -0800529 if Bool(c.image.available(m)) {
Bill Peckham945441c2020-08-31 16:07:58 -0700530 // Error: may not combine "vendor_available:
531 // true" with "exclude_from_vendor_snapshot:
532 // true".
Jose Galmesf7294582020-11-13 12:07:36 -0800533 ctx.Errorf(
534 "module %q may not use both \""+
535 c.name+
536 "_available: true\" and \"exclude_from_vendor_snapshot: true\"",
537 m.String())
Bill Peckham945441c2020-08-31 16:07:58 -0700538 return
539 }
540 }
541
Inseob Kim7cf14652021-01-06 23:06:52 +0900542 if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, c.image) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900543 return
544 }
545
Inseob Kimde5744a2020-12-02 13:14:28 +0900546 // installSnapshot installs prebuilts and json flag files
Inseob Kim8471cda2019-11-15 09:59:12 +0900547 snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
Inseob Kimde5744a2020-12-02 13:14:28 +0900548
549 // just gather headers and notice files here, because they are to be deduplicated
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900550 if l, ok := m.linker.(snapshotLibraryInterface); ok {
551 headers = append(headers, l.snapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +0900552 }
553
Bob Badoura75b0572020-02-18 20:21:55 -0800554 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900555 noticeName := ctx.ModuleName(m) + ".txt"
556 noticeOut := filepath.Join(noticeDir, noticeName)
557 // skip already copied notice file
558 if !installedNotices[noticeOut] {
559 installedNotices[noticeOut] = true
Inseob Kime9aec6a2021-01-05 20:03:22 +0900560 snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.NoticeFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900561 }
562 }
563 })
564
565 // install all headers after removing duplicates
566 for _, header := range android.FirstUniquePaths(headers) {
Inseob Kime9aec6a2021-01-05 20:03:22 +0900567 snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String())))
Inseob Kim8471cda2019-11-15 09:59:12 +0900568 }
569
570 // All artifacts are ready. Sort them to normalize ninja and then zip.
571 sort.Slice(snapshotOutputs, func(i, j int) bool {
572 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
573 })
574
Jose Galmesf7294582020-11-13 12:07:36 -0800575 zipPath := android.PathForOutput(
576 ctx,
577 snapshotDir,
578 c.name+"-"+ctx.Config().DeviceName()+".zip")
Colin Crossf1a035e2020-11-16 17:32:30 -0800579 zipRule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim8471cda2019-11-15 09:59:12 +0900580
581 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
Jose Galmesf7294582020-11-13 12:07:36 -0800582 snapshotOutputList := android.PathForOutput(
583 ctx,
584 snapshotDir,
585 c.name+"-"+ctx.Config().DeviceName()+"_list")
Inseob Kim8471cda2019-11-15 09:59:12 +0900586 zipRule.Command().
587 Text("tr").
588 FlagWithArg("-d ", "\\'").
589 FlagWithRspFileInputList("< ", snapshotOutputs).
590 FlagWithOutput("> ", snapshotOutputList)
591
592 zipRule.Temporary(snapshotOutputList)
593
594 zipRule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800595 BuiltTool("soong_zip").
Inseob Kim8471cda2019-11-15 09:59:12 +0900596 FlagWithOutput("-o ", zipPath).
597 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
598 FlagWithInput("-l ", snapshotOutputList)
599
Colin Crossf1a035e2020-11-16 17:32:30 -0800600 zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900601 zipRule.DeleteTemporaryFiles()
Jose Galmesf7294582020-11-13 12:07:36 -0800602 c.snapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim8471cda2019-11-15 09:59:12 +0900603}
604
Jose Galmesf7294582020-11-13 12:07:36 -0800605func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
606 ctx.Strict(
607 c.makeVar,
608 c.snapshotZipFile.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900609}