1// 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
16// This file defines snapshot prebuilt modules, e.g. vendor snapshot and recovery snapshot. Such
17// snapshot modules will override original source modules with setting BOARD_VNDK_VERSION, with
18// snapshot mutators and snapshot information maps which are also defined in this file.
19
20import (
21	"path/filepath"
22	"strings"
23
24	"android/soong/android"
25
26	"github.com/google/blueprint"
27)
28
29// Defines the specifics of different images to which the snapshot process is applicable, e.g.,
30// vendor, recovery, ramdisk.
31type snapshotImage interface {
32	// Returns true if a snapshot should be generated for this image.
33	shouldGenerateSnapshot(ctx android.SingletonContext) bool
34
35	// Function that returns true if the module is included in this image.
36	// Using a function return instead of a value to prevent early
37	// evalution of a function that may be not be defined.
38	inImage(m LinkableInterface) func() bool
39
40	// Returns true if the module is private and must not be included in the
41	// snapshot. For example VNDK-private modules must return true for the
42	// vendor snapshots. But false for the recovery snapshots.
43	private(m LinkableInterface) bool
44
45	// Returns true if a dir under source tree is an SoC-owned proprietary
46	// directory, such as device/, vendor/, etc.
47	//
48	// For a given snapshot (e.g., vendor, recovery, etc.) if
49	// isProprietaryPath(dir, deviceConfig) returns true, then the module in dir
50	// will be built from sources.
51	isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool
52
53	// Whether to include VNDK in the snapshot for this image.
54	includeVndk() bool
55
56	// Whether a given module has been explicitly excluded from the
57	// snapshot, e.g., using the exclude_from_vendor_snapshot or
58	// exclude_from_recovery_snapshot properties.
59	excludeFromSnapshot(m LinkableInterface) bool
60
61	// Returns true if the build is using a snapshot for this image.
62	isUsingSnapshot(cfg android.DeviceConfig) bool
63
64	// Returns a version of which the snapshot should be used in this target.
65	// This will only be meaningful when isUsingSnapshot is true.
66	targetSnapshotVersion(cfg android.DeviceConfig) string
67
68	// Whether to exclude a given module from the directed snapshot or not.
69	// If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on,
70	// and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured.
71	excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool
72
73	// The image variant name for this snapshot image.
74	// For example, recovery snapshot image will return "recovery", and vendor snapshot image will
75	// return "vendor." + version.
76	imageVariantName(cfg android.DeviceConfig) string
77
78	// The variant suffix for snapshot modules. For example, vendor snapshot modules will have
79	// ".vendor" as their suffix.
80	moduleNameSuffix() string
81}
82
83type vendorSnapshotImage struct{}
84type recoverySnapshotImage struct{}
85
86type directoryMap map[string]bool
87
88var (
89	// Modules under following directories are ignored. They are OEM's and vendor's
90	// proprietary modules(device/, kernel/, vendor/, and hardware/).
91	defaultDirectoryExcludedMap = directoryMap{
92		"device":   true,
93		"hardware": true,
94		"kernel":   true,
95		"vendor":   true,
96	}
97
98	// Modules under following directories are included as they are in AOSP,
99	// although hardware/ and kernel/ are normally for vendor's own.
100	defaultDirectoryIncludedMap = directoryMap{
101		"kernel/configs":              true,
102		"kernel/prebuilts":            true,
103		"kernel/tests":                true,
104		"hardware/interfaces":         true,
105		"hardware/libhardware":        true,
106		"hardware/libhardware_legacy": true,
107		"hardware/ril":                true,
108	}
109)
110
111func (vendorSnapshotImage) init(ctx android.RegistrationContext) {
112	ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
113	ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory)
114	ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
115	ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
116	ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
117	ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
118	ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory)
119
120	ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
121}
122
123func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
124	// BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot.
125	return ctx.DeviceConfig().VndkVersion() == "current"
126}
127
128func (vendorSnapshotImage) inImage(m LinkableInterface) func() bool {
129	return m.InVendor
130}
131
132func (vendorSnapshotImage) private(m LinkableInterface) bool {
133	return m.IsVndkPrivate()
134}
135
136func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool {
137	if dir == "." || dir == "/" {
138		return false
139	}
140	if includedMap[dir] {
141		return false
142	} else if excludedMap[dir] {
143		return true
144	} else if defaultDirectoryIncludedMap[dir] {
145		return false
146	} else if defaultDirectoryExcludedMap[dir] {
147		return true
148	} else {
149		return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap)
150	}
151}
152
153func (vendorSnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
154	return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap())
155}
156
157// vendor snapshot includes static/header libraries with vndk: {enabled: true}.
158func (vendorSnapshotImage) includeVndk() bool {
159	return true
160}
161
162func (vendorSnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
163	return m.ExcludeFromVendorSnapshot()
164}
165
166func (vendorSnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
167	vndkVersion := cfg.VndkVersion()
168	return vndkVersion != "current" && vndkVersion != ""
169}
170
171func (vendorSnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string {
172	return cfg.VndkVersion()
173}
174
175// returns true iff a given module SHOULD BE EXCLUDED, false if included
176func (vendorSnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
177	// If we're using full snapshot, not directed snapshot, capture every module
178	if !cfg.DirectedVendorSnapshot() {
179		return false
180	}
181	// Else, checks if name is in VENDOR_SNAPSHOT_MODULES.
182	return !cfg.VendorSnapshotModules()[name]
183}
184
185func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
186	return VendorVariationPrefix + cfg.VndkVersion()
187}
188
189func (vendorSnapshotImage) moduleNameSuffix() string {
190	return VendorSuffix
191}
192
193func (recoverySnapshotImage) init(ctx android.RegistrationContext) {
194	ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton)
195	ctx.RegisterModuleType("recovery_snapshot", recoverySnapshotFactory)
196	ctx.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory)
197	ctx.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory)
198	ctx.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory)
199	ctx.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory)
200	ctx.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory)
201}
202
203func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
204	// RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a
205	// snapshot.
206	return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
207}
208
209func (recoverySnapshotImage) inImage(m LinkableInterface) func() bool {
210	return m.InRecovery
211}
212
213// recovery snapshot does not have private libraries.
214func (recoverySnapshotImage) private(m LinkableInterface) bool {
215	return false
216}
217
218func (recoverySnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
219	return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap())
220}
221
222// recovery snapshot does NOT treat vndk specially.
223func (recoverySnapshotImage) includeVndk() bool {
224	return false
225}
226
227func (recoverySnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
228	return m.ExcludeFromRecoverySnapshot()
229}
230
231func (recoverySnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
232	recoverySnapshotVersion := cfg.RecoverySnapshotVersion()
233	return recoverySnapshotVersion != "current" && recoverySnapshotVersion != ""
234}
235
236func (recoverySnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string {
237	return cfg.RecoverySnapshotVersion()
238}
239
240func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
241	// If we're using full snapshot, not directed snapshot, capture every module
242	if !cfg.DirectedRecoverySnapshot() {
243		return false
244	}
245	// Else, checks if name is in RECOVERY_SNAPSHOT_MODULES.
246	return !cfg.RecoverySnapshotModules()[name]
247}
248
249func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
250	return android.RecoveryVariation
251}
252
253func (recoverySnapshotImage) moduleNameSuffix() string {
254	return recoverySuffix
255}
256
257var vendorSnapshotImageSingleton vendorSnapshotImage
258var recoverySnapshotImageSingleton recoverySnapshotImage
259
260func init() {
261	vendorSnapshotImageSingleton.init(android.InitRegistrationContext)
262	recoverySnapshotImageSingleton.init(android.InitRegistrationContext)
263}
264
265const (
266	snapshotHeaderSuffix = "_header."
267	snapshotSharedSuffix = "_shared."
268	snapshotStaticSuffix = "_static."
269	snapshotBinarySuffix = "_binary."
270	snapshotObjectSuffix = "_object."
271)
272
273type SnapshotProperties struct {
274	Header_libs []string `android:"arch_variant"`
275	Static_libs []string `android:"arch_variant"`
276	Shared_libs []string `android:"arch_variant"`
277	Vndk_libs   []string `android:"arch_variant"`
278	Binaries    []string `android:"arch_variant"`
279	Objects     []string `android:"arch_variant"`
280}
281
282type snapshot struct {
283	android.ModuleBase
284
285	properties SnapshotProperties
286
287	baseSnapshot baseSnapshotDecorator
288
289	image snapshotImage
290}
291
292func (s *snapshot) ImageMutatorBegin(ctx android.BaseModuleContext) {
293	cfg := ctx.DeviceConfig()
294	if !s.image.isUsingSnapshot(cfg) || s.image.targetSnapshotVersion(cfg) != s.baseSnapshot.version() {
295		s.Disable()
296	}
297}
298
299func (s *snapshot) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
300	return false
301}
302
303func (s *snapshot) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
304	return false
305}
306
307func (s *snapshot) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
308	return false
309}
310
311func (s *snapshot) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
312	return false
313}
314
315func (s *snapshot) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
316	return false
317}
318
319func (s *snapshot) ExtraImageVariations(ctx android.BaseModuleContext) []string {
320	return []string{s.image.imageVariantName(ctx.DeviceConfig())}
321}
322
323func (s *snapshot) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
324}
325
326func (s *snapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) {
327	// Nothing, the snapshot module is only used to forward dependency information in DepsMutator.
328}
329
330func getSnapshotNameSuffix(moduleSuffix, version, arch string) string {
331	versionSuffix := version
332	if arch != "" {
333		versionSuffix += "." + arch
334	}
335	return moduleSuffix + versionSuffix
336}
337
338func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
339	collectSnapshotMap := func(names []string, snapshotSuffix, moduleSuffix string) map[string]string {
340		snapshotMap := make(map[string]string)
341		for _, name := range names {
342			snapshotMap[name] = name +
343				getSnapshotNameSuffix(snapshotSuffix+moduleSuffix,
344					s.baseSnapshot.version(),
345					ctx.DeviceConfig().Arches()[0].ArchType.String())
346		}
347		return snapshotMap
348	}
349
350	snapshotSuffix := s.image.moduleNameSuffix()
351	headers := collectSnapshotMap(s.properties.Header_libs, snapshotSuffix, snapshotHeaderSuffix)
352	binaries := collectSnapshotMap(s.properties.Binaries, snapshotSuffix, snapshotBinarySuffix)
353	objects := collectSnapshotMap(s.properties.Objects, snapshotSuffix, snapshotObjectSuffix)
354	staticLibs := collectSnapshotMap(s.properties.Static_libs, snapshotSuffix, snapshotStaticSuffix)
355	sharedLibs := collectSnapshotMap(s.properties.Shared_libs, snapshotSuffix, snapshotSharedSuffix)
356	vndkLibs := collectSnapshotMap(s.properties.Vndk_libs, "", vndkSuffix)
357	for k, v := range vndkLibs {
358		sharedLibs[k] = v
359	}
360
361	ctx.SetProvider(SnapshotInfoProvider, SnapshotInfo{
362		HeaderLibs: headers,
363		Binaries:   binaries,
364		Objects:    objects,
365		StaticLibs: staticLibs,
366		SharedLibs: sharedLibs,
367	})
368}
369
370type SnapshotInfo struct {
371	HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs map[string]string
372}
373
374var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps")
375
376var _ android.ImageInterface = (*snapshot)(nil)
377
378func vendorSnapshotFactory() android.Module {
379	return snapshotFactory(vendorSnapshotImageSingleton)
380}
381
382func recoverySnapshotFactory() android.Module {
383	return snapshotFactory(recoverySnapshotImageSingleton)
384}
385
386func snapshotFactory(image snapshotImage) android.Module {
387	snapshot := &snapshot{}
388	snapshot.image = image
389	snapshot.AddProperties(
390		&snapshot.properties,
391		&snapshot.baseSnapshot.baseProperties)
392	android.InitAndroidArchModule(snapshot, android.DeviceSupported, android.MultilibBoth)
393	return snapshot
394}
395
396type baseSnapshotDecoratorProperties struct {
397	// snapshot version.
398	Version string
399
400	// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
401	Target_arch string
402
403	// Suffix to be added to the module name when exporting to Android.mk, e.g. ".vendor".
404	Androidmk_suffix string `blueprint:"mutated"`
405
406	// Suffix to be added to the module name, e.g., vendor_shared,
407	// recovery_shared, etc.
408	ModuleSuffix string `blueprint:"mutated"`
409}
410
411// baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
412// version, snapshot arch, etc. It also adds a special suffix to Soong module name, so it doesn't
413// collide with source modules. e.g. the following example module,
414//
415// vendor_snapshot_static {
416//     name: "libbase",
417//     arch: "arm64",
418//     version: 30,
419//     ...
420// }
421//
422// will be seen as "libbase.vendor_static.30.arm64" by Soong.
423type baseSnapshotDecorator struct {
424	baseProperties baseSnapshotDecoratorProperties
425	image          snapshotImage
426}
427
428func (p *baseSnapshotDecorator) Name(name string) string {
429	return name + p.NameSuffix()
430}
431
432func (p *baseSnapshotDecorator) NameSuffix() string {
433	return getSnapshotNameSuffix(p.moduleSuffix(), p.version(), p.arch())
434}
435
436func (p *baseSnapshotDecorator) version() string {
437	return p.baseProperties.Version
438}
439
440func (p *baseSnapshotDecorator) arch() string {
441	return p.baseProperties.Target_arch
442}
443
444func (p *baseSnapshotDecorator) moduleSuffix() string {
445	return p.baseProperties.ModuleSuffix
446}
447
448func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool {
449	return true
450}
451
452func (p *baseSnapshotDecorator) snapshotAndroidMkSuffix() string {
453	return p.baseProperties.Androidmk_suffix
454}
455
456func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleContext) {
457	coreVariations := append(ctx.Target().Variations(), blueprint.Variation{
458		Mutator:   "image",
459		Variation: android.CoreVariation})
460
461	if ctx.OtherModuleFarDependencyVariantExists(coreVariations, ctx.Module().(*Module).BaseModuleName()) {
462		p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix()
463		return
464	}
465
466	// If there is no matching core variation, there could still be a
467	// product variation, for example if a module is product specific and
468	// vendor available. In that case, we also want to add the androidmk
469	// suffix.
470
471	productVariations := append(ctx.Target().Variations(), blueprint.Variation{
472		Mutator:   "image",
473		Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()})
474
475	if ctx.OtherModuleFarDependencyVariantExists(productVariations, ctx.Module().(*Module).BaseModuleName()) {
476		p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix()
477		return
478	}
479
480	p.baseProperties.Androidmk_suffix = ""
481}
482
483// Call this with a module suffix after creating a snapshot module, such as
484// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc.
485func (p *baseSnapshotDecorator) init(m *Module, image snapshotImage, moduleSuffix string) {
486	p.image = image
487	p.baseProperties.ModuleSuffix = image.moduleNameSuffix() + moduleSuffix
488	m.AddProperties(&p.baseProperties)
489	android.AddLoadHook(m, func(ctx android.LoadHookContext) {
490		vendorSnapshotLoadHook(ctx, p)
491	})
492}
493
494// vendorSnapshotLoadHook disables snapshots if it's not BOARD_VNDK_VERSION.
495// As vendor snapshot is only for vendor, such modules won't be used at all.
496func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *baseSnapshotDecorator) {
497	if p.version() != ctx.DeviceConfig().VndkVersion() {
498		ctx.Module().Disable()
499		return
500	}
501}
502
503//
504// Module definitions for snapshots of libraries (shared, static, header).
505//
506// Modules (vendor|recovery)_snapshot_(shared|static|header) are defined here. Shared libraries and
507// static libraries have their prebuilt library files (.so for shared, .a for static) as their src,
508// which can be installed or linked against. Also they export flags needed when linked, such as
509// include directories, c flags, sanitize dependency information, etc.
510//
511// These modules are auto-generated by development/vendor_snapshot/update.py.
512type snapshotLibraryProperties struct {
513	// Prebuilt file for each arch.
514	Src *string `android:"arch_variant"`
515
516	// list of directories that will be added to the include path (using -I).
517	Export_include_dirs []string `android:"arch_variant"`
518
519	// list of directories that will be added to the system path (using -isystem).
520	Export_system_include_dirs []string `android:"arch_variant"`
521
522	// list of flags that will be used for any module that links against this module.
523	Export_flags []string `android:"arch_variant"`
524
525	// Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
526	Sanitize_ubsan_dep *bool `android:"arch_variant"`
527
528	// Whether this prebuilt needs to depend on sanitize minimal runtime or not.
529	Sanitize_minimal_dep *bool `android:"arch_variant"`
530}
531
532type snapshotSanitizer interface {
533	isSanitizerEnabled(t SanitizerType) bool
534	setSanitizerVariation(t SanitizerType, enabled bool)
535}
536
537type snapshotLibraryDecorator struct {
538	baseSnapshotDecorator
539	*libraryDecorator
540	properties          snapshotLibraryProperties
541	sanitizerProperties struct {
542		CfiEnabled bool `blueprint:"mutated"`
543
544		// Library flags for cfi variant.
545		Cfi snapshotLibraryProperties `android:"arch_variant"`
546	}
547}
548
549func (p *snapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
550	p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
551	return p.libraryDecorator.linkerFlags(ctx, flags)
552}
553
554func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
555	arches := config.Arches()
556	if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
557		return false
558	}
559	if !p.header() && p.properties.Src == nil {
560		return false
561	}
562	return true
563}
564
565// cc modules' link functions are to link compiled objects into final binaries.
566// As snapshots are prebuilts, this just returns the prebuilt binary after doing things which are
567// done by normal library decorator, e.g. exporting flags.
568func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
569	p.setSnapshotAndroidMkSuffix(ctx)
570
571	if p.header() {
572		return p.libraryDecorator.link(ctx, flags, deps, objs)
573	}
574
575	if p.sanitizerProperties.CfiEnabled {
576		p.properties = p.sanitizerProperties.Cfi
577	}
578
579	if !p.matchesWithDevice(ctx.DeviceConfig()) {
580		return nil
581	}
582
583	// Flags specified directly to this module.
584	p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
585	p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
586	p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
587
588	// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
589	p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
590	p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
591	p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
592	p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
593	p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
594
595	in := android.PathForModuleSrc(ctx, *p.properties.Src)
596	p.unstrippedOutputFile = in
597
598	if p.shared() {
599		libName := in.Base()
600		builderFlags := flagsToBuilderFlags(flags)
601
602		// Optimize out relinking against shared libraries whose interface hasn't changed by
603		// depending on a table of contents file instead of the library itself.
604		tocFile := android.PathForModuleOut(ctx, libName+".toc")
605		p.tocFile = android.OptionalPathForPath(tocFile)
606		transformSharedObjectToToc(ctx, in, tocFile, builderFlags)
607
608		ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
609			SharedLibrary:           in,
610			UnstrippedSharedLibrary: p.unstrippedOutputFile,
611			Target:                  ctx.Target(),
612
613			TableOfContents: p.tocFile,
614		})
615	}
616
617	if p.static() {
618		depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
619		ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
620			StaticLibrary: in,
621
622			TransitiveStaticLibrariesForOrdering: depSet,
623		})
624	}
625
626	p.libraryDecorator.flagExporter.setProvider(ctx)
627
628	return in
629}
630
631func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
632	if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
633		p.baseInstaller.install(ctx, file)
634	}
635}
636
637func (p *snapshotLibraryDecorator) nativeCoverage() bool {
638	return false
639}
640
641func (p *snapshotLibraryDecorator) isSanitizerEnabled(t SanitizerType) bool {
642	switch t {
643	case cfi:
644		return p.sanitizerProperties.Cfi.Src != nil
645	default:
646		return false
647	}
648}
649
650func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enabled bool) {
651	if !enabled {
652		return
653	}
654	switch t {
655	case cfi:
656		p.sanitizerProperties.CfiEnabled = true
657	default:
658		return
659	}
660}
661
662func snapshotLibraryFactory(image snapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
663	module, library := NewLibrary(android.DeviceSupported)
664
665	module.stl = nil
666	module.sanitize = nil
667	library.disableStripping()
668
669	prebuilt := &snapshotLibraryDecorator{
670		libraryDecorator: library,
671	}
672
673	prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
674	prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
675
676	// Prevent default system libs (libc, libm, and libdl) from being linked
677	if prebuilt.baseLinker.Properties.System_shared_libs == nil {
678		prebuilt.baseLinker.Properties.System_shared_libs = []string{}
679	}
680
681	module.compiler = nil
682	module.linker = prebuilt
683	module.installer = prebuilt
684
685	prebuilt.init(module, image, moduleSuffix)
686	module.AddProperties(
687		&prebuilt.properties,
688		&prebuilt.sanitizerProperties,
689	)
690
691	return module, prebuilt
692}
693
694// vendor_snapshot_shared is a special prebuilt shared library which is auto-generated by
695// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_shared
696// overrides the vendor variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
697// is set.
698func VendorSnapshotSharedFactory() android.Module {
699	module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotSharedSuffix)
700	prebuilt.libraryDecorator.BuildOnlyShared()
701	return module.Init()
702}
703
704// recovery_snapshot_shared is a special prebuilt shared library which is auto-generated by
705// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_shared
706// overrides the recovery variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
707// is set.
708func RecoverySnapshotSharedFactory() android.Module {
709	module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotSharedSuffix)
710	prebuilt.libraryDecorator.BuildOnlyShared()
711	return module.Init()
712}
713
714// vendor_snapshot_static is a special prebuilt static library which is auto-generated by
715// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_static
716// overrides the vendor variant of the cc static library with the same name, if BOARD_VNDK_VERSION
717// is set.
718func VendorSnapshotStaticFactory() android.Module {
719	module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotStaticSuffix)
720	prebuilt.libraryDecorator.BuildOnlyStatic()
721	return module.Init()
722}
723
724// recovery_snapshot_static is a special prebuilt static library which is auto-generated by
725// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_static
726// overrides the recovery variant of the cc static library with the same name, if BOARD_VNDK_VERSION
727// is set.
728func RecoverySnapshotStaticFactory() android.Module {
729	module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotStaticSuffix)
730	prebuilt.libraryDecorator.BuildOnlyStatic()
731	return module.Init()
732}
733
734// vendor_snapshot_header is a special header library which is auto-generated by
735// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_header
736// overrides the vendor variant of the cc header library with the same name, if BOARD_VNDK_VERSION
737// is set.
738func VendorSnapshotHeaderFactory() android.Module {
739	module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotHeaderSuffix)
740	prebuilt.libraryDecorator.HeaderOnly()
741	return module.Init()
742}
743
744// recovery_snapshot_header is a special header library which is auto-generated by
745// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_header
746// overrides the recovery variant of the cc header library with the same name, if BOARD_VNDK_VERSION
747// is set.
748func RecoverySnapshotHeaderFactory() android.Module {
749	module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotHeaderSuffix)
750	prebuilt.libraryDecorator.HeaderOnly()
751	return module.Init()
752}
753
754var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil)
755
756//
757// Module definitions for snapshots of executable binaries.
758//
759// Modules (vendor|recovery)_snapshot_binary are defined here. They have their prebuilt executable
760// binaries (e.g. toybox, sh) as their src, which can be installed.
761//
762// These modules are auto-generated by development/vendor_snapshot/update.py.
763type snapshotBinaryProperties struct {
764	// Prebuilt file for each arch.
765	Src *string `android:"arch_variant"`
766}
767
768type snapshotBinaryDecorator struct {
769	baseSnapshotDecorator
770	*binaryDecorator
771	properties snapshotBinaryProperties
772}
773
774func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
775	if config.DeviceArch() != p.arch() {
776		return false
777	}
778	if p.properties.Src == nil {
779		return false
780	}
781	return true
782}
783
784// cc modules' link functions are to link compiled objects into final binaries.
785// As snapshots are prebuilts, this just returns the prebuilt binary
786func (p *snapshotBinaryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
787	p.setSnapshotAndroidMkSuffix(ctx)
788
789	if !p.matchesWithDevice(ctx.DeviceConfig()) {
790		return nil
791	}
792
793	in := android.PathForModuleSrc(ctx, *p.properties.Src)
794	p.unstrippedOutputFile = in
795	binName := in.Base()
796
797	// use cpExecutable to make it executable
798	outputFile := android.PathForModuleOut(ctx, binName)
799	ctx.Build(pctx, android.BuildParams{
800		Rule:        android.CpExecutable,
801		Description: "prebuilt",
802		Output:      outputFile,
803		Input:       in,
804	})
805
806	return outputFile
807}
808
809func (p *snapshotBinaryDecorator) nativeCoverage() bool {
810	return false
811}
812
813// vendor_snapshot_binary is a special prebuilt executable binary which is auto-generated by
814// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_binary
815// overrides the vendor variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
816func VendorSnapshotBinaryFactory() android.Module {
817	return snapshotBinaryFactory(vendorSnapshotImageSingleton, snapshotBinarySuffix)
818}
819
820// recovery_snapshot_binary is a special prebuilt executable binary which is auto-generated by
821// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_binary
822// overrides the recovery variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
823func RecoverySnapshotBinaryFactory() android.Module {
824	return snapshotBinaryFactory(recoverySnapshotImageSingleton, snapshotBinarySuffix)
825}
826
827func snapshotBinaryFactory(image snapshotImage, moduleSuffix string) android.Module {
828	module, binary := NewBinary(android.DeviceSupported)
829	binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
830	binary.baseLinker.Properties.Nocrt = BoolPtr(true)
831
832	// Prevent default system libs (libc, libm, and libdl) from being linked
833	if binary.baseLinker.Properties.System_shared_libs == nil {
834		binary.baseLinker.Properties.System_shared_libs = []string{}
835	}
836
837	prebuilt := &snapshotBinaryDecorator{
838		binaryDecorator: binary,
839	}
840
841	module.compiler = nil
842	module.sanitize = nil
843	module.stl = nil
844	module.linker = prebuilt
845
846	prebuilt.init(module, image, moduleSuffix)
847	module.AddProperties(&prebuilt.properties)
848	return module.Init()
849}
850
851//
852// Module definitions for snapshots of object files (*.o).
853//
854// Modules (vendor|recovery)_snapshot_object are defined here. They have their prebuilt object
855// files (*.o) as their src.
856//
857// These modules are auto-generated by development/vendor_snapshot/update.py.
858type vendorSnapshotObjectProperties struct {
859	// Prebuilt file for each arch.
860	Src *string `android:"arch_variant"`
861}
862
863type snapshotObjectLinker struct {
864	baseSnapshotDecorator
865	objectLinker
866	properties vendorSnapshotObjectProperties
867}
868
869func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
870	if config.DeviceArch() != p.arch() {
871		return false
872	}
873	if p.properties.Src == nil {
874		return false
875	}
876	return true
877}
878
879// cc modules' link functions are to link compiled objects into final binaries.
880// As snapshots are prebuilts, this just returns the prebuilt binary
881func (p *snapshotObjectLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
882	p.setSnapshotAndroidMkSuffix(ctx)
883
884	if !p.matchesWithDevice(ctx.DeviceConfig()) {
885		return nil
886	}
887
888	return android.PathForModuleSrc(ctx, *p.properties.Src)
889}
890
891func (p *snapshotObjectLinker) nativeCoverage() bool {
892	return false
893}
894
895// vendor_snapshot_object is a special prebuilt compiled object file which is auto-generated by
896// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_object
897// overrides the vendor variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
898func VendorSnapshotObjectFactory() android.Module {
899	module := newObject()
900
901	prebuilt := &snapshotObjectLinker{
902		objectLinker: objectLinker{
903			baseLinker: NewBaseLinker(nil),
904		},
905	}
906	module.linker = prebuilt
907
908	prebuilt.init(module, vendorSnapshotImageSingleton, snapshotObjectSuffix)
909	module.AddProperties(&prebuilt.properties)
910	return module.Init()
911}
912
913// recovery_snapshot_object is a special prebuilt compiled object file which is auto-generated by
914// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_object
915// overrides the recovery variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
916func RecoverySnapshotObjectFactory() android.Module {
917	module := newObject()
918
919	prebuilt := &snapshotObjectLinker{
920		objectLinker: objectLinker{
921			baseLinker: NewBaseLinker(nil),
922		},
923	}
924	module.linker = prebuilt
925
926	prebuilt.init(module, recoverySnapshotImageSingleton, snapshotObjectSuffix)
927	module.AddProperties(&prebuilt.properties)
928	return module.Init()
929}
930
931type snapshotInterface interface {
932	matchesWithDevice(config android.DeviceConfig) bool
933	isSnapshotPrebuilt() bool
934	version() string
935	snapshotAndroidMkSuffix() string
936}
937
938var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
939var _ snapshotInterface = (*snapshotLibraryDecorator)(nil)
940var _ snapshotInterface = (*snapshotBinaryDecorator)(nil)
941var _ snapshotInterface = (*snapshotObjectLinker)(nil)
942