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