• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 Google Inc. All rights reserved.
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.
14
15package android
16
17import (
18	"crypto/md5"
19	"encoding/hex"
20	"encoding/json"
21	"fmt"
22	"net/url"
23	"path/filepath"
24	"reflect"
25	"slices"
26	"sort"
27	"strings"
28
29	"android/soong/bazel"
30
31	"github.com/google/blueprint"
32	"github.com/google/blueprint/proptools"
33)
34
35var (
36	DeviceSharedLibrary = "shared_library"
37	DeviceStaticLibrary = "static_library"
38	jarJarPrefixHandler func(ctx ModuleContext)
39)
40
41type Module interface {
42	blueprint.Module
43
44	// GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
45	// but GenerateAndroidBuildActions also has access to Android-specific information.
46	// For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
47	GenerateAndroidBuildActions(ModuleContext)
48
49	// Add dependencies to the components of a module, i.e. modules that are created
50	// by the module and which are considered to be part of the creating module.
51	//
52	// This is called before prebuilts are renamed so as to allow a dependency to be
53	// added directly to a prebuilt child module instead of depending on a source module
54	// and relying on prebuilt processing to switch to the prebuilt module if preferred.
55	//
56	// A dependency on a prebuilt must include the "prebuilt_" prefix.
57	ComponentDepsMutator(ctx BottomUpMutatorContext)
58
59	DepsMutator(BottomUpMutatorContext)
60
61	base() *ModuleBase
62	Disable()
63	Enabled(ctx ConfigAndErrorContext) bool
64	Target() Target
65	MultiTargets() []Target
66
67	// ImageVariation returns the image variation of this module.
68	//
69	// The returned structure has its Mutator field set to "image" and its Variation field set to the
70	// image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
71	// device modules that have no image variation.
72	ImageVariation() blueprint.Variation
73
74	Owner() string
75	InstallInData() bool
76	InstallInTestcases() bool
77	InstallInSanitizerDir() bool
78	InstallInRamdisk() bool
79	InstallInVendorRamdisk() bool
80	InstallInDebugRamdisk() bool
81	InstallInRecovery() bool
82	InstallInRoot() bool
83	InstallInOdm() bool
84	InstallInProduct() bool
85	InstallInVendor() bool
86	InstallForceOS() (*OsType, *ArchType)
87	PartitionTag(DeviceConfig) string
88	HideFromMake()
89	IsHideFromMake() bool
90	IsSkipInstall() bool
91	MakeUninstallable()
92	ReplacedByPrebuilt()
93	IsReplacedByPrebuilt() bool
94	ExportedToMake() bool
95	InitRc() Paths
96	VintfFragments() Paths
97	EffectiveLicenseKinds() []string
98	EffectiveLicenseFiles() Paths
99
100	AddProperties(props ...interface{})
101	GetProperties() []interface{}
102
103	BuildParamsForTests() []BuildParams
104	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
105	VariablesForTests() map[string]string
106
107	// String returns a string that includes the module name and variants for printing during debugging.
108	String() string
109
110	// Get the qualified module id for this module.
111	qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
112
113	// Get information about the properties that can contain visibility rules.
114	visibilityProperties() []visibilityProperty
115
116	RequiredModuleNames() []string
117	HostRequiredModuleNames() []string
118	TargetRequiredModuleNames() []string
119
120	FilesToInstall() InstallPaths
121	PackagingSpecs() []PackagingSpec
122
123	// TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
124	// dependencies with dependency tags for which IsInstallDepNeeded() returns true.
125	TransitivePackagingSpecs() []PackagingSpec
126
127	ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
128}
129
130// Qualified id for a module
131type qualifiedModuleName struct {
132	// The package (i.e. directory) in which the module is defined, without trailing /
133	pkg string
134
135	// The name of the module, empty string if package.
136	name string
137}
138
139func (q qualifiedModuleName) String() string {
140	if q.name == "" {
141		return "//" + q.pkg
142	}
143	return "//" + q.pkg + ":" + q.name
144}
145
146func (q qualifiedModuleName) isRootPackage() bool {
147	return q.pkg == "" && q.name == ""
148}
149
150// Get the id for the package containing this module.
151func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
152	pkg := q.pkg
153	if q.name == "" {
154		if pkg == "" {
155			panic(fmt.Errorf("Cannot get containing package id of root package"))
156		}
157
158		index := strings.LastIndex(pkg, "/")
159		if index == -1 {
160			pkg = ""
161		} else {
162			pkg = pkg[:index]
163		}
164	}
165	return newPackageId(pkg)
166}
167
168func newPackageId(pkg string) qualifiedModuleName {
169	// A qualified id for a package module has no name.
170	return qualifiedModuleName{pkg: pkg, name: ""}
171}
172
173type Dist struct {
174	// Copy the output of this module to the $DIST_DIR when `dist` is specified on the
175	// command line and any of these targets are also on the command line, or otherwise
176	// built
177	Targets []string `android:"arch_variant"`
178
179	// The name of the output artifact. This defaults to the basename of the output of
180	// the module.
181	Dest *string `android:"arch_variant"`
182
183	// The directory within the dist directory to store the artifact. Defaults to the
184	// top level directory ("").
185	Dir *string `android:"arch_variant"`
186
187	// A suffix to add to the artifact file name (before any extension).
188	Suffix *string `android:"arch_variant"`
189
190	// If true, then the artifact file will be appended with _<product name>. For
191	// example, if the product is coral and the module is an android_app module
192	// of name foo, then the artifact would be foo_coral.apk. If false, there is
193	// no change to the artifact file name.
194	Append_artifact_with_product *bool `android:"arch_variant"`
195
196	// A string tag to select the OutputFiles associated with the tag.
197	//
198	// If no tag is specified then it will select the default dist paths provided
199	// by the module type. If a tag of "" is specified then it will return the
200	// default output files provided by the modules, i.e. the result of calling
201	// OutputFiles("").
202	Tag *string `android:"arch_variant"`
203}
204
205// NamedPath associates a path with a name. e.g. a license text path with a package name
206type NamedPath struct {
207	Path Path
208	Name string
209}
210
211// String returns an escaped string representing the `NamedPath`.
212func (p NamedPath) String() string {
213	if len(p.Name) > 0 {
214		return p.Path.String() + ":" + url.QueryEscape(p.Name)
215	}
216	return p.Path.String()
217}
218
219// NamedPaths describes a list of paths each associated with a name.
220type NamedPaths []NamedPath
221
222// Strings returns a list of escaped strings representing each `NamedPath` in the list.
223func (l NamedPaths) Strings() []string {
224	result := make([]string, 0, len(l))
225	for _, p := range l {
226		result = append(result, p.String())
227	}
228	return result
229}
230
231// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset.
232func SortedUniqueNamedPaths(l NamedPaths) NamedPaths {
233	if len(l) == 0 {
234		return l
235	}
236	sort.Slice(l, func(i, j int) bool {
237		return l[i].String() < l[j].String()
238	})
239	k := 0
240	for i := 1; i < len(l); i++ {
241		if l[i].String() == l[k].String() {
242			continue
243		}
244		k++
245		if k < i {
246			l[k] = l[i]
247		}
248	}
249	return l[:k+1]
250}
251
252// soongConfigTrace holds all references to VendorVars. Uses []string for blueprint:"mutated"
253type soongConfigTrace struct {
254	Bools   []string `json:",omitempty"`
255	Strings []string `json:",omitempty"`
256	IsSets  []string `json:",omitempty"`
257}
258
259func (c *soongConfigTrace) isEmpty() bool {
260	return len(c.Bools) == 0 && len(c.Strings) == 0 && len(c.IsSets) == 0
261}
262
263// Returns hash of serialized trace records (empty string if there's no trace recorded)
264func (c *soongConfigTrace) hash() string {
265	// Use MD5 for speed. We don't care collision or preimage attack
266	if c.isEmpty() {
267		return ""
268	}
269	j, err := json.Marshal(c)
270	if err != nil {
271		panic(fmt.Errorf("json marshal of %#v failed: %#v", *c, err))
272	}
273	hash := md5.Sum(j)
274	return hex.EncodeToString(hash[:])
275}
276
277type nameProperties struct {
278	// The name of the module.  Must be unique across all modules.
279	Name *string
280}
281
282type commonProperties struct {
283	// emit build rules for this module
284	//
285	// Disabling a module should only be done for those modules that cannot be built
286	// in the current environment. Modules that can build in the current environment
287	// but are not usually required (e.g. superceded by a prebuilt) should not be
288	// disabled as that will prevent them from being built by the checkbuild target
289	// and so prevent early detection of changes that have broken those modules.
290	Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
291
292	// Controls the visibility of this module to other modules. Allowable values are one or more of
293	// these formats:
294	//
295	//  ["//visibility:public"]: Anyone can use this module.
296	//  ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
297	//      this module.
298	//  ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
299	//      Can only be used at the beginning of a list of visibility rules.
300	//  ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
301	//      other/package (defined in some/package/*.bp and other/package/*.bp) have access to
302	//      this module. Note that sub-packages do not have access to the rule; for example,
303	//      //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
304	//      is a special module and must be used verbatim. It represents all of the modules in the
305	//      package.
306	//  ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
307	//      or other or in one of their sub-packages have access to this module. For example,
308	//      //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
309	//      to depend on this rule (but not //independent:evil)
310	//  ["//project"]: This is shorthand for ["//project:__pkg__"]
311	//  [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
312	//      //project is the module's package. e.g. using [":__subpackages__"] in
313	//      packages/apps/Settings/Android.bp is equivalent to
314	//      //packages/apps/Settings:__subpackages__.
315	//  ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
316	//      for now. It is an error if it is used in a module.
317	//
318	// If a module does not specify the `visibility` property then it uses the
319	// `default_visibility` property of the `package` module in the module's package.
320	//
321	// If the `default_visibility` property is not set for the module's package then
322	// it will use the `default_visibility` of its closest ancestor package for which
323	// a `default_visibility` property is specified.
324	//
325	// If no `default_visibility` property can be found then the module uses the
326	// global default of `//visibility:legacy_public`.
327	//
328	// The `visibility` property has no effect on a defaults module although it does
329	// apply to any non-defaults module that uses it. To set the visibility of a
330	// defaults module, use the `defaults_visibility` property on the defaults module;
331	// not to be confused with the `default_visibility` property on the package module.
332	//
333	// See https://android.googlesource.com/platform/build/soong/+/main/README.md#visibility for
334	// more details.
335	Visibility []string
336
337	// Describes the licenses applicable to this module. Must reference license modules.
338	Licenses []string
339
340	// Flattened from direct license dependencies. Equal to Licenses unless particular module adds more.
341	Effective_licenses []string `blueprint:"mutated"`
342	// Override of module name when reporting licenses
343	Effective_package_name *string `blueprint:"mutated"`
344	// Notice files
345	Effective_license_text NamedPaths `blueprint:"mutated"`
346	// License names
347	Effective_license_kinds []string `blueprint:"mutated"`
348	// License conditions
349	Effective_license_conditions []string `blueprint:"mutated"`
350
351	// control whether this module compiles for 32-bit, 64-bit, or both.  Possible values
352	// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
353	// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
354	// platform).
355	Compile_multilib *string `android:"arch_variant"`
356
357	Target struct {
358		Host struct {
359			Compile_multilib *string
360		}
361		Android struct {
362			Compile_multilib *string
363		}
364	}
365
366	// If set to true then the archMutator will create variants for each arch specific target
367	// (e.g. 32/64) that the module is required to produce. If set to false then it will only
368	// create a variant for the architecture and will list the additional arch specific targets
369	// that the variant needs to produce in the CompileMultiTargets property.
370	UseTargetVariants bool   `blueprint:"mutated"`
371	Default_multilib  string `blueprint:"mutated"`
372
373	// whether this is a proprietary vendor module, and should be installed into /vendor
374	Proprietary *bool
375
376	// vendor who owns this module
377	Owner *string
378
379	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
380	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
381	// Use `soc_specific` instead for better meaning.
382	Vendor *bool
383
384	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
385	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
386	Soc_specific *bool
387
388	// whether this module is specific to a device, not only for SoC, but also for off-chip
389	// peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
390	// does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
391	// This implies `soc_specific:true`.
392	Device_specific *bool
393
394	// whether this module is specific to a software configuration of a product (e.g. country,
395	// network operator, etc). When set to true, it is installed into /product (or
396	// /system/product if product partition does not exist).
397	Product_specific *bool
398
399	// whether this module extends system. When set to true, it is installed into /system_ext
400	// (or /system/system_ext if system_ext partition does not exist).
401	System_ext_specific *bool
402
403	// Whether this module is installed to recovery partition
404	Recovery *bool
405
406	// Whether this module is installed to ramdisk
407	Ramdisk *bool
408
409	// Whether this module is installed to vendor ramdisk
410	Vendor_ramdisk *bool
411
412	// Whether this module is installed to debug ramdisk
413	Debug_ramdisk *bool
414
415	// Whether this module is built for non-native architectures (also known as native bridge binary)
416	Native_bridge_supported *bool `android:"arch_variant"`
417
418	// init.rc files to be installed if this module is installed
419	Init_rc []string `android:"arch_variant,path"`
420
421	// VINTF manifest fragments to be installed if this module is installed
422	Vintf_fragments []string `android:"path"`
423
424	// names of other modules to install if this module is installed
425	Required []string `android:"arch_variant"`
426
427	// names of other modules to install on host if this module is installed
428	Host_required []string `android:"arch_variant"`
429
430	// names of other modules to install on target if this module is installed
431	Target_required []string `android:"arch_variant"`
432
433	// The OsType of artifacts that this module variant is responsible for creating.
434	//
435	// Set by osMutator
436	CompileOS OsType `blueprint:"mutated"`
437
438	// Set to true after the arch mutator has run on this module and set CompileTarget,
439	// CompileMultiTargets, and CompilePrimary
440	ArchReady bool `blueprint:"mutated"`
441
442	// The Target of artifacts that this module variant is responsible for creating.
443	//
444	// Set by archMutator
445	CompileTarget Target `blueprint:"mutated"`
446
447	// The additional arch specific targets (e.g. 32/64 bit) that this module variant is
448	// responsible for creating.
449	//
450	// By default this is nil as, where necessary, separate variants are created for the
451	// different multilib types supported and that information is encapsulated in the
452	// CompileTarget so the module variant simply needs to create artifacts for that.
453	//
454	// However, if UseTargetVariants is set to false (e.g. by
455	// InitAndroidMultiTargetsArchModule)  then no separate variants are created for the
456	// multilib targets. Instead a single variant is created for the architecture and
457	// this contains the multilib specific targets that this variant should create.
458	//
459	// Set by archMutator
460	CompileMultiTargets []Target `blueprint:"mutated"`
461
462	// True if the module variant's CompileTarget is the primary target
463	//
464	// Set by archMutator
465	CompilePrimary bool `blueprint:"mutated"`
466
467	// Set by InitAndroidModule
468	HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
469	ArchSpecific          bool                  `blueprint:"mutated"`
470
471	// If set to true then a CommonOS variant will be created which will have dependencies
472	// on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
473	// that covers all os and architecture variants.
474	//
475	// The OsType specific variants can be retrieved by calling
476	// GetOsSpecificVariantsOfCommonOSVariant
477	//
478	// Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
479	CreateCommonOSVariant bool `blueprint:"mutated"`
480
481	// If set to true then this variant is the CommonOS variant that has dependencies on its
482	// OsType specific variants.
483	//
484	// Set by osMutator.
485	CommonOSVariant bool `blueprint:"mutated"`
486
487	// When set to true, this module is not installed to the full install path (ex: under
488	// out/target/product/<name>/<partition>). It can be installed only to the packaging
489	// modules like android_filesystem.
490	No_full_install *bool
491
492	// When HideFromMake is set to true, no entry for this variant will be emitted in the
493	// generated Android.mk file.
494	HideFromMake bool `blueprint:"mutated"`
495
496	// When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
497	// ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
498	// and don't create a rule to install the file.
499	SkipInstall bool `blueprint:"mutated"`
500
501	// UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
502	// mutator.  MakeUninstallable also sets HideFromMake.  UninstallableApexPlatformVariant
503	// is used to avoid adding install or packaging dependencies into libraries provided
504	// by apexes.
505	UninstallableApexPlatformVariant bool `blueprint:"mutated"`
506
507	// Whether the module has been replaced by a prebuilt
508	ReplacedByPrebuilt bool `blueprint:"mutated"`
509
510	// Disabled by mutators. If set to true, it overrides Enabled property.
511	ForcedDisabled bool `blueprint:"mutated"`
512
513	NamespaceExportedToMake bool `blueprint:"mutated"`
514
515	MissingDeps        []string `blueprint:"mutated"`
516	CheckedMissingDeps bool     `blueprint:"mutated"`
517
518	// Name and variant strings stored by mutators to enable Module.String()
519	DebugName       string   `blueprint:"mutated"`
520	DebugMutators   []string `blueprint:"mutated"`
521	DebugVariations []string `blueprint:"mutated"`
522
523	// ImageVariation is set by ImageMutator to specify which image this variation is for,
524	// for example "" for core or "recovery" for recovery.  It will often be set to one of the
525	// constants in image.go, but can also be set to a custom value by individual module types.
526	ImageVariation string `blueprint:"mutated"`
527
528	// SoongConfigTrace records accesses to VendorVars (soong_config). The trace will be hashed
529	// and used as a subdir of PathForModuleOut.  Note that we mainly focus on incremental
530	// builds among similar products (e.g. aosp_cf_x86_64_phone and aosp_cf_x86_64_foldable),
531	// and there are variables other than soong_config, which isn't captured by soong config
532	// trace, but influence modules among products.
533	SoongConfigTrace     soongConfigTrace `blueprint:"mutated"`
534	SoongConfigTraceHash string           `blueprint:"mutated"`
535
536	// The team (defined by the owner/vendor) who owns the property.
537	Team *string `android:"path"`
538}
539
540type distProperties struct {
541	// configuration to distribute output files from this module to the distribution
542	// directory (default: $OUT/dist, configurable with $DIST_DIR)
543	Dist Dist `android:"arch_variant"`
544
545	// a list of configurations to distribute output files from this module to the
546	// distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
547	Dists []Dist `android:"arch_variant"`
548}
549
550type TeamDepTagType struct {
551	blueprint.BaseDependencyTag
552}
553
554var teamDepTag = TeamDepTagType{}
555
556// Dependency tag for required, host_required, and target_required modules.
557var RequiredDepTag = struct {
558	blueprint.BaseDependencyTag
559	InstallAlwaysNeededDependencyTag
560	// Requiring disabled module has been supported (as a side effect of this being implemented
561	// in Make). We may want to make it an error, but for now, let's keep the existing behavior.
562	AlwaysAllowDisabledModuleDependencyTag
563}{}
564
565// CommonTestOptions represents the common `test_options` properties in
566// Android.bp.
567type CommonTestOptions struct {
568	// If the test is a hostside (no device required) unittest that shall be run
569	// during presubmit check.
570	Unit_test *bool
571
572	// Tags provide additional metadata to customize test execution by downstream
573	// test runners. The tags have no special meaning to Soong.
574	Tags []string
575}
576
577// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
578// `test_options`.
579func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
580	entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
581	if len(t.Tags) > 0 {
582		entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
583	}
584}
585
586// The key to use in TaggedDistFiles when a Dist structure does not specify a
587// tag property. This intentionally does not use "" as the default because that
588// would mean that an empty tag would have a different meaning when used in a dist
589// structure that when used to reference a specific set of output paths using the
590// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
591const DefaultDistTag = "<default-dist-tag>"
592
593// A map of OutputFile tag keys to Paths, for disting purposes.
594type TaggedDistFiles map[string]Paths
595
596// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
597// then it will create a map, update it and then return it. If a mapping already
598// exists for the tag then the paths are appended to the end of the current list
599// of paths, ignoring any duplicates.
600func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
601	if t == nil {
602		t = make(TaggedDistFiles)
603	}
604
605	for _, distFile := range paths {
606		if distFile != nil && !t[tag].containsPath(distFile) {
607			t[tag] = append(t[tag], distFile)
608		}
609	}
610
611	return t
612}
613
614// merge merges the entries from the other TaggedDistFiles object into this one.
615// If the TaggedDistFiles is nil then it will create a new instance, merge the
616// other into it, and then return it.
617func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
618	for tag, paths := range other {
619		t = t.addPathsForTag(tag, paths...)
620	}
621
622	return t
623}
624
625func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
626	for _, p := range paths {
627		if p == nil {
628			panic("The path to a dist file cannot be nil.")
629		}
630	}
631
632	// The default OutputFile tag is the empty "" string.
633	return TaggedDistFiles{DefaultDistTag: paths}
634}
635
636type hostAndDeviceProperties struct {
637	// If set to true, build a variant of the module for the host.  Defaults to false.
638	Host_supported *bool
639
640	// If set to true, build a variant of the module for the device.  Defaults to true.
641	Device_supported *bool
642}
643
644type Multilib string
645
646const (
647	MultilibBoth        Multilib = "both"
648	MultilibFirst       Multilib = "first"
649	MultilibCommon      Multilib = "common"
650	MultilibCommonFirst Multilib = "common_first"
651)
652
653type HostOrDeviceSupported int
654
655const (
656	hostSupported = 1 << iota
657	hostCrossSupported
658	deviceSupported
659	hostDefault
660	deviceDefault
661
662	// Host and HostCross are built by default. Device is not supported.
663	HostSupported = hostSupported | hostCrossSupported | hostDefault
664
665	// Host is built by default. HostCross and Device are not supported.
666	HostSupportedNoCross = hostSupported | hostDefault
667
668	// Device is built by default. Host and HostCross are not supported.
669	DeviceSupported = deviceSupported | deviceDefault
670
671	// By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
672	// Host and HostCross are disabled by default and can be enabled with `host_supported: true`
673	HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
674
675	// Host, HostCross, and Device are built by default.
676	// Building Device can be disabled with `device_supported: false`
677	// Building Host and HostCross can be disabled with `host_supported: false`
678	HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
679		deviceSupported | deviceDefault
680
681	// Nothing is supported. This is not exposed to the user, but used to mark a
682	// host only module as unsupported when the module type is not supported on
683	// the host OS. E.g. benchmarks are supported on Linux but not Darwin.
684	NeitherHostNorDeviceSupported = 0
685)
686
687type moduleKind int
688
689const (
690	platformModule moduleKind = iota
691	deviceSpecificModule
692	socSpecificModule
693	productSpecificModule
694	systemExtSpecificModule
695)
696
697func (k moduleKind) String() string {
698	switch k {
699	case platformModule:
700		return "platform"
701	case deviceSpecificModule:
702		return "device-specific"
703	case socSpecificModule:
704		return "soc-specific"
705	case productSpecificModule:
706		return "product-specific"
707	case systemExtSpecificModule:
708		return "systemext-specific"
709	default:
710		panic(fmt.Errorf("unknown module kind %d", k))
711	}
712}
713
714func initAndroidModuleBase(m Module) {
715	m.base().module = m
716}
717
718// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
719// It adds the common properties, for example "name" and "enabled".
720func InitAndroidModule(m Module) {
721	initAndroidModuleBase(m)
722	base := m.base()
723
724	m.AddProperties(
725		&base.nameProperties,
726		&base.commonProperties,
727		&base.distProperties)
728
729	initProductVariableModule(m)
730
731	// The default_visibility property needs to be checked and parsed by the visibility module during
732	// its checking and parsing phases so make it the primary visibility property.
733	setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
734
735	// The default_applicable_licenses property needs to be checked and parsed by the licenses module during
736	// its checking and parsing phases so make it the primary licenses property.
737	setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
738}
739
740// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
741// It adds the common properties, for example "name" and "enabled", as well as runtime generated
742// property structs for architecture-specific versions of generic properties tagged with
743// `android:"arch_variant"`.
744//
745//	InitAndroidModule should not be called if InitAndroidArchModule was called.
746func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
747	InitAndroidModule(m)
748
749	base := m.base()
750	base.commonProperties.HostOrDeviceSupported = hod
751	base.commonProperties.Default_multilib = string(defaultMultilib)
752	base.commonProperties.ArchSpecific = true
753	base.commonProperties.UseTargetVariants = true
754
755	if hod&hostSupported != 0 && hod&deviceSupported != 0 {
756		m.AddProperties(&base.hostAndDeviceProperties)
757	}
758
759	initArchModule(m)
760}
761
762// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
763// architecture-specific, but will only have a single variant per OS that handles all the
764// architectures simultaneously.  The list of Targets that it must handle will be available from
765// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
766// well as runtime generated property structs for architecture-specific versions of generic
767// properties tagged with `android:"arch_variant"`.
768//
769// InitAndroidModule or InitAndroidArchModule should not be called if
770// InitAndroidMultiTargetsArchModule was called.
771func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
772	InitAndroidArchModule(m, hod, defaultMultilib)
773	m.base().commonProperties.UseTargetVariants = false
774}
775
776// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
777// architecture-specific, but will only have a single variant per OS that handles all the
778// architectures simultaneously, and will also have an additional CommonOS variant that has
779// dependencies on all the OS-specific variants.  The list of Targets that it must handle will be
780// available from ModuleContext.MultiTargets.  It adds the common properties, for example "name" and
781// "enabled", as well as runtime generated property structs for architecture-specific versions of
782// generic properties tagged with `android:"arch_variant"`.
783//
784// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
785// called if InitCommonOSAndroidMultiTargetsArchModule was called.
786func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
787	InitAndroidArchModule(m, hod, defaultMultilib)
788	m.base().commonProperties.UseTargetVariants = false
789	m.base().commonProperties.CreateCommonOSVariant = true
790}
791
792// A ModuleBase object contains the properties that are common to all Android
793// modules.  It should be included as an anonymous field in every module
794// struct definition.  InitAndroidModule should then be called from the module's
795// factory function, and the return values from InitAndroidModule should be
796// returned from the factory function.
797//
798// The ModuleBase type is responsible for implementing the GenerateBuildActions
799// method to support the blueprint.Module interface. This method will then call
800// the module's GenerateAndroidBuildActions method once for each build variant
801// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
802// rather than the usual blueprint.ModuleContext.
803// ModuleContext exposes extra functionality specific to the Android build
804// system including details about the particular build variant that is to be
805// generated.
806//
807// For example:
808//
809//	import (
810//	    "android/soong/android"
811//	)
812//
813//	type myModule struct {
814//	    android.ModuleBase
815//	    properties struct {
816//	        MyProperty string
817//	    }
818//	}
819//
820//	func NewMyModule() android.Module {
821//	    m := &myModule{}
822//	    m.AddProperties(&m.properties)
823//	    android.InitAndroidModule(m)
824//	    return m
825//	}
826//
827//	func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
828//	    // Get the CPU architecture for the current build variant.
829//	    variantArch := ctx.Arch()
830//
831//	    // ...
832//	}
833type ModuleBase struct {
834	// Putting the curiously recurring thing pointing to the thing that contains
835	// the thing pattern to good use.
836	// TODO: remove this
837	module Module
838
839	nameProperties          nameProperties
840	commonProperties        commonProperties
841	distProperties          distProperties
842	variableProperties      interface{}
843	hostAndDeviceProperties hostAndDeviceProperties
844
845	// Arch specific versions of structs in GetProperties() prior to
846	// initialization in InitAndroidArchModule, lets call it `generalProperties`.
847	// The outer index has the same order as generalProperties and the inner index
848	// chooses the props specific to the architecture. The interface{} value is an
849	// archPropRoot that is filled with arch specific values by the arch mutator.
850	archProperties [][]interface{}
851
852	// Properties specific to the Blueprint to BUILD migration.
853	bazelTargetModuleProperties bazel.BazelTargetModuleProperties
854
855	// Information about all the properties on the module that contains visibility rules that need
856	// checking.
857	visibilityPropertyInfo []visibilityProperty
858
859	// The primary visibility property, may be nil, that controls access to the module.
860	primaryVisibilityProperty visibilityProperty
861
862	// The primary licenses property, may be nil, records license metadata for the module.
863	primaryLicensesProperty applicableLicensesProperty
864
865	noAddressSanitizer   bool
866	installFiles         InstallPaths
867	installFilesDepSet   *DepSet[InstallPath]
868	checkbuildFiles      Paths
869	packagingSpecs       []PackagingSpec
870	packagingSpecsDepSet *DepSet[PackagingSpec]
871	// katiInstalls tracks the install rules that were created by Soong but are being exported
872	// to Make to convert to ninja rules so that Make can add additional dependencies.
873	katiInstalls katiInstalls
874	// katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
875	// allowed to have duplicates across modules and variants.
876	katiInitRcInstalls katiInstalls
877	katiVintfInstalls  katiInstalls
878	katiSymlinks       katiInstalls
879	testData           []DataPath
880
881	// The files to copy to the dist as explicitly specified in the .bp file.
882	distFiles TaggedDistFiles
883
884	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
885	// Only set on the final variant of each module
886	installTarget    WritablePath
887	checkbuildTarget WritablePath
888	blueprintDir     string
889
890	hooks hooks
891
892	registerProps []interface{}
893
894	// For tests
895	buildParams []BuildParams
896	ruleParams  map[blueprint.Rule]blueprint.RuleParams
897	variables   map[string]string
898
899	initRcPaths         Paths
900	vintfFragmentsPaths Paths
901
902	installedInitRcPaths         InstallPaths
903	installedVintfFragmentsPaths InstallPaths
904
905	// Merged Aconfig files for all transitive deps.
906	aconfigFilePaths Paths
907
908	// set of dependency module:location mappings used to populate the license metadata for
909	// apex containers.
910	licenseInstallMap []string
911
912	// The path to the generated license metadata file for the module.
913	licenseMetadataFile WritablePath
914
915	// moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
916	// be included in the final module-info.json produced by Make.
917	moduleInfoJSON *ModuleInfoJSON
918
919	// outputFiles stores the output of a module by tag and is used to set
920	// the OutputFilesProvider in GenerateBuildActions
921	outputFiles OutputFilesInfo
922}
923
924func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
925	(*d)["Android"] = map[string]interface{}{
926		// Properties set in Blueprint or in blueprint of a defaults modules
927		"SetProperties": m.propertiesWithValues(),
928	}
929}
930
931type propInfo struct {
932	Name   string
933	Type   string
934	Value  string
935	Values []string
936}
937
938func (m *ModuleBase) propertiesWithValues() []propInfo {
939	var info []propInfo
940	props := m.GetProperties()
941
942	var propsWithValues func(name string, v reflect.Value)
943	propsWithValues = func(name string, v reflect.Value) {
944		kind := v.Kind()
945		switch kind {
946		case reflect.Ptr, reflect.Interface:
947			if v.IsNil() {
948				return
949			}
950			propsWithValues(name, v.Elem())
951		case reflect.Struct:
952			if v.IsZero() {
953				return
954			}
955			for i := 0; i < v.NumField(); i++ {
956				namePrefix := name
957				sTyp := v.Type().Field(i)
958				if proptools.ShouldSkipProperty(sTyp) {
959					continue
960				}
961				if name != "" && !strings.HasSuffix(namePrefix, ".") {
962					namePrefix += "."
963				}
964				if !proptools.IsEmbedded(sTyp) {
965					namePrefix += sTyp.Name
966				}
967				sVal := v.Field(i)
968				propsWithValues(namePrefix, sVal)
969			}
970		case reflect.Array, reflect.Slice:
971			if v.IsNil() {
972				return
973			}
974			elKind := v.Type().Elem().Kind()
975			info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
976		default:
977			info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
978		}
979	}
980
981	for _, p := range props {
982		propsWithValues("", reflect.ValueOf(p).Elem())
983	}
984	sort.Slice(info, func(i, j int) bool {
985		return info[i].Name < info[j].Name
986	})
987	return info
988}
989
990func reflectionValue(value reflect.Value) string {
991	switch value.Kind() {
992	case reflect.Bool:
993		return fmt.Sprintf("%t", value.Bool())
994	case reflect.Int64:
995		return fmt.Sprintf("%d", value.Int())
996	case reflect.String:
997		return fmt.Sprintf("%s", value.String())
998	case reflect.Struct:
999		if value.IsZero() {
1000			return "{}"
1001		}
1002		length := value.NumField()
1003		vals := make([]string, length, length)
1004		for i := 0; i < length; i++ {
1005			sTyp := value.Type().Field(i)
1006			if proptools.ShouldSkipProperty(sTyp) {
1007				continue
1008			}
1009			name := sTyp.Name
1010			vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
1011		}
1012		return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
1013	case reflect.Array, reflect.Slice:
1014		vals := sliceReflectionValue(value)
1015		return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
1016	}
1017	return ""
1018}
1019
1020func sliceReflectionValue(value reflect.Value) []string {
1021	length := value.Len()
1022	vals := make([]string, length, length)
1023	for i := 0; i < length; i++ {
1024		vals[i] = reflectionValue(value.Index(i))
1025	}
1026	return vals
1027}
1028
1029func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
1030
1031func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
1032
1033func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
1034	if m.Team() != "" {
1035		ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
1036	}
1037
1038	// TODO(jiyong): remove below case. This is to work around build errors happening
1039	// on branches with reduced manifest like aosp_kernel-build-tools.
1040	// In the branch, a build error occurs as follows.
1041	// 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
1042	// projects like external/bouncycastle
1043	// 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
1044	// the top-level build goal (in the shell file that invokes Soong).
1045	// 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
1046	// 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
1047	// ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
1048	// 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
1049	// absence of external/bouncycastle fails the build.
1050	//
1051	// Unfortunately, there's no way for Soong to correctly determine if it's running in a
1052	// reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
1053	// a strong signal, because that's very common across reduced manifest branches.
1054	pv := ctx.Config().productVariables
1055	fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
1056	if fullManifest {
1057		addRequiredDeps(ctx)
1058	}
1059}
1060
1061// addRequiredDeps adds required, target_required, and host_required as dependencies.
1062func addRequiredDeps(ctx BottomUpMutatorContext) {
1063	addDep := func(target Target, depName string) {
1064		if !ctx.OtherModuleExists(depName) {
1065			if ctx.Config().AllowMissingDependencies() {
1066				return
1067			}
1068		}
1069
1070		// If Android native module requires another Android native module, ensure that
1071		// they have the same bitness. This mimics the policy in select-bitness-of-required-modules
1072		// in build/make/core/main.mk.
1073		// TODO(jiyong): the Make-side does this only when the required module is a shared
1074		// library or a native test.
1075		bothInAndroid := ctx.Device() && target.Os.Class == Device
1076		nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) &&
1077			InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"})
1078		sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
1079		if bothInAndroid && nativeArch && !sameBitness {
1080			return
1081		}
1082
1083		// ... also don't make a dependency between native bridge arch and non-native bridge
1084		// arches. b/342945184
1085		if ctx.Target().NativeBridge != target.NativeBridge {
1086			return
1087		}
1088
1089		variation := target.Variations()
1090		if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
1091			ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
1092		}
1093	}
1094
1095	var deviceTargets []Target
1096	deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
1097	deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
1098
1099	var hostTargets []Target
1100	hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
1101	hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
1102
1103	if ctx.Device() {
1104		for _, depName := range ctx.Module().RequiredModuleNames() {
1105			for _, target := range deviceTargets {
1106				addDep(target, depName)
1107			}
1108		}
1109		for _, depName := range ctx.Module().HostRequiredModuleNames() {
1110			for _, target := range hostTargets {
1111				addDep(target, depName)
1112			}
1113		}
1114	}
1115
1116	if ctx.Host() {
1117		for _, depName := range ctx.Module().RequiredModuleNames() {
1118			for _, target := range hostTargets {
1119				// When a host module requires another host module, don't make a
1120				// dependency if they have different OSes (i.e. hostcross).
1121				if ctx.Target().HostCross != target.HostCross {
1122					continue
1123				}
1124				addDep(target, depName)
1125			}
1126		}
1127		for _, depName := range ctx.Module().TargetRequiredModuleNames() {
1128			for _, target := range deviceTargets {
1129				addDep(target, depName)
1130			}
1131		}
1132	}
1133}
1134
1135// AddProperties "registers" the provided props
1136// each value in props MUST be a pointer to a struct
1137func (m *ModuleBase) AddProperties(props ...interface{}) {
1138	m.registerProps = append(m.registerProps, props...)
1139}
1140
1141func (m *ModuleBase) GetProperties() []interface{} {
1142	return m.registerProps
1143}
1144
1145func (m *ModuleBase) BuildParamsForTests() []BuildParams {
1146	// Expand the references to module variables like $flags[0-9]*,
1147	// so we do not need to change many existing unit tests.
1148	// This looks like undoing the shareFlags optimization in cc's
1149	// transformSourceToObj, and should only affects unit tests.
1150	vars := m.VariablesForTests()
1151	buildParams := append([]BuildParams(nil), m.buildParams...)
1152	for i := range buildParams {
1153		newArgs := make(map[string]string)
1154		for k, v := range buildParams[i].Args {
1155			newArgs[k] = v
1156			// Replaces both ${flags1} and $flags1 syntax.
1157			if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1158				if value, found := vars[v[2:len(v)-1]]; found {
1159					newArgs[k] = value
1160				}
1161			} else if strings.HasPrefix(v, "$") {
1162				if value, found := vars[v[1:]]; found {
1163					newArgs[k] = value
1164				}
1165			}
1166		}
1167		buildParams[i].Args = newArgs
1168	}
1169	return buildParams
1170}
1171
1172func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1173	return m.ruleParams
1174}
1175
1176func (m *ModuleBase) VariablesForTests() map[string]string {
1177	return m.variables
1178}
1179
1180// Name returns the name of the module.  It may be overridden by individual module types, for
1181// example prebuilts will prepend prebuilt_ to the name.
1182func (m *ModuleBase) Name() string {
1183	return String(m.nameProperties.Name)
1184}
1185
1186// String returns a string that includes the module name and variants for printing during debugging.
1187func (m *ModuleBase) String() string {
1188	sb := strings.Builder{}
1189	sb.WriteString(m.commonProperties.DebugName)
1190	sb.WriteString("{")
1191	for i := range m.commonProperties.DebugMutators {
1192		if i != 0 {
1193			sb.WriteString(",")
1194		}
1195		sb.WriteString(m.commonProperties.DebugMutators[i])
1196		sb.WriteString(":")
1197		sb.WriteString(m.commonProperties.DebugVariations[i])
1198	}
1199	sb.WriteString("}")
1200	return sb.String()
1201}
1202
1203// BaseModuleName returns the name of the module as specified in the blueprints file.
1204func (m *ModuleBase) BaseModuleName() string {
1205	return String(m.nameProperties.Name)
1206}
1207
1208func (m *ModuleBase) base() *ModuleBase {
1209	return m
1210}
1211
1212func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1213	return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1214}
1215
1216func (m *ModuleBase) visibilityProperties() []visibilityProperty {
1217	return m.visibilityPropertyInfo
1218}
1219
1220func (m *ModuleBase) Dists() []Dist {
1221	if len(m.distProperties.Dist.Targets) > 0 {
1222		// Make a copy of the underlying Dists slice to protect against
1223		// backing array modifications with repeated calls to this method.
1224		distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1225		return append(distsCopy, m.distProperties.Dist)
1226	} else {
1227		return m.distProperties.Dists
1228	}
1229}
1230
1231func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
1232	var distFiles TaggedDistFiles
1233	for _, dist := range m.Dists() {
1234		// If no tag is specified then it means to use the default dist paths so use
1235		// the special tag name which represents that.
1236		tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1237
1238		if outputFileProducer, ok := m.module.(OutputFileProducer); ok {
1239			// Call the OutputFiles(tag) method to get the paths associated with the tag.
1240			distFilesForTag, err := outputFileProducer.OutputFiles(tag)
1241
1242			// If the tag was not supported and is not DefaultDistTag then it is an error.
1243			// Failing to find paths for DefaultDistTag is not an error. It just means
1244			// that the module type requires the legacy behavior.
1245			if err != nil && tag != DefaultDistTag {
1246				ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1247			}
1248
1249			distFiles = distFiles.addPathsForTag(tag, distFilesForTag...)
1250		} else if tag != DefaultDistTag {
1251			// If the tag was specified then it is an error if the module does not
1252			// implement OutputFileProducer because there is no other way of accessing
1253			// the paths for the specified tag.
1254			ctx.PropertyErrorf("dist.tag",
1255				"tag %s not supported because the module does not implement OutputFileProducer", tag)
1256		}
1257	}
1258
1259	return distFiles
1260}
1261
1262func (m *ModuleBase) ArchReady() bool {
1263	return m.commonProperties.ArchReady
1264}
1265
1266func (m *ModuleBase) Target() Target {
1267	return m.commonProperties.CompileTarget
1268}
1269
1270func (m *ModuleBase) TargetPrimary() bool {
1271	return m.commonProperties.CompilePrimary
1272}
1273
1274func (m *ModuleBase) MultiTargets() []Target {
1275	return m.commonProperties.CompileMultiTargets
1276}
1277
1278func (m *ModuleBase) Os() OsType {
1279	return m.Target().Os
1280}
1281
1282func (m *ModuleBase) Host() bool {
1283	return m.Os().Class == Host
1284}
1285
1286func (m *ModuleBase) Device() bool {
1287	return m.Os().Class == Device
1288}
1289
1290func (m *ModuleBase) Arch() Arch {
1291	return m.Target().Arch
1292}
1293
1294func (m *ModuleBase) ArchSpecific() bool {
1295	return m.commonProperties.ArchSpecific
1296}
1297
1298// True if the current variant is a CommonOS variant, false otherwise.
1299func (m *ModuleBase) IsCommonOSVariant() bool {
1300	return m.commonProperties.CommonOSVariant
1301}
1302
1303// supportsTarget returns true if the given Target is supported by the current module.
1304func (m *ModuleBase) supportsTarget(target Target) bool {
1305	switch target.Os.Class {
1306	case Host:
1307		if target.HostCross {
1308			return m.HostCrossSupported()
1309		} else {
1310			return m.HostSupported()
1311		}
1312	case Device:
1313		return m.DeviceSupported()
1314	default:
1315		return false
1316	}
1317}
1318
1319// DeviceSupported returns true if the current module is supported and enabled for device targets,
1320// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1321// the device support is enabled by default or enabled by the device_supported property.
1322func (m *ModuleBase) DeviceSupported() bool {
1323	hod := m.commonProperties.HostOrDeviceSupported
1324	// deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1325	// value has the deviceDefault bit set.
1326	deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1327	return hod&deviceSupported != 0 && deviceEnabled
1328}
1329
1330// HostSupported returns true if the current module is supported and enabled for host targets,
1331// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1332// the host support is enabled by default or enabled by the host_supported property.
1333func (m *ModuleBase) HostSupported() bool {
1334	hod := m.commonProperties.HostOrDeviceSupported
1335	// hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1336	// value has the hostDefault bit set.
1337	hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1338	return hod&hostSupported != 0 && hostEnabled
1339}
1340
1341// HostCrossSupported returns true if the current module is supported and enabled for host cross
1342// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1343// support and the host cross support is enabled by default or enabled by the
1344// host_supported property.
1345func (m *ModuleBase) HostCrossSupported() bool {
1346	hod := m.commonProperties.HostOrDeviceSupported
1347	// hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1348	// value has the hostDefault bit set.
1349	hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1350	return hod&hostCrossSupported != 0 && hostEnabled
1351}
1352
1353func (m *ModuleBase) Platform() bool {
1354	return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
1355}
1356
1357func (m *ModuleBase) DeviceSpecific() bool {
1358	return Bool(m.commonProperties.Device_specific)
1359}
1360
1361func (m *ModuleBase) SocSpecific() bool {
1362	return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1363}
1364
1365func (m *ModuleBase) ProductSpecific() bool {
1366	return Bool(m.commonProperties.Product_specific)
1367}
1368
1369func (m *ModuleBase) SystemExtSpecific() bool {
1370	return Bool(m.commonProperties.System_ext_specific)
1371}
1372
1373// RequiresStableAPIs returns true if the module will be installed to a partition that may
1374// be updated separately from the system image.
1375func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1376	return m.SocSpecific() || m.DeviceSpecific() ||
1377		(m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1378}
1379
1380func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1381	partition := "system"
1382	if m.SocSpecific() {
1383		// A SoC-specific module could be on the vendor partition at
1384		// "vendor" or the system partition at "system/vendor".
1385		if config.VendorPath() == "vendor" {
1386			partition = "vendor"
1387		}
1388	} else if m.DeviceSpecific() {
1389		// A device-specific module could be on the odm partition at
1390		// "odm", the vendor partition at "vendor/odm", or the system
1391		// partition at "system/vendor/odm".
1392		if config.OdmPath() == "odm" {
1393			partition = "odm"
1394		} else if strings.HasPrefix(config.OdmPath(), "vendor/") {
1395			partition = "vendor"
1396		}
1397	} else if m.ProductSpecific() {
1398		// A product-specific module could be on the product partition
1399		// at "product" or the system partition at "system/product".
1400		if config.ProductPath() == "product" {
1401			partition = "product"
1402		}
1403	} else if m.SystemExtSpecific() {
1404		// A system_ext-specific module could be on the system_ext
1405		// partition at "system_ext" or the system partition at
1406		// "system/system_ext".
1407		if config.SystemExtPath() == "system_ext" {
1408			partition = "system_ext"
1409		}
1410	}
1411	return partition
1412}
1413
1414func (m *ModuleBase) Enabled(ctx ConfigAndErrorContext) bool {
1415	if m.commonProperties.ForcedDisabled {
1416		return false
1417	}
1418	return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
1419}
1420
1421func (m *ModuleBase) Disable() {
1422	m.commonProperties.ForcedDisabled = true
1423}
1424
1425// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1426func (m *ModuleBase) HideFromMake() {
1427	m.commonProperties.HideFromMake = true
1428}
1429
1430// IsHideFromMake returns true if HideFromMake was previously called.
1431func (m *ModuleBase) IsHideFromMake() bool {
1432	return m.commonProperties.HideFromMake == true
1433}
1434
1435// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
1436func (m *ModuleBase) SkipInstall() {
1437	m.commonProperties.SkipInstall = true
1438}
1439
1440// IsSkipInstall returns true if this variant is marked to not create install
1441// rules when ctx.Install* are called.
1442func (m *ModuleBase) IsSkipInstall() bool {
1443	return m.commonProperties.SkipInstall
1444}
1445
1446// Similar to HideFromMake, but if the AndroidMk entry would set
1447// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
1448// rather than leaving it out altogether. That happens in cases where it would
1449// have other side effects, in particular when it adds a NOTICE file target,
1450// which other install targets might depend on.
1451func (m *ModuleBase) MakeUninstallable() {
1452	m.commonProperties.UninstallableApexPlatformVariant = true
1453	m.HideFromMake()
1454}
1455
1456func (m *ModuleBase) ReplacedByPrebuilt() {
1457	m.commonProperties.ReplacedByPrebuilt = true
1458	m.HideFromMake()
1459}
1460
1461func (m *ModuleBase) IsReplacedByPrebuilt() bool {
1462	return m.commonProperties.ReplacedByPrebuilt
1463}
1464
1465func (m *ModuleBase) ExportedToMake() bool {
1466	return m.commonProperties.NamespaceExportedToMake
1467}
1468
1469func (m *ModuleBase) EffectiveLicenseKinds() []string {
1470	return m.commonProperties.Effective_license_kinds
1471}
1472
1473func (m *ModuleBase) EffectiveLicenseFiles() Paths {
1474	result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
1475	for _, p := range m.commonProperties.Effective_license_text {
1476		result = append(result, p.Path)
1477	}
1478	return result
1479}
1480
1481// computeInstallDeps finds the installed paths of all dependencies that have a dependency
1482// tag that is annotated as needing installation via the isInstallDepNeeded method.
1483func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*DepSet[InstallPath], []*DepSet[PackagingSpec]) {
1484	var installDeps []*DepSet[InstallPath]
1485	var packagingSpecs []*DepSet[PackagingSpec]
1486	ctx.VisitDirectDeps(func(dep Module) {
1487		if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
1488			// Installation is still handled by Make, so anything hidden from Make is not
1489			// installable.
1490			if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
1491				installDeps = append(installDeps, dep.base().installFilesDepSet)
1492			}
1493			// Add packaging deps even when the dependency is not installed so that uninstallable
1494			// modules can still be packaged.  Often the package will be installed instead.
1495			packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet)
1496		}
1497	})
1498
1499	return installDeps, packagingSpecs
1500}
1501
1502// isInstallDepNeeded returns true if installing the output files of the current module
1503// should also install the output files of the given dependency and dependency tag.
1504func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool {
1505	// Don't add a dependency from the platform to a library provided by an apex.
1506	if dep.base().commonProperties.UninstallableApexPlatformVariant {
1507		return false
1508	}
1509	// Only install modules if the dependency tag is an InstallDepNeeded tag.
1510	return IsInstallDepNeededTag(tag)
1511}
1512
1513func (m *ModuleBase) FilesToInstall() InstallPaths {
1514	return m.installFiles
1515}
1516
1517func (m *ModuleBase) PackagingSpecs() []PackagingSpec {
1518	return m.packagingSpecs
1519}
1520
1521func (m *ModuleBase) TransitivePackagingSpecs() []PackagingSpec {
1522	return m.packagingSpecsDepSet.ToList()
1523}
1524
1525func (m *ModuleBase) NoAddressSanitizer() bool {
1526	return m.noAddressSanitizer
1527}
1528
1529func (m *ModuleBase) InstallInData() bool {
1530	return false
1531}
1532
1533func (m *ModuleBase) InstallInTestcases() bool {
1534	return false
1535}
1536
1537func (m *ModuleBase) InstallInSanitizerDir() bool {
1538	return false
1539}
1540
1541func (m *ModuleBase) InstallInRamdisk() bool {
1542	return Bool(m.commonProperties.Ramdisk)
1543}
1544
1545func (m *ModuleBase) InstallInVendorRamdisk() bool {
1546	return Bool(m.commonProperties.Vendor_ramdisk)
1547}
1548
1549func (m *ModuleBase) InstallInDebugRamdisk() bool {
1550	return Bool(m.commonProperties.Debug_ramdisk)
1551}
1552
1553func (m *ModuleBase) InstallInRecovery() bool {
1554	return Bool(m.commonProperties.Recovery)
1555}
1556
1557func (m *ModuleBase) InstallInOdm() bool {
1558	return false
1559}
1560
1561func (m *ModuleBase) InstallInProduct() bool {
1562	return false
1563}
1564
1565func (m *ModuleBase) InstallInVendor() bool {
1566	return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
1567}
1568
1569func (m *ModuleBase) InstallInRoot() bool {
1570	return false
1571}
1572
1573func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
1574	return nil, nil
1575}
1576
1577func (m *ModuleBase) Owner() string {
1578	return String(m.commonProperties.Owner)
1579}
1580
1581func (m *ModuleBase) Team() string {
1582	return String(m.commonProperties.Team)
1583}
1584
1585func (m *ModuleBase) setImageVariation(variant string) {
1586	m.commonProperties.ImageVariation = variant
1587}
1588
1589func (m *ModuleBase) ImageVariation() blueprint.Variation {
1590	return blueprint.Variation{
1591		Mutator:   "image",
1592		Variation: m.base().commonProperties.ImageVariation,
1593	}
1594}
1595
1596func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1597	for i, v := range m.commonProperties.DebugMutators {
1598		if v == mutator {
1599			return m.commonProperties.DebugVariations[i]
1600		}
1601	}
1602
1603	return ""
1604}
1605
1606func (m *ModuleBase) InRamdisk() bool {
1607	return m.base().commonProperties.ImageVariation == RamdiskVariation
1608}
1609
1610func (m *ModuleBase) InVendorRamdisk() bool {
1611	return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
1612}
1613
1614func (m *ModuleBase) InDebugRamdisk() bool {
1615	return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
1616}
1617
1618func (m *ModuleBase) InRecovery() bool {
1619	return m.base().commonProperties.ImageVariation == RecoveryVariation
1620}
1621
1622func (m *ModuleBase) RequiredModuleNames() []string {
1623	return m.base().commonProperties.Required
1624}
1625
1626func (m *ModuleBase) HostRequiredModuleNames() []string {
1627	return m.base().commonProperties.Host_required
1628}
1629
1630func (m *ModuleBase) TargetRequiredModuleNames() []string {
1631	return m.base().commonProperties.Target_required
1632}
1633
1634func (m *ModuleBase) InitRc() Paths {
1635	return append(Paths{}, m.initRcPaths...)
1636}
1637
1638func (m *ModuleBase) VintfFragments() Paths {
1639	return append(Paths{}, m.vintfFragmentsPaths...)
1640}
1641
1642func (m *ModuleBase) CompileMultilib() *string {
1643	return m.base().commonProperties.Compile_multilib
1644}
1645
1646// SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
1647// apex container for use when generation the license metadata file.
1648func (m *ModuleBase) SetLicenseInstallMap(installMap []string) {
1649	m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
1650}
1651
1652func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
1653	var allInstalledFiles InstallPaths
1654	var allCheckbuildFiles Paths
1655	ctx.VisitAllModuleVariants(func(module Module) {
1656		a := module.base()
1657		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
1658		// A module's -checkbuild phony targets should
1659		// not be created if the module is not exported to make.
1660		// Those could depend on the build target and fail to compile
1661		// for the current build target.
1662		if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a) {
1663			allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
1664		}
1665	})
1666
1667	var deps Paths
1668
1669	namespacePrefix := ctx.Namespace().id
1670	if namespacePrefix != "" {
1671		namespacePrefix = namespacePrefix + "-"
1672	}
1673
1674	if len(allInstalledFiles) > 0 {
1675		name := namespacePrefix + ctx.ModuleName() + "-install"
1676		ctx.Phony(name, allInstalledFiles.Paths()...)
1677		m.installTarget = PathForPhony(ctx, name)
1678		deps = append(deps, m.installTarget)
1679	}
1680
1681	if len(allCheckbuildFiles) > 0 {
1682		name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
1683		ctx.Phony(name, allCheckbuildFiles...)
1684		m.checkbuildTarget = PathForPhony(ctx, name)
1685		deps = append(deps, m.checkbuildTarget)
1686	}
1687
1688	if len(deps) > 0 {
1689		suffix := ""
1690		if ctx.Config().KatiEnabled() {
1691			suffix = "-soong"
1692		}
1693
1694		ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
1695
1696		m.blueprintDir = ctx.ModuleDir()
1697	}
1698}
1699
1700func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
1701	var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1702	var deviceSpecific = Bool(m.commonProperties.Device_specific)
1703	var productSpecific = Bool(m.commonProperties.Product_specific)
1704	var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
1705
1706	msg := "conflicting value set here"
1707	if socSpecific && deviceSpecific {
1708		ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
1709		if Bool(m.commonProperties.Vendor) {
1710			ctx.PropertyErrorf("vendor", msg)
1711		}
1712		if Bool(m.commonProperties.Proprietary) {
1713			ctx.PropertyErrorf("proprietary", msg)
1714		}
1715		if Bool(m.commonProperties.Soc_specific) {
1716			ctx.PropertyErrorf("soc_specific", msg)
1717		}
1718	}
1719
1720	if productSpecific && systemExtSpecific {
1721		ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1722		ctx.PropertyErrorf("system_ext_specific", msg)
1723	}
1724
1725	if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
1726		if productSpecific {
1727			ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1728		} else {
1729			ctx.PropertyErrorf("system_ext_specific", "a module cannot be specific to SoC or device and system_ext at the same time.")
1730		}
1731		if deviceSpecific {
1732			ctx.PropertyErrorf("device_specific", msg)
1733		} else {
1734			if Bool(m.commonProperties.Vendor) {
1735				ctx.PropertyErrorf("vendor", msg)
1736			}
1737			if Bool(m.commonProperties.Proprietary) {
1738				ctx.PropertyErrorf("proprietary", msg)
1739			}
1740			if Bool(m.commonProperties.Soc_specific) {
1741				ctx.PropertyErrorf("soc_specific", msg)
1742			}
1743		}
1744	}
1745
1746	if productSpecific {
1747		return productSpecificModule
1748	} else if systemExtSpecific {
1749		return systemExtSpecificModule
1750	} else if deviceSpecific {
1751		return deviceSpecificModule
1752	} else if socSpecific {
1753		return socSpecificModule
1754	} else {
1755		return platformModule
1756	}
1757}
1758
1759func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
1760	return earlyModuleContext{
1761		EarlyModuleContext: ctx,
1762		kind:               determineModuleKind(m, ctx),
1763		config:             ctx.Config().(Config),
1764	}
1765}
1766
1767func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1768	return baseModuleContext{
1769		bp:                 ctx,
1770		archModuleContext:  m.archModuleContextFactory(ctx),
1771		earlyModuleContext: m.earlyModuleContextFactory(ctx),
1772	}
1773}
1774
1775func (m *ModuleBase) archModuleContextFactory(ctx blueprint.IncomingTransitionContext) archModuleContext {
1776	config := ctx.Config().(Config)
1777	target := m.Target()
1778	primaryArch := false
1779	if len(config.Targets[target.Os]) <= 1 {
1780		primaryArch = true
1781	} else {
1782		primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
1783	}
1784
1785	return archModuleContext{
1786		ready:         m.commonProperties.ArchReady,
1787		os:            m.commonProperties.CompileOS,
1788		target:        m.commonProperties.CompileTarget,
1789		targetPrimary: m.commonProperties.CompilePrimary,
1790		multiTargets:  m.commonProperties.CompileMultiTargets,
1791		primaryArch:   primaryArch,
1792	}
1793
1794}
1795
1796func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
1797	ctx := &moduleContext{
1798		module:            m.module,
1799		bp:                blueprintCtx,
1800		baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
1801		variables:         make(map[string]string),
1802	}
1803
1804	m.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
1805
1806	dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
1807	// set m.installFilesDepSet to only the transitive dependencies to be used as the dependencies
1808	// of installed files of this module.  It will be replaced by a depset including the installed
1809	// files of this module at the end for use by modules that depend on this one.
1810	m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, nil, dependencyInstallFiles)
1811
1812	// Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
1813	// reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
1814	// TODO: This will be removed once defaults modules handle missing dependency errors
1815	blueprintCtx.GetMissingDependencies()
1816
1817	// For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
1818	// are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
1819	// (because the dependencies are added before the modules are disabled). The
1820	// GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
1821	// ignored.
1822	ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
1823
1824	if ctx.config.captureBuild {
1825		ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
1826	}
1827
1828	desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
1829	var suffix []string
1830	if ctx.Os().Class != Device && ctx.Os().Class != Generic {
1831		suffix = append(suffix, ctx.Os().String())
1832	}
1833	if !ctx.PrimaryArch() {
1834		suffix = append(suffix, ctx.Arch().ArchType.String())
1835	}
1836	if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() {
1837		suffix = append(suffix, apexInfo.ApexVariationName)
1838	}
1839
1840	ctx.Variable(pctx, "moduleDesc", desc)
1841
1842	s := ""
1843	if len(suffix) > 0 {
1844		s = " [" + strings.Join(suffix, " ") + "]"
1845	}
1846	ctx.Variable(pctx, "moduleDescSuffix", s)
1847
1848	// Some common property checks for properties that will be used later in androidmk.go
1849	checkDistProperties(ctx, "dist", &m.distProperties.Dist)
1850	for i := range m.distProperties.Dists {
1851		checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
1852	}
1853
1854	if m.Enabled(ctx) {
1855		// ensure all direct android.Module deps are enabled
1856		ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
1857			if m, ok := bm.(Module); ok {
1858				ctx.validateAndroidModule(bm, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps, false)
1859			}
1860		})
1861
1862		if m.Device() {
1863			// Handle any init.rc and vintf fragment files requested by the module.  All files installed by this
1864			// module will automatically have a dependency on the installed init.rc or vintf fragment file.
1865			// The same init.rc or vintf fragment file may be requested by multiple modules or variants,
1866			// so instead of installing them now just compute the install path and store it for later.
1867			// The full list of all init.rc and vintf fragment install rules will be deduplicated later
1868			// so only a single rule is created for each init.rc or vintf fragment file.
1869
1870			if !m.InVendorRamdisk() {
1871				m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
1872				rcDir := PathForModuleInstall(ctx, "etc", "init")
1873				for _, src := range m.initRcPaths {
1874					installedInitRc := rcDir.Join(ctx, src.Base())
1875					m.katiInitRcInstalls = append(m.katiInitRcInstalls, katiInstall{
1876						from: src,
1877						to:   installedInitRc,
1878					})
1879					ctx.PackageFile(rcDir, src.Base(), src)
1880					m.installedInitRcPaths = append(m.installedInitRcPaths, installedInitRc)
1881				}
1882			}
1883
1884			m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
1885			vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
1886			for _, src := range m.vintfFragmentsPaths {
1887				installedVintfFragment := vintfDir.Join(ctx, src.Base())
1888				m.katiVintfInstalls = append(m.katiVintfInstalls, katiInstall{
1889					from: src,
1890					to:   installedVintfFragment,
1891				})
1892				ctx.PackageFile(vintfDir, src.Base(), src)
1893				m.installedVintfFragmentsPaths = append(m.installedVintfFragmentsPaths, installedVintfFragment)
1894			}
1895		}
1896
1897		licensesPropertyFlattener(ctx)
1898		if ctx.Failed() {
1899			return
1900		}
1901
1902		if jarJarPrefixHandler != nil {
1903			jarJarPrefixHandler(ctx)
1904			if ctx.Failed() {
1905				return
1906			}
1907		}
1908
1909		// Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used
1910		// in m.module.GenerateAndroidBuildActions
1911		aconfigUpdateAndroidBuildActions(ctx)
1912		if ctx.Failed() {
1913			return
1914		}
1915
1916		m.module.GenerateAndroidBuildActions(ctx)
1917		if ctx.Failed() {
1918			return
1919		}
1920
1921		// Create the set of tagged dist files after calling GenerateAndroidBuildActions
1922		// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
1923		// output paths being set which must be done before or during
1924		// GenerateAndroidBuildActions.
1925		m.distFiles = m.GenerateTaggedDistFiles(ctx)
1926		if ctx.Failed() {
1927			return
1928		}
1929
1930		m.installFiles = append(m.installFiles, ctx.installFiles...)
1931		m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
1932		m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
1933		m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...)
1934		m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...)
1935		m.testData = append(m.testData, ctx.testData...)
1936	} else if ctx.Config().AllowMissingDependencies() {
1937		// If the module is not enabled it will not create any build rules, nothing will call
1938		// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
1939		// and report them as an error even when AllowMissingDependencies = true.  Call
1940		// ctx.GetMissingDependencies() here to tell blueprint not to handle them.
1941		ctx.GetMissingDependencies()
1942	}
1943
1944	if m == ctx.FinalModule().(Module).base() {
1945		m.generateModuleTarget(ctx)
1946		if ctx.Failed() {
1947			return
1948		}
1949	}
1950
1951	m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, m.installFiles, dependencyInstallFiles)
1952	m.packagingSpecsDepSet = NewDepSet[PackagingSpec](TOPOLOGICAL, m.packagingSpecs, dependencyPackagingSpecs)
1953
1954	buildLicenseMetadata(ctx, m.licenseMetadataFile)
1955
1956	if m.moduleInfoJSON != nil {
1957		var installed InstallPaths
1958		installed = append(installed, m.katiInstalls.InstallPaths()...)
1959		installed = append(installed, m.katiSymlinks.InstallPaths()...)
1960		installed = append(installed, m.katiInitRcInstalls.InstallPaths()...)
1961		installed = append(installed, m.katiVintfInstalls.InstallPaths()...)
1962		installedStrings := installed.Strings()
1963
1964		var targetRequired, hostRequired []string
1965		if ctx.Host() {
1966			targetRequired = m.commonProperties.Target_required
1967		} else {
1968			hostRequired = m.commonProperties.Host_required
1969		}
1970
1971		var data []string
1972		for _, d := range m.testData {
1973			data = append(data, d.ToRelativeInstallPath())
1974		}
1975
1976		if m.moduleInfoJSON.Uninstallable {
1977			installedStrings = nil
1978			if len(m.moduleInfoJSON.CompatibilitySuites) == 1 && m.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
1979				m.moduleInfoJSON.CompatibilitySuites = nil
1980				m.moduleInfoJSON.TestConfig = nil
1981				m.moduleInfoJSON.AutoTestConfig = nil
1982				data = nil
1983			}
1984		}
1985
1986		m.moduleInfoJSON.core = CoreModuleInfoJSON{
1987			RegisterName:       m.moduleInfoRegisterName(ctx, m.moduleInfoJSON.SubName),
1988			Path:               []string{ctx.ModuleDir()},
1989			Installed:          installedStrings,
1990			ModuleName:         m.BaseModuleName() + m.moduleInfoJSON.SubName,
1991			SupportedVariants:  []string{m.moduleInfoVariant(ctx)},
1992			TargetDependencies: targetRequired,
1993			HostDependencies:   hostRequired,
1994			Data:               data,
1995			Required:           m.RequiredModuleNames(),
1996		}
1997		SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON)
1998	}
1999
2000	m.buildParams = ctx.buildParams
2001	m.ruleParams = ctx.ruleParams
2002	m.variables = ctx.variables
2003
2004	if m.outputFiles.DefaultOutputFiles != nil || m.outputFiles.TaggedOutputFiles != nil {
2005		SetProvider(ctx, OutputFilesProvider, m.outputFiles)
2006	}
2007}
2008
2009func SetJarJarPrefixHandler(handler func(ModuleContext)) {
2010	if jarJarPrefixHandler != nil {
2011		panic("jarJarPrefixHandler already set")
2012	}
2013	jarJarPrefixHandler = handler
2014}
2015
2016func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
2017	name := m.BaseModuleName()
2018
2019	prefix := ""
2020	if ctx.Host() {
2021		if ctx.Os() != ctx.Config().BuildOS {
2022			prefix = "host_cross_"
2023		}
2024	}
2025	suffix := ""
2026	arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
2027	arches = slices.DeleteFunc(arches, func(target Target) bool {
2028		return target.NativeBridge != ctx.Target().NativeBridge
2029	})
2030	if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType {
2031		if ctx.Arch().ArchType.Multilib == "lib32" {
2032			suffix = "_32"
2033		} else {
2034			suffix = "_64"
2035		}
2036	}
2037	return prefix + name + subName + suffix
2038}
2039
2040func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
2041	variant := "DEVICE"
2042	if ctx.Host() {
2043		if ctx.Os() != ctx.Config().BuildOS {
2044			variant = "HOST_CROSS"
2045		} else {
2046			variant = "HOST"
2047		}
2048	}
2049	return variant
2050}
2051
2052// Check the supplied dist structure to make sure that it is valid.
2053//
2054// property - the base property, e.g. dist or dists[1], which is combined with the
2055// name of the nested property to produce the full property, e.g. dist.dest or
2056// dists[1].dir.
2057func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2058	if dist.Dest != nil {
2059		_, err := validateSafePath(*dist.Dest)
2060		if err != nil {
2061			ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2062		}
2063	}
2064	if dist.Dir != nil {
2065		_, err := validateSafePath(*dist.Dir)
2066		if err != nil {
2067			ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2068		}
2069	}
2070	if dist.Suffix != nil {
2071		if strings.Contains(*dist.Suffix, "/") {
2072			ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2073		}
2074	}
2075
2076}
2077
2078// katiInstall stores a request from Soong to Make to create an install rule.
2079type katiInstall struct {
2080	from          Path
2081	to            InstallPath
2082	implicitDeps  Paths
2083	orderOnlyDeps Paths
2084	executable    bool
2085	extraFiles    *extraFilesZip
2086
2087	absFrom string
2088}
2089
2090type extraFilesZip struct {
2091	zip Path
2092	dir InstallPath
2093}
2094
2095type katiInstalls []katiInstall
2096
2097// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2098// space separated list of from:to tuples.
2099func (installs katiInstalls) BuiltInstalled() string {
2100	sb := strings.Builder{}
2101	for i, install := range installs {
2102		if i != 0 {
2103			sb.WriteRune(' ')
2104		}
2105		sb.WriteString(install.from.String())
2106		sb.WriteRune(':')
2107		sb.WriteString(install.to.String())
2108	}
2109	return sb.String()
2110}
2111
2112// InstallPaths returns the install path of each entry.
2113func (installs katiInstalls) InstallPaths() InstallPaths {
2114	paths := make(InstallPaths, 0, len(installs))
2115	for _, install := range installs {
2116		paths = append(paths, install.to)
2117	}
2118	return paths
2119}
2120
2121// Makes this module a platform module, i.e. not specific to soc, device,
2122// product, or system_ext.
2123func (m *ModuleBase) MakeAsPlatform() {
2124	m.commonProperties.Vendor = boolPtr(false)
2125	m.commonProperties.Proprietary = boolPtr(false)
2126	m.commonProperties.Soc_specific = boolPtr(false)
2127	m.commonProperties.Product_specific = boolPtr(false)
2128	m.commonProperties.System_ext_specific = boolPtr(false)
2129}
2130
2131func (m *ModuleBase) MakeAsSystemExt() {
2132	m.commonProperties.Vendor = boolPtr(false)
2133	m.commonProperties.Proprietary = boolPtr(false)
2134	m.commonProperties.Soc_specific = boolPtr(false)
2135	m.commonProperties.Product_specific = boolPtr(false)
2136	m.commonProperties.System_ext_specific = boolPtr(true)
2137}
2138
2139// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
2140func (m *ModuleBase) IsNativeBridgeSupported() bool {
2141	return proptools.Bool(m.commonProperties.Native_bridge_supported)
2142}
2143
2144type ConfigAndErrorContext interface {
2145	Config() Config
2146	OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
2147}
2148
2149type configurationEvalutor struct {
2150	ctx ConfigAndErrorContext
2151	m   Module
2152}
2153
2154func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator {
2155	return configurationEvalutor{
2156		ctx: ctx,
2157		m:   m.module,
2158	}
2159}
2160
2161func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
2162	e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
2163}
2164
2165func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
2166	ctx := e.ctx
2167	m := e.m
2168	switch condition.FunctionName() {
2169	case "release_flag":
2170		if condition.NumArgs() != 1 {
2171			ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs())
2172			return proptools.ConfigurableValueUndefined()
2173		}
2174		if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok {
2175			v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]
2176			switch ty {
2177			case "unspecified", "obsolete":
2178				return proptools.ConfigurableValueUndefined()
2179			case "string":
2180				return proptools.ConfigurableValueString(v)
2181			case "bool":
2182				return proptools.ConfigurableValueBool(v == "true")
2183			default:
2184				panic("unhandled release flag type: " + ty)
2185			}
2186		}
2187		return proptools.ConfigurableValueUndefined()
2188	case "product_variable":
2189		if condition.NumArgs() != 1 {
2190			ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
2191			return proptools.ConfigurableValueUndefined()
2192		}
2193		variable := condition.Arg(0)
2194		switch variable {
2195		case "debuggable":
2196			return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
2197		default:
2198			// TODO(b/323382414): Might add these on a case-by-case basis
2199			ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
2200			return proptools.ConfigurableValueUndefined()
2201		}
2202	case "soong_config_variable":
2203		if condition.NumArgs() != 2 {
2204			ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
2205			return proptools.ConfigurableValueUndefined()
2206		}
2207		namespace := condition.Arg(0)
2208		variable := condition.Arg(1)
2209		if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
2210			if v, ok := n[variable]; ok {
2211				return proptools.ConfigurableValueString(v)
2212			}
2213		}
2214		return proptools.ConfigurableValueUndefined()
2215	case "arch":
2216		if condition.NumArgs() != 0 {
2217			ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
2218			return proptools.ConfigurableValueUndefined()
2219		}
2220		if !m.base().ArchReady() {
2221			ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
2222			return proptools.ConfigurableValueUndefined()
2223		}
2224		return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
2225	case "os":
2226		if condition.NumArgs() != 0 {
2227			ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
2228			return proptools.ConfigurableValueUndefined()
2229		}
2230		// the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
2231		if !m.base().ArchReady() {
2232			ctx.OtherModulePropertyErrorf(m, property, "A select on os was attempted before the arch mutator ran (arch runs after os, we use it to lazily detect that os is ready)")
2233			return proptools.ConfigurableValueUndefined()
2234		}
2235		return proptools.ConfigurableValueString(m.base().Os().Name)
2236	case "boolean_var_for_testing":
2237		// We currently don't have any other boolean variables (we should add support for typing
2238		// the soong config variables), so add this fake one for testing the boolean select
2239		// functionality.
2240		if condition.NumArgs() != 0 {
2241			ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
2242			return proptools.ConfigurableValueUndefined()
2243		}
2244
2245		if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
2246			if v, ok := n["for_testing"]; ok {
2247				switch v {
2248				case "true":
2249					return proptools.ConfigurableValueBool(true)
2250				case "false":
2251					return proptools.ConfigurableValueBool(false)
2252				default:
2253					ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
2254				}
2255			}
2256		}
2257		return proptools.ConfigurableValueUndefined()
2258	default:
2259		ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
2260		return proptools.ConfigurableValueUndefined()
2261	}
2262}
2263
2264// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
2265// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
2266// or if this variant is not overridden.
2267func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
2268	if overridable, ok := ctx.Module().(OverridableModule); ok {
2269		if o := overridable.GetOverriddenBy(); o != "" {
2270			return o
2271		}
2272	}
2273	return ctx.ModuleName()
2274}
2275
2276// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
2277// into the module name, or empty string if the input was not a module reference.
2278func SrcIsModule(s string) (module string) {
2279	if len(s) > 1 {
2280		if s[0] == ':' {
2281			module = s[1:]
2282			if !isUnqualifiedModuleName(module) {
2283				// The module name should be unqualified but is not so do not treat it as a module.
2284				module = ""
2285			}
2286		} else if s[0] == '/' && s[1] == '/' {
2287			module = s
2288		}
2289	}
2290	return module
2291}
2292
2293// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
2294// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
2295// into the module name and an empty string for the tag, or empty strings if the input was not a
2296// module reference.
2297func SrcIsModuleWithTag(s string) (module, tag string) {
2298	if len(s) > 1 {
2299		if s[0] == ':' {
2300			module = s[1:]
2301		} else if s[0] == '/' && s[1] == '/' {
2302			module = s
2303		}
2304
2305		if module != "" {
2306			if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2307				if module[len(module)-1] == '}' {
2308					tag = module[tagStart+1 : len(module)-1]
2309					module = module[:tagStart]
2310				}
2311			}
2312
2313			if s[0] == ':' && !isUnqualifiedModuleName(module) {
2314				// The module name should be unqualified but is not so do not treat it as a module.
2315				module = ""
2316				tag = ""
2317			}
2318		}
2319	}
2320
2321	return module, tag
2322}
2323
2324// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
2325// does not contain any /.
2326func isUnqualifiedModuleName(module string) bool {
2327	return strings.IndexByte(module, '/') == -1
2328}
2329
2330// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
2331// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
2332// or ExtractSourcesDeps.
2333//
2334// If uniquely identifies the dependency that was added as it contains both the module name used to
2335// add the dependency as well as the tag. That makes it very simple to find the matching dependency
2336// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
2337// used to add it. It does not need to check that the module name as returned by one of
2338// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
2339// name supplied in the tag. That means it does not need to handle differences in module names
2340// caused by prebuilt_ prefix, or fully qualified module names.
2341type sourceOrOutputDependencyTag struct {
2342	blueprint.BaseDependencyTag
2343	AlwaysPropagateAconfigValidationDependencyTag
2344
2345	// The name of the module.
2346	moduleName string
2347
2348	// The tag that will be passed to the module's OutputFileProducer.OutputFiles(tag) method.
2349	tag string
2350}
2351
2352func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
2353	return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
2354}
2355
2356// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
2357// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
2358// properties tagged with `android:"path"` AND it was added using a module reference of
2359// :moduleName{outputTag}.
2360func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
2361	t, ok := depTag.(sourceOrOutputDependencyTag)
2362	return ok && t.tag == outputTag
2363}
2364
2365// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2366// using ":module" syntax, if any.
2367//
2368// Deprecated: tag the property with `android:"path"` instead.
2369func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
2370	set := make(map[string]bool)
2371
2372	for _, s := range srcFiles {
2373		if m, t := SrcIsModuleWithTag(s); m != "" {
2374			if _, found := set[s]; found {
2375				ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
2376			} else {
2377				set[s] = true
2378				ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
2379			}
2380		}
2381	}
2382}
2383
2384// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2385// using ":module" syntax, if any.
2386//
2387// Deprecated: tag the property with `android:"path"` instead.
2388func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2389	if s != nil {
2390		if m, t := SrcIsModuleWithTag(*s); m != "" {
2391			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
2392		}
2393	}
2394}
2395
2396// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2397// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property.
2398type SourceFileProducer interface {
2399	Srcs() Paths
2400}
2401
2402// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
2403// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were
2404// listed in the property.
2405type OutputFileProducer interface {
2406	OutputFiles(tag string) (Paths, error)
2407}
2408
2409// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag.  On error, including if the
2410// module produced zero paths, it reports errors to the ctx and returns nil.
2411func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
2412	paths, err := outputFilesForModule(ctx, module, tag)
2413	if err != nil {
2414		reportPathError(ctx, err)
2415		return nil
2416	}
2417	return paths
2418}
2419
2420// OutputFileForModule returns the path from an OutputFileProducer with the given tag.  On error, including if the
2421// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
2422func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
2423	paths, err := outputFilesForModule(ctx, module, tag)
2424	if err != nil {
2425		reportPathError(ctx, err)
2426		return nil
2427	}
2428	if len(paths) == 0 {
2429		type addMissingDependenciesIntf interface {
2430			AddMissingDependencies([]string)
2431			OtherModuleName(blueprint.Module) string
2432		}
2433		if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
2434			mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
2435		} else {
2436			ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
2437		}
2438		// Return a fake output file to avoid nil dereferences of Path objects later.
2439		// This should never get used for an actual build as the error or missing
2440		// dependency has already been reported.
2441		p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
2442		if err != nil {
2443			reportPathError(ctx, err)
2444			return nil
2445		}
2446		return p
2447	}
2448	if len(paths) > 1 {
2449		ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
2450			pathContextName(ctx, module))
2451	}
2452	return paths[0]
2453}
2454
2455func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
2456	outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
2457	if outputFilesFromProvider != nil || err != nil {
2458		return outputFilesFromProvider, err
2459	}
2460	if outputFileProducer, ok := module.(OutputFileProducer); ok {
2461		paths, err := outputFileProducer.OutputFiles(tag)
2462		if err != nil {
2463			return nil, fmt.Errorf("failed to get output file from module %q at tag %q: %s",
2464				pathContextName(ctx, module), tag, err.Error())
2465		}
2466		return paths, nil
2467	} else if sourceFileProducer, ok := module.(SourceFileProducer); ok {
2468		if tag != "" {
2469			return nil, fmt.Errorf("module %q is a SourceFileProducer, not an OutputFileProducer, and so does not support tag %q", pathContextName(ctx, module), tag)
2470		}
2471		paths := sourceFileProducer.Srcs()
2472		return paths, nil
2473	} else {
2474		return nil, fmt.Errorf("module %q is not an OutputFileProducer or SourceFileProducer", pathContextName(ctx, module))
2475	}
2476}
2477
2478// This method uses OutputFilesProvider for output files
2479// *inter-module-communication*.
2480// If mctx module is the same as the param module the output files are obtained
2481// from outputFiles property of module base, to avoid both setting and
2482// reading OutputFilesProvider before  GenerateBuildActions is finished. Also
2483// only empty-string-tag is supported in this case.
2484// If a module doesn't have the OutputFilesProvider, nil is returned.
2485func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
2486	// TODO: support OutputFilesProvider for singletons
2487	mctx, ok := ctx.(ModuleContext)
2488	if !ok {
2489		return nil, nil
2490	}
2491	if mctx.Module() != module {
2492		if outputFilesProvider, ok := OtherModuleProvider(mctx, module, OutputFilesProvider); ok {
2493			if tag == "" {
2494				return outputFilesProvider.DefaultOutputFiles, nil
2495			} else if taggedOutputFiles, hasTag := outputFilesProvider.TaggedOutputFiles[tag]; hasTag {
2496				return taggedOutputFiles, nil
2497			} else {
2498				return nil, fmt.Errorf("unsupported module reference tag %q", tag)
2499			}
2500		}
2501	} else {
2502		if tag == "" {
2503			return mctx.Module().base().outputFiles.DefaultOutputFiles, nil
2504		} else {
2505			return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
2506		}
2507	}
2508	// TODO: Add a check for param module not having OutputFilesProvider set
2509	return nil, nil
2510}
2511
2512type OutputFilesInfo struct {
2513	// default output files when tag is an empty string ""
2514	DefaultOutputFiles Paths
2515
2516	// the corresponding output files for given tags
2517	TaggedOutputFiles map[string]Paths
2518}
2519
2520var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
2521
2522// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
2523// specify that they can be used as a tool by a genrule module.
2524type HostToolProvider interface {
2525	Module
2526	// HostToolPath returns the path to the host tool for the module if it is one, or an invalid
2527	// OptionalPath.
2528	HostToolPath() OptionalPath
2529}
2530
2531func init() {
2532	RegisterParallelSingletonType("buildtarget", BuildTargetSingleton)
2533	RegisterParallelSingletonType("soongconfigtrace", soongConfigTraceSingletonFunc)
2534	FinalDepsMutators(registerSoongConfigTraceMutator)
2535}
2536
2537func BuildTargetSingleton() Singleton {
2538	return &buildTargetSingleton{}
2539}
2540
2541func parentDir(dir string) string {
2542	dir, _ = filepath.Split(dir)
2543	return filepath.Clean(dir)
2544}
2545
2546type buildTargetSingleton struct{}
2547
2548func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
2549	// Ensure ancestor directories are in dirMap
2550	// Make directories build their direct subdirectories
2551	// Returns a slice of all directories and a slice of top-level directories.
2552	dirs := SortedKeys(dirMap)
2553	for _, dir := range dirs {
2554		dir := parentDir(dir)
2555		for dir != "." && dir != "/" {
2556			if _, exists := dirMap[dir]; exists {
2557				break
2558			}
2559			dirMap[dir] = nil
2560			dir = parentDir(dir)
2561		}
2562	}
2563	dirs = SortedKeys(dirMap)
2564	var topDirs []string
2565	for _, dir := range dirs {
2566		p := parentDir(dir)
2567		if p != "." && p != "/" {
2568			dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
2569		} else if dir != "." && dir != "/" && dir != "" {
2570			topDirs = append(topDirs, dir)
2571		}
2572	}
2573	return SortedKeys(dirMap), topDirs
2574}
2575
2576func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
2577	var checkbuildDeps Paths
2578
2579	mmTarget := func(dir string) string {
2580		return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
2581	}
2582
2583	modulesInDir := make(map[string]Paths)
2584
2585	ctx.VisitAllModules(func(module Module) {
2586		blueprintDir := module.base().blueprintDir
2587		installTarget := module.base().installTarget
2588		checkbuildTarget := module.base().checkbuildTarget
2589
2590		if checkbuildTarget != nil {
2591			checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
2592			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
2593		}
2594
2595		if installTarget != nil {
2596			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
2597		}
2598	})
2599
2600	suffix := ""
2601	if ctx.Config().KatiEnabled() {
2602		suffix = "-soong"
2603	}
2604
2605	// Create a top-level checkbuild target that depends on all modules
2606	ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
2607
2608	// Make will generate the MODULES-IN-* targets
2609	if ctx.Config().KatiEnabled() {
2610		return
2611	}
2612
2613	dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
2614
2615	// Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
2616	// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
2617	// files.
2618	for _, dir := range dirs {
2619		ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
2620	}
2621
2622	// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
2623	type osAndCross struct {
2624		os        OsType
2625		hostCross bool
2626	}
2627	osDeps := map[osAndCross]Paths{}
2628	ctx.VisitAllModules(func(module Module) {
2629		if module.Enabled(ctx) {
2630			key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
2631			osDeps[key] = append(osDeps[key], module.base().checkbuildFiles...)
2632		}
2633	})
2634
2635	osClass := make(map[string]Paths)
2636	for key, deps := range osDeps {
2637		var className string
2638
2639		switch key.os.Class {
2640		case Host:
2641			if key.hostCross {
2642				className = "host-cross"
2643			} else {
2644				className = "host"
2645			}
2646		case Device:
2647			className = "target"
2648		default:
2649			continue
2650		}
2651
2652		name := className + "-" + key.os.Name
2653		osClass[className] = append(osClass[className], PathForPhony(ctx, name))
2654
2655		ctx.Phony(name, deps...)
2656	}
2657
2658	// Wrap those into host|host-cross|target phony rules
2659	for _, class := range SortedKeys(osClass) {
2660		ctx.Phony(class, osClass[class]...)
2661	}
2662}
2663
2664// Collect information for opening IDE project files in java/jdeps.go.
2665type IDEInfo interface {
2666	IDEInfo(ideInfo *IdeInfo)
2667	BaseModuleName() string
2668}
2669
2670// Extract the base module name from the Import name.
2671// Often the Import name has a prefix "prebuilt_".
2672// Remove the prefix explicitly if needed
2673// until we find a better solution to get the Import name.
2674type IDECustomizedModuleName interface {
2675	IDECustomizedModuleName() string
2676}
2677
2678type IdeInfo struct {
2679	Deps              []string `json:"dependencies,omitempty"`
2680	Srcs              []string `json:"srcs,omitempty"`
2681	Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
2682	Jarjar_rules      []string `json:"jarjar_rules,omitempty"`
2683	Jars              []string `json:"jars,omitempty"`
2684	Classes           []string `json:"class,omitempty"`
2685	Installed_paths   []string `json:"installed,omitempty"`
2686	SrcJars           []string `json:"srcjars,omitempty"`
2687	Paths             []string `json:"path,omitempty"`
2688	Static_libs       []string `json:"static_libs,omitempty"`
2689	Libs              []string `json:"libs,omitempty"`
2690}
2691
2692func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
2693	bpctx := ctx.blueprintBaseModuleContext()
2694	return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
2695}
2696
2697func registerSoongConfigTraceMutator(ctx RegisterMutatorsContext) {
2698	ctx.BottomUp("soongconfigtrace", soongConfigTraceMutator).Parallel()
2699}
2700
2701// soongConfigTraceMutator accumulates recorded soong_config trace from children. Also it normalizes
2702// SoongConfigTrace to make it consistent.
2703func soongConfigTraceMutator(ctx BottomUpMutatorContext) {
2704	trace := &ctx.Module().base().commonProperties.SoongConfigTrace
2705	ctx.VisitDirectDeps(func(m Module) {
2706		childTrace := &m.base().commonProperties.SoongConfigTrace
2707		trace.Bools = append(trace.Bools, childTrace.Bools...)
2708		trace.Strings = append(trace.Strings, childTrace.Strings...)
2709		trace.IsSets = append(trace.IsSets, childTrace.IsSets...)
2710	})
2711	trace.Bools = SortedUniqueStrings(trace.Bools)
2712	trace.Strings = SortedUniqueStrings(trace.Strings)
2713	trace.IsSets = SortedUniqueStrings(trace.IsSets)
2714
2715	ctx.Module().base().commonProperties.SoongConfigTraceHash = trace.hash()
2716}
2717
2718// soongConfigTraceSingleton writes a map from each module's config hash value to trace data.
2719func soongConfigTraceSingletonFunc() Singleton {
2720	return &soongConfigTraceSingleton{}
2721}
2722
2723type soongConfigTraceSingleton struct {
2724}
2725
2726func (s *soongConfigTraceSingleton) GenerateBuildActions(ctx SingletonContext) {
2727	outFile := PathForOutput(ctx, "soong_config_trace.json")
2728
2729	traces := make(map[string]*soongConfigTrace)
2730	ctx.VisitAllModules(func(module Module) {
2731		trace := &module.base().commonProperties.SoongConfigTrace
2732		if !trace.isEmpty() {
2733			hash := module.base().commonProperties.SoongConfigTraceHash
2734			traces[hash] = trace
2735		}
2736	})
2737
2738	j, err := json.Marshal(traces)
2739	if err != nil {
2740		ctx.Errorf("json marshal to %q failed: %#v", outFile, err)
2741		return
2742	}
2743
2744	WriteFileRule(ctx, outFile, string(j))
2745	ctx.Phony("soong_config_trace", outFile)
2746}
2747