blob: 0a89e471c2051cff2d5814e8ee2aacafcd40c8d4 [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.
201func isSnapshotAware(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 Kim8471cda2019-11-15 09:59:12 +0900244
245 // Libraries
246 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim7f283f42020-06-01 21:53:49 +0900247 if m.sanitize != nil {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900248 // scs and hwasan export both sanitized and unsanitized variants for static and header
Inseob Kim7f283f42020-06-01 21:53:49 +0900249 // Always use unsanitized variants of them.
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500250 for _, t := range []SanitizerType{scs, hwasan} {
Inseob Kim7f283f42020-06-01 21:53:49 +0900251 if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
252 return false
253 }
254 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900255 // cfi also exports both variants. But for static, we capture both.
Inseob Kimde5744a2020-12-02 13:14:28 +0900256 // This is because cfi static libraries can't be linked from non-cfi modules,
257 // and vice versa. This isn't the case for scs and hwasan sanitizers.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900258 if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
259 return false
260 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900261 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900262 if l.static() {
Jose Galmesf7294582020-11-13 12:07:36 -0800263 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900264 }
265 if l.shared() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700266 if !m.outputFile.Valid() {
267 return false
268 }
Jose Galmesf7294582020-11-13 12:07:36 -0800269 if image.includeVndk() {
270 if !m.IsVndk() {
271 return true
272 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500273 return m.IsVndkExt()
Bill Peckham7d3f0962020-06-29 16:49:15 -0700274 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900275 }
276 return true
277 }
278
Inseob Kim1042d292020-06-01 23:23:05 +0900279 // Binaries and Objects
280 if m.binary() || m.object() {
Jose Galmesf7294582020-11-13 12:07:36 -0800281 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900282 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900283
284 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900285}
286
Inseob Kimde5744a2020-12-02 13:14:28 +0900287// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
288// These flags become Android.bp snapshot module properties.
289type snapshotJsonFlags struct {
290 ModuleName string `json:",omitempty"`
291 RelativeInstallPath string `json:",omitempty"`
292
293 // library flags
294 ExportedDirs []string `json:",omitempty"`
295 ExportedSystemDirs []string `json:",omitempty"`
296 ExportedFlags []string `json:",omitempty"`
297 Sanitize string `json:",omitempty"`
298 SanitizeMinimalDep bool `json:",omitempty"`
299 SanitizeUbsanDep bool `json:",omitempty"`
300
301 // binary flags
302 Symlinks []string `json:",omitempty"`
303
304 // dependencies
305 SharedLibs []string `json:",omitempty"`
306 RuntimeLibs []string `json:",omitempty"`
307 Required []string `json:",omitempty"`
308
309 // extra config files
310 InitRc []string `json:",omitempty"`
311 VintfFragments []string `json:",omitempty"`
312}
313
Jose Galmesf7294582020-11-13 12:07:36 -0800314func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800315 if !c.image.shouldGenerateSnapshot(ctx) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900316 return
317 }
318
319 var snapshotOutputs android.Paths
320
321 /*
322 Vendor snapshot zipped artifacts directory structure:
323 {SNAPSHOT_ARCH}/
324 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
325 shared/
326 (.so shared libraries)
327 static/
328 (.a static libraries)
329 header/
330 (header only libraries)
331 binary/
332 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900333 object/
334 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900335 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
336 shared/
337 (.so shared libraries)
338 static/
339 (.a static libraries)
340 header/
341 (header only libraries)
342 binary/
343 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900344 object/
345 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900346 NOTICE_FILES/
347 (notice files, e.g. libbase.txt)
348 configs/
349 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
350 include/
351 (header files of same directory structure with source tree)
352 */
353
Jose Galmesf7294582020-11-13 12:07:36 -0800354 snapshotDir := c.name + "-snapshot"
Inseob Kime9aec6a2021-01-05 20:03:22 +0900355 if c.fake {
356 // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
357 // collision with real snapshot files
358 snapshotDir = filepath.Join("fake", snapshotDir)
359 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900360 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
361
362 includeDir := filepath.Join(snapshotArchDir, "include")
363 configsDir := filepath.Join(snapshotArchDir, "configs")
364 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
365
366 installedNotices := make(map[string]bool)
367 installedConfigs := make(map[string]bool)
368
369 var headers android.Paths
370
Inseob Kime9aec6a2021-01-05 20:03:22 +0900371 copyFile := copyFileRule
372 if c.fake {
373 // All prebuilt binaries and headers are installed by copyFile function. This makes a fake
374 // snapshot just touch prebuilts and headers, rather than installing real files.
375 copyFile = func(ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
376 return writeStringToFileRule(ctx, "", out)
377 }
378 }
379
Inseob Kimde5744a2020-12-02 13:14:28 +0900380 // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
381 // For executables, init_rc and vintf_fragments files are also copied.
Inseob Kim8471cda2019-11-15 09:59:12 +0900382 installSnapshot := func(m *Module) android.Paths {
383 targetArch := "arch-" + m.Target().Arch.ArchType.String()
384 if m.Target().Arch.ArchVariant != "" {
385 targetArch += "-" + m.Target().Arch.ArchVariant
386 }
387
388 var ret android.Paths
389
Inseob Kimde5744a2020-12-02 13:14:28 +0900390 prop := snapshotJsonFlags{}
Inseob Kim8471cda2019-11-15 09:59:12 +0900391
392 // Common properties among snapshots.
393 prop.ModuleName = ctx.ModuleName(m)
Ivan Lozanof9e21722020-12-02 09:00:51 -0500394 if c.supportsVndkExt && m.IsVndkExt() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700395 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
396 if m.isVndkSp() {
397 prop.RelativeInstallPath = "vndk-sp"
398 } else {
399 prop.RelativeInstallPath = "vndk"
400 }
401 } else {
402 prop.RelativeInstallPath = m.RelativeInstallPath()
403 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900404 prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
405 prop.Required = m.RequiredModuleNames()
406 for _, path := range m.InitRc() {
407 prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
408 }
409 for _, path := range m.VintfFragments() {
410 prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
411 }
412
413 // install config files. ignores any duplicates.
414 for _, path := range append(m.InitRc(), m.VintfFragments()...) {
415 out := filepath.Join(configsDir, path.Base())
416 if !installedConfigs[out] {
417 installedConfigs[out] = true
Inseob Kime9aec6a2021-01-05 20:03:22 +0900418 ret = append(ret, copyFile(ctx, path, out))
Inseob Kim8471cda2019-11-15 09:59:12 +0900419 }
420 }
421
422 var propOut string
423
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900424 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Colin Cross0de8a1e2020-09-18 14:15:30 -0700425 exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
Inseob Kimc42f2f22020-07-29 20:32:10 +0900426
Inseob Kim8471cda2019-11-15 09:59:12 +0900427 // library flags
Colin Cross0de8a1e2020-09-18 14:15:30 -0700428 prop.ExportedFlags = exporterInfo.Flags
429 for _, dir := range exporterInfo.IncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900430 prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
431 }
Colin Cross0de8a1e2020-09-18 14:15:30 -0700432 for _, dir := range exporterInfo.SystemIncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900433 prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
434 }
435 // shared libs dependencies aren't meaningful on static or header libs
436 if l.shared() {
437 prop.SharedLibs = m.Properties.SnapshotSharedLibs
438 }
439 if l.static() && m.sanitize != nil {
440 prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
441 prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
442 }
443
444 var libType string
445 if l.static() {
446 libType = "static"
447 } else if l.shared() {
448 libType = "shared"
449 } else {
450 libType = "header"
451 }
452
453 var stem string
454
455 // install .a or .so
456 if libType != "header" {
457 libPath := m.outputFile.Path()
458 stem = libPath.Base()
Inseob Kimc42f2f22020-07-29 20:32:10 +0900459 if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(cfi) {
460 // both cfi and non-cfi variant for static libraries can exist.
461 // attach .cfi to distinguish between cfi and non-cfi.
462 // e.g. libbase.a -> libbase.cfi.a
463 ext := filepath.Ext(stem)
464 stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
465 prop.Sanitize = "cfi"
466 prop.ModuleName += ".cfi"
467 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900468 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
Inseob Kime9aec6a2021-01-05 20:03:22 +0900469 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900470 } else {
471 stem = ctx.ModuleName(m)
472 }
473
474 propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
Inseob Kim7f283f42020-06-01 21:53:49 +0900475 } else if m.binary() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900476 // binary flags
477 prop.Symlinks = m.Symlinks()
478 prop.SharedLibs = m.Properties.SnapshotSharedLibs
479
480 // install bin
481 binPath := m.outputFile.Path()
482 snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
Inseob Kime9aec6a2021-01-05 20:03:22 +0900483 ret = append(ret, copyFile(ctx, binPath, snapshotBinOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900484 propOut = snapshotBinOut + ".json"
Inseob Kim1042d292020-06-01 23:23:05 +0900485 } else if m.object() {
486 // object files aren't installed to the device, so their names can conflict.
487 // Use module name as stem.
488 objPath := m.outputFile.Path()
489 snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
490 ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
Inseob Kime9aec6a2021-01-05 20:03:22 +0900491 ret = append(ret, copyFile(ctx, objPath, snapshotObjOut))
Inseob Kim1042d292020-06-01 23:23:05 +0900492 propOut = snapshotObjOut + ".json"
Inseob Kim7f283f42020-06-01 21:53:49 +0900493 } else {
494 ctx.Errorf("unknown module %q in vendor snapshot", m.String())
495 return nil
Inseob Kim8471cda2019-11-15 09:59:12 +0900496 }
497
498 j, err := json.Marshal(prop)
499 if err != nil {
500 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
501 return nil
502 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900503 ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900504
505 return ret
506 }
507
508 ctx.VisitAllModules(func(module android.Module) {
509 m, ok := module.(*Module)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900510 if !ok {
511 return
512 }
513
514 moduleDir := ctx.ModuleDir(module)
Jose Galmesf7294582020-11-13 12:07:36 -0800515 inProprietaryPath := c.image.isProprietaryPath(moduleDir)
Colin Cross56a83212020-09-15 18:30:11 -0700516 apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
Bill Peckham945441c2020-08-31 16:07:58 -0700517
Jose Galmes6f843bc2020-12-11 13:36:29 -0800518 if c.image.excludeFromSnapshot(m) {
Jose Galmesf7294582020-11-13 12:07:36 -0800519 if inProprietaryPath {
Bill Peckham945441c2020-08-31 16:07:58 -0700520 // Error: exclude_from_vendor_snapshot applies
521 // to framework-path modules only.
522 ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
523 return
524 }
Jose Galmesf7294582020-11-13 12:07:36 -0800525 if Bool(c.image.available(m)) {
Bill Peckham945441c2020-08-31 16:07:58 -0700526 // Error: may not combine "vendor_available:
527 // true" with "exclude_from_vendor_snapshot:
528 // true".
Jose Galmesf7294582020-11-13 12:07:36 -0800529 ctx.Errorf(
530 "module %q may not use both \""+
531 c.name+
532 "_available: true\" and \"exclude_from_vendor_snapshot: true\"",
533 m.String())
Bill Peckham945441c2020-08-31 16:07:58 -0700534 return
535 }
536 }
537
Inseob Kimde5744a2020-12-02 13:14:28 +0900538 if !isSnapshotAware(m, inProprietaryPath, apexInfo, c.image) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900539 return
540 }
541
Inseob Kimde5744a2020-12-02 13:14:28 +0900542 // installSnapshot installs prebuilts and json flag files
Inseob Kim8471cda2019-11-15 09:59:12 +0900543 snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
Inseob Kimde5744a2020-12-02 13:14:28 +0900544
545 // just gather headers and notice files here, because they are to be deduplicated
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900546 if l, ok := m.linker.(snapshotLibraryInterface); ok {
547 headers = append(headers, l.snapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +0900548 }
549
Bob Badoura75b0572020-02-18 20:21:55 -0800550 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900551 noticeName := ctx.ModuleName(m) + ".txt"
552 noticeOut := filepath.Join(noticeDir, noticeName)
553 // skip already copied notice file
554 if !installedNotices[noticeOut] {
555 installedNotices[noticeOut] = true
Inseob Kime9aec6a2021-01-05 20:03:22 +0900556 snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.NoticeFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900557 }
558 }
559 })
560
561 // install all headers after removing duplicates
562 for _, header := range android.FirstUniquePaths(headers) {
Inseob Kime9aec6a2021-01-05 20:03:22 +0900563 snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String())))
Inseob Kim8471cda2019-11-15 09:59:12 +0900564 }
565
566 // All artifacts are ready. Sort them to normalize ninja and then zip.
567 sort.Slice(snapshotOutputs, func(i, j int) bool {
568 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
569 })
570
Jose Galmesf7294582020-11-13 12:07:36 -0800571 zipPath := android.PathForOutput(
572 ctx,
573 snapshotDir,
574 c.name+"-"+ctx.Config().DeviceName()+".zip")
Colin Crossf1a035e2020-11-16 17:32:30 -0800575 zipRule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim8471cda2019-11-15 09:59:12 +0900576
577 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
Jose Galmesf7294582020-11-13 12:07:36 -0800578 snapshotOutputList := android.PathForOutput(
579 ctx,
580 snapshotDir,
581 c.name+"-"+ctx.Config().DeviceName()+"_list")
Inseob Kim8471cda2019-11-15 09:59:12 +0900582 zipRule.Command().
583 Text("tr").
584 FlagWithArg("-d ", "\\'").
585 FlagWithRspFileInputList("< ", snapshotOutputs).
586 FlagWithOutput("> ", snapshotOutputList)
587
588 zipRule.Temporary(snapshotOutputList)
589
590 zipRule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800591 BuiltTool("soong_zip").
Inseob Kim8471cda2019-11-15 09:59:12 +0900592 FlagWithOutput("-o ", zipPath).
593 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
594 FlagWithInput("-l ", snapshotOutputList)
595
Colin Crossf1a035e2020-11-16 17:32:30 -0800596 zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900597 zipRule.DeleteTemporaryFiles()
Jose Galmesf7294582020-11-13 12:07:36 -0800598 c.snapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim8471cda2019-11-15 09:59:12 +0900599}
600
Jose Galmesf7294582020-11-13 12:07:36 -0800601func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
602 ctx.Strict(
603 c.makeVar,
604 c.snapshotZipFile.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900605}