blob: 417516bf9fe509c0a16b6664df8a339a1ae61512 [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,
Jose Galmesf7294582020-11-13 12:07:36 -080037}
38
39var recoverySnapshotSingleton = snapshotSingleton{
40 "recovery",
41 "SOONG_RECOVERY_SNAPSHOT_ZIP",
42 android.OptionalPath{},
43 false,
Inseob Kimde5744a2020-12-02 13:14:28 +090044 recoverySnapshotImageSingleton,
Inseob Kim8471cda2019-11-15 09:59:12 +090045}
46
47func VendorSnapshotSingleton() android.Singleton {
Jose Galmesf7294582020-11-13 12:07:36 -080048 return &vendorSnapshotSingleton
Inseob Kim8471cda2019-11-15 09:59:12 +090049}
50
Jose Galmesf7294582020-11-13 12:07:36 -080051func RecoverySnapshotSingleton() android.Singleton {
52 return &recoverySnapshotSingleton
53}
54
55type snapshotSingleton struct {
56 // Name, e.g., "vendor", "recovery", "ramdisk".
57 name string
58
59 // Make variable that points to the snapshot file, e.g.,
60 // "SOONG_RECOVERY_SNAPSHOT_ZIP".
61 makeVar string
62
63 // Path to the snapshot zip file.
64 snapshotZipFile android.OptionalPath
65
66 // Whether the image supports VNDK extension modules.
67 supportsVndkExt bool
68
69 // Implementation of the image interface specific to the image
70 // associated with this snapshot (e.g., specific to the vendor image,
71 // recovery image, etc.).
Inseob Kimde5744a2020-12-02 13:14:28 +090072 image snapshotImage
Inseob Kim8471cda2019-11-15 09:59:12 +090073}
74
75var (
76 // Modules under following directories are ignored. They are OEM's and vendor's
Daniel Norman713387d2020-07-28 16:04:38 -070077 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Inseob Kim8471cda2019-11-15 09:59:12 +090078 vendorProprietaryDirs = []string{
79 "device",
Daniel Norman713387d2020-07-28 16:04:38 -070080 "kernel",
Inseob Kim8471cda2019-11-15 09:59:12 +090081 "vendor",
82 "hardware",
83 }
84
Jose Galmesf7294582020-11-13 12:07:36 -080085 // Modules under following directories are ignored. They are OEM's and vendor's
86 // proprietary modules(device/, kernel/, vendor/, and hardware/).
Jose Galmesf7294582020-11-13 12:07:36 -080087 recoveryProprietaryDirs = []string{
Jose Galmesf7294582020-11-13 12:07:36 -080088 "device",
89 "hardware",
90 "kernel",
91 "vendor",
92 }
93
Inseob Kim8471cda2019-11-15 09:59:12 +090094 // Modules under following directories are included as they are in AOSP,
Daniel Norman713387d2020-07-28 16:04:38 -070095 // although hardware/ and kernel/ are normally for vendor's own.
Inseob Kim8471cda2019-11-15 09:59:12 +090096 aospDirsUnderProprietary = []string{
Daniel Norman713387d2020-07-28 16:04:38 -070097 "kernel/configs",
98 "kernel/prebuilts",
99 "kernel/tests",
Inseob Kim8471cda2019-11-15 09:59:12 +0900100 "hardware/interfaces",
101 "hardware/libhardware",
102 "hardware/libhardware_legacy",
103 "hardware/ril",
104 }
105)
106
107// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
108// device/, vendor/, etc.
109func isVendorProprietaryPath(dir string) bool {
Jose Galmesf7294582020-11-13 12:07:36 -0800110 return isProprietaryPath(dir, vendorProprietaryDirs)
111}
112
113func isRecoveryProprietaryPath(dir string) bool {
114 return isProprietaryPath(dir, recoveryProprietaryDirs)
115}
116
117// Determine if a dir under source tree is an SoC-owned proprietary directory, such as
118// device/, vendor/, etc.
119func isProprietaryPath(dir string, proprietaryDirs []string) bool {
120 for _, p := range proprietaryDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900121 if strings.HasPrefix(dir, p) {
122 // filter out AOSP defined directories, e.g. hardware/interfaces/
123 aosp := false
124 for _, p := range aospDirsUnderProprietary {
125 if strings.HasPrefix(dir, p) {
126 aosp = true
127 break
128 }
129 }
130 if !aosp {
131 return true
132 }
133 }
134 }
135 return false
136}
137
Bill Peckham945441c2020-08-31 16:07:58 -0700138func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
Bill Peckham945441c2020-08-31 16:07:58 -0700139 // Any module in a vendor proprietary path is a vendor proprietary
140 // module.
Bill Peckham945441c2020-08-31 16:07:58 -0700141 if isVendorProprietaryPath(ctx.ModuleDir()) {
142 return true
143 }
144
145 // However if the module is not in a vendor proprietary path, it may
146 // still be a vendor proprietary module. This happens for cc modules
147 // that are excluded from the vendor snapshot, and it means that the
148 // vendor has assumed control of the framework-provided module.
Bill Peckham945441c2020-08-31 16:07:58 -0700149 if c, ok := ctx.Module().(*Module); ok {
150 if c.ExcludeFromVendorSnapshot() {
151 return true
152 }
153 }
154
155 return false
156}
157
Jose Galmes6f843bc2020-12-11 13:36:29 -0800158func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
159
160 // Any module in a vendor proprietary path is a vendor proprietary
161 // module.
162 if isRecoveryProprietaryPath(ctx.ModuleDir()) {
163 return true
164 }
165
166 // However if the module is not in a vendor proprietary path, it may
167 // still be a vendor proprietary module. This happens for cc modules
168 // that are excluded from the vendor snapshot, and it means that the
169 // vendor has assumed control of the framework-provided module.
170
171 if c, ok := ctx.Module().(*Module); ok {
172 if c.ExcludeFromRecoverySnapshot() {
173 return true
174 }
175 }
176
177 return false
178}
179
Inseob Kim8471cda2019-11-15 09:59:12 +0900180// Determine if a module is going to be included in vendor snapshot or not.
181//
182// Targets of vendor snapshot are "vendor: true" or "vendor_available: true" modules in
183// AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might
184// depend on newer VNDK) So they are captured as vendor snapshot To build older vendor
185// image and newer system image altogether.
Inseob Kimde5744a2020-12-02 13:14:28 +0900186func isVendorSnapshotAware(m *Module, inVendorProprietaryPath bool, apexInfo android.ApexInfo) bool {
187 return isSnapshotAware(m, inVendorProprietaryPath, apexInfo, vendorSnapshotImageSingleton)
Jose Galmesf7294582020-11-13 12:07:36 -0800188}
189
Inseob Kimde5744a2020-12-02 13:14:28 +0900190// Determine if a module is going to be included in recovery snapshot or not.
191//
192// Targets of recovery snapshot are "recovery: true" or "recovery_available: true"
193// modules in AOSP. They are not guaranteed to be compatible with older recovery images.
194// So they are captured as recovery snapshot To build older recovery image.
195func isRecoverySnapshotAware(m *Module, inRecoveryProprietaryPath bool, apexInfo android.ApexInfo) bool {
196 return isSnapshotAware(m, inRecoveryProprietaryPath, apexInfo, recoverySnapshotImageSingleton)
Jose Galmesf7294582020-11-13 12:07:36 -0800197}
198
Inseob Kimde5744a2020-12-02 13:14:28 +0900199// Determines if the module is a candidate for snapshot.
200func isSnapshotAware(m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
Inseob Kim7f283f42020-06-01 21:53:49 +0900201 if !m.Enabled() || m.Properties.HideFromMake {
Inseob Kim8471cda2019-11-15 09:59:12 +0900202 return false
203 }
Martin Stjernholm809d5182020-09-10 01:46:05 +0100204 // When android/prebuilt.go selects between source and prebuilt, it sets
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800205 // HideFromMake on the other one to avoid duplicate install rules in make.
206 if m.IsHideFromMake() {
Martin Stjernholm809d5182020-09-10 01:46:05 +0100207 return false
208 }
Jose Galmesf7294582020-11-13 12:07:36 -0800209 // skip proprietary modules, but (for the vendor snapshot only)
210 // include all VNDK (static)
211 if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) {
Bill Peckham945441c2020-08-31 16:07:58 -0700212 return false
213 }
214 // If the module would be included based on its path, check to see if
215 // the module is marked to be excluded. If so, skip it.
Jose Galmes6f843bc2020-12-11 13:36:29 -0800216 if image.excludeFromSnapshot(m) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900217 return false
218 }
219 if m.Target().Os.Class != android.Device {
220 return false
221 }
222 if m.Target().NativeBridge == android.NativeBridgeEnabled {
223 return false
224 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900225 // the module must be installed in target image
Jose Galmesf7294582020-11-13 12:07:36 -0800226 if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !image.inImage(m)() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900227 return false
228 }
Inseob Kim65ca36a2020-06-11 13:55:45 +0900229 // skip kernel_headers which always depend on vendor
230 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
231 return false
232 }
Justin Yunf2664c62020-07-30 18:57:54 +0900233 // skip llndk_library and llndk_headers which are backward compatible
Colin Cross127bb8b2020-12-16 16:46:01 -0800234 if m.IsLlndk() {
235 return false
236 }
Justin Yunf2664c62020-07-30 18:57:54 +0900237 if _, ok := m.linker.(*llndkStubDecorator); ok {
238 return false
239 }
240 if _, ok := m.linker.(*llndkHeadersDecorator); ok {
241 return false
242 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900243
244 // Libraries
245 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim7f283f42020-06-01 21:53:49 +0900246 if m.sanitize != nil {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900247 // scs and hwasan export both sanitized and unsanitized variants for static and header
Inseob Kim7f283f42020-06-01 21:53:49 +0900248 // Always use unsanitized variants of them.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900249 for _, t := range []sanitizerType{scs, hwasan} {
Inseob Kim7f283f42020-06-01 21:53:49 +0900250 if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
251 return false
252 }
253 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900254 // cfi also exports both variants. But for static, we capture both.
Inseob Kimde5744a2020-12-02 13:14:28 +0900255 // This is because cfi static libraries can't be linked from non-cfi modules,
256 // and vice versa. This isn't the case for scs and hwasan sanitizers.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900257 if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
258 return false
259 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900260 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900261 if l.static() {
Jose Galmesf7294582020-11-13 12:07:36 -0800262 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900263 }
264 if l.shared() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700265 if !m.outputFile.Valid() {
266 return false
267 }
Jose Galmesf7294582020-11-13 12:07:36 -0800268 if image.includeVndk() {
269 if !m.IsVndk() {
270 return true
271 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500272 return m.IsVndkExt()
Bill Peckham7d3f0962020-06-29 16:49:15 -0700273 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900274 }
275 return true
276 }
277
Inseob Kim1042d292020-06-01 23:23:05 +0900278 // Binaries and Objects
279 if m.binary() || m.object() {
Jose Galmesf7294582020-11-13 12:07:36 -0800280 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900281 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900282
283 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900284}
285
Inseob Kimde5744a2020-12-02 13:14:28 +0900286// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
287// These flags become Android.bp snapshot module properties.
288type snapshotJsonFlags struct {
289 ModuleName string `json:",omitempty"`
290 RelativeInstallPath string `json:",omitempty"`
291
292 // library flags
293 ExportedDirs []string `json:",omitempty"`
294 ExportedSystemDirs []string `json:",omitempty"`
295 ExportedFlags []string `json:",omitempty"`
296 Sanitize string `json:",omitempty"`
297 SanitizeMinimalDep bool `json:",omitempty"`
298 SanitizeUbsanDep bool `json:",omitempty"`
299
300 // binary flags
301 Symlinks []string `json:",omitempty"`
302
303 // dependencies
304 SharedLibs []string `json:",omitempty"`
305 RuntimeLibs []string `json:",omitempty"`
306 Required []string `json:",omitempty"`
307
308 // extra config files
309 InitRc []string `json:",omitempty"`
310 VintfFragments []string `json:",omitempty"`
311}
312
Jose Galmesf7294582020-11-13 12:07:36 -0800313func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800314 if !c.image.shouldGenerateSnapshot(ctx) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900315 return
316 }
317
318 var snapshotOutputs android.Paths
319
320 /*
321 Vendor snapshot zipped artifacts directory structure:
322 {SNAPSHOT_ARCH}/
323 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
324 shared/
325 (.so shared libraries)
326 static/
327 (.a static libraries)
328 header/
329 (header only libraries)
330 binary/
331 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900332 object/
333 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900334 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
335 shared/
336 (.so shared libraries)
337 static/
338 (.a static libraries)
339 header/
340 (header only libraries)
341 binary/
342 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900343 object/
344 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900345 NOTICE_FILES/
346 (notice files, e.g. libbase.txt)
347 configs/
348 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
349 include/
350 (header files of same directory structure with source tree)
351 */
352
Jose Galmesf7294582020-11-13 12:07:36 -0800353 snapshotDir := c.name + "-snapshot"
Inseob Kim8471cda2019-11-15 09:59:12 +0900354 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
355
356 includeDir := filepath.Join(snapshotArchDir, "include")
357 configsDir := filepath.Join(snapshotArchDir, "configs")
358 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
359
360 installedNotices := make(map[string]bool)
361 installedConfigs := make(map[string]bool)
362
363 var headers android.Paths
364
Inseob Kimde5744a2020-12-02 13:14:28 +0900365 // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
366 // For executables, init_rc and vintf_fragments files are also copied.
Inseob Kim8471cda2019-11-15 09:59:12 +0900367 installSnapshot := func(m *Module) android.Paths {
368 targetArch := "arch-" + m.Target().Arch.ArchType.String()
369 if m.Target().Arch.ArchVariant != "" {
370 targetArch += "-" + m.Target().Arch.ArchVariant
371 }
372
373 var ret android.Paths
374
Inseob Kimde5744a2020-12-02 13:14:28 +0900375 prop := snapshotJsonFlags{}
Inseob Kim8471cda2019-11-15 09:59:12 +0900376
377 // Common properties among snapshots.
378 prop.ModuleName = ctx.ModuleName(m)
Ivan Lozanof9e21722020-12-02 09:00:51 -0500379 if c.supportsVndkExt && m.IsVndkExt() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700380 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
381 if m.isVndkSp() {
382 prop.RelativeInstallPath = "vndk-sp"
383 } else {
384 prop.RelativeInstallPath = "vndk"
385 }
386 } else {
387 prop.RelativeInstallPath = m.RelativeInstallPath()
388 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900389 prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
390 prop.Required = m.RequiredModuleNames()
391 for _, path := range m.InitRc() {
392 prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
393 }
394 for _, path := range m.VintfFragments() {
395 prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
396 }
397
398 // install config files. ignores any duplicates.
399 for _, path := range append(m.InitRc(), m.VintfFragments()...) {
400 out := filepath.Join(configsDir, path.Base())
401 if !installedConfigs[out] {
402 installedConfigs[out] = true
Inseob Kimde5744a2020-12-02 13:14:28 +0900403 ret = append(ret, copyFileRule(ctx, path, out))
Inseob Kim8471cda2019-11-15 09:59:12 +0900404 }
405 }
406
407 var propOut string
408
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900409 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Colin Cross0de8a1e2020-09-18 14:15:30 -0700410 exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
Inseob Kimc42f2f22020-07-29 20:32:10 +0900411
Inseob Kim8471cda2019-11-15 09:59:12 +0900412 // library flags
Colin Cross0de8a1e2020-09-18 14:15:30 -0700413 prop.ExportedFlags = exporterInfo.Flags
414 for _, dir := range exporterInfo.IncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900415 prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
416 }
Colin Cross0de8a1e2020-09-18 14:15:30 -0700417 for _, dir := range exporterInfo.SystemIncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900418 prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
419 }
420 // shared libs dependencies aren't meaningful on static or header libs
421 if l.shared() {
422 prop.SharedLibs = m.Properties.SnapshotSharedLibs
423 }
424 if l.static() && m.sanitize != nil {
425 prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
426 prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
427 }
428
429 var libType string
430 if l.static() {
431 libType = "static"
432 } else if l.shared() {
433 libType = "shared"
434 } else {
435 libType = "header"
436 }
437
438 var stem string
439
440 // install .a or .so
441 if libType != "header" {
442 libPath := m.outputFile.Path()
443 stem = libPath.Base()
Inseob Kimc42f2f22020-07-29 20:32:10 +0900444 if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(cfi) {
445 // both cfi and non-cfi variant for static libraries can exist.
446 // attach .cfi to distinguish between cfi and non-cfi.
447 // e.g. libbase.a -> libbase.cfi.a
448 ext := filepath.Ext(stem)
449 stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
450 prop.Sanitize = "cfi"
451 prop.ModuleName += ".cfi"
452 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900453 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
Inseob Kimde5744a2020-12-02 13:14:28 +0900454 ret = append(ret, copyFileRule(ctx, libPath, snapshotLibOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900455 } else {
456 stem = ctx.ModuleName(m)
457 }
458
459 propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
Inseob Kim7f283f42020-06-01 21:53:49 +0900460 } else if m.binary() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900461 // binary flags
462 prop.Symlinks = m.Symlinks()
463 prop.SharedLibs = m.Properties.SnapshotSharedLibs
464
465 // install bin
466 binPath := m.outputFile.Path()
467 snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
Inseob Kimde5744a2020-12-02 13:14:28 +0900468 ret = append(ret, copyFileRule(ctx, binPath, snapshotBinOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900469 propOut = snapshotBinOut + ".json"
Inseob Kim1042d292020-06-01 23:23:05 +0900470 } else if m.object() {
471 // object files aren't installed to the device, so their names can conflict.
472 // Use module name as stem.
473 objPath := m.outputFile.Path()
474 snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
475 ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
Inseob Kimde5744a2020-12-02 13:14:28 +0900476 ret = append(ret, copyFileRule(ctx, objPath, snapshotObjOut))
Inseob Kim1042d292020-06-01 23:23:05 +0900477 propOut = snapshotObjOut + ".json"
Inseob Kim7f283f42020-06-01 21:53:49 +0900478 } else {
479 ctx.Errorf("unknown module %q in vendor snapshot", m.String())
480 return nil
Inseob Kim8471cda2019-11-15 09:59:12 +0900481 }
482
483 j, err := json.Marshal(prop)
484 if err != nil {
485 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
486 return nil
487 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900488 ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900489
490 return ret
491 }
492
493 ctx.VisitAllModules(func(module android.Module) {
494 m, ok := module.(*Module)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900495 if !ok {
496 return
497 }
498
499 moduleDir := ctx.ModuleDir(module)
Jose Galmesf7294582020-11-13 12:07:36 -0800500 inProprietaryPath := c.image.isProprietaryPath(moduleDir)
Colin Cross56a83212020-09-15 18:30:11 -0700501 apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
Bill Peckham945441c2020-08-31 16:07:58 -0700502
Jose Galmes6f843bc2020-12-11 13:36:29 -0800503 if c.image.excludeFromSnapshot(m) {
Jose Galmesf7294582020-11-13 12:07:36 -0800504 if inProprietaryPath {
Bill Peckham945441c2020-08-31 16:07:58 -0700505 // Error: exclude_from_vendor_snapshot applies
506 // to framework-path modules only.
507 ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
508 return
509 }
Jose Galmesf7294582020-11-13 12:07:36 -0800510 if Bool(c.image.available(m)) {
Bill Peckham945441c2020-08-31 16:07:58 -0700511 // Error: may not combine "vendor_available:
512 // true" with "exclude_from_vendor_snapshot:
513 // true".
Jose Galmesf7294582020-11-13 12:07:36 -0800514 ctx.Errorf(
515 "module %q may not use both \""+
516 c.name+
517 "_available: true\" and \"exclude_from_vendor_snapshot: true\"",
518 m.String())
Bill Peckham945441c2020-08-31 16:07:58 -0700519 return
520 }
521 }
522
Inseob Kimde5744a2020-12-02 13:14:28 +0900523 if !isSnapshotAware(m, inProprietaryPath, apexInfo, c.image) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900524 return
525 }
526
Inseob Kimde5744a2020-12-02 13:14:28 +0900527 // installSnapshot installs prebuilts and json flag files
Inseob Kim8471cda2019-11-15 09:59:12 +0900528 snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
Inseob Kimde5744a2020-12-02 13:14:28 +0900529
530 // just gather headers and notice files here, because they are to be deduplicated
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900531 if l, ok := m.linker.(snapshotLibraryInterface); ok {
532 headers = append(headers, l.snapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +0900533 }
534
Bob Badoura75b0572020-02-18 20:21:55 -0800535 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900536 noticeName := ctx.ModuleName(m) + ".txt"
537 noticeOut := filepath.Join(noticeDir, noticeName)
538 // skip already copied notice file
539 if !installedNotices[noticeOut] {
540 installedNotices[noticeOut] = true
Inseob Kimde5744a2020-12-02 13:14:28 +0900541 snapshotOutputs = append(snapshotOutputs, combineNoticesRule(
Bob Badoura75b0572020-02-18 20:21:55 -0800542 ctx, m.NoticeFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900543 }
544 }
545 })
546
547 // install all headers after removing duplicates
548 for _, header := range android.FirstUniquePaths(headers) {
Inseob Kimde5744a2020-12-02 13:14:28 +0900549 snapshotOutputs = append(snapshotOutputs, copyFileRule(
Inseob Kim8471cda2019-11-15 09:59:12 +0900550 ctx, header, filepath.Join(includeDir, header.String())))
551 }
552
553 // All artifacts are ready. Sort them to normalize ninja and then zip.
554 sort.Slice(snapshotOutputs, func(i, j int) bool {
555 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
556 })
557
Jose Galmesf7294582020-11-13 12:07:36 -0800558 zipPath := android.PathForOutput(
559 ctx,
560 snapshotDir,
561 c.name+"-"+ctx.Config().DeviceName()+".zip")
Colin Crossf1a035e2020-11-16 17:32:30 -0800562 zipRule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim8471cda2019-11-15 09:59:12 +0900563
564 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
Jose Galmesf7294582020-11-13 12:07:36 -0800565 snapshotOutputList := android.PathForOutput(
566 ctx,
567 snapshotDir,
568 c.name+"-"+ctx.Config().DeviceName()+"_list")
Inseob Kim8471cda2019-11-15 09:59:12 +0900569 zipRule.Command().
570 Text("tr").
571 FlagWithArg("-d ", "\\'").
572 FlagWithRspFileInputList("< ", snapshotOutputs).
573 FlagWithOutput("> ", snapshotOutputList)
574
575 zipRule.Temporary(snapshotOutputList)
576
577 zipRule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800578 BuiltTool("soong_zip").
Inseob Kim8471cda2019-11-15 09:59:12 +0900579 FlagWithOutput("-o ", zipPath).
580 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
581 FlagWithInput("-l ", snapshotOutputList)
582
Colin Crossf1a035e2020-11-16 17:32:30 -0800583 zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900584 zipRule.DeleteTemporaryFiles()
Jose Galmesf7294582020-11-13 12:07:36 -0800585 c.snapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim8471cda2019-11-15 09:59:12 +0900586}
587
Jose Galmesf7294582020-11-13 12:07:36 -0800588func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
589 ctx.Strict(
590 c.makeVar,
591 c.snapshotZipFile.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900592}