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