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