blob: 0e1dd6b4c60e10ee6f859c250bfab247849e3a90 [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 Kim8471cda2019-11-15 09:59:12 +0900200// Determine if a module is going to be included in vendor snapshot or not.
201//
202// Targets of vendor snapshot are "vendor: true" or "vendor_available: true" modules in
203// AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might
204// depend on newer VNDK) So they are captured as vendor snapshot To build older vendor
205// image and newer system image altogether.
Inseob Kimde5744a2020-12-02 13:14:28 +0900206func isVendorSnapshotAware(m *Module, inVendorProprietaryPath bool, apexInfo android.ApexInfo) bool {
207 return isSnapshotAware(m, inVendorProprietaryPath, apexInfo, vendorSnapshotImageSingleton)
Jose Galmesf7294582020-11-13 12:07:36 -0800208}
209
Inseob Kimde5744a2020-12-02 13:14:28 +0900210// Determine if a module is going to be included in recovery snapshot or not.
211//
212// Targets of recovery snapshot are "recovery: true" or "recovery_available: true"
213// modules in AOSP. They are not guaranteed to be compatible with older recovery images.
214// So they are captured as recovery snapshot To build older recovery image.
215func isRecoverySnapshotAware(m *Module, inRecoveryProprietaryPath bool, apexInfo android.ApexInfo) bool {
216 return isSnapshotAware(m, inRecoveryProprietaryPath, apexInfo, recoverySnapshotImageSingleton)
Jose Galmesf7294582020-11-13 12:07:36 -0800217}
218
Inseob Kimde5744a2020-12-02 13:14:28 +0900219// Determines if the module is a candidate for snapshot.
220func isSnapshotAware(m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
Inseob Kim7f283f42020-06-01 21:53:49 +0900221 if !m.Enabled() || m.Properties.HideFromMake {
Inseob Kim8471cda2019-11-15 09:59:12 +0900222 return false
223 }
Martin Stjernholm809d5182020-09-10 01:46:05 +0100224 // When android/prebuilt.go selects between source and prebuilt, it sets
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800225 // HideFromMake on the other one to avoid duplicate install rules in make.
226 if m.IsHideFromMake() {
Martin Stjernholm809d5182020-09-10 01:46:05 +0100227 return false
228 }
Jose Galmesf7294582020-11-13 12:07:36 -0800229 // skip proprietary modules, but (for the vendor snapshot only)
230 // include all VNDK (static)
231 if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) {
Bill Peckham945441c2020-08-31 16:07:58 -0700232 return false
233 }
234 // If the module would be included based on its path, check to see if
235 // the module is marked to be excluded. If so, skip it.
Jose Galmes6f843bc2020-12-11 13:36:29 -0800236 if image.excludeFromSnapshot(m) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900237 return false
238 }
239 if m.Target().Os.Class != android.Device {
240 return false
241 }
242 if m.Target().NativeBridge == android.NativeBridgeEnabled {
243 return false
244 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900245 // the module must be installed in target image
Jose Galmesf7294582020-11-13 12:07:36 -0800246 if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !image.inImage(m)() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900247 return false
248 }
Inseob Kim65ca36a2020-06-11 13:55:45 +0900249 // skip kernel_headers which always depend on vendor
250 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
251 return false
252 }
Justin Yunf2664c62020-07-30 18:57:54 +0900253 // skip llndk_library and llndk_headers which are backward compatible
Colin Cross127bb8b2020-12-16 16:46:01 -0800254 if m.IsLlndk() {
255 return false
256 }
Justin Yunf2664c62020-07-30 18:57:54 +0900257 if _, ok := m.linker.(*llndkStubDecorator); ok {
258 return false
259 }
260 if _, ok := m.linker.(*llndkHeadersDecorator); ok {
261 return false
262 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900263
264 // Libraries
265 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Inseob Kim7f283f42020-06-01 21:53:49 +0900266 if m.sanitize != nil {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900267 // scs and hwasan export both sanitized and unsanitized variants for static and header
Inseob Kim7f283f42020-06-01 21:53:49 +0900268 // Always use unsanitized variants of them.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900269 for _, t := range []sanitizerType{scs, hwasan} {
Inseob Kim7f283f42020-06-01 21:53:49 +0900270 if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
271 return false
272 }
273 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900274 // cfi also exports both variants. But for static, we capture both.
Inseob Kimde5744a2020-12-02 13:14:28 +0900275 // This is because cfi static libraries can't be linked from non-cfi modules,
276 // and vice versa. This isn't the case for scs and hwasan sanitizers.
Inseob Kimc42f2f22020-07-29 20:32:10 +0900277 if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
278 return false
279 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900280 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900281 if l.static() {
Jose Galmesf7294582020-11-13 12:07:36 -0800282 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900283 }
284 if l.shared() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700285 if !m.outputFile.Valid() {
286 return false
287 }
Jose Galmesf7294582020-11-13 12:07:36 -0800288 if image.includeVndk() {
289 if !m.IsVndk() {
290 return true
291 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500292 return m.IsVndkExt()
Bill Peckham7d3f0962020-06-29 16:49:15 -0700293 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900294 }
295 return true
296 }
297
Inseob Kim1042d292020-06-01 23:23:05 +0900298 // Binaries and Objects
299 if m.binary() || m.object() {
Jose Galmesf7294582020-11-13 12:07:36 -0800300 return m.outputFile.Valid() && proptools.BoolDefault(image.available(m), true)
Inseob Kim8471cda2019-11-15 09:59:12 +0900301 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900302
303 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900304}
305
Inseob Kimde5744a2020-12-02 13:14:28 +0900306// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
307// These flags become Android.bp snapshot module properties.
308type snapshotJsonFlags struct {
309 ModuleName string `json:",omitempty"`
310 RelativeInstallPath string `json:",omitempty"`
311
312 // library flags
313 ExportedDirs []string `json:",omitempty"`
314 ExportedSystemDirs []string `json:",omitempty"`
315 ExportedFlags []string `json:",omitempty"`
316 Sanitize string `json:",omitempty"`
317 SanitizeMinimalDep bool `json:",omitempty"`
318 SanitizeUbsanDep bool `json:",omitempty"`
319
320 // binary flags
321 Symlinks []string `json:",omitempty"`
322
323 // dependencies
324 SharedLibs []string `json:",omitempty"`
325 RuntimeLibs []string `json:",omitempty"`
326 Required []string `json:",omitempty"`
327
328 // extra config files
329 InitRc []string `json:",omitempty"`
330 VintfFragments []string `json:",omitempty"`
331}
332
Jose Galmesf7294582020-11-13 12:07:36 -0800333func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800334 if !c.image.shouldGenerateSnapshot(ctx) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900335 return
336 }
337
338 var snapshotOutputs android.Paths
339
340 /*
341 Vendor snapshot zipped artifacts directory structure:
342 {SNAPSHOT_ARCH}/
343 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
344 shared/
345 (.so shared libraries)
346 static/
347 (.a static libraries)
348 header/
349 (header only libraries)
350 binary/
351 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900352 object/
353 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900354 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
355 shared/
356 (.so shared libraries)
357 static/
358 (.a static libraries)
359 header/
360 (header only libraries)
361 binary/
362 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900363 object/
364 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900365 NOTICE_FILES/
366 (notice files, e.g. libbase.txt)
367 configs/
368 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
369 include/
370 (header files of same directory structure with source tree)
371 */
372
Jose Galmesf7294582020-11-13 12:07:36 -0800373 snapshotDir := c.name + "-snapshot"
Inseob Kime9aec6a2021-01-05 20:03:22 +0900374 if c.fake {
375 // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
376 // collision with real snapshot files
377 snapshotDir = filepath.Join("fake", snapshotDir)
378 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900379 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
380
381 includeDir := filepath.Join(snapshotArchDir, "include")
382 configsDir := filepath.Join(snapshotArchDir, "configs")
383 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
384
385 installedNotices := make(map[string]bool)
386 installedConfigs := make(map[string]bool)
387
388 var headers android.Paths
389
Inseob Kime9aec6a2021-01-05 20:03:22 +0900390 copyFile := copyFileRule
391 if c.fake {
392 // All prebuilt binaries and headers are installed by copyFile function. This makes a fake
393 // snapshot just touch prebuilts and headers, rather than installing real files.
394 copyFile = func(ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
395 return writeStringToFileRule(ctx, "", out)
396 }
397 }
398
Inseob Kimde5744a2020-12-02 13:14:28 +0900399 // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
400 // For executables, init_rc and vintf_fragments files are also copied.
Inseob Kim8471cda2019-11-15 09:59:12 +0900401 installSnapshot := func(m *Module) android.Paths {
402 targetArch := "arch-" + m.Target().Arch.ArchType.String()
403 if m.Target().Arch.ArchVariant != "" {
404 targetArch += "-" + m.Target().Arch.ArchVariant
405 }
406
407 var ret android.Paths
408
Inseob Kimde5744a2020-12-02 13:14:28 +0900409 prop := snapshotJsonFlags{}
Inseob Kim8471cda2019-11-15 09:59:12 +0900410
411 // Common properties among snapshots.
412 prop.ModuleName = ctx.ModuleName(m)
Ivan Lozanof9e21722020-12-02 09:00:51 -0500413 if c.supportsVndkExt && m.IsVndkExt() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700414 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
415 if m.isVndkSp() {
416 prop.RelativeInstallPath = "vndk-sp"
417 } else {
418 prop.RelativeInstallPath = "vndk"
419 }
420 } else {
421 prop.RelativeInstallPath = m.RelativeInstallPath()
422 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900423 prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
424 prop.Required = m.RequiredModuleNames()
425 for _, path := range m.InitRc() {
426 prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
427 }
428 for _, path := range m.VintfFragments() {
429 prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
430 }
431
432 // install config files. ignores any duplicates.
433 for _, path := range append(m.InitRc(), m.VintfFragments()...) {
434 out := filepath.Join(configsDir, path.Base())
435 if !installedConfigs[out] {
436 installedConfigs[out] = true
Inseob Kime9aec6a2021-01-05 20:03:22 +0900437 ret = append(ret, copyFile(ctx, path, out))
Inseob Kim8471cda2019-11-15 09:59:12 +0900438 }
439 }
440
441 var propOut string
442
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900443 if l, ok := m.linker.(snapshotLibraryInterface); ok {
Colin Cross0de8a1e2020-09-18 14:15:30 -0700444 exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
Inseob Kimc42f2f22020-07-29 20:32:10 +0900445
Inseob Kim8471cda2019-11-15 09:59:12 +0900446 // library flags
Colin Cross0de8a1e2020-09-18 14:15:30 -0700447 prop.ExportedFlags = exporterInfo.Flags
448 for _, dir := range exporterInfo.IncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900449 prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
450 }
Colin Cross0de8a1e2020-09-18 14:15:30 -0700451 for _, dir := range exporterInfo.SystemIncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900452 prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
453 }
454 // shared libs dependencies aren't meaningful on static or header libs
455 if l.shared() {
456 prop.SharedLibs = m.Properties.SnapshotSharedLibs
457 }
458 if l.static() && m.sanitize != nil {
459 prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
460 prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
461 }
462
463 var libType string
464 if l.static() {
465 libType = "static"
466 } else if l.shared() {
467 libType = "shared"
468 } else {
469 libType = "header"
470 }
471
472 var stem string
473
474 // install .a or .so
475 if libType != "header" {
476 libPath := m.outputFile.Path()
477 stem = libPath.Base()
Inseob Kimc42f2f22020-07-29 20:32:10 +0900478 if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(cfi) {
479 // both cfi and non-cfi variant for static libraries can exist.
480 // attach .cfi to distinguish between cfi and non-cfi.
481 // e.g. libbase.a -> libbase.cfi.a
482 ext := filepath.Ext(stem)
483 stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
484 prop.Sanitize = "cfi"
485 prop.ModuleName += ".cfi"
486 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900487 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
Inseob Kime9aec6a2021-01-05 20:03:22 +0900488 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900489 } else {
490 stem = ctx.ModuleName(m)
491 }
492
493 propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
Inseob Kim7f283f42020-06-01 21:53:49 +0900494 } else if m.binary() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900495 // binary flags
496 prop.Symlinks = m.Symlinks()
497 prop.SharedLibs = m.Properties.SnapshotSharedLibs
498
499 // install bin
500 binPath := m.outputFile.Path()
501 snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
Inseob Kime9aec6a2021-01-05 20:03:22 +0900502 ret = append(ret, copyFile(ctx, binPath, snapshotBinOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900503 propOut = snapshotBinOut + ".json"
Inseob Kim1042d292020-06-01 23:23:05 +0900504 } else if m.object() {
505 // object files aren't installed to the device, so their names can conflict.
506 // Use module name as stem.
507 objPath := m.outputFile.Path()
508 snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
509 ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
Inseob Kime9aec6a2021-01-05 20:03:22 +0900510 ret = append(ret, copyFile(ctx, objPath, snapshotObjOut))
Inseob Kim1042d292020-06-01 23:23:05 +0900511 propOut = snapshotObjOut + ".json"
Inseob Kim7f283f42020-06-01 21:53:49 +0900512 } else {
513 ctx.Errorf("unknown module %q in vendor snapshot", m.String())
514 return nil
Inseob Kim8471cda2019-11-15 09:59:12 +0900515 }
516
517 j, err := json.Marshal(prop)
518 if err != nil {
519 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
520 return nil
521 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900522 ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900523
524 return ret
525 }
526
527 ctx.VisitAllModules(func(module android.Module) {
528 m, ok := module.(*Module)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900529 if !ok {
530 return
531 }
532
533 moduleDir := ctx.ModuleDir(module)
Jose Galmesf7294582020-11-13 12:07:36 -0800534 inProprietaryPath := c.image.isProprietaryPath(moduleDir)
Colin Cross56a83212020-09-15 18:30:11 -0700535 apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
Bill Peckham945441c2020-08-31 16:07:58 -0700536
Jose Galmes6f843bc2020-12-11 13:36:29 -0800537 if c.image.excludeFromSnapshot(m) {
Jose Galmesf7294582020-11-13 12:07:36 -0800538 if inProprietaryPath {
Bill Peckham945441c2020-08-31 16:07:58 -0700539 // Error: exclude_from_vendor_snapshot applies
540 // to framework-path modules only.
541 ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
542 return
543 }
Jose Galmesf7294582020-11-13 12:07:36 -0800544 if Bool(c.image.available(m)) {
Bill Peckham945441c2020-08-31 16:07:58 -0700545 // Error: may not combine "vendor_available:
546 // true" with "exclude_from_vendor_snapshot:
547 // true".
Jose Galmesf7294582020-11-13 12:07:36 -0800548 ctx.Errorf(
549 "module %q may not use both \""+
550 c.name+
551 "_available: true\" and \"exclude_from_vendor_snapshot: true\"",
552 m.String())
Bill Peckham945441c2020-08-31 16:07:58 -0700553 return
554 }
555 }
556
Inseob Kimde5744a2020-12-02 13:14:28 +0900557 if !isSnapshotAware(m, inProprietaryPath, apexInfo, c.image) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900558 return
559 }
560
Inseob Kimde5744a2020-12-02 13:14:28 +0900561 // installSnapshot installs prebuilts and json flag files
Inseob Kim8471cda2019-11-15 09:59:12 +0900562 snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
Inseob Kimde5744a2020-12-02 13:14:28 +0900563
564 // just gather headers and notice files here, because they are to be deduplicated
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900565 if l, ok := m.linker.(snapshotLibraryInterface); ok {
566 headers = append(headers, l.snapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +0900567 }
568
Bob Badoura75b0572020-02-18 20:21:55 -0800569 if len(m.NoticeFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900570 noticeName := ctx.ModuleName(m) + ".txt"
571 noticeOut := filepath.Join(noticeDir, noticeName)
572 // skip already copied notice file
573 if !installedNotices[noticeOut] {
574 installedNotices[noticeOut] = true
Inseob Kime9aec6a2021-01-05 20:03:22 +0900575 snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.NoticeFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900576 }
577 }
578 })
579
580 // install all headers after removing duplicates
581 for _, header := range android.FirstUniquePaths(headers) {
Inseob Kime9aec6a2021-01-05 20:03:22 +0900582 snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String())))
Inseob Kim8471cda2019-11-15 09:59:12 +0900583 }
584
585 // All artifacts are ready. Sort them to normalize ninja and then zip.
586 sort.Slice(snapshotOutputs, func(i, j int) bool {
587 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
588 })
589
Jose Galmesf7294582020-11-13 12:07:36 -0800590 zipPath := android.PathForOutput(
591 ctx,
592 snapshotDir,
593 c.name+"-"+ctx.Config().DeviceName()+".zip")
Colin Crossf1a035e2020-11-16 17:32:30 -0800594 zipRule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim8471cda2019-11-15 09:59:12 +0900595
596 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
Jose Galmesf7294582020-11-13 12:07:36 -0800597 snapshotOutputList := android.PathForOutput(
598 ctx,
599 snapshotDir,
600 c.name+"-"+ctx.Config().DeviceName()+"_list")
Inseob Kim8471cda2019-11-15 09:59:12 +0900601 zipRule.Command().
602 Text("tr").
603 FlagWithArg("-d ", "\\'").
604 FlagWithRspFileInputList("< ", snapshotOutputs).
605 FlagWithOutput("> ", snapshotOutputList)
606
607 zipRule.Temporary(snapshotOutputList)
608
609 zipRule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800610 BuiltTool("soong_zip").
Inseob Kim8471cda2019-11-15 09:59:12 +0900611 FlagWithOutput("-o ", zipPath).
612 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
613 FlagWithInput("-l ", snapshotOutputList)
614
Colin Crossf1a035e2020-11-16 17:32:30 -0800615 zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900616 zipRule.DeleteTemporaryFiles()
Jose Galmesf7294582020-11-13 12:07:36 -0800617 c.snapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim8471cda2019-11-15 09:59:12 +0900618}
619
Jose Galmesf7294582020-11-13 12:07:36 -0800620func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
621 ctx.Strict(
622 c.makeVar,
623 c.snapshotZipFile.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900624}