• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18	"fmt"
19	"net/url"
20	"os"
21	"path"
22	"path/filepath"
23	"reflect"
24	"regexp"
25	"sort"
26	"strings"
27	"text/scanner"
28
29	"android/soong/bazel"
30
31	"github.com/google/blueprint"
32	"github.com/google/blueprint/proptools"
33)
34
35var (
36	DeviceSharedLibrary = "shared_library"
37	DeviceStaticLibrary = "static_library"
38)
39
40// BuildParameters describes the set of potential parameters to build a Ninja rule.
41// In general, these correspond to a Ninja concept.
42type BuildParams struct {
43	// A Ninja Rule that will be written to the Ninja file. This allows factoring out common code
44	// among multiple modules to reduce repetition in the Ninja file of action requirements. A rule
45	// can contain variables that should be provided in Args.
46	Rule blueprint.Rule
47	// Deps represents the depfile format. When using RuleBuilder, this defaults to GCC when depfiles
48	// are used.
49	Deps blueprint.Deps
50	// Depfile is a writeable path that allows correct incremental builds when the inputs have not
51	// been fully specified by the Ninja rule. Ninja supports a subset of the Makefile depfile syntax.
52	Depfile WritablePath
53	// A description of the build action.
54	Description string
55	// Output is an output file of the action. When using this field, references to $out in the Ninja
56	// command will refer to this file.
57	Output WritablePath
58	// Outputs is a slice of output file of the action. When using this field, references to $out in
59	// the Ninja command will refer to these files.
60	Outputs WritablePaths
61	// SymlinkOutput is an output file specifically that is a symlink.
62	SymlinkOutput WritablePath
63	// SymlinkOutputs is a slice of output files specifically that is a symlink.
64	SymlinkOutputs WritablePaths
65	// ImplicitOutput is an output file generated by the action. Note: references to `$out` in the
66	// Ninja command will NOT include references to this file.
67	ImplicitOutput WritablePath
68	// ImplicitOutputs is a slice of output files generated by the action. Note: references to `$out`
69	// in the Ninja command will NOT include references to these files.
70	ImplicitOutputs WritablePaths
71	// Input is an input file to the Ninja action. When using this field, references to $in in the
72	// Ninja command will refer to this file.
73	Input Path
74	// Inputs is a slice of input files to the Ninja action. When using this field, references to $in
75	// in the Ninja command will refer to these files.
76	Inputs Paths
77	// Implicit is an input file to the Ninja action. Note: references to `$in` in the Ninja command
78	// will NOT include references to this file.
79	Implicit Path
80	// Implicits is a slice of input files to the Ninja action. Note: references to `$in` in the Ninja
81	// command will NOT include references to these files.
82	Implicits Paths
83	// OrderOnly are Ninja order-only inputs to the action. When these are out of date, the output is
84	// not rebuilt until they are built, but changes in order-only dependencies alone do not cause the
85	// output to be rebuilt.
86	OrderOnly Paths
87	// Validation is an output path for a validation action. Validation outputs imply lower
88	// non-blocking priority to building non-validation outputs.
89	Validation Path
90	// Validations is a slice of output path for a validation action. Validation outputs imply lower
91	// non-blocking priority to building non-validation outputs.
92	Validations Paths
93	// Whether to skip outputting a default target statement which will be built by Ninja when no
94	// targets are specified on Ninja's command line.
95	Default bool
96	// Args is a key value mapping for replacements of variables within the Rule
97	Args map[string]string
98}
99
100type ModuleBuildParams BuildParams
101
102// EarlyModuleContext provides methods that can be called early, as soon as the properties have
103// been parsed into the module and before any mutators have run.
104type EarlyModuleContext interface {
105	// Module returns the current module as a Module.  It should rarely be necessary, as the module already has a
106	// reference to itself.
107	Module() Module
108
109	// ModuleName returns the name of the module.  This is generally the value that was returned by Module.Name() when
110	// the module was created, but may have been modified by calls to BaseMutatorContext.Rename.
111	ModuleName() string
112
113	// ModuleDir returns the path to the directory that contains the definition of the module.
114	ModuleDir() string
115
116	// ModuleType returns the name of the module type that was used to create the module, as specified in
117	// RegisterModuleType.
118	ModuleType() string
119
120	// BlueprintFile returns the name of the blueprint file that contains the definition of this
121	// module.
122	BlueprintsFile() string
123
124	// ContainsProperty returns true if the specified property name was set in the module definition.
125	ContainsProperty(name string) bool
126
127	// Errorf reports an error at the specified position of the module definition file.
128	Errorf(pos scanner.Position, fmt string, args ...interface{})
129
130	// ModuleErrorf reports an error at the line number of the module type in the module definition.
131	ModuleErrorf(fmt string, args ...interface{})
132
133	// PropertyErrorf reports an error at the line number of a property in the module definition.
134	PropertyErrorf(property, fmt string, args ...interface{})
135
136	// Failed returns true if any errors have been reported.  In most cases the module can continue with generating
137	// build rules after an error, allowing it to report additional errors in a single run, but in cases where the error
138	// has prevented the module from creating necessary data it can return early when Failed returns true.
139	Failed() bool
140
141	// AddNinjaFileDeps adds dependencies on the specified files to the rule that creates the ninja manifest.  The
142	// primary builder will be rerun whenever the specified files are modified.
143	AddNinjaFileDeps(deps ...string)
144
145	DeviceSpecific() bool
146	SocSpecific() bool
147	ProductSpecific() bool
148	SystemExtSpecific() bool
149	Platform() bool
150
151	Config() Config
152	DeviceConfig() DeviceConfig
153
154	// Deprecated: use Config()
155	AConfig() Config
156
157	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
158	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
159	// builder whenever a file matching the pattern as added or removed, without rerunning if a
160	// file that does not match the pattern is added to a searched directory.
161	GlobWithDeps(pattern string, excludes []string) ([]string, error)
162
163	Glob(globPattern string, excludes []string) Paths
164	GlobFiles(globPattern string, excludes []string) Paths
165	IsSymlink(path Path) bool
166	Readlink(path Path) string
167
168	// Namespace returns the Namespace object provided by the NameInterface set by Context.SetNameInterface, or the
169	// default SimpleNameInterface if Context.SetNameInterface was not called.
170	Namespace() *Namespace
171}
172
173// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
174// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
175// instead of a blueprint.Module, plus some extra methods that return Android-specific information
176// about the current module.
177type BaseModuleContext interface {
178	EarlyModuleContext
179
180	blueprintBaseModuleContext() blueprint.BaseModuleContext
181
182	// OtherModuleName returns the name of another Module.  See BaseModuleContext.ModuleName for more information.
183	// It is intended for use inside the visit functions of Visit* and WalkDeps.
184	OtherModuleName(m blueprint.Module) string
185
186	// OtherModuleDir returns the directory of another Module.  See BaseModuleContext.ModuleDir for more information.
187	// It is intended for use inside the visit functions of Visit* and WalkDeps.
188	OtherModuleDir(m blueprint.Module) string
189
190	// OtherModuleErrorf reports an error on another Module.  See BaseModuleContext.ModuleErrorf for more information.
191	// It is intended for use inside the visit functions of Visit* and WalkDeps.
192	OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
193
194	// OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency
195	// on the module.  When called inside a Visit* method with current module being visited, and there are multiple
196	// dependencies on the module being visited, it returns the dependency tag used for the current dependency.
197	OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
198
199	// OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface
200	// passed to Context.SetNameInterface, or SimpleNameInterface if it was not called.
201	OtherModuleExists(name string) bool
202
203	// OtherModuleDependencyVariantExists returns true if a module with the
204	// specified name and variant exists. The variant must match the given
205	// variations. It must also match all the non-local variations of the current
206	// module. In other words, it checks for the module that AddVariationDependencies
207	// would add a dependency on with the same arguments.
208	OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool
209
210	// OtherModuleFarDependencyVariantExists returns true if a module with the
211	// specified name and variant exists. The variant must match the given
212	// variations, but not the non-local variations of the current module. In
213	// other words, it checks for the module that AddFarVariationDependencies
214	// would add a dependency on with the same arguments.
215	OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool
216
217	// OtherModuleReverseDependencyVariantExists returns true if a module with the
218	// specified name exists with the same variations as the current module. In
219	// other words, it checks for the module that AddReverseDependency would add a
220	// dependency on with the same argument.
221	OtherModuleReverseDependencyVariantExists(name string) bool
222
223	// OtherModuleType returns the type of another Module.  See BaseModuleContext.ModuleType for more information.
224	// It is intended for use inside the visit functions of Visit* and WalkDeps.
225	OtherModuleType(m blueprint.Module) string
226
227	// OtherModuleProvider returns the value for a provider for the given module.  If the value is
228	// not set it returns the zero value of the type of the provider, so the return value can always
229	// be type asserted to the type of the provider.  The value returned may be a deep copy of the
230	// value originally passed to SetProvider.
231	OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{}
232
233	// OtherModuleHasProvider returns true if the provider for the given module has been set.
234	OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool
235
236	// Provider returns the value for a provider for the current module.  If the value is
237	// not set it returns the zero value of the type of the provider, so the return value can always
238	// be type asserted to the type of the provider.  It panics if called before the appropriate
239	// mutator or GenerateBuildActions pass for the provider.  The value returned may be a deep
240	// copy of the value originally passed to SetProvider.
241	Provider(provider blueprint.ProviderKey) interface{}
242
243	// HasProvider returns true if the provider for the current module has been set.
244	HasProvider(provider blueprint.ProviderKey) bool
245
246	// SetProvider sets the value for a provider for the current module.  It panics if not called
247	// during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
248	// is not of the appropriate type, or if the value has already been set.  The value should not
249	// be modified after being passed to SetProvider.
250	SetProvider(provider blueprint.ProviderKey, value interface{})
251
252	GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
253
254	// GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if
255	// none exists.  It panics if the dependency does not have the specified tag.  It skips any
256	// dependencies that are not an android.Module.
257	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
258
259	// GetDirectDep returns the Module and DependencyTag for the  direct dependency with the specified
260	// name, or nil if none exists.  If there are multiple dependencies on the same module it returns
261	// the first DependencyTag.
262	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
263
264	ModuleFromName(name string) (blueprint.Module, bool)
265
266	// VisitDirectDepsBlueprint calls visit for each direct dependency.  If there are multiple
267	// direct dependencies on the same module visit will be called multiple times on that module
268	// and OtherModuleDependencyTag will return a different tag for each.
269	//
270	// The Module passed to the visit function should not be retained outside of the visit
271	// function, it may be invalidated by future mutators.
272	VisitDirectDepsBlueprint(visit func(blueprint.Module))
273
274	// VisitDirectDeps calls visit for each direct dependency.  If there are multiple
275	// direct dependencies on the same module visit will be called multiple times on that module
276	// and OtherModuleDependencyTag will return a different tag for each.  It raises an error if any of the
277	// dependencies are not an android.Module.
278	//
279	// The Module passed to the visit function should not be retained outside of the visit
280	// function, it may be invalidated by future mutators.
281	VisitDirectDeps(visit func(Module))
282
283	VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
284
285	// VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit.  If there are
286	// multiple direct dependencies on the same module pred and visit will be called multiple times on that module and
287	// OtherModuleDependencyTag will return a different tag for each.  It skips any
288	// dependencies that are not an android.Module.
289	//
290	// The Module passed to the visit function should not be retained outside of the visit function, it may be
291	// invalidated by future mutators.
292	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
293	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
294	VisitDepsDepthFirst(visit func(Module))
295	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
296	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
297
298	// WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order.  visit may
299	// be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
300	// child and parent with different tags.  OtherModuleDependencyTag will return the tag for the currently visited
301	// (child, parent) pair.  If visit returns false WalkDeps will not continue recursing down to child.  It skips
302	// any dependencies that are not an android.Module.
303	//
304	// The Modules passed to the visit function should not be retained outside of the visit function, they may be
305	// invalidated by future mutators.
306	WalkDeps(visit func(child, parent Module) bool)
307
308	// WalkDepsBlueprint calls visit for each transitive dependency, traversing the dependency
309	// tree in top down order.  visit may be called multiple times for the same (child, parent)
310	// pair if there are multiple direct dependencies between the child and parent with different
311	// tags.  OtherModuleDependencyTag will return the tag for the currently visited
312	// (child, parent) pair.  If visit returns false WalkDeps will not continue recursing down
313	// to child.
314	//
315	// The Modules passed to the visit function should not be retained outside of the visit function, they may be
316	// invalidated by future mutators.
317	WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
318
319	// GetWalkPath is supposed to be called in visit function passed in WalkDeps()
320	// and returns a top-down dependency path from a start module to current child module.
321	GetWalkPath() []Module
322
323	// PrimaryModule returns the first variant of the current module.  Variants of a module are always visited in
324	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the
325	// Module returned by PrimaryModule without data races.  This can be used to perform singleton actions that are
326	// only done once for all variants of a module.
327	PrimaryModule() Module
328
329	// FinalModule returns the last variant of the current module.  Variants of a module are always visited in
330	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
331	// variants using VisitAllModuleVariants if the current module == FinalModule().  This can be used to perform
332	// singleton actions that are only done once for all variants of a module.
333	FinalModule() Module
334
335	// VisitAllModuleVariants calls visit for each variant of the current module.  Variants of a module are always
336	// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
337	// from all variants if the current module == FinalModule().  Otherwise, care must be taken to not access any
338	// data modified by the current mutator.
339	VisitAllModuleVariants(visit func(Module))
340
341	// GetTagPath is supposed to be called in visit function passed in WalkDeps()
342	// and returns a top-down dependency tags path from a start module to current child module.
343	// It has one less entry than GetWalkPath() as it contains the dependency tags that
344	// exist between each adjacent pair of modules in the GetWalkPath().
345	// GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
346	GetTagPath() []blueprint.DependencyTag
347
348	// GetPathString is supposed to be called in visit function passed in WalkDeps()
349	// and returns a multi-line string showing the modules and dependency tags
350	// among them along the top-down dependency path from a start module to current child module.
351	// skipFirst when set to true, the output doesn't include the start module,
352	// which is already printed when this function is used along with ModuleErrorf().
353	GetPathString(skipFirst bool) string
354
355	AddMissingDependencies(missingDeps []string)
356
357	// AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build
358	AddUnconvertedBp2buildDep(dep string)
359
360	// AddMissingBp2buildDep stores the module name of a direct dependency that was not found.
361	AddMissingBp2buildDep(dep string)
362
363	Target() Target
364	TargetPrimary() bool
365
366	// The additional arch specific targets (e.g. 32/64 bit) that this module variant is
367	// responsible for creating.
368	MultiTargets() []Target
369	Arch() Arch
370	Os() OsType
371	Host() bool
372	Device() bool
373	Darwin() bool
374	Windows() bool
375	Debug() bool
376	PrimaryArch() bool
377}
378
379// Deprecated: use EarlyModuleContext instead
380type BaseContext interface {
381	EarlyModuleContext
382}
383
384type ModuleContext interface {
385	BaseModuleContext
386
387	blueprintModuleContext() blueprint.ModuleContext
388
389	// Deprecated: use ModuleContext.Build instead.
390	ModuleBuild(pctx PackageContext, params ModuleBuildParams)
391
392	// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.  The property must
393	// be tagged with `android:"path" to support automatic source module dependency resolution.
394	//
395	// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
396	ExpandSources(srcFiles, excludes []string) Paths
397
398	// Returns a single path expanded from globs and modules referenced using ":module" syntax.  The property must
399	// be tagged with `android:"path" to support automatic source module dependency resolution.
400	//
401	// Deprecated: use PathForModuleSrc instead.
402	ExpandSource(srcFile, prop string) Path
403
404	ExpandOptionalSource(srcFile *string, prop string) OptionalPath
405
406	// InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
407	// with the given additional dependencies.  The file is marked executable after copying.
408	//
409	// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
410	// installed file will be returned by PackagingSpecs() on this module or by
411	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
412	// for which IsInstallDepNeeded returns true.
413	InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
414
415	// InstallFile creates a rule to copy srcPath to name in the installPath directory,
416	// with the given additional dependencies.
417	//
418	// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
419	// installed file will be returned by PackagingSpecs() on this module or by
420	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
421	// for which IsInstallDepNeeded returns true.
422	InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
423
424	// InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
425	// directory, and also unzip a zip file containing extra files to install into the same
426	// directory.
427	//
428	// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
429	// installed file will be returned by PackagingSpecs() on this module or by
430	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
431	// for which IsInstallDepNeeded returns true.
432	InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...Path) InstallPath
433
434	// InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
435	// directory.
436	//
437	// The installed symlink will be returned by FilesToInstall(), and the PackagingSpec for the
438	// installed file will be returned by PackagingSpecs() on this module or by
439	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
440	// for which IsInstallDepNeeded returns true.
441	InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
442
443	// InstallAbsoluteSymlink creates a rule to create an absolute symlink from src srcPath to name
444	// in the installPath directory.
445	//
446	// The installed symlink will be returned by FilesToInstall(), and the PackagingSpec for the
447	// installed file will be returned by PackagingSpecs() on this module or by
448	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
449	// for which IsInstallDepNeeded returns true.
450	InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
451
452	// PackageFile creates a PackagingSpec as if InstallFile was called, but without creating
453	// the rule to copy the file.  This is useful to define how a module would be packaged
454	// without installing it into the global installation directories.
455	//
456	// The created PackagingSpec for the will be returned by PackagingSpecs() on this module or by
457	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
458	// for which IsInstallDepNeeded returns true.
459	PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
460
461	CheckbuildFile(srcPath Path)
462
463	InstallInData() bool
464	InstallInTestcases() bool
465	InstallInSanitizerDir() bool
466	InstallInRamdisk() bool
467	InstallInVendorRamdisk() bool
468	InstallInDebugRamdisk() bool
469	InstallInRecovery() bool
470	InstallInRoot() bool
471	InstallInVendor() bool
472	InstallForceOS() (*OsType, *ArchType)
473
474	RequiredModuleNames() []string
475	HostRequiredModuleNames() []string
476	TargetRequiredModuleNames() []string
477
478	ModuleSubDir() string
479
480	Variable(pctx PackageContext, name, value string)
481	Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
482	// Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
483	// and performs more verification.
484	Build(pctx PackageContext, params BuildParams)
485	// Phony creates a Make-style phony rule, a rule with no commands that can depend on other
486	// phony rules or real files.  Phony can be called on the same name multiple times to add
487	// additional dependencies.
488	Phony(phony string, deps ...Path)
489
490	// GetMissingDependencies returns the list of dependencies that were passed to AddDependencies or related methods,
491	// but do not exist.
492	GetMissingDependencies() []string
493
494	// LicenseMetadataFile returns the path where the license metadata for this module will be
495	// generated.
496	LicenseMetadataFile() Path
497}
498
499type Module interface {
500	blueprint.Module
501
502	// GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
503	// but GenerateAndroidBuildActions also has access to Android-specific information.
504	// For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
505	GenerateAndroidBuildActions(ModuleContext)
506
507	// Add dependencies to the components of a module, i.e. modules that are created
508	// by the module and which are considered to be part of the creating module.
509	//
510	// This is called before prebuilts are renamed so as to allow a dependency to be
511	// added directly to a prebuilt child module instead of depending on a source module
512	// and relying on prebuilt processing to switch to the prebuilt module if preferred.
513	//
514	// A dependency on a prebuilt must include the "prebuilt_" prefix.
515	ComponentDepsMutator(ctx BottomUpMutatorContext)
516
517	DepsMutator(BottomUpMutatorContext)
518
519	base() *ModuleBase
520	Disable()
521	Enabled() bool
522	Target() Target
523	MultiTargets() []Target
524
525	// ImageVariation returns the image variation of this module.
526	//
527	// The returned structure has its Mutator field set to "image" and its Variation field set to the
528	// image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
529	// device modules that have no image variation.
530	ImageVariation() blueprint.Variation
531
532	Owner() string
533	InstallInData() bool
534	InstallInTestcases() bool
535	InstallInSanitizerDir() bool
536	InstallInRamdisk() bool
537	InstallInVendorRamdisk() bool
538	InstallInDebugRamdisk() bool
539	InstallInRecovery() bool
540	InstallInRoot() bool
541	InstallInVendor() bool
542	InstallForceOS() (*OsType, *ArchType)
543	PartitionTag(DeviceConfig) string
544	HideFromMake()
545	IsHideFromMake() bool
546	IsSkipInstall() bool
547	MakeUninstallable()
548	ReplacedByPrebuilt()
549	IsReplacedByPrebuilt() bool
550	ExportedToMake() bool
551	InitRc() Paths
552	VintfFragments() Paths
553	EffectiveLicenseKinds() []string
554	EffectiveLicenseFiles() Paths
555
556	AddProperties(props ...interface{})
557	GetProperties() []interface{}
558
559	// IsConvertedByBp2build returns whether this module was converted via bp2build
560	IsConvertedByBp2build() bool
561	// Bp2buildTargets returns the target(s) generated for Bazel via bp2build for this module
562	Bp2buildTargets() []bp2buildInfo
563	GetUnconvertedBp2buildDeps() []string
564	GetMissingBp2buildDeps() []string
565
566	BuildParamsForTests() []BuildParams
567	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
568	VariablesForTests() map[string]string
569
570	// String returns a string that includes the module name and variants for printing during debugging.
571	String() string
572
573	// Get the qualified module id for this module.
574	qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
575
576	// Get information about the properties that can contain visibility rules.
577	visibilityProperties() []visibilityProperty
578
579	RequiredModuleNames() []string
580	HostRequiredModuleNames() []string
581	TargetRequiredModuleNames() []string
582
583	FilesToInstall() InstallPaths
584	PackagingSpecs() []PackagingSpec
585
586	// TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
587	// dependencies with dependency tags for which IsInstallDepNeeded() returns true.
588	TransitivePackagingSpecs() []PackagingSpec
589}
590
591// Qualified id for a module
592type qualifiedModuleName struct {
593	// The package (i.e. directory) in which the module is defined, without trailing /
594	pkg string
595
596	// The name of the module, empty string if package.
597	name string
598}
599
600func (q qualifiedModuleName) String() string {
601	if q.name == "" {
602		return "//" + q.pkg
603	}
604	return "//" + q.pkg + ":" + q.name
605}
606
607func (q qualifiedModuleName) isRootPackage() bool {
608	return q.pkg == "" && q.name == ""
609}
610
611// Get the id for the package containing this module.
612func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
613	pkg := q.pkg
614	if q.name == "" {
615		if pkg == "" {
616			panic(fmt.Errorf("Cannot get containing package id of root package"))
617		}
618
619		index := strings.LastIndex(pkg, "/")
620		if index == -1 {
621			pkg = ""
622		} else {
623			pkg = pkg[:index]
624		}
625	}
626	return newPackageId(pkg)
627}
628
629func newPackageId(pkg string) qualifiedModuleName {
630	// A qualified id for a package module has no name.
631	return qualifiedModuleName{pkg: pkg, name: ""}
632}
633
634type Dist struct {
635	// Copy the output of this module to the $DIST_DIR when `dist` is specified on the
636	// command line and any of these targets are also on the command line, or otherwise
637	// built
638	Targets []string `android:"arch_variant"`
639
640	// The name of the output artifact. This defaults to the basename of the output of
641	// the module.
642	Dest *string `android:"arch_variant"`
643
644	// The directory within the dist directory to store the artifact. Defaults to the
645	// top level directory ("").
646	Dir *string `android:"arch_variant"`
647
648	// A suffix to add to the artifact file name (before any extension).
649	Suffix *string `android:"arch_variant"`
650
651	// If true, then the artifact file will be appended with _<product name>. For
652	// example, if the product is coral and the module is an android_app module
653	// of name foo, then the artifact would be foo_coral.apk. If false, there is
654	// no change to the artifact file name.
655	Append_artifact_with_product *bool `android:"arch_variant"`
656
657	// A string tag to select the OutputFiles associated with the tag.
658	//
659	// If no tag is specified then it will select the default dist paths provided
660	// by the module type. If a tag of "" is specified then it will return the
661	// default output files provided by the modules, i.e. the result of calling
662	// OutputFiles("").
663	Tag *string `android:"arch_variant"`
664}
665
666// NamedPath associates a path with a name. e.g. a license text path with a package name
667type NamedPath struct {
668	Path Path
669	Name string
670}
671
672// String returns an escaped string representing the `NamedPath`.
673func (p NamedPath) String() string {
674	if len(p.Name) > 0 {
675		return p.Path.String() + ":" + url.QueryEscape(p.Name)
676	}
677	return p.Path.String()
678}
679
680// NamedPaths describes a list of paths each associated with a name.
681type NamedPaths []NamedPath
682
683// Strings returns a list of escaped strings representing each `NamedPath` in the list.
684func (l NamedPaths) Strings() []string {
685	result := make([]string, 0, len(l))
686	for _, p := range l {
687		result = append(result, p.String())
688	}
689	return result
690}
691
692// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset.
693func SortedUniqueNamedPaths(l NamedPaths) NamedPaths {
694	if len(l) == 0 {
695		return l
696	}
697	sort.Slice(l, func(i, j int) bool {
698		return l[i].String() < l[j].String()
699	})
700	k := 0
701	for i := 1; i < len(l); i++ {
702		if l[i].String() == l[k].String() {
703			continue
704		}
705		k++
706		if k < i {
707			l[k] = l[i]
708		}
709	}
710	return l[:k+1]
711}
712
713type nameProperties struct {
714	// The name of the module.  Must be unique across all modules.
715	Name *string
716}
717
718type commonProperties struct {
719	// emit build rules for this module
720	//
721	// Disabling a module should only be done for those modules that cannot be built
722	// in the current environment. Modules that can build in the current environment
723	// but are not usually required (e.g. superceded by a prebuilt) should not be
724	// disabled as that will prevent them from being built by the checkbuild target
725	// and so prevent early detection of changes that have broken those modules.
726	Enabled *bool `android:"arch_variant"`
727
728	// Controls the visibility of this module to other modules. Allowable values are one or more of
729	// these formats:
730	//
731	//  ["//visibility:public"]: Anyone can use this module.
732	//  ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
733	//      this module.
734	//  ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
735	//      Can only be used at the beginning of a list of visibility rules.
736	//  ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
737	//      other/package (defined in some/package/*.bp and other/package/*.bp) have access to
738	//      this module. Note that sub-packages do not have access to the rule; for example,
739	//      //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
740	//      is a special module and must be used verbatim. It represents all of the modules in the
741	//      package.
742	//  ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
743	//      or other or in one of their sub-packages have access to this module. For example,
744	//      //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
745	//      to depend on this rule (but not //independent:evil)
746	//  ["//project"]: This is shorthand for ["//project:__pkg__"]
747	//  [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
748	//      //project is the module's package. e.g. using [":__subpackages__"] in
749	//      packages/apps/Settings/Android.bp is equivalent to
750	//      //packages/apps/Settings:__subpackages__.
751	//  ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
752	//      for now. It is an error if it is used in a module.
753	//
754	// If a module does not specify the `visibility` property then it uses the
755	// `default_visibility` property of the `package` module in the module's package.
756	//
757	// If the `default_visibility` property is not set for the module's package then
758	// it will use the `default_visibility` of its closest ancestor package for which
759	// a `default_visibility` property is specified.
760	//
761	// If no `default_visibility` property can be found then the module uses the
762	// global default of `//visibility:legacy_public`.
763	//
764	// The `visibility` property has no effect on a defaults module although it does
765	// apply to any non-defaults module that uses it. To set the visibility of a
766	// defaults module, use the `defaults_visibility` property on the defaults module;
767	// not to be confused with the `default_visibility` property on the package module.
768	//
769	// See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
770	// more details.
771	Visibility []string
772
773	// Describes the licenses applicable to this module. Must reference license modules.
774	Licenses []string
775
776	// Flattened from direct license dependencies. Equal to Licenses unless particular module adds more.
777	Effective_licenses []string `blueprint:"mutated"`
778	// Override of module name when reporting licenses
779	Effective_package_name *string `blueprint:"mutated"`
780	// Notice files
781	Effective_license_text NamedPaths `blueprint:"mutated"`
782	// License names
783	Effective_license_kinds []string `blueprint:"mutated"`
784	// License conditions
785	Effective_license_conditions []string `blueprint:"mutated"`
786
787	// control whether this module compiles for 32-bit, 64-bit, or both.  Possible values
788	// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
789	// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
790	// platform).
791	Compile_multilib *string `android:"arch_variant"`
792
793	Target struct {
794		Host struct {
795			Compile_multilib *string
796		}
797		Android struct {
798			Compile_multilib *string
799		}
800	}
801
802	// If set to true then the archMutator will create variants for each arch specific target
803	// (e.g. 32/64) that the module is required to produce. If set to false then it will only
804	// create a variant for the architecture and will list the additional arch specific targets
805	// that the variant needs to produce in the CompileMultiTargets property.
806	UseTargetVariants bool   `blueprint:"mutated"`
807	Default_multilib  string `blueprint:"mutated"`
808
809	// whether this is a proprietary vendor module, and should be installed into /vendor
810	Proprietary *bool
811
812	// vendor who owns this module
813	Owner *string
814
815	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
816	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
817	// Use `soc_specific` instead for better meaning.
818	Vendor *bool
819
820	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
821	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
822	Soc_specific *bool
823
824	// whether this module is specific to a device, not only for SoC, but also for off-chip
825	// peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
826	// does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
827	// This implies `soc_specific:true`.
828	Device_specific *bool
829
830	// whether this module is specific to a software configuration of a product (e.g. country,
831	// network operator, etc). When set to true, it is installed into /product (or
832	// /system/product if product partition does not exist).
833	Product_specific *bool
834
835	// whether this module extends system. When set to true, it is installed into /system_ext
836	// (or /system/system_ext if system_ext partition does not exist).
837	System_ext_specific *bool
838
839	// Whether this module is installed to recovery partition
840	Recovery *bool
841
842	// Whether this module is installed to ramdisk
843	Ramdisk *bool
844
845	// Whether this module is installed to vendor ramdisk
846	Vendor_ramdisk *bool
847
848	// Whether this module is installed to debug ramdisk
849	Debug_ramdisk *bool
850
851	// Whether this module is built for non-native architectures (also known as native bridge binary)
852	Native_bridge_supported *bool `android:"arch_variant"`
853
854	// init.rc files to be installed if this module is installed
855	Init_rc []string `android:"arch_variant,path"`
856
857	// VINTF manifest fragments to be installed if this module is installed
858	Vintf_fragments []string `android:"path"`
859
860	// names of other modules to install if this module is installed
861	Required []string `android:"arch_variant"`
862
863	// names of other modules to install on host if this module is installed
864	Host_required []string `android:"arch_variant"`
865
866	// names of other modules to install on target if this module is installed
867	Target_required []string `android:"arch_variant"`
868
869	// The OsType of artifacts that this module variant is responsible for creating.
870	//
871	// Set by osMutator
872	CompileOS OsType `blueprint:"mutated"`
873
874	// The Target of artifacts that this module variant is responsible for creating.
875	//
876	// Set by archMutator
877	CompileTarget Target `blueprint:"mutated"`
878
879	// The additional arch specific targets (e.g. 32/64 bit) that this module variant is
880	// responsible for creating.
881	//
882	// By default this is nil as, where necessary, separate variants are created for the
883	// different multilib types supported and that information is encapsulated in the
884	// CompileTarget so the module variant simply needs to create artifacts for that.
885	//
886	// However, if UseTargetVariants is set to false (e.g. by
887	// InitAndroidMultiTargetsArchModule)  then no separate variants are created for the
888	// multilib targets. Instead a single variant is created for the architecture and
889	// this contains the multilib specific targets that this variant should create.
890	//
891	// Set by archMutator
892	CompileMultiTargets []Target `blueprint:"mutated"`
893
894	// True if the module variant's CompileTarget is the primary target
895	//
896	// Set by archMutator
897	CompilePrimary bool `blueprint:"mutated"`
898
899	// Set by InitAndroidModule
900	HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
901	ArchSpecific          bool                  `blueprint:"mutated"`
902
903	// If set to true then a CommonOS variant will be created which will have dependencies
904	// on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
905	// that covers all os and architecture variants.
906	//
907	// The OsType specific variants can be retrieved by calling
908	// GetOsSpecificVariantsOfCommonOSVariant
909	//
910	// Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
911	CreateCommonOSVariant bool `blueprint:"mutated"`
912
913	// If set to true then this variant is the CommonOS variant that has dependencies on its
914	// OsType specific variants.
915	//
916	// Set by osMutator.
917	CommonOSVariant bool `blueprint:"mutated"`
918
919	// When HideFromMake is set to true, no entry for this variant will be emitted in the
920	// generated Android.mk file.
921	HideFromMake bool `blueprint:"mutated"`
922
923	// When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
924	// ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
925	// and don't create a rule to install the file.
926	SkipInstall bool `blueprint:"mutated"`
927
928	// UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
929	// mutator.  MakeUninstallable also sets HideFromMake.  UninstallableApexPlatformVariant
930	// is used to avoid adding install or packaging dependencies into libraries provided
931	// by apexes.
932	UninstallableApexPlatformVariant bool `blueprint:"mutated"`
933
934	// Whether the module has been replaced by a prebuilt
935	ReplacedByPrebuilt bool `blueprint:"mutated"`
936
937	// Disabled by mutators. If set to true, it overrides Enabled property.
938	ForcedDisabled bool `blueprint:"mutated"`
939
940	NamespaceExportedToMake bool `blueprint:"mutated"`
941
942	MissingDeps []string `blueprint:"mutated"`
943
944	// Name and variant strings stored by mutators to enable Module.String()
945	DebugName       string   `blueprint:"mutated"`
946	DebugMutators   []string `blueprint:"mutated"`
947	DebugVariations []string `blueprint:"mutated"`
948
949	// ImageVariation is set by ImageMutator to specify which image this variation is for,
950	// for example "" for core or "recovery" for recovery.  It will often be set to one of the
951	// constants in image.go, but can also be set to a custom value by individual module types.
952	ImageVariation string `blueprint:"mutated"`
953
954	// Bazel conversion status
955	BazelConversionStatus BazelConversionStatus `blueprint:"mutated"`
956}
957
958// CommonAttributes represents the common Bazel attributes from which properties
959// in `commonProperties` are translated/mapped; such properties are annotated in
960// a list their corresponding attribute. It is embedded within `bp2buildInfo`.
961type CommonAttributes struct {
962	// Soong nameProperties -> Bazel name
963	Name string
964
965	// Data mapped from: Required
966	Data bazel.LabelListAttribute
967
968	// SkipData is neither a Soong nor Bazel target attribute
969	// If true, this will not fill the data attribute automatically
970	// This is useful for Soong modules that have 1:many Bazel targets
971	// Some of the generated Bazel targets might not have a data attribute
972	SkipData *bool
973
974	Tags bazel.StringListAttribute
975
976	Applicable_licenses bazel.LabelListAttribute
977
978	Testonly *bool
979}
980
981// constraintAttributes represents Bazel attributes pertaining to build constraints,
982// which make restrict building a Bazel target for some set of platforms.
983type constraintAttributes struct {
984	// Constraint values this target can be built for.
985	Target_compatible_with bazel.LabelListAttribute
986}
987
988type distProperties struct {
989	// configuration to distribute output files from this module to the distribution
990	// directory (default: $OUT/dist, configurable with $DIST_DIR)
991	Dist Dist `android:"arch_variant"`
992
993	// a list of configurations to distribute output files from this module to the
994	// distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
995	Dists []Dist `android:"arch_variant"`
996}
997
998// CommonTestOptions represents the common `test_options` properties in
999// Android.bp.
1000type CommonTestOptions struct {
1001	// If the test is a hostside (no device required) unittest that shall be run
1002	// during presubmit check.
1003	Unit_test *bool
1004
1005	// Tags provide additional metadata to customize test execution by downstream
1006	// test runners. The tags have no special meaning to Soong.
1007	Tags []string
1008}
1009
1010// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
1011// `test_options`.
1012func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
1013	entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
1014	if len(t.Tags) > 0 {
1015		entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
1016	}
1017}
1018
1019// The key to use in TaggedDistFiles when a Dist structure does not specify a
1020// tag property. This intentionally does not use "" as the default because that
1021// would mean that an empty tag would have a different meaning when used in a dist
1022// structure that when used to reference a specific set of output paths using the
1023// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
1024const DefaultDistTag = "<default-dist-tag>"
1025
1026// A map of OutputFile tag keys to Paths, for disting purposes.
1027type TaggedDistFiles map[string]Paths
1028
1029// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
1030// then it will create a map, update it and then return it. If a mapping already
1031// exists for the tag then the paths are appended to the end of the current list
1032// of paths, ignoring any duplicates.
1033func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
1034	if t == nil {
1035		t = make(TaggedDistFiles)
1036	}
1037
1038	for _, distFile := range paths {
1039		if distFile != nil && !t[tag].containsPath(distFile) {
1040			t[tag] = append(t[tag], distFile)
1041		}
1042	}
1043
1044	return t
1045}
1046
1047// merge merges the entries from the other TaggedDistFiles object into this one.
1048// If the TaggedDistFiles is nil then it will create a new instance, merge the
1049// other into it, and then return it.
1050func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
1051	for tag, paths := range other {
1052		t = t.addPathsForTag(tag, paths...)
1053	}
1054
1055	return t
1056}
1057
1058func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
1059	for _, p := range paths {
1060		if p == nil {
1061			panic("The path to a dist file cannot be nil.")
1062		}
1063	}
1064
1065	// The default OutputFile tag is the empty "" string.
1066	return TaggedDistFiles{DefaultDistTag: paths}
1067}
1068
1069type hostAndDeviceProperties struct {
1070	// If set to true, build a variant of the module for the host.  Defaults to false.
1071	Host_supported *bool
1072
1073	// If set to true, build a variant of the module for the device.  Defaults to true.
1074	Device_supported *bool
1075}
1076
1077type Multilib string
1078
1079const (
1080	MultilibBoth        Multilib = "both"
1081	MultilibFirst       Multilib = "first"
1082	MultilibCommon      Multilib = "common"
1083	MultilibCommonFirst Multilib = "common_first"
1084)
1085
1086type HostOrDeviceSupported int
1087
1088const (
1089	hostSupported = 1 << iota
1090	hostCrossSupported
1091	deviceSupported
1092	hostDefault
1093	deviceDefault
1094
1095	// Host and HostCross are built by default. Device is not supported.
1096	HostSupported = hostSupported | hostCrossSupported | hostDefault
1097
1098	// Host is built by default. HostCross and Device are not supported.
1099	HostSupportedNoCross = hostSupported | hostDefault
1100
1101	// Device is built by default. Host and HostCross are not supported.
1102	DeviceSupported = deviceSupported | deviceDefault
1103
1104	// By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
1105	// Host and HostCross are disabled by default and can be enabled with `host_supported: true`
1106	HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
1107
1108	// Host, HostCross, and Device are built by default.
1109	// Building Device can be disabled with `device_supported: false`
1110	// Building Host and HostCross can be disabled with `host_supported: false`
1111	HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
1112		deviceSupported | deviceDefault
1113
1114	// Nothing is supported. This is not exposed to the user, but used to mark a
1115	// host only module as unsupported when the module type is not supported on
1116	// the host OS. E.g. benchmarks are supported on Linux but not Darwin.
1117	NeitherHostNorDeviceSupported = 0
1118)
1119
1120type moduleKind int
1121
1122const (
1123	platformModule moduleKind = iota
1124	deviceSpecificModule
1125	socSpecificModule
1126	productSpecificModule
1127	systemExtSpecificModule
1128)
1129
1130func (k moduleKind) String() string {
1131	switch k {
1132	case platformModule:
1133		return "platform"
1134	case deviceSpecificModule:
1135		return "device-specific"
1136	case socSpecificModule:
1137		return "soc-specific"
1138	case productSpecificModule:
1139		return "product-specific"
1140	case systemExtSpecificModule:
1141		return "systemext-specific"
1142	default:
1143		panic(fmt.Errorf("unknown module kind %d", k))
1144	}
1145}
1146
1147func initAndroidModuleBase(m Module) {
1148	m.base().module = m
1149}
1150
1151// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
1152// It adds the common properties, for example "name" and "enabled".
1153func InitAndroidModule(m Module) {
1154	initAndroidModuleBase(m)
1155	base := m.base()
1156
1157	m.AddProperties(
1158		&base.nameProperties,
1159		&base.commonProperties,
1160		&base.distProperties)
1161
1162	initProductVariableModule(m)
1163
1164	// The default_visibility property needs to be checked and parsed by the visibility module during
1165	// its checking and parsing phases so make it the primary visibility property.
1166	setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
1167
1168	// The default_applicable_licenses property needs to be checked and parsed by the licenses module during
1169	// its checking and parsing phases so make it the primary licenses property.
1170	setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
1171}
1172
1173// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
1174// It adds the common properties, for example "name" and "enabled", as well as runtime generated
1175// property structs for architecture-specific versions of generic properties tagged with
1176// `android:"arch_variant"`.
1177//
1178//	InitAndroidModule should not be called if InitAndroidArchModule was called.
1179func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
1180	InitAndroidModule(m)
1181
1182	base := m.base()
1183	base.commonProperties.HostOrDeviceSupported = hod
1184	base.commonProperties.Default_multilib = string(defaultMultilib)
1185	base.commonProperties.ArchSpecific = true
1186	base.commonProperties.UseTargetVariants = true
1187
1188	if hod&hostSupported != 0 && hod&deviceSupported != 0 {
1189		m.AddProperties(&base.hostAndDeviceProperties)
1190	}
1191
1192	initArchModule(m)
1193}
1194
1195// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
1196// architecture-specific, but will only have a single variant per OS that handles all the
1197// architectures simultaneously.  The list of Targets that it must handle will be available from
1198// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
1199// well as runtime generated property structs for architecture-specific versions of generic
1200// properties tagged with `android:"arch_variant"`.
1201//
1202// InitAndroidModule or InitAndroidArchModule should not be called if
1203// InitAndroidMultiTargetsArchModule was called.
1204func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
1205	InitAndroidArchModule(m, hod, defaultMultilib)
1206	m.base().commonProperties.UseTargetVariants = false
1207}
1208
1209// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
1210// architecture-specific, but will only have a single variant per OS that handles all the
1211// architectures simultaneously, and will also have an additional CommonOS variant that has
1212// dependencies on all the OS-specific variants.  The list of Targets that it must handle will be
1213// available from ModuleContext.MultiTargets.  It adds the common properties, for example "name" and
1214// "enabled", as well as runtime generated property structs for architecture-specific versions of
1215// generic properties tagged with `android:"arch_variant"`.
1216//
1217// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
1218// called if InitCommonOSAndroidMultiTargetsArchModule was called.
1219func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
1220	InitAndroidArchModule(m, hod, defaultMultilib)
1221	m.base().commonProperties.UseTargetVariants = false
1222	m.base().commonProperties.CreateCommonOSVariant = true
1223}
1224
1225func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext,
1226	enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes {
1227
1228	mod := ctx.Module().base()
1229	// Assert passed-in attributes include Name
1230	if len(attrs.Name) == 0 {
1231		if ctx.ModuleType() != "package" {
1232			ctx.ModuleErrorf("CommonAttributes in fillCommonBp2BuildModuleAttrs expects a `.Name`!")
1233		}
1234	}
1235
1236	depsToLabelList := func(deps []string) bazel.LabelListAttribute {
1237		return bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, deps))
1238	}
1239
1240	var enabledProperty bazel.BoolAttribute
1241
1242	onlyAndroid := false
1243	neitherHostNorDevice := false
1244
1245	osSupport := map[string]bool{}
1246
1247	// if the target is enabled and supports arch variance, determine the defaults based on the module
1248	// type's host or device property and host_supported/device_supported properties
1249	if mod.commonProperties.ArchSpecific {
1250		moduleSupportsDevice := mod.DeviceSupported()
1251		moduleSupportsHost := mod.HostSupported()
1252		if moduleSupportsHost && !moduleSupportsDevice {
1253			// for host only, we specify as unsupported on android rather than listing all host osSupport
1254			// TODO(b/220874839): consider replacing this with a constraint that covers all host osSupport
1255			// instead
1256			enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(false))
1257		} else if moduleSupportsDevice && !moduleSupportsHost {
1258			enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(true))
1259			// specify as a positive to ensure any target-specific enabled can be resolved
1260			// also save that a target is only android, as if there is only the positive restriction on
1261			// android, it'll be dropped, so we may need to add it back later
1262			onlyAndroid = true
1263		} else if !moduleSupportsHost && !moduleSupportsDevice {
1264			neitherHostNorDevice = true
1265		}
1266
1267		for _, osType := range OsTypeList() {
1268			if osType.Class == Host {
1269				osSupport[osType.Name] = moduleSupportsHost
1270			} else if osType.Class == Device {
1271				osSupport[osType.Name] = moduleSupportsDevice
1272			}
1273		}
1274	}
1275
1276	if neitherHostNorDevice {
1277		// we can't build this, disable
1278		enabledProperty.Value = proptools.BoolPtr(false)
1279	} else if mod.commonProperties.Enabled != nil {
1280		enabledProperty.SetValue(mod.commonProperties.Enabled)
1281		if !*mod.commonProperties.Enabled {
1282			for oss, enabled := range osSupport {
1283				if val := enabledProperty.SelectValue(bazel.OsConfigurationAxis, oss); enabled && val != nil && *val {
1284					// if this should be disabled by default, clear out any enabling we've done
1285					enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, oss, nil)
1286				}
1287			}
1288		}
1289	}
1290
1291	attrs.Applicable_licenses = bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, mod.commonProperties.Licenses))
1292
1293	// The required property can contain the module itself. This causes a cycle
1294	// when generated as the 'data' label list attribute in Bazel. Remove it if
1295	// it exists. See b/247985196.
1296	_, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), mod.commonProperties.Required)
1297	requiredWithoutCycles = FirstUniqueStrings(requiredWithoutCycles)
1298	required := depsToLabelList(requiredWithoutCycles)
1299	archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{})
1300	for axis, configToProps := range archVariantProps {
1301		for config, _props := range configToProps {
1302			if archProps, ok := _props.(*commonProperties); ok {
1303				_, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), archProps.Required)
1304				requiredWithoutCycles = FirstUniqueStrings(requiredWithoutCycles)
1305				required.SetSelectValue(axis, config, depsToLabelList(requiredWithoutCycles).Value)
1306				if !neitherHostNorDevice {
1307					if archProps.Enabled != nil {
1308						if axis != bazel.OsConfigurationAxis || osSupport[config] {
1309							enabledProperty.SetSelectValue(axis, config, archProps.Enabled)
1310						}
1311					}
1312				}
1313			}
1314		}
1315	}
1316
1317	if !neitherHostNorDevice {
1318		if enabledPropertyOverrides.Value != nil {
1319			enabledProperty.Value = enabledPropertyOverrides.Value
1320		}
1321		for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() {
1322			configToBools := enabledPropertyOverrides.ConfigurableValues[axis]
1323			for cfg, val := range configToBools {
1324				if axis != bazel.OsConfigurationAxis || osSupport[cfg] {
1325					enabledProperty.SetSelectValue(axis, cfg, &val)
1326				}
1327			}
1328		}
1329	}
1330
1331	productConfigEnabledLabels := []bazel.Label{}
1332	// TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we
1333	// should handle it correctly
1334	if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice {
1335		// If the module is not enabled by default, then we can check if a
1336		// product variable enables it
1337		productConfigEnabledLabels = productVariableConfigEnableLabels(ctx)
1338
1339		if len(productConfigEnabledLabels) > 0 {
1340			// In this case, an existing product variable configuration overrides any
1341			// module-level `enable: false` definition
1342			newValue := true
1343			enabledProperty.Value = &newValue
1344		}
1345	}
1346
1347	productConfigEnabledAttribute := bazel.MakeLabelListAttribute(bazel.LabelList{
1348		productConfigEnabledLabels, nil,
1349	})
1350
1351	platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute(
1352		bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil},
1353		bazel.LabelList{[]bazel.Label{}, nil})
1354	if err != nil {
1355		ctx.ModuleErrorf("Error processing platform enabled attribute: %s", err)
1356	}
1357
1358	// if android is the only arch/os enabled, then add a restriction to only be compatible with android
1359	if platformEnabledAttribute.IsNil() && onlyAndroid {
1360		l := bazel.LabelAttribute{}
1361		l.SetValue(bazel.Label{Label: bazel.OsConfigurationAxis.SelectKey(Android.Name)})
1362		platformEnabledAttribute.Add(&l)
1363	}
1364
1365	if !proptools.Bool(attrs.SkipData) {
1366		attrs.Data.Append(required)
1367	}
1368	// SkipData is not an attribute of any Bazel target
1369	// Set this to nil so that it does not appear in the generated build file
1370	attrs.SkipData = nil
1371
1372	moduleEnableConstraints := bazel.LabelListAttribute{}
1373	moduleEnableConstraints.Append(platformEnabledAttribute)
1374	moduleEnableConstraints.Append(productConfigEnabledAttribute)
1375
1376	return constraintAttributes{Target_compatible_with: moduleEnableConstraints}
1377}
1378
1379// Check product variables for `enabled: true` flag override.
1380// Returns a list of the constraint_value targets who enable this override.
1381func productVariableConfigEnableLabels(ctx *topDownMutatorContext) []bazel.Label {
1382	productVariableProps := ProductVariableProperties(ctx, ctx.Module())
1383	productConfigEnablingTargets := []bazel.Label{}
1384	const propName = "Enabled"
1385	if productConfigProps, exists := productVariableProps[propName]; exists {
1386		for productConfigProp, prop := range productConfigProps {
1387			flag, ok := prop.(*bool)
1388			if !ok {
1389				ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
1390			}
1391
1392			if *flag {
1393				axis := productConfigProp.ConfigurationAxis()
1394				targetLabel := axis.SelectKey(productConfigProp.SelectKey())
1395				productConfigEnablingTargets = append(productConfigEnablingTargets, bazel.Label{
1396					Label: targetLabel,
1397				})
1398			} else {
1399				// TODO(b/210546943): handle negative case where `enabled: false`
1400				ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943", proptools.PropertyNameForField(propName))
1401			}
1402		}
1403	}
1404
1405	return productConfigEnablingTargets
1406}
1407
1408// A ModuleBase object contains the properties that are common to all Android
1409// modules.  It should be included as an anonymous field in every module
1410// struct definition.  InitAndroidModule should then be called from the module's
1411// factory function, and the return values from InitAndroidModule should be
1412// returned from the factory function.
1413//
1414// The ModuleBase type is responsible for implementing the GenerateBuildActions
1415// method to support the blueprint.Module interface. This method will then call
1416// the module's GenerateAndroidBuildActions method once for each build variant
1417// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
1418// rather than the usual blueprint.ModuleContext.
1419// ModuleContext exposes extra functionality specific to the Android build
1420// system including details about the particular build variant that is to be
1421// generated.
1422//
1423// For example:
1424//
1425//	import (
1426//	    "android/soong/android"
1427//	)
1428//
1429//	type myModule struct {
1430//	    android.ModuleBase
1431//	    properties struct {
1432//	        MyProperty string
1433//	    }
1434//	}
1435//
1436//	func NewMyModule() android.Module {
1437//	    m := &myModule{}
1438//	    m.AddProperties(&m.properties)
1439//	    android.InitAndroidModule(m)
1440//	    return m
1441//	}
1442//
1443//	func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1444//	    // Get the CPU architecture for the current build variant.
1445//	    variantArch := ctx.Arch()
1446//
1447//	    // ...
1448//	}
1449type ModuleBase struct {
1450	// Putting the curiously recurring thing pointing to the thing that contains
1451	// the thing pattern to good use.
1452	// TODO: remove this
1453	module Module
1454
1455	nameProperties          nameProperties
1456	commonProperties        commonProperties
1457	distProperties          distProperties
1458	variableProperties      interface{}
1459	hostAndDeviceProperties hostAndDeviceProperties
1460
1461	// Arch specific versions of structs in GetProperties() prior to
1462	// initialization in InitAndroidArchModule, lets call it `generalProperties`.
1463	// The outer index has the same order as generalProperties and the inner index
1464	// chooses the props specific to the architecture. The interface{} value is an
1465	// archPropRoot that is filled with arch specific values by the arch mutator.
1466	archProperties [][]interface{}
1467
1468	// Properties specific to the Blueprint to BUILD migration.
1469	bazelTargetModuleProperties bazel.BazelTargetModuleProperties
1470
1471	// Information about all the properties on the module that contains visibility rules that need
1472	// checking.
1473	visibilityPropertyInfo []visibilityProperty
1474
1475	// The primary visibility property, may be nil, that controls access to the module.
1476	primaryVisibilityProperty visibilityProperty
1477
1478	// The primary licenses property, may be nil, records license metadata for the module.
1479	primaryLicensesProperty applicableLicensesProperty
1480
1481	noAddressSanitizer   bool
1482	installFiles         InstallPaths
1483	installFilesDepSet   *installPathsDepSet
1484	checkbuildFiles      Paths
1485	packagingSpecs       []PackagingSpec
1486	packagingSpecsDepSet *packagingSpecsDepSet
1487	// katiInstalls tracks the install rules that were created by Soong but are being exported
1488	// to Make to convert to ninja rules so that Make can add additional dependencies.
1489	katiInstalls katiInstalls
1490	katiSymlinks katiInstalls
1491
1492	// The files to copy to the dist as explicitly specified in the .bp file.
1493	distFiles TaggedDistFiles
1494
1495	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
1496	// Only set on the final variant of each module
1497	installTarget    WritablePath
1498	checkbuildTarget WritablePath
1499	blueprintDir     string
1500
1501	hooks hooks
1502
1503	registerProps []interface{}
1504
1505	// For tests
1506	buildParams []BuildParams
1507	ruleParams  map[blueprint.Rule]blueprint.RuleParams
1508	variables   map[string]string
1509
1510	initRcPaths         Paths
1511	vintfFragmentsPaths Paths
1512
1513	// set of dependency module:location mappings used to populate the license metadata for
1514	// apex containers.
1515	licenseInstallMap []string
1516
1517	// The path to the generated license metadata file for the module.
1518	licenseMetadataFile WritablePath
1519}
1520
1521// A struct containing all relevant information about a Bazel target converted via bp2build.
1522type bp2buildInfo struct {
1523	Dir             string
1524	BazelProps      bazel.BazelTargetModuleProperties
1525	CommonAttrs     CommonAttributes
1526	ConstraintAttrs constraintAttributes
1527	Attrs           interface{}
1528}
1529
1530// TargetName returns the Bazel target name of a bp2build converted target.
1531func (b bp2buildInfo) TargetName() string {
1532	return b.CommonAttrs.Name
1533}
1534
1535// TargetPackage returns the Bazel package of a bp2build converted target.
1536func (b bp2buildInfo) TargetPackage() string {
1537	return b.Dir
1538}
1539
1540// BazelRuleClass returns the Bazel rule class of a bp2build converted target.
1541func (b bp2buildInfo) BazelRuleClass() string {
1542	return b.BazelProps.Rule_class
1543}
1544
1545// BazelRuleLoadLocation returns the location of the  Bazel rule of a bp2build converted target.
1546// This may be empty as native Bazel rules do not need to be loaded.
1547func (b bp2buildInfo) BazelRuleLoadLocation() string {
1548	return b.BazelProps.Bzl_load_location
1549}
1550
1551// BazelAttributes returns the Bazel attributes of a bp2build converted target.
1552func (b bp2buildInfo) BazelAttributes() []interface{} {
1553	return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs}
1554}
1555
1556func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
1557	m.commonProperties.BazelConversionStatus.Bp2buildInfo = append(m.commonProperties.BazelConversionStatus.Bp2buildInfo, info)
1558}
1559
1560// IsConvertedByBp2build returns whether this module was converted via bp2build.
1561func (m *ModuleBase) IsConvertedByBp2build() bool {
1562	return len(m.commonProperties.BazelConversionStatus.Bp2buildInfo) > 0
1563}
1564
1565// Bp2buildTargets returns the Bazel targets bp2build generated for this module.
1566func (m *ModuleBase) Bp2buildTargets() []bp2buildInfo {
1567	return m.commonProperties.BazelConversionStatus.Bp2buildInfo
1568}
1569
1570// AddUnconvertedBp2buildDep stores module name of a dependency that was not converted to Bazel.
1571func (b *baseModuleContext) AddUnconvertedBp2buildDep(dep string) {
1572	unconvertedDeps := &b.Module().base().commonProperties.BazelConversionStatus.UnconvertedDeps
1573	*unconvertedDeps = append(*unconvertedDeps, dep)
1574}
1575
1576// AddMissingBp2buildDep stores module name of a dependency that was not found in a Android.bp file.
1577func (b *baseModuleContext) AddMissingBp2buildDep(dep string) {
1578	missingDeps := &b.Module().base().commonProperties.BazelConversionStatus.MissingDeps
1579	*missingDeps = append(*missingDeps, dep)
1580}
1581
1582// GetUnconvertedBp2buildDeps returns the list of module names of this module's direct dependencies that
1583// were not converted to Bazel.
1584func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string {
1585	return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.UnconvertedDeps)
1586}
1587
1588// GetMissingBp2buildDeps returns the list of module names that were not found in Android.bp files.
1589func (m *ModuleBase) GetMissingBp2buildDeps() []string {
1590	return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.MissingDeps)
1591}
1592
1593func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
1594	(*d)["Android"] = map[string]interface{}{
1595		// Properties set in Blueprint or in blueprint of a defaults modules
1596		"SetProperties": m.propertiesWithValues(),
1597	}
1598}
1599
1600type propInfo struct {
1601	Name   string
1602	Type   string
1603	Value  string
1604	Values []string
1605}
1606
1607func (m *ModuleBase) propertiesWithValues() []propInfo {
1608	var info []propInfo
1609	props := m.GetProperties()
1610
1611	var propsWithValues func(name string, v reflect.Value)
1612	propsWithValues = func(name string, v reflect.Value) {
1613		kind := v.Kind()
1614		switch kind {
1615		case reflect.Ptr, reflect.Interface:
1616			if v.IsNil() {
1617				return
1618			}
1619			propsWithValues(name, v.Elem())
1620		case reflect.Struct:
1621			if v.IsZero() {
1622				return
1623			}
1624			for i := 0; i < v.NumField(); i++ {
1625				namePrefix := name
1626				sTyp := v.Type().Field(i)
1627				if proptools.ShouldSkipProperty(sTyp) {
1628					continue
1629				}
1630				if name != "" && !strings.HasSuffix(namePrefix, ".") {
1631					namePrefix += "."
1632				}
1633				if !proptools.IsEmbedded(sTyp) {
1634					namePrefix += sTyp.Name
1635				}
1636				sVal := v.Field(i)
1637				propsWithValues(namePrefix, sVal)
1638			}
1639		case reflect.Array, reflect.Slice:
1640			if v.IsNil() {
1641				return
1642			}
1643			elKind := v.Type().Elem().Kind()
1644			info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
1645		default:
1646			info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
1647		}
1648	}
1649
1650	for _, p := range props {
1651		propsWithValues("", reflect.ValueOf(p).Elem())
1652	}
1653	sort.Slice(info, func(i, j int) bool {
1654		return info[i].Name < info[j].Name
1655	})
1656	return info
1657}
1658
1659func reflectionValue(value reflect.Value) string {
1660	switch value.Kind() {
1661	case reflect.Bool:
1662		return fmt.Sprintf("%t", value.Bool())
1663	case reflect.Int64:
1664		return fmt.Sprintf("%d", value.Int())
1665	case reflect.String:
1666		return fmt.Sprintf("%s", value.String())
1667	case reflect.Struct:
1668		if value.IsZero() {
1669			return "{}"
1670		}
1671		length := value.NumField()
1672		vals := make([]string, length, length)
1673		for i := 0; i < length; i++ {
1674			sTyp := value.Type().Field(i)
1675			if proptools.ShouldSkipProperty(sTyp) {
1676				continue
1677			}
1678			name := sTyp.Name
1679			vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
1680		}
1681		return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
1682	case reflect.Array, reflect.Slice:
1683		vals := sliceReflectionValue(value)
1684		return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
1685	}
1686	return ""
1687}
1688
1689func sliceReflectionValue(value reflect.Value) []string {
1690	length := value.Len()
1691	vals := make([]string, length, length)
1692	for i := 0; i < length; i++ {
1693		vals[i] = reflectionValue(value.Index(i))
1694	}
1695	return vals
1696}
1697
1698func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
1699
1700func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
1701
1702// AddProperties "registers" the provided props
1703// each value in props MUST be a pointer to a struct
1704func (m *ModuleBase) AddProperties(props ...interface{}) {
1705	m.registerProps = append(m.registerProps, props...)
1706}
1707
1708func (m *ModuleBase) GetProperties() []interface{} {
1709	return m.registerProps
1710}
1711
1712func (m *ModuleBase) BuildParamsForTests() []BuildParams {
1713	// Expand the references to module variables like $flags[0-9]*,
1714	// so we do not need to change many existing unit tests.
1715	// This looks like undoing the shareFlags optimization in cc's
1716	// transformSourceToObj, and should only affects unit tests.
1717	vars := m.VariablesForTests()
1718	buildParams := append([]BuildParams(nil), m.buildParams...)
1719	for i := range buildParams {
1720		newArgs := make(map[string]string)
1721		for k, v := range buildParams[i].Args {
1722			newArgs[k] = v
1723			// Replaces both ${flags1} and $flags1 syntax.
1724			if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1725				if value, found := vars[v[2:len(v)-1]]; found {
1726					newArgs[k] = value
1727				}
1728			} else if strings.HasPrefix(v, "$") {
1729				if value, found := vars[v[1:]]; found {
1730					newArgs[k] = value
1731				}
1732			}
1733		}
1734		buildParams[i].Args = newArgs
1735	}
1736	return buildParams
1737}
1738
1739func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1740	return m.ruleParams
1741}
1742
1743func (m *ModuleBase) VariablesForTests() map[string]string {
1744	return m.variables
1745}
1746
1747// Name returns the name of the module.  It may be overridden by individual module types, for
1748// example prebuilts will prepend prebuilt_ to the name.
1749func (m *ModuleBase) Name() string {
1750	return String(m.nameProperties.Name)
1751}
1752
1753// String returns a string that includes the module name and variants for printing during debugging.
1754func (m *ModuleBase) String() string {
1755	sb := strings.Builder{}
1756	sb.WriteString(m.commonProperties.DebugName)
1757	sb.WriteString("{")
1758	for i := range m.commonProperties.DebugMutators {
1759		if i != 0 {
1760			sb.WriteString(",")
1761		}
1762		sb.WriteString(m.commonProperties.DebugMutators[i])
1763		sb.WriteString(":")
1764		sb.WriteString(m.commonProperties.DebugVariations[i])
1765	}
1766	sb.WriteString("}")
1767	return sb.String()
1768}
1769
1770// BaseModuleName returns the name of the module as specified in the blueprints file.
1771func (m *ModuleBase) BaseModuleName() string {
1772	return String(m.nameProperties.Name)
1773}
1774
1775func (m *ModuleBase) base() *ModuleBase {
1776	return m
1777}
1778
1779func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1780	return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1781}
1782
1783func (m *ModuleBase) visibilityProperties() []visibilityProperty {
1784	return m.visibilityPropertyInfo
1785}
1786
1787func (m *ModuleBase) Dists() []Dist {
1788	if len(m.distProperties.Dist.Targets) > 0 {
1789		// Make a copy of the underlying Dists slice to protect against
1790		// backing array modifications with repeated calls to this method.
1791		distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1792		return append(distsCopy, m.distProperties.Dist)
1793	} else {
1794		return m.distProperties.Dists
1795	}
1796}
1797
1798func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
1799	var distFiles TaggedDistFiles
1800	for _, dist := range m.Dists() {
1801		// If no tag is specified then it means to use the default dist paths so use
1802		// the special tag name which represents that.
1803		tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1804
1805		if outputFileProducer, ok := m.module.(OutputFileProducer); ok {
1806			// Call the OutputFiles(tag) method to get the paths associated with the tag.
1807			distFilesForTag, err := outputFileProducer.OutputFiles(tag)
1808
1809			// If the tag was not supported and is not DefaultDistTag then it is an error.
1810			// Failing to find paths for DefaultDistTag is not an error. It just means
1811			// that the module type requires the legacy behavior.
1812			if err != nil && tag != DefaultDistTag {
1813				ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1814			}
1815
1816			distFiles = distFiles.addPathsForTag(tag, distFilesForTag...)
1817		} else if tag != DefaultDistTag {
1818			// If the tag was specified then it is an error if the module does not
1819			// implement OutputFileProducer because there is no other way of accessing
1820			// the paths for the specified tag.
1821			ctx.PropertyErrorf("dist.tag",
1822				"tag %s not supported because the module does not implement OutputFileProducer", tag)
1823		}
1824	}
1825
1826	return distFiles
1827}
1828
1829func (m *ModuleBase) Target() Target {
1830	return m.commonProperties.CompileTarget
1831}
1832
1833func (m *ModuleBase) TargetPrimary() bool {
1834	return m.commonProperties.CompilePrimary
1835}
1836
1837func (m *ModuleBase) MultiTargets() []Target {
1838	return m.commonProperties.CompileMultiTargets
1839}
1840
1841func (m *ModuleBase) Os() OsType {
1842	return m.Target().Os
1843}
1844
1845func (m *ModuleBase) Host() bool {
1846	return m.Os().Class == Host
1847}
1848
1849func (m *ModuleBase) Device() bool {
1850	return m.Os().Class == Device
1851}
1852
1853func (m *ModuleBase) Arch() Arch {
1854	return m.Target().Arch
1855}
1856
1857func (m *ModuleBase) ArchSpecific() bool {
1858	return m.commonProperties.ArchSpecific
1859}
1860
1861// True if the current variant is a CommonOS variant, false otherwise.
1862func (m *ModuleBase) IsCommonOSVariant() bool {
1863	return m.commonProperties.CommonOSVariant
1864}
1865
1866// supportsTarget returns true if the given Target is supported by the current module.
1867func (m *ModuleBase) supportsTarget(target Target) bool {
1868	switch target.Os.Class {
1869	case Host:
1870		if target.HostCross {
1871			return m.HostCrossSupported()
1872		} else {
1873			return m.HostSupported()
1874		}
1875	case Device:
1876		return m.DeviceSupported()
1877	default:
1878		return false
1879	}
1880}
1881
1882// DeviceSupported returns true if the current module is supported and enabled for device targets,
1883// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1884// the device support is enabled by default or enabled by the device_supported property.
1885func (m *ModuleBase) DeviceSupported() bool {
1886	hod := m.commonProperties.HostOrDeviceSupported
1887	// deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1888	// value has the deviceDefault bit set.
1889	deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1890	return hod&deviceSupported != 0 && deviceEnabled
1891}
1892
1893// HostSupported returns true if the current module is supported and enabled for host targets,
1894// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1895// the host support is enabled by default or enabled by the host_supported property.
1896func (m *ModuleBase) HostSupported() bool {
1897	hod := m.commonProperties.HostOrDeviceSupported
1898	// hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1899	// value has the hostDefault bit set.
1900	hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1901	return hod&hostSupported != 0 && hostEnabled
1902}
1903
1904// HostCrossSupported returns true if the current module is supported and enabled for host cross
1905// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1906// support and the host cross support is enabled by default or enabled by the
1907// host_supported property.
1908func (m *ModuleBase) HostCrossSupported() bool {
1909	hod := m.commonProperties.HostOrDeviceSupported
1910	// hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1911	// value has the hostDefault bit set.
1912	hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1913	return hod&hostCrossSupported != 0 && hostEnabled
1914}
1915
1916func (m *ModuleBase) Platform() bool {
1917	return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
1918}
1919
1920func (m *ModuleBase) DeviceSpecific() bool {
1921	return Bool(m.commonProperties.Device_specific)
1922}
1923
1924func (m *ModuleBase) SocSpecific() bool {
1925	return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1926}
1927
1928func (m *ModuleBase) ProductSpecific() bool {
1929	return Bool(m.commonProperties.Product_specific)
1930}
1931
1932func (m *ModuleBase) SystemExtSpecific() bool {
1933	return Bool(m.commonProperties.System_ext_specific)
1934}
1935
1936// RequiresStableAPIs returns true if the module will be installed to a partition that may
1937// be updated separately from the system image.
1938func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1939	return m.SocSpecific() || m.DeviceSpecific() ||
1940		(m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1941}
1942
1943func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1944	partition := "system"
1945	if m.SocSpecific() {
1946		// A SoC-specific module could be on the vendor partition at
1947		// "vendor" or the system partition at "system/vendor".
1948		if config.VendorPath() == "vendor" {
1949			partition = "vendor"
1950		}
1951	} else if m.DeviceSpecific() {
1952		// A device-specific module could be on the odm partition at
1953		// "odm", the vendor partition at "vendor/odm", or the system
1954		// partition at "system/vendor/odm".
1955		if config.OdmPath() == "odm" {
1956			partition = "odm"
1957		} else if strings.HasPrefix(config.OdmPath(), "vendor/") {
1958			partition = "vendor"
1959		}
1960	} else if m.ProductSpecific() {
1961		// A product-specific module could be on the product partition
1962		// at "product" or the system partition at "system/product".
1963		if config.ProductPath() == "product" {
1964			partition = "product"
1965		}
1966	} else if m.SystemExtSpecific() {
1967		// A system_ext-specific module could be on the system_ext
1968		// partition at "system_ext" or the system partition at
1969		// "system/system_ext".
1970		if config.SystemExtPath() == "system_ext" {
1971			partition = "system_ext"
1972		}
1973	}
1974	return partition
1975}
1976
1977func (m *ModuleBase) Enabled() bool {
1978	if m.commonProperties.ForcedDisabled {
1979		return false
1980	}
1981	if m.commonProperties.Enabled == nil {
1982		return !m.Os().DefaultDisabled
1983	}
1984	return *m.commonProperties.Enabled
1985}
1986
1987func (m *ModuleBase) Disable() {
1988	m.commonProperties.ForcedDisabled = true
1989}
1990
1991// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1992func (m *ModuleBase) HideFromMake() {
1993	m.commonProperties.HideFromMake = true
1994}
1995
1996// IsHideFromMake returns true if HideFromMake was previously called.
1997func (m *ModuleBase) IsHideFromMake() bool {
1998	return m.commonProperties.HideFromMake == true
1999}
2000
2001// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
2002func (m *ModuleBase) SkipInstall() {
2003	m.commonProperties.SkipInstall = true
2004}
2005
2006// IsSkipInstall returns true if this variant is marked to not create install
2007// rules when ctx.Install* are called.
2008func (m *ModuleBase) IsSkipInstall() bool {
2009	return m.commonProperties.SkipInstall
2010}
2011
2012// Similar to HideFromMake, but if the AndroidMk entry would set
2013// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
2014// rather than leaving it out altogether. That happens in cases where it would
2015// have other side effects, in particular when it adds a NOTICE file target,
2016// which other install targets might depend on.
2017func (m *ModuleBase) MakeUninstallable() {
2018	m.commonProperties.UninstallableApexPlatformVariant = true
2019	m.HideFromMake()
2020}
2021
2022func (m *ModuleBase) ReplacedByPrebuilt() {
2023	m.commonProperties.ReplacedByPrebuilt = true
2024	m.HideFromMake()
2025}
2026
2027func (m *ModuleBase) IsReplacedByPrebuilt() bool {
2028	return m.commonProperties.ReplacedByPrebuilt
2029}
2030
2031func (m *ModuleBase) ExportedToMake() bool {
2032	return m.commonProperties.NamespaceExportedToMake
2033}
2034
2035func (m *ModuleBase) EffectiveLicenseKinds() []string {
2036	return m.commonProperties.Effective_license_kinds
2037}
2038
2039func (m *ModuleBase) EffectiveLicenseFiles() Paths {
2040	result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
2041	for _, p := range m.commonProperties.Effective_license_text {
2042		result = append(result, p.Path)
2043	}
2044	return result
2045}
2046
2047// computeInstallDeps finds the installed paths of all dependencies that have a dependency
2048// tag that is annotated as needing installation via the isInstallDepNeeded method.
2049func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSet, []*packagingSpecsDepSet) {
2050	var installDeps []*installPathsDepSet
2051	var packagingSpecs []*packagingSpecsDepSet
2052	ctx.VisitDirectDeps(func(dep Module) {
2053		if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
2054			// Installation is still handled by Make, so anything hidden from Make is not
2055			// installable.
2056			if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
2057				installDeps = append(installDeps, dep.base().installFilesDepSet)
2058			}
2059			// Add packaging deps even when the dependency is not installed so that uninstallable
2060			// modules can still be packaged.  Often the package will be installed instead.
2061			packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet)
2062		}
2063	})
2064
2065	return installDeps, packagingSpecs
2066}
2067
2068// isInstallDepNeeded returns true if installing the output files of the current module
2069// should also install the output files of the given dependency and dependency tag.
2070func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool {
2071	// Don't add a dependency from the platform to a library provided by an apex.
2072	if dep.base().commonProperties.UninstallableApexPlatformVariant {
2073		return false
2074	}
2075	// Only install modules if the dependency tag is an InstallDepNeeded tag.
2076	return IsInstallDepNeededTag(tag)
2077}
2078
2079func (m *ModuleBase) FilesToInstall() InstallPaths {
2080	return m.installFiles
2081}
2082
2083func (m *ModuleBase) PackagingSpecs() []PackagingSpec {
2084	return m.packagingSpecs
2085}
2086
2087func (m *ModuleBase) TransitivePackagingSpecs() []PackagingSpec {
2088	return m.packagingSpecsDepSet.ToList()
2089}
2090
2091func (m *ModuleBase) NoAddressSanitizer() bool {
2092	return m.noAddressSanitizer
2093}
2094
2095func (m *ModuleBase) InstallInData() bool {
2096	return false
2097}
2098
2099func (m *ModuleBase) InstallInTestcases() bool {
2100	return false
2101}
2102
2103func (m *ModuleBase) InstallInSanitizerDir() bool {
2104	return false
2105}
2106
2107func (m *ModuleBase) InstallInRamdisk() bool {
2108	return Bool(m.commonProperties.Ramdisk)
2109}
2110
2111func (m *ModuleBase) InstallInVendorRamdisk() bool {
2112	return Bool(m.commonProperties.Vendor_ramdisk)
2113}
2114
2115func (m *ModuleBase) InstallInDebugRamdisk() bool {
2116	return Bool(m.commonProperties.Debug_ramdisk)
2117}
2118
2119func (m *ModuleBase) InstallInRecovery() bool {
2120	return Bool(m.commonProperties.Recovery)
2121}
2122
2123func (m *ModuleBase) InstallInVendor() bool {
2124	return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
2125}
2126
2127func (m *ModuleBase) InstallInRoot() bool {
2128	return false
2129}
2130
2131func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
2132	return nil, nil
2133}
2134
2135func (m *ModuleBase) Owner() string {
2136	return String(m.commonProperties.Owner)
2137}
2138
2139func (m *ModuleBase) setImageVariation(variant string) {
2140	m.commonProperties.ImageVariation = variant
2141}
2142
2143func (m *ModuleBase) ImageVariation() blueprint.Variation {
2144	return blueprint.Variation{
2145		Mutator:   "image",
2146		Variation: m.base().commonProperties.ImageVariation,
2147	}
2148}
2149
2150func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
2151	for i, v := range m.commonProperties.DebugMutators {
2152		if v == mutator {
2153			return m.commonProperties.DebugVariations[i]
2154		}
2155	}
2156
2157	return ""
2158}
2159
2160func (m *ModuleBase) InRamdisk() bool {
2161	return m.base().commonProperties.ImageVariation == RamdiskVariation
2162}
2163
2164func (m *ModuleBase) InVendorRamdisk() bool {
2165	return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
2166}
2167
2168func (m *ModuleBase) InDebugRamdisk() bool {
2169	return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
2170}
2171
2172func (m *ModuleBase) InRecovery() bool {
2173	return m.base().commonProperties.ImageVariation == RecoveryVariation
2174}
2175
2176func (m *ModuleBase) RequiredModuleNames() []string {
2177	return m.base().commonProperties.Required
2178}
2179
2180func (m *ModuleBase) HostRequiredModuleNames() []string {
2181	return m.base().commonProperties.Host_required
2182}
2183
2184func (m *ModuleBase) TargetRequiredModuleNames() []string {
2185	return m.base().commonProperties.Target_required
2186}
2187
2188func (m *ModuleBase) InitRc() Paths {
2189	return append(Paths{}, m.initRcPaths...)
2190}
2191
2192func (m *ModuleBase) VintfFragments() Paths {
2193	return append(Paths{}, m.vintfFragmentsPaths...)
2194}
2195
2196func (m *ModuleBase) CompileMultilib() *string {
2197	return m.base().commonProperties.Compile_multilib
2198}
2199
2200// SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
2201// apex container for use when generation the license metadata file.
2202func (m *ModuleBase) SetLicenseInstallMap(installMap []string) {
2203	m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
2204}
2205
2206func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
2207	var allInstalledFiles InstallPaths
2208	var allCheckbuildFiles Paths
2209	ctx.VisitAllModuleVariants(func(module Module) {
2210		a := module.base()
2211		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
2212		// A module's -checkbuild phony targets should
2213		// not be created if the module is not exported to make.
2214		// Those could depend on the build target and fail to compile
2215		// for the current build target.
2216		if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(a) {
2217			allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
2218		}
2219	})
2220
2221	var deps Paths
2222
2223	namespacePrefix := ctx.Namespace().id
2224	if namespacePrefix != "" {
2225		namespacePrefix = namespacePrefix + "-"
2226	}
2227
2228	if len(allInstalledFiles) > 0 {
2229		name := namespacePrefix + ctx.ModuleName() + "-install"
2230		ctx.Phony(name, allInstalledFiles.Paths()...)
2231		m.installTarget = PathForPhony(ctx, name)
2232		deps = append(deps, m.installTarget)
2233	}
2234
2235	if len(allCheckbuildFiles) > 0 {
2236		name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
2237		ctx.Phony(name, allCheckbuildFiles...)
2238		m.checkbuildTarget = PathForPhony(ctx, name)
2239		deps = append(deps, m.checkbuildTarget)
2240	}
2241
2242	if len(deps) > 0 {
2243		suffix := ""
2244		if ctx.Config().KatiEnabled() {
2245			suffix = "-soong"
2246		}
2247
2248		ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
2249
2250		m.blueprintDir = ctx.ModuleDir()
2251	}
2252}
2253
2254func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
2255	var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
2256	var deviceSpecific = Bool(m.commonProperties.Device_specific)
2257	var productSpecific = Bool(m.commonProperties.Product_specific)
2258	var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
2259
2260	msg := "conflicting value set here"
2261	if socSpecific && deviceSpecific {
2262		ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
2263		if Bool(m.commonProperties.Vendor) {
2264			ctx.PropertyErrorf("vendor", msg)
2265		}
2266		if Bool(m.commonProperties.Proprietary) {
2267			ctx.PropertyErrorf("proprietary", msg)
2268		}
2269		if Bool(m.commonProperties.Soc_specific) {
2270			ctx.PropertyErrorf("soc_specific", msg)
2271		}
2272	}
2273
2274	if productSpecific && systemExtSpecific {
2275		ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
2276		ctx.PropertyErrorf("system_ext_specific", msg)
2277	}
2278
2279	if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
2280		if productSpecific {
2281			ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
2282		} else {
2283			ctx.PropertyErrorf("system_ext_specific", "a module cannot be specific to SoC or device and system_ext at the same time.")
2284		}
2285		if deviceSpecific {
2286			ctx.PropertyErrorf("device_specific", msg)
2287		} else {
2288			if Bool(m.commonProperties.Vendor) {
2289				ctx.PropertyErrorf("vendor", msg)
2290			}
2291			if Bool(m.commonProperties.Proprietary) {
2292				ctx.PropertyErrorf("proprietary", msg)
2293			}
2294			if Bool(m.commonProperties.Soc_specific) {
2295				ctx.PropertyErrorf("soc_specific", msg)
2296			}
2297		}
2298	}
2299
2300	if productSpecific {
2301		return productSpecificModule
2302	} else if systemExtSpecific {
2303		return systemExtSpecificModule
2304	} else if deviceSpecific {
2305		return deviceSpecificModule
2306	} else if socSpecific {
2307		return socSpecificModule
2308	} else {
2309		return platformModule
2310	}
2311}
2312
2313func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
2314	return earlyModuleContext{
2315		EarlyModuleContext: ctx,
2316		kind:               determineModuleKind(m, ctx),
2317		config:             ctx.Config().(Config),
2318	}
2319}
2320
2321func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
2322	return baseModuleContext{
2323		bp:                 ctx,
2324		earlyModuleContext: m.earlyModuleContextFactory(ctx),
2325		os:                 m.commonProperties.CompileOS,
2326		target:             m.commonProperties.CompileTarget,
2327		targetPrimary:      m.commonProperties.CompilePrimary,
2328		multiTargets:       m.commonProperties.CompileMultiTargets,
2329	}
2330}
2331
2332func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
2333	ctx := &moduleContext{
2334		module:            m.module,
2335		bp:                blueprintCtx,
2336		baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
2337		variables:         make(map[string]string),
2338	}
2339
2340	m.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
2341
2342	dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
2343	// set m.installFilesDepSet to only the transitive dependencies to be used as the dependencies
2344	// of installed files of this module.  It will be replaced by a depset including the installed
2345	// files of this module at the end for use by modules that depend on this one.
2346	m.installFilesDepSet = newInstallPathsDepSet(nil, dependencyInstallFiles)
2347
2348	// Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
2349	// reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
2350	// TODO: This will be removed once defaults modules handle missing dependency errors
2351	blueprintCtx.GetMissingDependencies()
2352
2353	// For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
2354	// are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
2355	// (because the dependencies are added before the modules are disabled). The
2356	// GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
2357	// ignored.
2358	ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
2359
2360	if ctx.config.captureBuild {
2361		ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
2362	}
2363
2364	desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
2365	var suffix []string
2366	if ctx.Os().Class != Device && ctx.Os().Class != Generic {
2367		suffix = append(suffix, ctx.Os().String())
2368	}
2369	if !ctx.PrimaryArch() {
2370		suffix = append(suffix, ctx.Arch().ArchType.String())
2371	}
2372	if apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo); !apexInfo.IsForPlatform() {
2373		suffix = append(suffix, apexInfo.ApexVariationName)
2374	}
2375
2376	ctx.Variable(pctx, "moduleDesc", desc)
2377
2378	s := ""
2379	if len(suffix) > 0 {
2380		s = " [" + strings.Join(suffix, " ") + "]"
2381	}
2382	ctx.Variable(pctx, "moduleDescSuffix", s)
2383
2384	// Some common property checks for properties that will be used later in androidmk.go
2385	checkDistProperties(ctx, "dist", &m.distProperties.Dist)
2386	for i := range m.distProperties.Dists {
2387		checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
2388	}
2389
2390	if m.Enabled() {
2391		// ensure all direct android.Module deps are enabled
2392		ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
2393			if m, ok := bm.(Module); ok {
2394				ctx.validateAndroidModule(bm, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps)
2395			}
2396		})
2397
2398		licensesPropertyFlattener(ctx)
2399		if ctx.Failed() {
2400			return
2401		}
2402
2403		if mixedBuildMod, handled := m.isHandledByBazel(ctx); handled {
2404			mixedBuildMod.ProcessBazelQueryResponse(ctx)
2405		} else {
2406			m.module.GenerateAndroidBuildActions(ctx)
2407		}
2408		if ctx.Failed() {
2409			return
2410		}
2411
2412		m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
2413		rcDir := PathForModuleInstall(ctx, "etc", "init")
2414		for _, src := range m.initRcPaths {
2415			ctx.PackageFile(rcDir, filepath.Base(src.String()), src)
2416		}
2417
2418		m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
2419		vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
2420		for _, src := range m.vintfFragmentsPaths {
2421			ctx.PackageFile(vintfDir, filepath.Base(src.String()), src)
2422		}
2423
2424		// Create the set of tagged dist files after calling GenerateAndroidBuildActions
2425		// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
2426		// output paths being set which must be done before or during
2427		// GenerateAndroidBuildActions.
2428		m.distFiles = m.GenerateTaggedDistFiles(ctx)
2429		if ctx.Failed() {
2430			return
2431		}
2432
2433		m.installFiles = append(m.installFiles, ctx.installFiles...)
2434		m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
2435		m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
2436		m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...)
2437		m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...)
2438	} else if ctx.Config().AllowMissingDependencies() {
2439		// If the module is not enabled it will not create any build rules, nothing will call
2440		// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
2441		// and report them as an error even when AllowMissingDependencies = true.  Call
2442		// ctx.GetMissingDependencies() here to tell blueprint not to handle them.
2443		ctx.GetMissingDependencies()
2444	}
2445
2446	if m == ctx.FinalModule().(Module).base() {
2447		m.generateModuleTarget(ctx)
2448		if ctx.Failed() {
2449			return
2450		}
2451	}
2452
2453	m.installFilesDepSet = newInstallPathsDepSet(m.installFiles, dependencyInstallFiles)
2454	m.packagingSpecsDepSet = newPackagingSpecsDepSet(m.packagingSpecs, dependencyPackagingSpecs)
2455
2456	buildLicenseMetadata(ctx, m.licenseMetadataFile)
2457
2458	m.buildParams = ctx.buildParams
2459	m.ruleParams = ctx.ruleParams
2460	m.variables = ctx.variables
2461}
2462
2463func (m *ModuleBase) isHandledByBazel(ctx ModuleContext) (MixedBuildBuildable, bool) {
2464	if mixedBuildMod, ok := m.module.(MixedBuildBuildable); ok {
2465		if mixedBuildMod.IsMixedBuildSupported(ctx) && MixedBuildsEnabled(ctx) {
2466			return mixedBuildMod, true
2467		}
2468	}
2469	return nil, false
2470}
2471
2472// Check the supplied dist structure to make sure that it is valid.
2473//
2474// property - the base property, e.g. dist or dists[1], which is combined with the
2475// name of the nested property to produce the full property, e.g. dist.dest or
2476// dists[1].dir.
2477func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2478	if dist.Dest != nil {
2479		_, err := validateSafePath(*dist.Dest)
2480		if err != nil {
2481			ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2482		}
2483	}
2484	if dist.Dir != nil {
2485		_, err := validateSafePath(*dist.Dir)
2486		if err != nil {
2487			ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2488		}
2489	}
2490	if dist.Suffix != nil {
2491		if strings.Contains(*dist.Suffix, "/") {
2492			ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2493		}
2494	}
2495
2496}
2497
2498type earlyModuleContext struct {
2499	blueprint.EarlyModuleContext
2500
2501	kind   moduleKind
2502	config Config
2503}
2504
2505func (e *earlyModuleContext) Glob(globPattern string, excludes []string) Paths {
2506	return Glob(e, globPattern, excludes)
2507}
2508
2509func (e *earlyModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
2510	return GlobFiles(e, globPattern, excludes)
2511}
2512
2513func (e *earlyModuleContext) IsSymlink(path Path) bool {
2514	fileInfo, err := e.config.fs.Lstat(path.String())
2515	if err != nil {
2516		e.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
2517	}
2518	return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
2519}
2520
2521func (e *earlyModuleContext) Readlink(path Path) string {
2522	dest, err := e.config.fs.Readlink(path.String())
2523	if err != nil {
2524		e.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
2525	}
2526	return dest
2527}
2528
2529func (e *earlyModuleContext) Module() Module {
2530	module, _ := e.EarlyModuleContext.Module().(Module)
2531	return module
2532}
2533
2534func (e *earlyModuleContext) Config() Config {
2535	return e.EarlyModuleContext.Config().(Config)
2536}
2537
2538func (e *earlyModuleContext) AConfig() Config {
2539	return e.config
2540}
2541
2542func (e *earlyModuleContext) DeviceConfig() DeviceConfig {
2543	return DeviceConfig{e.config.deviceConfig}
2544}
2545
2546func (e *earlyModuleContext) Platform() bool {
2547	return e.kind == platformModule
2548}
2549
2550func (e *earlyModuleContext) DeviceSpecific() bool {
2551	return e.kind == deviceSpecificModule
2552}
2553
2554func (e *earlyModuleContext) SocSpecific() bool {
2555	return e.kind == socSpecificModule
2556}
2557
2558func (e *earlyModuleContext) ProductSpecific() bool {
2559	return e.kind == productSpecificModule
2560}
2561
2562func (e *earlyModuleContext) SystemExtSpecific() bool {
2563	return e.kind == systemExtSpecificModule
2564}
2565
2566func (e *earlyModuleContext) Namespace() *Namespace {
2567	return e.EarlyModuleContext.Namespace().(*Namespace)
2568}
2569
2570type baseModuleContext struct {
2571	bp blueprint.BaseModuleContext
2572	earlyModuleContext
2573	os            OsType
2574	target        Target
2575	multiTargets  []Target
2576	targetPrimary bool
2577	debug         bool
2578
2579	walkPath []Module
2580	tagPath  []blueprint.DependencyTag
2581
2582	strictVisitDeps bool // If true, enforce that all dependencies are enabled
2583
2584	bazelConversionMode bool
2585}
2586
2587func (b *baseModuleContext) isBazelConversionMode() bool {
2588	return b.bazelConversionMode
2589}
2590func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
2591	return b.bp.OtherModuleName(m)
2592}
2593func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) }
2594func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
2595	b.bp.OtherModuleErrorf(m, fmt, args...)
2596}
2597func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
2598	return b.bp.OtherModuleDependencyTag(m)
2599}
2600func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
2601func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool {
2602	return b.bp.OtherModuleDependencyVariantExists(variations, name)
2603}
2604func (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool {
2605	return b.bp.OtherModuleFarDependencyVariantExists(variations, name)
2606}
2607func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool {
2608	return b.bp.OtherModuleReverseDependencyVariantExists(name)
2609}
2610func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
2611	return b.bp.OtherModuleType(m)
2612}
2613func (b *baseModuleContext) OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{} {
2614	return b.bp.OtherModuleProvider(m, provider)
2615}
2616func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool {
2617	return b.bp.OtherModuleHasProvider(m, provider)
2618}
2619func (b *baseModuleContext) Provider(provider blueprint.ProviderKey) interface{} {
2620	return b.bp.Provider(provider)
2621}
2622func (b *baseModuleContext) HasProvider(provider blueprint.ProviderKey) bool {
2623	return b.bp.HasProvider(provider)
2624}
2625func (b *baseModuleContext) SetProvider(provider blueprint.ProviderKey, value interface{}) {
2626	b.bp.SetProvider(provider, value)
2627}
2628
2629func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
2630	return b.bp.GetDirectDepWithTag(name, tag)
2631}
2632
2633func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext {
2634	return b.bp
2635}
2636
2637type moduleContext struct {
2638	bp blueprint.ModuleContext
2639	baseModuleContext
2640	packagingSpecs  []PackagingSpec
2641	installFiles    InstallPaths
2642	checkbuildFiles Paths
2643	module          Module
2644	phonies         map[string]Paths
2645
2646	katiInstalls []katiInstall
2647	katiSymlinks []katiInstall
2648
2649	// For tests
2650	buildParams []BuildParams
2651	ruleParams  map[blueprint.Rule]blueprint.RuleParams
2652	variables   map[string]string
2653}
2654
2655// katiInstall stores a request from Soong to Make to create an install rule.
2656type katiInstall struct {
2657	from          Path
2658	to            InstallPath
2659	implicitDeps  Paths
2660	orderOnlyDeps Paths
2661	executable    bool
2662	extraFiles    *extraFilesZip
2663
2664	absFrom string
2665}
2666
2667type extraFilesZip struct {
2668	zip Path
2669	dir InstallPath
2670}
2671
2672type katiInstalls []katiInstall
2673
2674// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2675// space separated list of from:to tuples.
2676func (installs katiInstalls) BuiltInstalled() string {
2677	sb := strings.Builder{}
2678	for i, install := range installs {
2679		if i != 0 {
2680			sb.WriteRune(' ')
2681		}
2682		sb.WriteString(install.from.String())
2683		sb.WriteRune(':')
2684		sb.WriteString(install.to.String())
2685	}
2686	return sb.String()
2687}
2688
2689// InstallPaths returns the install path of each entry.
2690func (installs katiInstalls) InstallPaths() InstallPaths {
2691	paths := make(InstallPaths, 0, len(installs))
2692	for _, install := range installs {
2693		paths = append(paths, install.to)
2694	}
2695	return paths
2696}
2697
2698func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
2699	return pctx, BuildParams{
2700		Rule:            ErrorRule,
2701		Description:     params.Description,
2702		Output:          params.Output,
2703		Outputs:         params.Outputs,
2704		ImplicitOutput:  params.ImplicitOutput,
2705		ImplicitOutputs: params.ImplicitOutputs,
2706		Args: map[string]string{
2707			"error": err.Error(),
2708		},
2709	}
2710}
2711
2712func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
2713	m.Build(pctx, BuildParams(params))
2714}
2715
2716func validateBuildParams(params blueprint.BuildParams) error {
2717	// Validate that the symlink outputs are declared outputs or implicit outputs
2718	allOutputs := map[string]bool{}
2719	for _, output := range params.Outputs {
2720		allOutputs[output] = true
2721	}
2722	for _, output := range params.ImplicitOutputs {
2723		allOutputs[output] = true
2724	}
2725	for _, symlinkOutput := range params.SymlinkOutputs {
2726		if !allOutputs[symlinkOutput] {
2727			return fmt.Errorf(
2728				"Symlink output %s is not a declared output or implicit output",
2729				symlinkOutput)
2730		}
2731	}
2732	return nil
2733}
2734
2735// Convert build parameters from their concrete Android types into their string representations,
2736// and combine the singular and plural fields of the same type (e.g. Output and Outputs).
2737func convertBuildParams(params BuildParams) blueprint.BuildParams {
2738	bparams := blueprint.BuildParams{
2739		Rule:            params.Rule,
2740		Description:     params.Description,
2741		Deps:            params.Deps,
2742		Outputs:         params.Outputs.Strings(),
2743		ImplicitOutputs: params.ImplicitOutputs.Strings(),
2744		SymlinkOutputs:  params.SymlinkOutputs.Strings(),
2745		Inputs:          params.Inputs.Strings(),
2746		Implicits:       params.Implicits.Strings(),
2747		OrderOnly:       params.OrderOnly.Strings(),
2748		Validations:     params.Validations.Strings(),
2749		Args:            params.Args,
2750		Optional:        !params.Default,
2751	}
2752
2753	if params.Depfile != nil {
2754		bparams.Depfile = params.Depfile.String()
2755	}
2756	if params.Output != nil {
2757		bparams.Outputs = append(bparams.Outputs, params.Output.String())
2758	}
2759	if params.SymlinkOutput != nil {
2760		bparams.SymlinkOutputs = append(bparams.SymlinkOutputs, params.SymlinkOutput.String())
2761	}
2762	if params.ImplicitOutput != nil {
2763		bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
2764	}
2765	if params.Input != nil {
2766		bparams.Inputs = append(bparams.Inputs, params.Input.String())
2767	}
2768	if params.Implicit != nil {
2769		bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
2770	}
2771	if params.Validation != nil {
2772		bparams.Validations = append(bparams.Validations, params.Validation.String())
2773	}
2774
2775	bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
2776	bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
2777	bparams.SymlinkOutputs = proptools.NinjaEscapeList(bparams.SymlinkOutputs)
2778	bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
2779	bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
2780	bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
2781	bparams.Validations = proptools.NinjaEscapeList(bparams.Validations)
2782	bparams.Depfile = proptools.NinjaEscape(bparams.Depfile)
2783
2784	return bparams
2785}
2786
2787func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
2788	if m.config.captureBuild {
2789		m.variables[name] = value
2790	}
2791
2792	m.bp.Variable(pctx.PackageContext, name, value)
2793}
2794
2795func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
2796	argNames ...string) blueprint.Rule {
2797
2798	if m.config.UseRemoteBuild() {
2799		if params.Pool == nil {
2800			// When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
2801			// jobs to the local parallelism value
2802			params.Pool = localPool
2803		} else if params.Pool == remotePool {
2804			// remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
2805			// pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
2806			// parallelism.
2807			params.Pool = nil
2808		}
2809	}
2810
2811	rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
2812
2813	if m.config.captureBuild {
2814		m.ruleParams[rule] = params
2815	}
2816
2817	return rule
2818}
2819
2820func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
2821	if params.Description != "" {
2822		params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
2823	}
2824
2825	if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 {
2826		pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n",
2827			m.ModuleName(), strings.Join(missingDeps, ", ")))
2828	}
2829
2830	if m.config.captureBuild {
2831		m.buildParams = append(m.buildParams, params)
2832	}
2833
2834	bparams := convertBuildParams(params)
2835	err := validateBuildParams(bparams)
2836	if err != nil {
2837		m.ModuleErrorf(
2838			"%s: build parameter validation failed: %s",
2839			m.ModuleName(),
2840			err.Error())
2841	}
2842	m.bp.Build(pctx.PackageContext, bparams)
2843}
2844
2845func (m *moduleContext) Phony(name string, deps ...Path) {
2846	addPhony(m.config, name, deps...)
2847}
2848
2849func (m *moduleContext) GetMissingDependencies() []string {
2850	var missingDeps []string
2851	missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
2852	missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...)
2853	missingDeps = FirstUniqueStrings(missingDeps)
2854	return missingDeps
2855}
2856
2857func (b *baseModuleContext) AddMissingDependencies(deps []string) {
2858	if deps != nil {
2859		missingDeps := &b.Module().base().commonProperties.MissingDeps
2860		*missingDeps = append(*missingDeps, deps...)
2861		*missingDeps = FirstUniqueStrings(*missingDeps)
2862	}
2863}
2864
2865type AllowDisabledModuleDependency interface {
2866	blueprint.DependencyTag
2867	AllowDisabledModuleDependency(target Module) bool
2868}
2869
2870func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool) Module {
2871	aModule, _ := module.(Module)
2872
2873	if !strict {
2874		return aModule
2875	}
2876
2877	if aModule == nil {
2878		b.ModuleErrorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag)
2879		return nil
2880	}
2881
2882	if !aModule.Enabled() {
2883		if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependency(aModule) {
2884			if b.Config().AllowMissingDependencies() {
2885				b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
2886			} else {
2887				b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
2888			}
2889		}
2890		return nil
2891	}
2892	return aModule
2893}
2894
2895type dep struct {
2896	mod blueprint.Module
2897	tag blueprint.DependencyTag
2898}
2899
2900func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
2901	var deps []dep
2902	b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2903		if aModule, _ := module.(Module); aModule != nil {
2904			if aModule.base().BaseModuleName() == name {
2905				returnedTag := b.bp.OtherModuleDependencyTag(aModule)
2906				if tag == nil || returnedTag == tag {
2907					deps = append(deps, dep{aModule, returnedTag})
2908				}
2909			}
2910		} else if b.bp.OtherModuleName(module) == name {
2911			returnedTag := b.bp.OtherModuleDependencyTag(module)
2912			if tag == nil || returnedTag == tag {
2913				deps = append(deps, dep{module, returnedTag})
2914			}
2915		}
2916	})
2917	return deps
2918}
2919
2920func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
2921	deps := b.getDirectDepsInternal(name, tag)
2922	if len(deps) == 1 {
2923		return deps[0].mod, deps[0].tag
2924	} else if len(deps) >= 2 {
2925		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
2926			name, b.ModuleName()))
2927	} else {
2928		return nil, nil
2929	}
2930}
2931
2932func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) {
2933	foundDeps := b.getDirectDepsInternal(name, nil)
2934	deps := map[blueprint.Module]bool{}
2935	for _, dep := range foundDeps {
2936		deps[dep.mod] = true
2937	}
2938	if len(deps) == 1 {
2939		return foundDeps[0].mod, foundDeps[0].tag
2940	} else if len(deps) >= 2 {
2941		// this could happen if two dependencies have the same name in different namespaces
2942		// TODO(b/186554727): this should not occur if namespaces are handled within
2943		// getDirectDepsInternal.
2944		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
2945			name, b.ModuleName()))
2946	} else {
2947		return nil, nil
2948	}
2949}
2950
2951func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
2952	var deps []Module
2953	b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2954		if aModule, _ := module.(Module); aModule != nil {
2955			if b.bp.OtherModuleDependencyTag(aModule) == tag {
2956				deps = append(deps, aModule)
2957			}
2958		}
2959	})
2960	return deps
2961}
2962
2963func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
2964	module, _ := m.getDirectDepInternal(name, tag)
2965	return module
2966}
2967
2968// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
2969// name, or nil if none exists. If there are multiple dependencies on the same module it returns the
2970// first DependencyTag.
2971func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
2972	return b.getDirectDepFirstTag(name)
2973}
2974
2975func (b *baseModuleContext) ModuleFromName(name string) (blueprint.Module, bool) {
2976	if !b.isBazelConversionMode() {
2977		panic("cannot call ModuleFromName if not in bazel conversion mode")
2978	}
2979	if moduleName, _ := SrcIsModuleWithTag(name); moduleName != "" {
2980		return b.bp.ModuleFromName(moduleName)
2981	} else {
2982		return b.bp.ModuleFromName(name)
2983	}
2984}
2985
2986func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
2987	b.bp.VisitDirectDeps(visit)
2988}
2989
2990func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
2991	b.bp.VisitDirectDeps(func(module blueprint.Module) {
2992		if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
2993			visit(aModule)
2994		}
2995	})
2996}
2997
2998func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
2999	b.bp.VisitDirectDeps(func(module blueprint.Module) {
3000		if b.bp.OtherModuleDependencyTag(module) == tag {
3001			if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
3002				visit(aModule)
3003			}
3004		}
3005	})
3006}
3007
3008func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
3009	b.bp.VisitDirectDepsIf(
3010		// pred
3011		func(module blueprint.Module) bool {
3012			if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
3013				return pred(aModule)
3014			} else {
3015				return false
3016			}
3017		},
3018		// visit
3019		func(module blueprint.Module) {
3020			visit(module.(Module))
3021		})
3022}
3023
3024func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
3025	b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
3026		if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
3027			visit(aModule)
3028		}
3029	})
3030}
3031
3032func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
3033	b.bp.VisitDepsDepthFirstIf(
3034		// pred
3035		func(module blueprint.Module) bool {
3036			if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
3037				return pred(aModule)
3038			} else {
3039				return false
3040			}
3041		},
3042		// visit
3043		func(module blueprint.Module) {
3044			visit(module.(Module))
3045		})
3046}
3047
3048func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
3049	b.bp.WalkDeps(visit)
3050}
3051
3052func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
3053	b.walkPath = []Module{b.Module()}
3054	b.tagPath = []blueprint.DependencyTag{}
3055	b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
3056		childAndroidModule, _ := child.(Module)
3057		parentAndroidModule, _ := parent.(Module)
3058		if childAndroidModule != nil && parentAndroidModule != nil {
3059			// record walkPath before visit
3060			for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
3061				b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
3062				b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
3063			}
3064			b.walkPath = append(b.walkPath, childAndroidModule)
3065			b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
3066			return visit(childAndroidModule, parentAndroidModule)
3067		} else {
3068			return false
3069		}
3070	})
3071}
3072
3073func (b *baseModuleContext) GetWalkPath() []Module {
3074	return b.walkPath
3075}
3076
3077func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
3078	return b.tagPath
3079}
3080
3081func (b *baseModuleContext) VisitAllModuleVariants(visit func(Module)) {
3082	b.bp.VisitAllModuleVariants(func(module blueprint.Module) {
3083		visit(module.(Module))
3084	})
3085}
3086
3087func (b *baseModuleContext) PrimaryModule() Module {
3088	return b.bp.PrimaryModule().(Module)
3089}
3090
3091func (b *baseModuleContext) FinalModule() Module {
3092	return b.bp.FinalModule().(Module)
3093}
3094
3095// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
3096func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
3097	if tag == licenseKindTag {
3098		return true
3099	} else if tag == licensesTag {
3100		return true
3101	}
3102	return false
3103}
3104
3105// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
3106// a dependency tag.
3107var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
3108
3109// PrettyPrintTag returns string representation of the tag, but prefers
3110// custom String() method if available.
3111func PrettyPrintTag(tag blueprint.DependencyTag) string {
3112	// Use tag's custom String() method if available.
3113	if stringer, ok := tag.(fmt.Stringer); ok {
3114		return stringer.String()
3115	}
3116
3117	// Otherwise, get a default string representation of the tag's struct.
3118	tagString := fmt.Sprintf("%T: %+v", tag, tag)
3119
3120	// Remove the boilerplate from BaseDependencyTag as it adds no value.
3121	tagString = tagCleaner.ReplaceAllString(tagString, "")
3122	return tagString
3123}
3124
3125func (b *baseModuleContext) GetPathString(skipFirst bool) string {
3126	sb := strings.Builder{}
3127	tagPath := b.GetTagPath()
3128	walkPath := b.GetWalkPath()
3129	if !skipFirst {
3130		sb.WriteString(walkPath[0].String())
3131	}
3132	for i, m := range walkPath[1:] {
3133		sb.WriteString("\n")
3134		sb.WriteString(fmt.Sprintf("           via tag %s\n", PrettyPrintTag(tagPath[i])))
3135		sb.WriteString(fmt.Sprintf("    -> %s", m.String()))
3136	}
3137	return sb.String()
3138}
3139
3140func (m *moduleContext) ModuleSubDir() string {
3141	return m.bp.ModuleSubDir()
3142}
3143
3144func (b *baseModuleContext) Target() Target {
3145	return b.target
3146}
3147
3148func (b *baseModuleContext) TargetPrimary() bool {
3149	return b.targetPrimary
3150}
3151
3152func (b *baseModuleContext) MultiTargets() []Target {
3153	return b.multiTargets
3154}
3155
3156func (b *baseModuleContext) Arch() Arch {
3157	return b.target.Arch
3158}
3159
3160func (b *baseModuleContext) Os() OsType {
3161	return b.os
3162}
3163
3164func (b *baseModuleContext) Host() bool {
3165	return b.os.Class == Host
3166}
3167
3168func (b *baseModuleContext) Device() bool {
3169	return b.os.Class == Device
3170}
3171
3172func (b *baseModuleContext) Darwin() bool {
3173	return b.os == Darwin
3174}
3175
3176func (b *baseModuleContext) Windows() bool {
3177	return b.os == Windows
3178}
3179
3180func (b *baseModuleContext) Debug() bool {
3181	return b.debug
3182}
3183
3184func (b *baseModuleContext) PrimaryArch() bool {
3185	if len(b.config.Targets[b.target.Os]) <= 1 {
3186		return true
3187	}
3188	return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType
3189}
3190
3191// Makes this module a platform module, i.e. not specific to soc, device,
3192// product, or system_ext.
3193func (m *ModuleBase) MakeAsPlatform() {
3194	m.commonProperties.Vendor = boolPtr(false)
3195	m.commonProperties.Proprietary = boolPtr(false)
3196	m.commonProperties.Soc_specific = boolPtr(false)
3197	m.commonProperties.Product_specific = boolPtr(false)
3198	m.commonProperties.System_ext_specific = boolPtr(false)
3199}
3200
3201func (m *ModuleBase) MakeAsSystemExt() {
3202	m.commonProperties.Vendor = boolPtr(false)
3203	m.commonProperties.Proprietary = boolPtr(false)
3204	m.commonProperties.Soc_specific = boolPtr(false)
3205	m.commonProperties.Product_specific = boolPtr(false)
3206	m.commonProperties.System_ext_specific = boolPtr(true)
3207}
3208
3209// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
3210func (m *ModuleBase) IsNativeBridgeSupported() bool {
3211	return proptools.Bool(m.commonProperties.Native_bridge_supported)
3212}
3213
3214func (m *moduleContext) InstallInData() bool {
3215	return m.module.InstallInData()
3216}
3217
3218func (m *moduleContext) InstallInTestcases() bool {
3219	return m.module.InstallInTestcases()
3220}
3221
3222func (m *moduleContext) InstallInSanitizerDir() bool {
3223	return m.module.InstallInSanitizerDir()
3224}
3225
3226func (m *moduleContext) InstallInRamdisk() bool {
3227	return m.module.InstallInRamdisk()
3228}
3229
3230func (m *moduleContext) InstallInVendorRamdisk() bool {
3231	return m.module.InstallInVendorRamdisk()
3232}
3233
3234func (m *moduleContext) InstallInDebugRamdisk() bool {
3235	return m.module.InstallInDebugRamdisk()
3236}
3237
3238func (m *moduleContext) InstallInRecovery() bool {
3239	return m.module.InstallInRecovery()
3240}
3241
3242func (m *moduleContext) InstallInRoot() bool {
3243	return m.module.InstallInRoot()
3244}
3245
3246func (m *moduleContext) InstallForceOS() (*OsType, *ArchType) {
3247	return m.module.InstallForceOS()
3248}
3249
3250func (m *moduleContext) InstallInVendor() bool {
3251	return m.module.InstallInVendor()
3252}
3253
3254func (m *moduleContext) skipInstall() bool {
3255	if m.module.base().commonProperties.SkipInstall {
3256		return true
3257	}
3258
3259	if m.module.base().commonProperties.HideFromMake {
3260		return true
3261	}
3262
3263	// We'll need a solution for choosing which of modules with the same name in different
3264	// namespaces to install.  For now, reuse the list of namespaces exported to Make as the
3265	// list of namespaces to install in a Soong-only build.
3266	if !m.module.base().commonProperties.NamespaceExportedToMake {
3267		return true
3268	}
3269
3270	return false
3271}
3272
3273func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
3274	deps ...Path) InstallPath {
3275	return m.installFile(installPath, name, srcPath, deps, false, nil)
3276}
3277
3278func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
3279	deps ...Path) InstallPath {
3280	return m.installFile(installPath, name, srcPath, deps, true, nil)
3281}
3282
3283func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path,
3284	extraZip Path, deps ...Path) InstallPath {
3285	return m.installFile(installPath, name, srcPath, deps, false, &extraFilesZip{
3286		zip: extraZip,
3287		dir: installPath,
3288	})
3289}
3290
3291func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
3292	fullInstallPath := installPath.Join(m, name)
3293	return m.packageFile(fullInstallPath, srcPath, false)
3294}
3295
3296func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
3297	licenseFiles := m.Module().EffectiveLicenseFiles()
3298	spec := PackagingSpec{
3299		relPathInPackage:      Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
3300		srcPath:               srcPath,
3301		symlinkTarget:         "",
3302		executable:            executable,
3303		effectiveLicenseFiles: &licenseFiles,
3304		partition:             fullInstallPath.partition,
3305	}
3306	m.packagingSpecs = append(m.packagingSpecs, spec)
3307	return spec
3308}
3309
3310func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []Path,
3311	executable bool, extraZip *extraFilesZip) InstallPath {
3312
3313	fullInstallPath := installPath.Join(m, name)
3314	m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
3315
3316	if !m.skipInstall() {
3317		deps = append(deps, m.module.base().installFilesDepSet.ToList().Paths()...)
3318
3319		var implicitDeps, orderOnlyDeps Paths
3320
3321		if m.Host() {
3322			// Installed host modules might be used during the build, depend directly on their
3323			// dependencies so their timestamp is updated whenever their dependency is updated
3324			implicitDeps = deps
3325		} else {
3326			orderOnlyDeps = deps
3327		}
3328
3329		if m.Config().KatiEnabled() {
3330			// When creating the install rule in Soong but embedding in Make, write the rule to a
3331			// makefile instead of directly to the ninja file so that main.mk can add the
3332			// dependencies from the `required` property that are hard to resolve in Soong.
3333			m.katiInstalls = append(m.katiInstalls, katiInstall{
3334				from:          srcPath,
3335				to:            fullInstallPath,
3336				implicitDeps:  implicitDeps,
3337				orderOnlyDeps: orderOnlyDeps,
3338				executable:    executable,
3339				extraFiles:    extraZip,
3340			})
3341		} else {
3342			rule := Cp
3343			if executable {
3344				rule = CpExecutable
3345			}
3346
3347			extraCmds := ""
3348			if extraZip != nil {
3349				extraCmds += fmt.Sprintf(" && ( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} )",
3350					extraZip.dir.String(), extraZip.zip.String())
3351				extraCmds += " || ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )"
3352				implicitDeps = append(implicitDeps, extraZip.zip)
3353			}
3354
3355			m.Build(pctx, BuildParams{
3356				Rule:        rule,
3357				Description: "install " + fullInstallPath.Base(),
3358				Output:      fullInstallPath,
3359				Input:       srcPath,
3360				Implicits:   implicitDeps,
3361				OrderOnly:   orderOnlyDeps,
3362				Default:     !m.Config().KatiEnabled(),
3363				Args: map[string]string{
3364					"extraCmds": extraCmds,
3365				},
3366			})
3367		}
3368
3369		m.installFiles = append(m.installFiles, fullInstallPath)
3370	}
3371
3372	m.packageFile(fullInstallPath, srcPath, executable)
3373
3374	m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
3375
3376	return fullInstallPath
3377}
3378
3379func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath {
3380	fullInstallPath := installPath.Join(m, name)
3381	m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, true)
3382
3383	relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
3384	if err != nil {
3385		panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
3386	}
3387	if !m.skipInstall() {
3388
3389		if m.Config().KatiEnabled() {
3390			// When creating the symlink rule in Soong but embedding in Make, write the rule to a
3391			// makefile instead of directly to the ninja file so that main.mk can add the
3392			// dependencies from the `required` property that are hard to resolve in Soong.
3393			m.katiSymlinks = append(m.katiSymlinks, katiInstall{
3394				from: srcPath,
3395				to:   fullInstallPath,
3396			})
3397		} else {
3398			// The symlink doesn't need updating when the target is modified, but we sometimes
3399			// have a dependency on a symlink to a binary instead of to the binary directly, and
3400			// the mtime of the symlink must be updated when the binary is modified, so use a
3401			// normal dependency here instead of an order-only dependency.
3402			m.Build(pctx, BuildParams{
3403				Rule:        Symlink,
3404				Description: "install symlink " + fullInstallPath.Base(),
3405				Output:      fullInstallPath,
3406				Input:       srcPath,
3407				Default:     !m.Config().KatiEnabled(),
3408				Args: map[string]string{
3409					"fromPath": relPath,
3410				},
3411			})
3412		}
3413
3414		m.installFiles = append(m.installFiles, fullInstallPath)
3415		m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
3416	}
3417
3418	m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
3419		relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
3420		srcPath:          nil,
3421		symlinkTarget:    relPath,
3422		executable:       false,
3423		partition:        fullInstallPath.partition,
3424	})
3425
3426	return fullInstallPath
3427}
3428
3429// installPath/name -> absPath where absPath might be a path that is available only at runtime
3430// (e.g. /apex/...)
3431func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath {
3432	fullInstallPath := installPath.Join(m, name)
3433	m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
3434
3435	if !m.skipInstall() {
3436		if m.Config().KatiEnabled() {
3437			// When creating the symlink rule in Soong but embedding in Make, write the rule to a
3438			// makefile instead of directly to the ninja file so that main.mk can add the
3439			// dependencies from the `required` property that are hard to resolve in Soong.
3440			m.katiSymlinks = append(m.katiSymlinks, katiInstall{
3441				absFrom: absPath,
3442				to:      fullInstallPath,
3443			})
3444		} else {
3445			m.Build(pctx, BuildParams{
3446				Rule:        Symlink,
3447				Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
3448				Output:      fullInstallPath,
3449				Default:     !m.Config().KatiEnabled(),
3450				Args: map[string]string{
3451					"fromPath": absPath,
3452				},
3453			})
3454		}
3455
3456		m.installFiles = append(m.installFiles, fullInstallPath)
3457	}
3458
3459	m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
3460		relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
3461		srcPath:          nil,
3462		symlinkTarget:    absPath,
3463		executable:       false,
3464		partition:        fullInstallPath.partition,
3465	})
3466
3467	return fullInstallPath
3468}
3469
3470func (m *moduleContext) CheckbuildFile(srcPath Path) {
3471	m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
3472}
3473
3474func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext {
3475	return m.bp
3476}
3477
3478func (m *moduleContext) LicenseMetadataFile() Path {
3479	return m.module.base().licenseMetadataFile
3480}
3481
3482// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
3483// into the module name, or empty string if the input was not a module reference.
3484func SrcIsModule(s string) (module string) {
3485	if len(s) > 1 {
3486		if s[0] == ':' {
3487			module = s[1:]
3488			if !isUnqualifiedModuleName(module) {
3489				// The module name should be unqualified but is not so do not treat it as a module.
3490				module = ""
3491			}
3492		} else if s[0] == '/' && s[1] == '/' {
3493			module = s
3494		}
3495	}
3496	return module
3497}
3498
3499// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
3500// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
3501// into the module name and an empty string for the tag, or empty strings if the input was not a
3502// module reference.
3503func SrcIsModuleWithTag(s string) (module, tag string) {
3504	if len(s) > 1 {
3505		if s[0] == ':' {
3506			module = s[1:]
3507		} else if s[0] == '/' && s[1] == '/' {
3508			module = s
3509		}
3510
3511		if module != "" {
3512			if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
3513				if module[len(module)-1] == '}' {
3514					tag = module[tagStart+1 : len(module)-1]
3515					module = module[:tagStart]
3516				}
3517			}
3518
3519			if s[0] == ':' && !isUnqualifiedModuleName(module) {
3520				// The module name should be unqualified but is not so do not treat it as a module.
3521				module = ""
3522				tag = ""
3523			}
3524		}
3525	}
3526
3527	return module, tag
3528}
3529
3530// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
3531// does not contain any /.
3532func isUnqualifiedModuleName(module string) bool {
3533	return strings.IndexByte(module, '/') == -1
3534}
3535
3536// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
3537// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
3538// or ExtractSourcesDeps.
3539//
3540// If uniquely identifies the dependency that was added as it contains both the module name used to
3541// add the dependency as well as the tag. That makes it very simple to find the matching dependency
3542// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
3543// used to add it. It does not need to check that the module name as returned by one of
3544// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
3545// name supplied in the tag. That means it does not need to handle differences in module names
3546// caused by prebuilt_ prefix, or fully qualified module names.
3547type sourceOrOutputDependencyTag struct {
3548	blueprint.BaseDependencyTag
3549
3550	// The name of the module.
3551	moduleName string
3552
3553	// The tag that will be passed to the module's OutputFileProducer.OutputFiles(tag) method.
3554	tag string
3555}
3556
3557func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
3558	return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
3559}
3560
3561// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
3562// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
3563// properties tagged with `android:"path"` AND it was added using a module reference of
3564// :moduleName{outputTag}.
3565func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
3566	t, ok := depTag.(sourceOrOutputDependencyTag)
3567	return ok && t.tag == outputTag
3568}
3569
3570// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
3571// using ":module" syntax, if any.
3572//
3573// Deprecated: tag the property with `android:"path"` instead.
3574func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
3575	set := make(map[string]bool)
3576
3577	for _, s := range srcFiles {
3578		if m, t := SrcIsModuleWithTag(s); m != "" {
3579			if _, found := set[s]; found {
3580				ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
3581			} else {
3582				set[s] = true
3583				ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
3584			}
3585		}
3586	}
3587}
3588
3589// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
3590// using ":module" syntax, if any.
3591//
3592// Deprecated: tag the property with `android:"path"` instead.
3593func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
3594	if s != nil {
3595		if m, t := SrcIsModuleWithTag(*s); m != "" {
3596			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
3597		}
3598	}
3599}
3600
3601// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
3602// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property.
3603type SourceFileProducer interface {
3604	Srcs() Paths
3605}
3606
3607// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
3608// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were
3609// listed in the property.
3610type OutputFileProducer interface {
3611	OutputFiles(tag string) (Paths, error)
3612}
3613
3614// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag.  On error, including if the
3615// module produced zero paths, it reports errors to the ctx and returns nil.
3616func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
3617	paths, err := outputFilesForModule(ctx, module, tag)
3618	if err != nil {
3619		reportPathError(ctx, err)
3620		return nil
3621	}
3622	return paths
3623}
3624
3625// OutputFileForModule returns the path from an OutputFileProducer with the given tag.  On error, including if the
3626// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
3627func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
3628	paths, err := outputFilesForModule(ctx, module, tag)
3629	if err != nil {
3630		reportPathError(ctx, err)
3631		return nil
3632	}
3633	if len(paths) == 0 {
3634		type addMissingDependenciesIntf interface {
3635			AddMissingDependencies([]string)
3636			OtherModuleName(blueprint.Module) string
3637		}
3638		if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
3639			mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
3640		} else {
3641			ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
3642		}
3643		// Return a fake output file to avoid nil dereferences of Path objects later.
3644		// This should never get used for an actual build as the error or missing
3645		// dependency has already been reported.
3646		p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
3647		if err != nil {
3648			reportPathError(ctx, err)
3649			return nil
3650		}
3651		return p
3652	}
3653	if len(paths) > 1 {
3654		ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
3655			pathContextName(ctx, module))
3656	}
3657	return paths[0]
3658}
3659
3660func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
3661	if outputFileProducer, ok := module.(OutputFileProducer); ok {
3662		paths, err := outputFileProducer.OutputFiles(tag)
3663		if err != nil {
3664			return nil, fmt.Errorf("failed to get output file from module %q: %s",
3665				pathContextName(ctx, module), err.Error())
3666		}
3667		return paths, nil
3668	} else if sourceFileProducer, ok := module.(SourceFileProducer); ok {
3669		if tag != "" {
3670			return nil, fmt.Errorf("module %q is a SourceFileProducer, not an OutputFileProducer, and so does not support tag %q", pathContextName(ctx, module), tag)
3671		}
3672		paths := sourceFileProducer.Srcs()
3673		return paths, nil
3674	} else {
3675		return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
3676	}
3677}
3678
3679// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
3680// specify that they can be used as a tool by a genrule module.
3681type HostToolProvider interface {
3682	Module
3683	// HostToolPath returns the path to the host tool for the module if it is one, or an invalid
3684	// OptionalPath.
3685	HostToolPath() OptionalPath
3686}
3687
3688// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.  The property must
3689// be tagged with `android:"path" to support automatic source module dependency resolution.
3690//
3691// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
3692func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
3693	return PathsForModuleSrcExcludes(m, srcFiles, excludes)
3694}
3695
3696// Returns a single path expanded from globs and modules referenced using ":module" syntax.  The property must
3697// be tagged with `android:"path" to support automatic source module dependency resolution.
3698//
3699// Deprecated: use PathForModuleSrc instead.
3700func (m *moduleContext) ExpandSource(srcFile, _ string) Path {
3701	return PathForModuleSrc(m, srcFile)
3702}
3703
3704// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
3705// the srcFile is non-nil.  The property must be tagged with `android:"path" to support automatic source module
3706// dependency resolution.
3707func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) OptionalPath {
3708	if srcFile != nil {
3709		return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
3710	}
3711	return OptionalPath{}
3712}
3713
3714func (m *moduleContext) RequiredModuleNames() []string {
3715	return m.module.RequiredModuleNames()
3716}
3717
3718func (m *moduleContext) HostRequiredModuleNames() []string {
3719	return m.module.HostRequiredModuleNames()
3720}
3721
3722func (m *moduleContext) TargetRequiredModuleNames() []string {
3723	return m.module.TargetRequiredModuleNames()
3724}
3725
3726func init() {
3727	RegisterSingletonType("buildtarget", BuildTargetSingleton)
3728}
3729
3730func BuildTargetSingleton() Singleton {
3731	return &buildTargetSingleton{}
3732}
3733
3734func parentDir(dir string) string {
3735	dir, _ = filepath.Split(dir)
3736	return filepath.Clean(dir)
3737}
3738
3739type buildTargetSingleton struct{}
3740
3741func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
3742	// Ensure ancestor directories are in dirMap
3743	// Make directories build their direct subdirectories
3744	// Returns a slice of all directories and a slice of top-level directories.
3745	dirs := SortedKeys(dirMap)
3746	for _, dir := range dirs {
3747		dir := parentDir(dir)
3748		for dir != "." && dir != "/" {
3749			if _, exists := dirMap[dir]; exists {
3750				break
3751			}
3752			dirMap[dir] = nil
3753			dir = parentDir(dir)
3754		}
3755	}
3756	dirs = SortedKeys(dirMap)
3757	var topDirs []string
3758	for _, dir := range dirs {
3759		p := parentDir(dir)
3760		if p != "." && p != "/" {
3761			dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
3762		} else if dir != "." && dir != "/" && dir != "" {
3763			topDirs = append(topDirs, dir)
3764		}
3765	}
3766	return SortedKeys(dirMap), topDirs
3767}
3768
3769func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
3770	var checkbuildDeps Paths
3771
3772	mmTarget := func(dir string) string {
3773		return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
3774	}
3775
3776	modulesInDir := make(map[string]Paths)
3777
3778	ctx.VisitAllModules(func(module Module) {
3779		blueprintDir := module.base().blueprintDir
3780		installTarget := module.base().installTarget
3781		checkbuildTarget := module.base().checkbuildTarget
3782
3783		if checkbuildTarget != nil {
3784			checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
3785			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
3786		}
3787
3788		if installTarget != nil {
3789			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
3790		}
3791	})
3792
3793	suffix := ""
3794	if ctx.Config().KatiEnabled() {
3795		suffix = "-soong"
3796	}
3797
3798	// Create a top-level checkbuild target that depends on all modules
3799	ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
3800
3801	// Make will generate the MODULES-IN-* targets
3802	if ctx.Config().KatiEnabled() {
3803		return
3804	}
3805
3806	dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
3807
3808	// Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
3809	// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
3810	// files.
3811	for _, dir := range dirs {
3812		ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
3813	}
3814
3815	// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
3816	type osAndCross struct {
3817		os        OsType
3818		hostCross bool
3819	}
3820	osDeps := map[osAndCross]Paths{}
3821	ctx.VisitAllModules(func(module Module) {
3822		if module.Enabled() {
3823			key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
3824			osDeps[key] = append(osDeps[key], module.base().checkbuildFiles...)
3825		}
3826	})
3827
3828	osClass := make(map[string]Paths)
3829	for key, deps := range osDeps {
3830		var className string
3831
3832		switch key.os.Class {
3833		case Host:
3834			if key.hostCross {
3835				className = "host-cross"
3836			} else {
3837				className = "host"
3838			}
3839		case Device:
3840			className = "target"
3841		default:
3842			continue
3843		}
3844
3845		name := className + "-" + key.os.Name
3846		osClass[className] = append(osClass[className], PathForPhony(ctx, name))
3847
3848		ctx.Phony(name, deps...)
3849	}
3850
3851	// Wrap those into host|host-cross|target phony rules
3852	for _, class := range SortedKeys(osClass) {
3853		ctx.Phony(class, osClass[class]...)
3854	}
3855}
3856
3857// Collect information for opening IDE project files in java/jdeps.go.
3858type IDEInfo interface {
3859	IDEInfo(ideInfo *IdeInfo)
3860	BaseModuleName() string
3861}
3862
3863// Extract the base module name from the Import name.
3864// Often the Import name has a prefix "prebuilt_".
3865// Remove the prefix explicitly if needed
3866// until we find a better solution to get the Import name.
3867type IDECustomizedModuleName interface {
3868	IDECustomizedModuleName() string
3869}
3870
3871type IdeInfo struct {
3872	Deps              []string `json:"dependencies,omitempty"`
3873	Srcs              []string `json:"srcs,omitempty"`
3874	Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
3875	Jarjar_rules      []string `json:"jarjar_rules,omitempty"`
3876	Jars              []string `json:"jars,omitempty"`
3877	Classes           []string `json:"class,omitempty"`
3878	Installed_paths   []string `json:"installed,omitempty"`
3879	SrcJars           []string `json:"srcjars,omitempty"`
3880	Paths             []string `json:"path,omitempty"`
3881	Static_libs       []string `json:"static_libs,omitempty"`
3882	Libs              []string `json:"libs,omitempty"`
3883}
3884
3885func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
3886	bpctx := ctx.blueprintBaseModuleContext()
3887	return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
3888}
3889
3890// installPathsDepSet is a thin type-safe wrapper around the generic depSet.  It always uses
3891// topological order.
3892type installPathsDepSet struct {
3893	depSet
3894}
3895
3896// newInstallPathsDepSet returns an immutable packagingSpecsDepSet with the given direct and
3897// transitive contents.
3898func newInstallPathsDepSet(direct InstallPaths, transitive []*installPathsDepSet) *installPathsDepSet {
3899	return &installPathsDepSet{*newDepSet(TOPOLOGICAL, direct, transitive)}
3900}
3901
3902// ToList returns the installPathsDepSet flattened to a list in topological order.
3903func (d *installPathsDepSet) ToList() InstallPaths {
3904	if d == nil {
3905		return nil
3906	}
3907	return d.depSet.ToList().(InstallPaths)
3908}
3909