blob: 35fc1c1fa3b58d57417ea8a411a061411c6c8fdb [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
Inseob Kim8471cda2019-11-15 09:59:12 +090026 "android/soong/android"
27)
28
Jose Galmesf7294582020-11-13 12:07:36 -080029var vendorSnapshotSingleton = snapshotSingleton{
30 "vendor",
31 "SOONG_VENDOR_SNAPSHOT_ZIP",
32 android.OptionalPath{},
33 true,
Inseob Kimde5744a2020-12-02 13:14:28 +090034 vendorSnapshotImageSingleton,
Inseob Kime9aec6a2021-01-05 20:03:22 +090035 false, /* fake */
36}
37
38var vendorFakeSnapshotSingleton = snapshotSingleton{
39 "vendor",
40 "SOONG_VENDOR_FAKE_SNAPSHOT_ZIP",
41 android.OptionalPath{},
42 true,
43 vendorSnapshotImageSingleton,
44 true, /* fake */
Jose Galmesf7294582020-11-13 12:07:36 -080045}
46
47var recoverySnapshotSingleton = snapshotSingleton{
48 "recovery",
49 "SOONG_RECOVERY_SNAPSHOT_ZIP",
50 android.OptionalPath{},
51 false,
Inseob Kimde5744a2020-12-02 13:14:28 +090052 recoverySnapshotImageSingleton,
Inseob Kime9aec6a2021-01-05 20:03:22 +090053 false, /* fake */
Inseob Kim8471cda2019-11-15 09:59:12 +090054}
55
56func VendorSnapshotSingleton() android.Singleton {
Jose Galmesf7294582020-11-13 12:07:36 -080057 return &vendorSnapshotSingleton
Inseob Kim8471cda2019-11-15 09:59:12 +090058}
59
Inseob Kime9aec6a2021-01-05 20:03:22 +090060func VendorFakeSnapshotSingleton() android.Singleton {
61 return &vendorFakeSnapshotSingleton
62}
63
Jose Galmesf7294582020-11-13 12:07:36 -080064func RecoverySnapshotSingleton() android.Singleton {
65 return &recoverySnapshotSingleton
66}
67
68type snapshotSingleton struct {
69 // Name, e.g., "vendor", "recovery", "ramdisk".
70 name string
71
72 // Make variable that points to the snapshot file, e.g.,
73 // "SOONG_RECOVERY_SNAPSHOT_ZIP".
74 makeVar string
75
76 // Path to the snapshot zip file.
77 snapshotZipFile android.OptionalPath
78
79 // Whether the image supports VNDK extension modules.
80 supportsVndkExt bool
81
82 // Implementation of the image interface specific to the image
83 // associated with this snapshot (e.g., specific to the vendor image,
84 // recovery image, etc.).
Inseob Kimde5744a2020-12-02 13:14:28 +090085 image snapshotImage
Inseob Kime9aec6a2021-01-05 20:03:22 +090086
87 // Whether this singleton is for fake snapshot or not.
88 // Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
89 // It is much faster to generate, and can be used to inspect dependencies.
90 fake bool
Inseob Kim8471cda2019-11-15 09:59:12 +090091}
92
93var (
94 // Modules under following directories are ignored. They are OEM's and vendor's
Daniel Norman713387d2020-07-28 16:04:38 -070095 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Inseob Kim8471cda2019-11-15 09:59:12 +090096 vendorProprietaryDirs = []string{
97 "device",
Daniel Norman713387d2020-07-28 16:04:38 -070098 "kernel",
Inseob Kim8471cda2019-11-15 09:59:12 +090099 "vendor",
100 "hardware",
101 }
102
Jose Galmesf7294582020-11-13 12:07:36 -0800103 // Modules under following directories are ignored. They are OEM's and vendor's
104 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Jose Galmesf7294582020-11-13 12:07:36 -0800105 recoveryProprietaryDirs = []string{
Jose Galmesf7294582020-11-13 12:07:36 -0800106 "device",
107 "hardware",
108 "kernel",
109 "vendor",
110 }
111
Inseob Kim8471cda2019-11-15 09:59:12 +0900112 // Modules under following directories are included as they are in AOSP,
Daniel Norman713387d2020-07-28 16:04:38 -0700113 // although hardware/ and kernel/ are normally for vendor's own.
Inseob Kim8471cda2019-11-15 09:59:12 +0900114 aospDirsUnderProprietary = []string{
Daniel Norman713387d2020-07-28 16:04:38 -0700115 "kernel/configs",
116 "kernel/prebuilts",
117 "kernel/tests",
Inseob Kim8471cda2019-11-15 09:59:12 +0900118 "hardware/interfaces",
119 "hardware/libhardware",
120 "hardware/libhardware_legacy",
121 "hardware/ril",
122 }
123)
124
125// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
126// device/, vendor/, etc.
127func isVendorProprietaryPath(dir string) bool {
Jose Galmesf7294582020-11-13 12:07:36 -0800128 return isProprietaryPath(dir, vendorProprietaryDirs)
129}
130
131func isRecoveryProprietaryPath(dir string) bool {
132 return isProprietaryPath(dir, recoveryProprietaryDirs)
133}
134
135// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
136// device/, vendor/, etc.
137func isProprietaryPath(dir string, proprietaryDirs []string) bool {
138 for _, p := range proprietaryDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900139 if strings.HasPrefix(dir, p) {
140 // filter out AOSP defined directories, e.g. hardware/interfaces/
141 aosp := false
142 for _, p := range aospDirsUnderProprietary {
143 if strings.HasPrefix(dir, p) {
144 aosp = true
145 break
146 }
147 }
148 if !aosp {
149 return true
150 }
151 }
152 }
153 return false
154}
155
Bill Peckham945441c2020-08-31 16:07:58 -0700156func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
Bill Peckham945441c2020-08-31 16:07:58 -0700157 // Any module in a vendor proprietary path is a vendor proprietary
158 // module.
Bill Peckham945441c2020-08-31 16:07:58 -0700159 if isVendorProprietaryPath(ctx.ModuleDir()) {
160 return true
161 }
162
163 // However if the module is not in a vendor proprietary path, it may
164 // still be a vendor proprietary module. This happens for cc modules
165 // that are excluded from the vendor snapshot, and it means that the
166 // vendor has assumed control of the framework-provided module.
Bill Peckham945441c2020-08-31 16:07:58 -0700167 if c, ok := ctx.Module().(*Module); ok {
168 if c.ExcludeFromVendorSnapshot() {
169 return true
170 }
171 }
172
173 return false
174}
175
Jose Galmes6f843bc2020-12-11 13:36:29 -0800176func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
177
Justin Yune09ac172021-01-20 19:49:01 +0900178 // Any module in a recovery proprietary path is a recovery proprietary
Jose Galmes6f843bc2020-12-11 13:36:29 -0800179 // module.
180 if isRecoveryProprietaryPath(ctx.ModuleDir()) {
181 return true
182 }
183
Justin Yune09ac172021-01-20 19:49:01 +0900184 // However if the module is not in a recovery proprietary path, it may
185 // still be a recovery proprietary module. This happens for cc modules
186 // that are excluded from the recovery snapshot, and it means that the
Jose Galmes6f843bc2020-12-11 13:36:29 -0800187 // vendor has assumed control of the framework-provided module.
188
189 if c, ok := ctx.Module().(*Module); ok {
190 if c.ExcludeFromRecoverySnapshot() {
191 return true
192 }
193 }
194
195 return false
196}
197
Inseob Kimde5744a2020-12-02 13:14:28 +0900198// Determines if the module is a candidate for snapshot.
Inseob Kim7cf14652021-01-06 23:06:52 +0900199func isSnapshotAware(cfg android.DeviceConfig, m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
Inseob Kim7f283f42020-06-01 21:53:49 +0900200 if !m.Enabled() || m.Properties.HideFromMake {
Inseob Kim8471cda2019-11-15 09:59:12 +0900201 return false
202 }
Martin Stjernholm809d5182020-09-10 01:46:05 +0100203 // When android/prebuilt.go selects between source and prebuilt, it sets
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800204 // HideFromMake on the other one to avoid duplicate install rules in make.
205 if m.IsHideFromMake() {
Martin Stjernholm809d5182020-09-10 01:46:05 +0100206 return false
207 }
Jose Galmesf7294582020-11-13 12:07:36 -0800208 // skip proprietary modules, but (for the vendor snapshot only)
209 // include all VNDK (static)
210 if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) {
Bill Peckham945441c2020-08-31 16:07:58 -0700211 return false
212 }
213 // If the module would be included based on its path, check to see if
214 // the module is marked to be excluded. If so, skip it.
Jose Galmes6f843bc2020-12-11 13:36:29 -0800215 if image.excludeFromSnapshot(m) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900216 return false
217 }
218 if m.Target().Os.Class != android.Device {
219 return false
220 }
221 if m.Target().NativeBridge == android.NativeBridgeEnabled {
222 return false
223 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900224 // the module must be installed in target image
Jose Galmesf7294582020-11-13 12:07:36 -0800225 if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !image.inImage(m)() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900226 return false
227 }
Inseob Kim65ca36a2020-06-11 13:55:45 +0900228 // skip kernel_headers which always depend on vendor
229 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
230 return false
231 }
Justin Yunf2664c62020-07-30 18:57:54 +0900232 // skip llndk_library and llndk_headers which are backward compatible
Colin Cross127bb8b2020-12-16 16:46:01 -0800233 if m.IsLlndk() {
234 return false
235 }
Justin Yunf2664c62020-07-30 18:57:54 +0900236 if _, ok := m.linker.(*llndkStubDecorator); ok {
237 return false
238 }
239 if _, ok := m.linker.(*llndkHeadersDecorator); ok {
240 return false
241 }
Inseob Kim7cf14652021-01-06 23:06:52 +0900242 // If we are using directed snapshot AND we have to exclude this module, skip this
243 if image.excludeFromDirectedSnapshot(cfg, m.BaseModuleName()) {
244 return false
245 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900246
247 // Libraries
248 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim7f283f42020-06-01 21:53:49 +0900249 if m.sanitize != nil {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900250 // scs and hwasan export both sanitized and unsanitized variants for static and header
Inseob Kim7f283f42020-06-01 21:53:49 +0900251 // Always use unsanitized variants of them.
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500252 for _, t := range []SanitizerType{scs, hwasan} {
Inseob Kim7f283f42020-06-01 21:53:49 +0900253 if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
254 return false
255 }
256 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900257 // cfi also exports both variants. But for static, we capture both.
Inseob Kimde5744a2020-12-02 13:14:28 +0900258 // This is because cfi static libraries can't be linked from non-cfi modules,
259 // and vice versa. This isn't the case for scs and hwasan sanitizers.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900260 if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
261 return false
262 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900263 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900264 if l.static() {
Justin Yune09ac172021-01-20 19:49:01 +0900265 return m.outputFile.Valid() && !image.private(m)
Inseob Kim8471cda2019-11-15 09:59:12 +0900266 }
267 if l.shared() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700268 if !m.outputFile.Valid() {
269 return false
270 }
Jose Galmesf7294582020-11-13 12:07:36 -0800271 if image.includeVndk() {
272 if !m.IsVndk() {
273 return true
274 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500275 return m.IsVndkExt()
Bill Peckham7d3f0962020-06-29 16:49:15 -0700276 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900277 }
278 return true
279 }
280
Inseob Kim1042d292020-06-01 23:23:05 +0900281 // Binaries and Objects
282 if m.binary() || m.object() {
Justin Yune09ac172021-01-20 19:49:01 +0900283 return m.outputFile.Valid()
Inseob Kim8471cda2019-11-15 09:59:12 +0900284 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900285
286 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900287}
288
Inseob Kimde5744a2020-12-02 13:14:28 +0900289// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
290// These flags become Android.bp snapshot module properties.
291type snapshotJsonFlags struct {
292 ModuleName string `json:",omitempty"`
293 RelativeInstallPath string `json:",omitempty"`
Colin Crossa8890802021-01-22 14:06:33 -0800294 AndroidMkSuffix string `json:",omitempty"`
Inseob Kimde5744a2020-12-02 13:14:28 +0900295
296 // library flags
297 ExportedDirs []string `json:",omitempty"`
298 ExportedSystemDirs []string `json:",omitempty"`
299 ExportedFlags []string `json:",omitempty"`
300 Sanitize string `json:",omitempty"`
301 SanitizeMinimalDep bool `json:",omitempty"`
302 SanitizeUbsanDep bool `json:",omitempty"`
303
304 // binary flags
305 Symlinks []string `json:",omitempty"`
306
307 // dependencies
308 SharedLibs []string `json:",omitempty"`
309 RuntimeLibs []string `json:",omitempty"`
310 Required []string `json:",omitempty"`
311
312 // extra config files
313 InitRc []string `json:",omitempty"`
314 VintfFragments []string `json:",omitempty"`
315}
316
Jose Galmesf7294582020-11-13 12:07:36 -0800317func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800318 if !c.image.shouldGenerateSnapshot(ctx) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900319 return
320 }
321
322 var snapshotOutputs android.Paths
323
324 /*
325 Vendor snapshot zipped artifacts directory structure:
326 {SNAPSHOT_ARCH}/
327 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
328 shared/
329 (.so shared libraries)
330 static/
331 (.a static libraries)
332 header/
333 (header only libraries)
334 binary/
335 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900336 object/
337 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900338 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
339 shared/
340 (.so shared libraries)
341 static/
342 (.a static libraries)
343 header/
344 (header only libraries)
345 binary/
346 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900347 object/
348 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900349 NOTICE_FILES/
350 (notice files, e.g. libbase.txt)
351 configs/
352 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
353 include/
354 (header files of same directory structure with source tree)
355 */
356
Jose Galmesf7294582020-11-13 12:07:36 -0800357 snapshotDir := c.name + "-snapshot"
Inseob Kime9aec6a2021-01-05 20:03:22 +0900358 if c.fake {
359 // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
360 // collision with real snapshot files
361 snapshotDir = filepath.Join("fake", snapshotDir)
362 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900363 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
364
365 includeDir := filepath.Join(snapshotArchDir, "include")
366 configsDir := filepath.Join(snapshotArchDir, "configs")
367 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
368
369 installedNotices := make(map[string]bool)
370 installedConfigs := make(map[string]bool)
371
372 var headers android.Paths
373
Inseob Kime9aec6a2021-01-05 20:03:22 +0900374 copyFile := copyFileRule
375 if c.fake {
376 // All prebuilt binaries and headers are installed by copyFile function. This makes a fake
377 // snapshot just touch prebuilts and headers, rather than installing real files.
378 copyFile = func(ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
379 return writeStringToFileRule(ctx, "", out)
380 }
381 }
382
Inseob Kimde5744a2020-12-02 13:14:28 +0900383 // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
384 // For executables, init_rc and vintf_fragments files are also copied.
Inseob Kim8471cda2019-11-15 09:59:12 +0900385 installSnapshot := func(m *Module) android.Paths {
386 targetArch := "arch-" + m.Target().Arch.ArchType.String()
387 if m.Target().Arch.ArchVariant != "" {
388 targetArch += "-" + m.Target().Arch.ArchVariant
389 }
390
391 var ret android.Paths
392
Inseob Kimde5744a2020-12-02 13:14:28 +0900393 prop := snapshotJsonFlags{}
Inseob Kim8471cda2019-11-15 09:59:12 +0900394
395 // Common properties among snapshots.
396 prop.ModuleName = ctx.ModuleName(m)
Ivan Lozanof9e21722020-12-02 09:00:51 -0500397 if c.supportsVndkExt && m.IsVndkExt() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700398 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
399 if m.isVndkSp() {
400 prop.RelativeInstallPath = "vndk-sp"
401 } else {
402 prop.RelativeInstallPath = "vndk"
403 }
404 } else {
405 prop.RelativeInstallPath = m.RelativeInstallPath()
406 }
Colin Crossa8890802021-01-22 14:06:33 -0800407 prop.AndroidMkSuffix = m.Properties.SubName
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 }
Bill Peckham945441c2020-08-31 16:07:58 -0700529 }
530
Inseob Kim7cf14652021-01-06 23:06:52 +0900531 if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, c.image) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900532 return
533 }
534
Inseob Kimde5744a2020-12-02 13:14:28 +0900535 // installSnapshot installs prebuilts and json flag files
Inseob Kim8471cda2019-11-15 09:59:12 +0900536 snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
Inseob Kimde5744a2020-12-02 13:14:28 +0900537
538 // just gather headers and notice files here, because they are to be deduplicated
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900539 if l, ok := m.linker.(snapshotLibraryInterface); ok {
540 headers = append(headers, l.snapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +0900541 }
542
Bob Badoura75b0572020-02-18 20:21:55 -0800543 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900544 noticeName := ctx.ModuleName(m) + ".txt"
545 noticeOut := filepath.Join(noticeDir, noticeName)
546 // skip already copied notice file
547 if !installedNotices[noticeOut] {
548 installedNotices[noticeOut] = true
Inseob Kime9aec6a2021-01-05 20:03:22 +0900549 snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.NoticeFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900550 }
551 }
552 })
553
554 // install all headers after removing duplicates
555 for _, header := range android.FirstUniquePaths(headers) {
Inseob Kime9aec6a2021-01-05 20:03:22 +0900556 snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String())))
Inseob Kim8471cda2019-11-15 09:59:12 +0900557 }
558
559 // All artifacts are ready. Sort them to normalize ninja and then zip.
560 sort.Slice(snapshotOutputs, func(i, j int) bool {
561 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
562 })
563
Jose Galmesf7294582020-11-13 12:07:36 -0800564 zipPath := android.PathForOutput(
565 ctx,
566 snapshotDir,
567 c.name+"-"+ctx.Config().DeviceName()+".zip")
Colin Crossf1a035e2020-11-16 17:32:30 -0800568 zipRule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim8471cda2019-11-15 09:59:12 +0900569
570 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
Jose Galmesf7294582020-11-13 12:07:36 -0800571 snapshotOutputList := android.PathForOutput(
572 ctx,
573 snapshotDir,
574 c.name+"-"+ctx.Config().DeviceName()+"_list")
Inseob Kim8471cda2019-11-15 09:59:12 +0900575 zipRule.Command().
576 Text("tr").
577 FlagWithArg("-d ", "\\'").
578 FlagWithRspFileInputList("< ", snapshotOutputs).
579 FlagWithOutput("> ", snapshotOutputList)
580
581 zipRule.Temporary(snapshotOutputList)
582
583 zipRule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800584 BuiltTool("soong_zip").
Inseob Kim8471cda2019-11-15 09:59:12 +0900585 FlagWithOutput("-o ", zipPath).
586 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
587 FlagWithInput("-l ", snapshotOutputList)
588
Colin Crossf1a035e2020-11-16 17:32:30 -0800589 zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900590 zipRule.DeleteTemporaryFiles()
Jose Galmesf7294582020-11-13 12:07:36 -0800591 c.snapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim8471cda2019-11-15 09:59:12 +0900592}
593
Jose Galmesf7294582020-11-13 12:07:36 -0800594func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
595 ctx.Strict(
596 c.makeVar,
597 c.snapshotZipFile.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900598}