blob: 003b7c98bf6e671aa03d25361bf50c2d7bc374db [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,
Ivan Lozanod67a6b02021-05-20 13:01:32 -040034 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,
Ivan Lozanod67a6b02021-05-20 13:01:32 -040043 VendorSnapshotImageSingleton,
Inseob Kime9aec6a2021-01-05 20:03:22 +090044 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.).
Ivan Lozanod1dec542021-05-26 15:33:11 -040085 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
Justin DeMartino383bfb32021-02-24 10:49:43 -080093// Determine if a dir under source tree is an SoC-owned proprietary directory based
94// on vendor snapshot configuration
95// Examples: device/, vendor/
96func isVendorProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
97 return VendorSnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig)
Jose Galmesf7294582020-11-13 12:07:36 -080098}
99
Justin DeMartino383bfb32021-02-24 10:49:43 -0800100// Determine if a dir under source tree is an SoC-owned proprietary directory based
101// on recovery snapshot configuration
102// Examples: device/, vendor/
103func isRecoveryProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
104 return RecoverySnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig)
Inseob Kim8471cda2019-11-15 09:59:12 +0900105}
106
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400107func IsVendorProprietaryModule(ctx android.BaseModuleContext) bool {
Bill Peckham945441c2020-08-31 16:07:58 -0700108 // Any module in a vendor proprietary path is a vendor proprietary
109 // module.
Justin DeMartino383bfb32021-02-24 10:49:43 -0800110 if isVendorProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
Bill Peckham945441c2020-08-31 16:07:58 -0700111 return true
112 }
113
114 // However if the module is not in a vendor proprietary path, it may
115 // still be a vendor proprietary module. This happens for cc modules
116 // that are excluded from the vendor snapshot, and it means that the
117 // vendor has assumed control of the framework-provided module.
Ivan Lozanod7586b62021-04-01 09:49:36 -0400118 if c, ok := ctx.Module().(LinkableInterface); ok {
Bill Peckham945441c2020-08-31 16:07:58 -0700119 if c.ExcludeFromVendorSnapshot() {
120 return true
121 }
122 }
123
124 return false
125}
126
Jose Galmes6f843bc2020-12-11 13:36:29 -0800127func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
128
Justin Yune09ac172021-01-20 19:49:01 +0900129 // Any module in a recovery proprietary path is a recovery proprietary
Jose Galmes6f843bc2020-12-11 13:36:29 -0800130 // module.
Justin DeMartino383bfb32021-02-24 10:49:43 -0800131 if isRecoveryProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800132 return true
133 }
134
Justin Yune09ac172021-01-20 19:49:01 +0900135 // However if the module is not in a recovery proprietary path, it may
136 // still be a recovery proprietary module. This happens for cc modules
137 // that are excluded from the recovery snapshot, and it means that the
Jose Galmes6f843bc2020-12-11 13:36:29 -0800138 // vendor has assumed control of the framework-provided module.
139
Ivan Lozanod7586b62021-04-01 09:49:36 -0400140 if c, ok := ctx.Module().(LinkableInterface); ok {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800141 if c.ExcludeFromRecoverySnapshot() {
142 return true
143 }
144 }
145
146 return false
147}
148
Inseob Kimde5744a2020-12-02 13:14:28 +0900149// Determines if the module is a candidate for snapshot.
Ivan Lozanod1dec542021-05-26 15:33:11 -0400150func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image SnapshotImage) bool {
Ivan Lozanod7586b62021-04-01 09:49:36 -0400151 if !m.Enabled() || m.HiddenFromMake() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900152 return false
153 }
Martin Stjernholm809d5182020-09-10 01:46:05 +0100154 // When android/prebuilt.go selects between source and prebuilt, it sets
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800155 // HideFromMake on the other one to avoid duplicate install rules in make.
156 if m.IsHideFromMake() {
Martin Stjernholm809d5182020-09-10 01:46:05 +0100157 return false
158 }
Jose Galmesf7294582020-11-13 12:07:36 -0800159 // skip proprietary modules, but (for the vendor snapshot only)
160 // include all VNDK (static)
161 if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) {
Bill Peckham945441c2020-08-31 16:07:58 -0700162 return false
163 }
164 // If the module would be included based on its path, check to see if
165 // the module is marked to be excluded. If so, skip it.
Jose Galmes6f843bc2020-12-11 13:36:29 -0800166 if image.excludeFromSnapshot(m) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900167 return false
168 }
169 if m.Target().Os.Class != android.Device {
170 return false
171 }
172 if m.Target().NativeBridge == android.NativeBridgeEnabled {
173 return false
174 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900175 // the module must be installed in target image
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400176 if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.inImage(m)() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900177 return false
178 }
Inseob Kim65ca36a2020-06-11 13:55:45 +0900179 // skip kernel_headers which always depend on vendor
Ivan Lozanod7586b62021-04-01 09:49:36 -0400180 if m.KernelHeadersDecorator() {
Inseob Kim65ca36a2020-06-11 13:55:45 +0900181 return false
182 }
Ivan Lozanod7586b62021-04-01 09:49:36 -0400183
Colin Cross127bb8b2020-12-16 16:46:01 -0800184 if m.IsLlndk() {
185 return false
186 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900187
188 // Libraries
Ivan Lozanod7586b62021-04-01 09:49:36 -0400189 if sanitizable, ok := m.(PlatformSanitizeable); ok && sanitizable.IsSnapshotLibrary() {
190 if sanitizable.SanitizePropDefined() {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900191 // scs and hwasan export both sanitized and unsanitized variants for static and header
Inseob Kim7f283f42020-06-01 21:53:49 +0900192 // Always use unsanitized variants of them.
Tri Vo6eafc362021-04-01 11:29:09 -0700193 for _, t := range []SanitizerType{scs, Hwasan} {
Ivan Lozanod7586b62021-04-01 09:49:36 -0400194 if !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(t) {
Inseob Kim7f283f42020-06-01 21:53:49 +0900195 return false
196 }
197 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900198 // cfi also exports both variants. But for static, we capture both.
Inseob Kimde5744a2020-12-02 13:14:28 +0900199 // This is because cfi static libraries can't be linked from non-cfi modules,
200 // and vice versa. This isn't the case for scs and hwasan sanitizers.
Ivan Lozanod7586b62021-04-01 09:49:36 -0400201 if !sanitizable.Static() && !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(cfi) {
Inseob Kimc42f2f22020-07-29 20:32:10 +0900202 return false
203 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900204 }
Ivan Lozanod7586b62021-04-01 09:49:36 -0400205 if sanitizable.Static() {
206 return sanitizable.OutputFile().Valid() && !image.private(m)
Inseob Kim8471cda2019-11-15 09:59:12 +0900207 }
Ivan Lozano3149e6e2021-06-01 15:09:53 -0400208 if sanitizable.Shared() || sanitizable.Rlib() {
Ivan Lozanod7586b62021-04-01 09:49:36 -0400209 if !sanitizable.OutputFile().Valid() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700210 return false
211 }
Jose Galmesf7294582020-11-13 12:07:36 -0800212 if image.includeVndk() {
Ivan Lozanod7586b62021-04-01 09:49:36 -0400213 if !sanitizable.IsVndk() {
Jose Galmesf7294582020-11-13 12:07:36 -0800214 return true
215 }
Ivan Lozanod7586b62021-04-01 09:49:36 -0400216 return sanitizable.IsVndkExt()
Bill Peckham7d3f0962020-06-29 16:49:15 -0700217 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900218 }
219 return true
220 }
221
Inseob Kim1042d292020-06-01 23:23:05 +0900222 // Binaries and Objects
Ivan Lozanod7586b62021-04-01 09:49:36 -0400223 if m.Binary() || m.Object() {
224 return m.OutputFile().Valid()
Inseob Kim8471cda2019-11-15 09:59:12 +0900225 }
Inseob Kim7f283f42020-06-01 21:53:49 +0900226
227 return false
Inseob Kim8471cda2019-11-15 09:59:12 +0900228}
229
Inseob Kimde5744a2020-12-02 13:14:28 +0900230// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
231// These flags become Android.bp snapshot module properties.
232type snapshotJsonFlags struct {
233 ModuleName string `json:",omitempty"`
234 RelativeInstallPath string `json:",omitempty"`
235
236 // library flags
237 ExportedDirs []string `json:",omitempty"`
238 ExportedSystemDirs []string `json:",omitempty"`
239 ExportedFlags []string `json:",omitempty"`
240 Sanitize string `json:",omitempty"`
241 SanitizeMinimalDep bool `json:",omitempty"`
242 SanitizeUbsanDep bool `json:",omitempty"`
243
244 // binary flags
Justin Yun5e035862021-06-29 20:50:37 +0900245 Symlinks []string `json:",omitempty"`
246 StaticExecutable bool `json:",omitempty"`
Inseob Kimde5744a2020-12-02 13:14:28 +0900247
248 // dependencies
249 SharedLibs []string `json:",omitempty"`
Justin Yun5e035862021-06-29 20:50:37 +0900250 StaticLibs []string `json:",omitempty"`
Inseob Kimde5744a2020-12-02 13:14:28 +0900251 RuntimeLibs []string `json:",omitempty"`
252 Required []string `json:",omitempty"`
253
254 // extra config files
255 InitRc []string `json:",omitempty"`
256 VintfFragments []string `json:",omitempty"`
257}
258
Jose Galmesf7294582020-11-13 12:07:36 -0800259func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800260 if !c.image.shouldGenerateSnapshot(ctx) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900261 return
262 }
263
264 var snapshotOutputs android.Paths
265
266 /*
267 Vendor snapshot zipped artifacts directory structure:
268 {SNAPSHOT_ARCH}/
269 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
270 shared/
271 (.so shared libraries)
272 static/
273 (.a static libraries)
274 header/
275 (header only libraries)
276 binary/
277 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900278 object/
279 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900280 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
281 shared/
282 (.so shared libraries)
283 static/
284 (.a static libraries)
285 header/
286 (header only libraries)
287 binary/
288 (executable binaries)
Inseob Kim1042d292020-06-01 23:23:05 +0900289 object/
290 (.o object files)
Inseob Kim8471cda2019-11-15 09:59:12 +0900291 NOTICE_FILES/
292 (notice files, e.g. libbase.txt)
293 configs/
294 (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
295 include/
296 (header files of same directory structure with source tree)
297 */
298
Jose Galmesf7294582020-11-13 12:07:36 -0800299 snapshotDir := c.name + "-snapshot"
Inseob Kime9aec6a2021-01-05 20:03:22 +0900300 if c.fake {
301 // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
302 // collision with real snapshot files
303 snapshotDir = filepath.Join("fake", snapshotDir)
304 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900305 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
306
307 includeDir := filepath.Join(snapshotArchDir, "include")
308 configsDir := filepath.Join(snapshotArchDir, "configs")
309 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
310
311 installedNotices := make(map[string]bool)
312 installedConfigs := make(map[string]bool)
313
314 var headers android.Paths
315
Jose Galmes0a942a02021-02-03 14:23:15 -0800316 copyFile := func(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
317 if fake {
318 // All prebuilt binaries and headers are installed by copyFile function. This makes a fake
319 // snapshot just touch prebuilts and headers, rather than installing real files.
Inseob Kime9aec6a2021-01-05 20:03:22 +0900320 return writeStringToFileRule(ctx, "", out)
Jose Galmes0a942a02021-02-03 14:23:15 -0800321 } else {
322 return copyFileRule(ctx, path, out)
Inseob Kime9aec6a2021-01-05 20:03:22 +0900323 }
324 }
325
Inseob Kimde5744a2020-12-02 13:14:28 +0900326 // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
327 // For executables, init_rc and vintf_fragments files are also copied.
Ivan Lozanod7586b62021-04-01 09:49:36 -0400328 installSnapshot := func(m LinkableInterface, fake bool) android.Paths {
Inseob Kim8471cda2019-11-15 09:59:12 +0900329 targetArch := "arch-" + m.Target().Arch.ArchType.String()
330 if m.Target().Arch.ArchVariant != "" {
331 targetArch += "-" + m.Target().Arch.ArchVariant
332 }
333
334 var ret android.Paths
335
Inseob Kimde5744a2020-12-02 13:14:28 +0900336 prop := snapshotJsonFlags{}
Inseob Kim8471cda2019-11-15 09:59:12 +0900337
338 // Common properties among snapshots.
339 prop.ModuleName = ctx.ModuleName(m)
Ivan Lozanof9e21722020-12-02 09:00:51 -0500340 if c.supportsVndkExt && m.IsVndkExt() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700341 // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
Ivan Lozanod7586b62021-04-01 09:49:36 -0400342 if m.IsVndkSp() {
Bill Peckham7d3f0962020-06-29 16:49:15 -0700343 prop.RelativeInstallPath = "vndk-sp"
344 } else {
345 prop.RelativeInstallPath = "vndk"
346 }
347 } else {
348 prop.RelativeInstallPath = m.RelativeInstallPath()
349 }
Ivan Lozanod7586b62021-04-01 09:49:36 -0400350 prop.RuntimeLibs = m.SnapshotRuntimeLibs()
Inseob Kim8471cda2019-11-15 09:59:12 +0900351 prop.Required = m.RequiredModuleNames()
352 for _, path := range m.InitRc() {
353 prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
354 }
355 for _, path := range m.VintfFragments() {
356 prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
357 }
358
359 // install config files. ignores any duplicates.
360 for _, path := range append(m.InitRc(), m.VintfFragments()...) {
361 out := filepath.Join(configsDir, path.Base())
362 if !installedConfigs[out] {
363 installedConfigs[out] = true
Jose Galmes0a942a02021-02-03 14:23:15 -0800364 ret = append(ret, copyFile(ctx, path, out, fake))
Inseob Kim8471cda2019-11-15 09:59:12 +0900365 }
366 }
367
368 var propOut string
369
Ivan Lozanod7586b62021-04-01 09:49:36 -0400370 if m.IsSnapshotLibrary() {
371 exporterInfo := ctx.ModuleProvider(m.Module(), FlagExporterInfoProvider).(FlagExporterInfo)
Inseob Kimc42f2f22020-07-29 20:32:10 +0900372
Inseob Kim8471cda2019-11-15 09:59:12 +0900373 // library flags
Colin Cross0de8a1e2020-09-18 14:15:30 -0700374 prop.ExportedFlags = exporterInfo.Flags
375 for _, dir := range exporterInfo.IncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900376 prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
377 }
Colin Cross0de8a1e2020-09-18 14:15:30 -0700378 for _, dir := range exporterInfo.SystemIncludeDirs {
Inseob Kim8471cda2019-11-15 09:59:12 +0900379 prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
380 }
Ivan Lozanod7586b62021-04-01 09:49:36 -0400381
Inseob Kim8471cda2019-11-15 09:59:12 +0900382 // shared libs dependencies aren't meaningful on static or header libs
Ivan Lozanod7586b62021-04-01 09:49:36 -0400383 if m.Shared() {
384 prop.SharedLibs = m.SnapshotSharedLibs()
Inseob Kim8471cda2019-11-15 09:59:12 +0900385 }
Justin Yun5e035862021-06-29 20:50:37 +0900386 // static libs dependencies are required to collect the NOTICE files.
387 prop.StaticLibs = m.SnapshotStaticLibs()
Ivan Lozanod7586b62021-04-01 09:49:36 -0400388 if sanitizable, ok := m.(PlatformSanitizeable); ok {
389 if sanitizable.Static() && sanitizable.SanitizePropDefined() {
390 prop.SanitizeMinimalDep = sanitizable.MinimalRuntimeDep() || sanitizable.MinimalRuntimeNeeded()
391 prop.SanitizeUbsanDep = sanitizable.UbsanRuntimeDep() || sanitizable.UbsanRuntimeNeeded()
392 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900393 }
394
395 var libType string
Ivan Lozanod7586b62021-04-01 09:49:36 -0400396 if m.Static() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900397 libType = "static"
Ivan Lozanod7586b62021-04-01 09:49:36 -0400398 } else if m.Shared() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900399 libType = "shared"
Ivan Lozano3149e6e2021-06-01 15:09:53 -0400400 } else if m.Rlib() {
401 libType = "rlib"
Inseob Kim8471cda2019-11-15 09:59:12 +0900402 } else {
403 libType = "header"
404 }
405
406 var stem string
407
408 // install .a or .so
409 if libType != "header" {
Ivan Lozanod7586b62021-04-01 09:49:36 -0400410 libPath := m.OutputFile().Path()
Inseob Kim8471cda2019-11-15 09:59:12 +0900411 stem = libPath.Base()
Ivan Lozanod7586b62021-04-01 09:49:36 -0400412 if sanitizable, ok := m.(PlatformSanitizeable); ok {
Ivan Lozano3149e6e2021-06-01 15:09:53 -0400413 if (sanitizable.Static() || sanitizable.Rlib()) && sanitizable.SanitizePropDefined() && sanitizable.IsSanitizerEnabled(cfi) {
Ivan Lozanod7586b62021-04-01 09:49:36 -0400414 // both cfi and non-cfi variant for static libraries can exist.
415 // attach .cfi to distinguish between cfi and non-cfi.
416 // e.g. libbase.a -> libbase.cfi.a
417 ext := filepath.Ext(stem)
418 stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
419 prop.Sanitize = "cfi"
420 prop.ModuleName += ".cfi"
421 }
Inseob Kimc42f2f22020-07-29 20:32:10 +0900422 }
Inseob Kim8471cda2019-11-15 09:59:12 +0900423 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
Jose Galmes0a942a02021-02-03 14:23:15 -0800424 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut, fake))
Inseob Kim8471cda2019-11-15 09:59:12 +0900425 } else {
426 stem = ctx.ModuleName(m)
427 }
428
429 propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
Ivan Lozanod7586b62021-04-01 09:49:36 -0400430 } else if m.Binary() {
Inseob Kim8471cda2019-11-15 09:59:12 +0900431 // binary flags
432 prop.Symlinks = m.Symlinks()
Justin Yun5e035862021-06-29 20:50:37 +0900433 prop.StaticExecutable = m.StaticExecutable()
Ivan Lozanod7586b62021-04-01 09:49:36 -0400434 prop.SharedLibs = m.SnapshotSharedLibs()
Justin Yun5e035862021-06-29 20:50:37 +0900435 // static libs dependencies are required to collect the NOTICE files.
436 prop.StaticLibs = m.SnapshotStaticLibs()
Inseob Kim8471cda2019-11-15 09:59:12 +0900437 // install bin
Ivan Lozanod7586b62021-04-01 09:49:36 -0400438 binPath := m.OutputFile().Path()
Inseob Kim8471cda2019-11-15 09:59:12 +0900439 snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
Jose Galmes0a942a02021-02-03 14:23:15 -0800440 ret = append(ret, copyFile(ctx, binPath, snapshotBinOut, fake))
Inseob Kim8471cda2019-11-15 09:59:12 +0900441 propOut = snapshotBinOut + ".json"
Ivan Lozanod7586b62021-04-01 09:49:36 -0400442 } else if m.Object() {
Inseob Kim1042d292020-06-01 23:23:05 +0900443 // object files aren't installed to the device, so their names can conflict.
444 // Use module name as stem.
Ivan Lozanod7586b62021-04-01 09:49:36 -0400445 objPath := m.OutputFile().Path()
Inseob Kim1042d292020-06-01 23:23:05 +0900446 snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
447 ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
Jose Galmes0a942a02021-02-03 14:23:15 -0800448 ret = append(ret, copyFile(ctx, objPath, snapshotObjOut, fake))
Inseob Kim1042d292020-06-01 23:23:05 +0900449 propOut = snapshotObjOut + ".json"
Inseob Kim7f283f42020-06-01 21:53:49 +0900450 } else {
451 ctx.Errorf("unknown module %q in vendor snapshot", m.String())
452 return nil
Inseob Kim8471cda2019-11-15 09:59:12 +0900453 }
454
455 j, err := json.Marshal(prop)
456 if err != nil {
457 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
458 return nil
459 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900460 ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900461
462 return ret
463 }
464
465 ctx.VisitAllModules(func(module android.Module) {
Ivan Lozanod7586b62021-04-01 09:49:36 -0400466 m, ok := module.(LinkableInterface)
Inseob Kimeda2e9c2020-03-03 22:06:32 +0900467 if !ok {
468 return
469 }
470
471 moduleDir := ctx.ModuleDir(module)
Justin DeMartino383bfb32021-02-24 10:49:43 -0800472 inProprietaryPath := c.image.isProprietaryPath(moduleDir, ctx.DeviceConfig())
Colin Cross56a83212020-09-15 18:30:11 -0700473 apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
Bill Peckham945441c2020-08-31 16:07:58 -0700474
Jose Galmes6f843bc2020-12-11 13:36:29 -0800475 if c.image.excludeFromSnapshot(m) {
Jose Galmesf7294582020-11-13 12:07:36 -0800476 if inProprietaryPath {
Bill Peckham945441c2020-08-31 16:07:58 -0700477 // Error: exclude_from_vendor_snapshot applies
478 // to framework-path modules only.
479 ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
480 return
481 }
Bill Peckham945441c2020-08-31 16:07:58 -0700482 }
483
Inseob Kim7cf14652021-01-06 23:06:52 +0900484 if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, c.image) {
Inseob Kim8471cda2019-11-15 09:59:12 +0900485 return
486 }
487
Jose Galmes0a942a02021-02-03 14:23:15 -0800488 // If we are using directed snapshot and a module is not included in the
489 // list, we will still include the module as if it was a fake module.
490 // The reason is that soong needs all the dependencies to be present, even
491 // if they are not using during the build.
492 installAsFake := c.fake
493 if c.image.excludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
494 installAsFake = true
495 }
Inseob Kimde5744a2020-12-02 13:14:28 +0900496
Jose Galmes0a942a02021-02-03 14:23:15 -0800497 // installSnapshot installs prebuilts and json flag files
498 snapshotOutputs = append(snapshotOutputs, installSnapshot(m, installAsFake)...)
Inseob Kimde5744a2020-12-02 13:14:28 +0900499 // just gather headers and notice files here, because they are to be deduplicated
Ivan Lozanod7586b62021-04-01 09:49:36 -0400500 if m.IsSnapshotLibrary() {
501 headers = append(headers, m.SnapshotHeaders()...)
Inseob Kim8471cda2019-11-15 09:59:12 +0900502 }
503
Justin Yun885a7de2021-06-29 20:34:53 +0900504 if len(m.EffectiveLicenseFiles()) > 0 {
Inseob Kim8471cda2019-11-15 09:59:12 +0900505 noticeName := ctx.ModuleName(m) + ".txt"
506 noticeOut := filepath.Join(noticeDir, noticeName)
507 // skip already copied notice file
508 if !installedNotices[noticeOut] {
509 installedNotices[noticeOut] = true
Justin Yun885a7de2021-06-29 20:34:53 +0900510 snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.EffectiveLicenseFiles(), noticeOut))
Inseob Kim8471cda2019-11-15 09:59:12 +0900511 }
512 }
513 })
514
515 // install all headers after removing duplicates
516 for _, header := range android.FirstUniquePaths(headers) {
Jose Galmes0a942a02021-02-03 14:23:15 -0800517 snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String()), c.fake))
Inseob Kim8471cda2019-11-15 09:59:12 +0900518 }
519
520 // All artifacts are ready. Sort them to normalize ninja and then zip.
521 sort.Slice(snapshotOutputs, func(i, j int) bool {
522 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
523 })
524
Jose Galmesf7294582020-11-13 12:07:36 -0800525 zipPath := android.PathForOutput(
526 ctx,
527 snapshotDir,
528 c.name+"-"+ctx.Config().DeviceName()+".zip")
Colin Crossf1a035e2020-11-16 17:32:30 -0800529 zipRule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim8471cda2019-11-15 09:59:12 +0900530
531 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
Jose Galmesf7294582020-11-13 12:07:36 -0800532 snapshotOutputList := android.PathForOutput(
533 ctx,
534 snapshotDir,
535 c.name+"-"+ctx.Config().DeviceName()+"_list")
Colin Cross70c47412021-03-12 17:48:14 -0800536 rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
Inseob Kim8471cda2019-11-15 09:59:12 +0900537 zipRule.Command().
538 Text("tr").
539 FlagWithArg("-d ", "\\'").
Colin Cross70c47412021-03-12 17:48:14 -0800540 FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
Inseob Kim8471cda2019-11-15 09:59:12 +0900541 FlagWithOutput("> ", snapshotOutputList)
542
543 zipRule.Temporary(snapshotOutputList)
544
545 zipRule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800546 BuiltTool("soong_zip").
Inseob Kim8471cda2019-11-15 09:59:12 +0900547 FlagWithOutput("-o ", zipPath).
548 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
549 FlagWithInput("-l ", snapshotOutputList)
550
Colin Crossf1a035e2020-11-16 17:32:30 -0800551 zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900552 zipRule.DeleteTemporaryFiles()
Jose Galmesf7294582020-11-13 12:07:36 -0800553 c.snapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim8471cda2019-11-15 09:59:12 +0900554}
555
Jose Galmesf7294582020-11-13 12:07:36 -0800556func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
557 ctx.Strict(
558 c.makeVar,
559 c.snapshotZipFile.String())
Inseob Kim8471cda2019-11-15 09:59:12 +0900560}