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