• 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	"os"
20	"path"
21	"path/filepath"
22	"strings"
23	"text/scanner"
24
25	"github.com/google/blueprint"
26	"github.com/google/blueprint/proptools"
27)
28
29var (
30	DeviceSharedLibrary = "shared_library"
31	DeviceStaticLibrary = "static_library"
32	DeviceExecutable    = "executable"
33	HostSharedLibrary   = "host_shared_library"
34	HostStaticLibrary   = "host_static_library"
35	HostExecutable      = "host_executable"
36)
37
38type BuildParams struct {
39	Rule            blueprint.Rule
40	Deps            blueprint.Deps
41	Depfile         WritablePath
42	Description     string
43	Output          WritablePath
44	Outputs         WritablePaths
45	ImplicitOutput  WritablePath
46	ImplicitOutputs WritablePaths
47	Input           Path
48	Inputs          Paths
49	Implicit        Path
50	Implicits       Paths
51	OrderOnly       Paths
52	Default         bool
53	Args            map[string]string
54}
55
56type ModuleBuildParams BuildParams
57
58// EarlyModuleContext provides methods that can be called early, as soon as the properties have
59// been parsed into the module and before any mutators have run.
60type EarlyModuleContext interface {
61	Module() Module
62	ModuleName() string
63	ModuleDir() string
64	ModuleType() string
65	BlueprintsFile() string
66
67	ContainsProperty(name string) bool
68	Errorf(pos scanner.Position, fmt string, args ...interface{})
69	ModuleErrorf(fmt string, args ...interface{})
70	PropertyErrorf(property, fmt string, args ...interface{})
71	Failed() bool
72
73	AddNinjaFileDeps(deps ...string)
74
75	DeviceSpecific() bool
76	SocSpecific() bool
77	ProductSpecific() bool
78	SystemExtSpecific() bool
79	Platform() bool
80
81	Config() Config
82	DeviceConfig() DeviceConfig
83
84	// Deprecated: use Config()
85	AConfig() Config
86
87	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
88	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
89	// builder whenever a file matching the pattern as added or removed, without rerunning if a
90	// file that does not match the pattern is added to a searched directory.
91	GlobWithDeps(pattern string, excludes []string) ([]string, error)
92
93	Glob(globPattern string, excludes []string) Paths
94	GlobFiles(globPattern string, excludes []string) Paths
95	IsSymlink(path Path) bool
96	Readlink(path Path) string
97}
98
99// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
100// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
101// instead of a blueprint.Module, plus some extra methods that return Android-specific information
102// about the current module.
103type BaseModuleContext interface {
104	EarlyModuleContext
105
106	OtherModuleName(m blueprint.Module) string
107	OtherModuleDir(m blueprint.Module) string
108	OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
109	OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
110	OtherModuleExists(name string) bool
111	OtherModuleType(m blueprint.Module) string
112
113	GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
114	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
115	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
116
117	VisitDirectDepsBlueprint(visit func(blueprint.Module))
118	VisitDirectDeps(visit func(Module))
119	VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
120	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
121	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
122	VisitDepsDepthFirst(visit func(Module))
123	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
124	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
125	WalkDeps(visit func(Module, Module) bool)
126	WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
127	// GetWalkPath is supposed to be called in visit function passed in WalkDeps()
128	// and returns a top-down dependency path from a start module to current child module.
129	GetWalkPath() []Module
130
131	// GetTagPath is supposed to be called in visit function passed in WalkDeps()
132	// and returns a top-down dependency tags path from a start module to current child module.
133	// It has one less entry than GetWalkPath() as it contains the dependency tags that
134	// exist between each adjacent pair of modules in the GetWalkPath().
135	// GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
136	GetTagPath() []blueprint.DependencyTag
137
138	AddMissingDependencies(missingDeps []string)
139
140	Target() Target
141	TargetPrimary() bool
142
143	// The additional arch specific targets (e.g. 32/64 bit) that this module variant is
144	// responsible for creating.
145	MultiTargets() []Target
146	Arch() Arch
147	Os() OsType
148	Host() bool
149	Device() bool
150	Darwin() bool
151	Fuchsia() bool
152	Windows() bool
153	Debug() bool
154	PrimaryArch() bool
155}
156
157// Deprecated: use EarlyModuleContext instead
158type BaseContext interface {
159	EarlyModuleContext
160}
161
162type ModuleContext interface {
163	BaseModuleContext
164
165	// Deprecated: use ModuleContext.Build instead.
166	ModuleBuild(pctx PackageContext, params ModuleBuildParams)
167
168	ExpandSources(srcFiles, excludes []string) Paths
169	ExpandSource(srcFile, prop string) Path
170	ExpandOptionalSource(srcFile *string, prop string) OptionalPath
171
172	InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
173	InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
174	InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
175	InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
176	CheckbuildFile(srcPath Path)
177
178	InstallInData() bool
179	InstallInTestcases() bool
180	InstallInSanitizerDir() bool
181	InstallInRamdisk() bool
182	InstallInRecovery() bool
183	InstallInRoot() bool
184	InstallBypassMake() bool
185
186	RequiredModuleNames() []string
187	HostRequiredModuleNames() []string
188	TargetRequiredModuleNames() []string
189
190	ModuleSubDir() string
191
192	Variable(pctx PackageContext, name, value string)
193	Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
194	// Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
195	// and performs more verification.
196	Build(pctx PackageContext, params BuildParams)
197	// Phony creates a Make-style phony rule, a rule with no commands that can depend on other
198	// phony rules or real files.  Phony can be called on the same name multiple times to add
199	// additional dependencies.
200	Phony(phony string, deps ...Path)
201
202	PrimaryModule() Module
203	FinalModule() Module
204	VisitAllModuleVariants(visit func(Module))
205
206	GetMissingDependencies() []string
207	Namespace() blueprint.Namespace
208}
209
210type Module interface {
211	blueprint.Module
212
213	// GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
214	// but GenerateAndroidBuildActions also has access to Android-specific information.
215	// For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
216	GenerateAndroidBuildActions(ModuleContext)
217
218	DepsMutator(BottomUpMutatorContext)
219
220	base() *ModuleBase
221	Disable()
222	Enabled() bool
223	Target() Target
224	Owner() string
225	InstallInData() bool
226	InstallInTestcases() bool
227	InstallInSanitizerDir() bool
228	InstallInRamdisk() bool
229	InstallInRecovery() bool
230	InstallInRoot() bool
231	InstallBypassMake() bool
232	SkipInstall()
233	IsSkipInstall() bool
234	ExportedToMake() bool
235	InitRc() Paths
236	VintfFragments() Paths
237	NoticeFile() OptionalPath
238
239	AddProperties(props ...interface{})
240	GetProperties() []interface{}
241
242	BuildParamsForTests() []BuildParams
243	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
244	VariablesForTests() map[string]string
245
246	// String returns a string that includes the module name and variants for printing during debugging.
247	String() string
248
249	// Get the qualified module id for this module.
250	qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
251
252	// Get information about the properties that can contain visibility rules.
253	visibilityProperties() []visibilityProperty
254
255	RequiredModuleNames() []string
256	HostRequiredModuleNames() []string
257	TargetRequiredModuleNames() []string
258}
259
260// Qualified id for a module
261type qualifiedModuleName struct {
262	// The package (i.e. directory) in which the module is defined, without trailing /
263	pkg string
264
265	// The name of the module, empty string if package.
266	name string
267}
268
269func (q qualifiedModuleName) String() string {
270	if q.name == "" {
271		return "//" + q.pkg
272	}
273	return "//" + q.pkg + ":" + q.name
274}
275
276func (q qualifiedModuleName) isRootPackage() bool {
277	return q.pkg == "" && q.name == ""
278}
279
280// Get the id for the package containing this module.
281func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
282	pkg := q.pkg
283	if q.name == "" {
284		if pkg == "" {
285			panic(fmt.Errorf("Cannot get containing package id of root package"))
286		}
287
288		index := strings.LastIndex(pkg, "/")
289		if index == -1 {
290			pkg = ""
291		} else {
292			pkg = pkg[:index]
293		}
294	}
295	return newPackageId(pkg)
296}
297
298func newPackageId(pkg string) qualifiedModuleName {
299	// A qualified id for a package module has no name.
300	return qualifiedModuleName{pkg: pkg, name: ""}
301}
302
303type nameProperties struct {
304	// The name of the module.  Must be unique across all modules.
305	Name *string
306}
307
308type commonProperties struct {
309	// emit build rules for this module
310	//
311	// Disabling a module should only be done for those modules that cannot be built
312	// in the current environment. Modules that can build in the current environment
313	// but are not usually required (e.g. superceded by a prebuilt) should not be
314	// disabled as that will prevent them from being built by the checkbuild target
315	// and so prevent early detection of changes that have broken those modules.
316	Enabled *bool `android:"arch_variant"`
317
318	// Controls the visibility of this module to other modules. Allowable values are one or more of
319	// these formats:
320	//
321	//  ["//visibility:public"]: Anyone can use this module.
322	//  ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
323	//      this module.
324	//  ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
325	//      Can only be used at the beginning of a list of visibility rules.
326	//  ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
327	//      other/package (defined in some/package/*.bp and other/package/*.bp) have access to
328	//      this module. Note that sub-packages do not have access to the rule; for example,
329	//      //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
330	//      is a special module and must be used verbatim. It represents all of the modules in the
331	//      package.
332	//  ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
333	//      or other or in one of their sub-packages have access to this module. For example,
334	//      //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
335	//      to depend on this rule (but not //independent:evil)
336	//  ["//project"]: This is shorthand for ["//project:__pkg__"]
337	//  [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
338	//      //project is the module's package. e.g. using [":__subpackages__"] in
339	//      packages/apps/Settings/Android.bp is equivalent to
340	//      //packages/apps/Settings:__subpackages__.
341	//  ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
342	//      for now. It is an error if it is used in a module.
343	//
344	// If a module does not specify the `visibility` property then it uses the
345	// `default_visibility` property of the `package` module in the module's package.
346	//
347	// If the `default_visibility` property is not set for the module's package then
348	// it will use the `default_visibility` of its closest ancestor package for which
349	// a `default_visibility` property is specified.
350	//
351	// If no `default_visibility` property can be found then the module uses the
352	// global default of `//visibility:legacy_public`.
353	//
354	// The `visibility` property has no effect on a defaults module although it does
355	// apply to any non-defaults module that uses it. To set the visibility of a
356	// defaults module, use the `defaults_visibility` property on the defaults module;
357	// not to be confused with the `default_visibility` property on the package module.
358	//
359	// See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
360	// more details.
361	Visibility []string
362
363	// Names of the licenses that apply to this module.
364	Licenses []string
365
366	// control whether this module compiles for 32-bit, 64-bit, or both.  Possible values
367	// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
368	// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
369	// platform
370	Compile_multilib *string `android:"arch_variant"`
371
372	Target struct {
373		Host struct {
374			Compile_multilib *string
375		}
376		Android struct {
377			Compile_multilib *string
378		}
379	}
380
381	// If set to true then the archMutator will create variants for each arch specific target
382	// (e.g. 32/64) that the module is required to produce. If set to false then it will only
383	// create a variant for the architecture and will list the additional arch specific targets
384	// that the variant needs to produce in the CompileMultiTargets property.
385	UseTargetVariants bool   `blueprint:"mutated"`
386	Default_multilib  string `blueprint:"mutated"`
387
388	// whether this is a proprietary vendor module, and should be installed into /vendor
389	Proprietary *bool
390
391	// vendor who owns this module
392	Owner *string
393
394	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
395	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
396	// Use `soc_specific` instead for better meaning.
397	Vendor *bool
398
399	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
400	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
401	Soc_specific *bool
402
403	// whether this module is specific to a device, not only for SoC, but also for off-chip
404	// peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
405	// does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
406	// This implies `soc_specific:true`.
407	Device_specific *bool
408
409	// whether this module is specific to a software configuration of a product (e.g. country,
410	// network operator, etc). When set to true, it is installed into /product (or
411	// /system/product if product partition does not exist).
412	Product_specific *bool
413
414	// whether this module extends system. When set to true, it is installed into /system_ext
415	// (or /system/system_ext if system_ext partition does not exist).
416	System_ext_specific *bool
417
418	// Whether this module is installed to recovery partition
419	Recovery *bool
420
421	// Whether this module is installed to ramdisk
422	Ramdisk *bool
423
424	// Whether this module is built for non-native architecures (also known as native bridge binary)
425	Native_bridge_supported *bool `android:"arch_variant"`
426
427	// init.rc files to be installed if this module is installed
428	Init_rc []string `android:"path"`
429
430	// VINTF manifest fragments to be installed if this module is installed
431	Vintf_fragments []string `android:"path"`
432
433	// names of other modules to install if this module is installed
434	Required []string `android:"arch_variant"`
435
436	// names of other modules to install on host if this module is installed
437	Host_required []string `android:"arch_variant"`
438
439	// names of other modules to install on target if this module is installed
440	Target_required []string `android:"arch_variant"`
441
442	// relative path to a file to include in the list of notices for the device
443	Notice *string `android:"path"`
444
445	Dist struct {
446		// copy the output of this module to the $DIST_DIR when `dist` is specified on the
447		// command line and  any of these targets are also on the command line, or otherwise
448		// built
449		Targets []string `android:"arch_variant"`
450
451		// The name of the output artifact. This defaults to the basename of the output of
452		// the module.
453		Dest *string `android:"arch_variant"`
454
455		// The directory within the dist directory to store the artifact. Defaults to the
456		// top level directory ("").
457		Dir *string `android:"arch_variant"`
458
459		// A suffix to add to the artifact file name (before any extension).
460		Suffix *string `android:"arch_variant"`
461	} `android:"arch_variant"`
462
463	// The OsType of artifacts that this module variant is responsible for creating.
464	//
465	// Set by osMutator
466	CompileOS OsType `blueprint:"mutated"`
467
468	// The Target of artifacts that this module variant is responsible for creating.
469	//
470	// Set by archMutator
471	CompileTarget Target `blueprint:"mutated"`
472
473	// The additional arch specific targets (e.g. 32/64 bit) that this module variant is
474	// responsible for creating.
475	//
476	// By default this is nil as, where necessary, separate variants are created for the
477	// different multilib types supported and that information is encapsulated in the
478	// CompileTarget so the module variant simply needs to create artifacts for that.
479	//
480	// However, if UseTargetVariants is set to false (e.g. by
481	// InitAndroidMultiTargetsArchModule)  then no separate variants are created for the
482	// multilib targets. Instead a single variant is created for the architecture and
483	// this contains the multilib specific targets that this variant should create.
484	//
485	// Set by archMutator
486	CompileMultiTargets []Target `blueprint:"mutated"`
487
488	// True if the module variant's CompileTarget is the primary target
489	//
490	// Set by archMutator
491	CompilePrimary bool `blueprint:"mutated"`
492
493	// Set by InitAndroidModule
494	HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
495	ArchSpecific          bool                  `blueprint:"mutated"`
496
497	// If set to true then a CommonOS variant will be created which will have dependencies
498	// on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
499	// that covers all os and architecture variants.
500	//
501	// The OsType specific variants can be retrieved by calling
502	// GetOsSpecificVariantsOfCommonOSVariant
503	//
504	// Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
505	CreateCommonOSVariant bool `blueprint:"mutated"`
506
507	// If set to true then this variant is the CommonOS variant that has dependencies on its
508	// OsType specific variants.
509	//
510	// Set by osMutator.
511	CommonOSVariant bool `blueprint:"mutated"`
512
513	SkipInstall bool `blueprint:"mutated"`
514
515	NamespaceExportedToMake bool `blueprint:"mutated"`
516
517	MissingDeps []string `blueprint:"mutated"`
518
519	// Name and variant strings stored by mutators to enable Module.String()
520	DebugName       string   `blueprint:"mutated"`
521	DebugMutators   []string `blueprint:"mutated"`
522	DebugVariations []string `blueprint:"mutated"`
523
524	// set by ImageMutator
525	ImageVariation string `blueprint:"mutated"`
526}
527
528type hostAndDeviceProperties struct {
529	// If set to true, build a variant of the module for the host.  Defaults to false.
530	Host_supported *bool
531
532	// If set to true, build a variant of the module for the device.  Defaults to true.
533	Device_supported *bool
534}
535
536type Multilib string
537
538const (
539	MultilibBoth        Multilib = "both"
540	MultilibFirst       Multilib = "first"
541	MultilibCommon      Multilib = "common"
542	MultilibCommonFirst Multilib = "common_first"
543	MultilibDefault     Multilib = ""
544)
545
546type HostOrDeviceSupported int
547
548const (
549	_ HostOrDeviceSupported = iota
550
551	// Host and HostCross are built by default. Device is not supported.
552	HostSupported
553
554	// Host is built by default. HostCross and Device are not supported.
555	HostSupportedNoCross
556
557	// Device is built by default. Host and HostCross are not supported.
558	DeviceSupported
559
560	// Device is built by default. Host and HostCross are supported.
561	HostAndDeviceSupported
562
563	// Host, HostCross, and Device are built by default.
564	HostAndDeviceDefault
565
566	// Nothing is supported. This is not exposed to the user, but used to mark a
567	// host only module as unsupported when the module type is not supported on
568	// the host OS. E.g. benchmarks are supported on Linux but not Darwin.
569	NeitherHostNorDeviceSupported
570)
571
572type moduleKind int
573
574const (
575	platformModule moduleKind = iota
576	deviceSpecificModule
577	socSpecificModule
578	productSpecificModule
579	systemExtSpecificModule
580)
581
582func (k moduleKind) String() string {
583	switch k {
584	case platformModule:
585		return "platform"
586	case deviceSpecificModule:
587		return "device-specific"
588	case socSpecificModule:
589		return "soc-specific"
590	case productSpecificModule:
591		return "product-specific"
592	case systemExtSpecificModule:
593		return "systemext-specific"
594	default:
595		panic(fmt.Errorf("unknown module kind %d", k))
596	}
597}
598
599func initAndroidModuleBase(m Module) {
600	m.base().module = m
601}
602
603func InitAndroidModule(m Module) {
604	initAndroidModuleBase(m)
605	base := m.base()
606
607	m.AddProperties(
608		&base.nameProperties,
609		&base.commonProperties)
610
611	initProductVariableModule(m)
612
613	base.generalProperties = m.GetProperties()
614	base.customizableProperties = m.GetProperties()
615
616	// The default_visibility property needs to be checked and parsed by the visibility module during
617	// its checking and parsing phases so make it the primary visibility property.
618	setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
619}
620
621func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
622	InitAndroidModule(m)
623
624	base := m.base()
625	base.commonProperties.HostOrDeviceSupported = hod
626	base.commonProperties.Default_multilib = string(defaultMultilib)
627	base.commonProperties.ArchSpecific = true
628	base.commonProperties.UseTargetVariants = true
629
630	switch hod {
631	case HostAndDeviceSupported, HostAndDeviceDefault:
632		m.AddProperties(&base.hostAndDeviceProperties)
633	}
634
635	InitArchModule(m)
636}
637
638func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
639	InitAndroidArchModule(m, hod, defaultMultilib)
640	m.base().commonProperties.UseTargetVariants = false
641}
642
643// As InitAndroidMultiTargetsArchModule except it creates an additional CommonOS variant that
644// has dependencies on all the OsType specific variants.
645func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
646	InitAndroidArchModule(m, hod, defaultMultilib)
647	m.base().commonProperties.UseTargetVariants = false
648	m.base().commonProperties.CreateCommonOSVariant = true
649}
650
651// A ModuleBase object contains the properties that are common to all Android
652// modules.  It should be included as an anonymous field in every module
653// struct definition.  InitAndroidModule should then be called from the module's
654// factory function, and the return values from InitAndroidModule should be
655// returned from the factory function.
656//
657// The ModuleBase type is responsible for implementing the GenerateBuildActions
658// method to support the blueprint.Module interface. This method will then call
659// the module's GenerateAndroidBuildActions method once for each build variant
660// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
661// rather than the usual blueprint.ModuleContext.
662// ModuleContext exposes extra functionality specific to the Android build
663// system including details about the particular build variant that is to be
664// generated.
665//
666// For example:
667//
668//     import (
669//         "android/soong/android"
670//     )
671//
672//     type myModule struct {
673//         android.ModuleBase
674//         properties struct {
675//             MyProperty string
676//         }
677//     }
678//
679//     func NewMyModule() android.Module) {
680//         m := &myModule{}
681//         m.AddProperties(&m.properties)
682//         android.InitAndroidModule(m)
683//         return m
684//     }
685//
686//     func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
687//         // Get the CPU architecture for the current build variant.
688//         variantArch := ctx.Arch()
689//
690//         // ...
691//     }
692type ModuleBase struct {
693	// Putting the curiously recurring thing pointing to the thing that contains
694	// the thing pattern to good use.
695	// TODO: remove this
696	module Module
697
698	nameProperties          nameProperties
699	commonProperties        commonProperties
700	variableProperties      interface{}
701	hostAndDeviceProperties hostAndDeviceProperties
702	generalProperties       []interface{}
703	archProperties          [][]interface{}
704	customizableProperties  []interface{}
705
706	// Information about all the properties on the module that contains visibility rules that need
707	// checking.
708	visibilityPropertyInfo []visibilityProperty
709
710	// The primary visibility property, may be nil, that controls access to the module.
711	primaryVisibilityProperty visibilityProperty
712
713	noAddressSanitizer bool
714	installFiles       Paths
715	checkbuildFiles    Paths
716	noticeFile         OptionalPath
717	phonies            map[string]Paths
718
719	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
720	// Only set on the final variant of each module
721	installTarget    WritablePath
722	checkbuildTarget WritablePath
723	blueprintDir     string
724
725	hooks hooks
726
727	registerProps []interface{}
728
729	// For tests
730	buildParams []BuildParams
731	ruleParams  map[blueprint.Rule]blueprint.RuleParams
732	variables   map[string]string
733
734	initRcPaths         Paths
735	vintfFragmentsPaths Paths
736
737	prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
738}
739
740func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
741
742func (m *ModuleBase) AddProperties(props ...interface{}) {
743	m.registerProps = append(m.registerProps, props...)
744}
745
746func (m *ModuleBase) GetProperties() []interface{} {
747	return m.registerProps
748}
749
750func (m *ModuleBase) BuildParamsForTests() []BuildParams {
751	return m.buildParams
752}
753
754func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
755	return m.ruleParams
756}
757
758func (m *ModuleBase) VariablesForTests() map[string]string {
759	return m.variables
760}
761
762func (m *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) {
763	m.prefer32 = prefer32
764}
765
766// Name returns the name of the module.  It may be overridden by individual module types, for
767// example prebuilts will prepend prebuilt_ to the name.
768func (m *ModuleBase) Name() string {
769	return String(m.nameProperties.Name)
770}
771
772// String returns a string that includes the module name and variants for printing during debugging.
773func (m *ModuleBase) String() string {
774	sb := strings.Builder{}
775	sb.WriteString(m.commonProperties.DebugName)
776	sb.WriteString("{")
777	for i := range m.commonProperties.DebugMutators {
778		if i != 0 {
779			sb.WriteString(",")
780		}
781		sb.WriteString(m.commonProperties.DebugMutators[i])
782		sb.WriteString(":")
783		sb.WriteString(m.commonProperties.DebugVariations[i])
784	}
785	sb.WriteString("}")
786	return sb.String()
787}
788
789// BaseModuleName returns the name of the module as specified in the blueprints file.
790func (m *ModuleBase) BaseModuleName() string {
791	return String(m.nameProperties.Name)
792}
793
794func (m *ModuleBase) base() *ModuleBase {
795	return m
796}
797
798func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
799	return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
800}
801
802func (m *ModuleBase) visibilityProperties() []visibilityProperty {
803	return m.visibilityPropertyInfo
804}
805
806func (m *ModuleBase) Target() Target {
807	return m.commonProperties.CompileTarget
808}
809
810func (m *ModuleBase) TargetPrimary() bool {
811	return m.commonProperties.CompilePrimary
812}
813
814func (m *ModuleBase) MultiTargets() []Target {
815	return m.commonProperties.CompileMultiTargets
816}
817
818func (m *ModuleBase) Os() OsType {
819	return m.Target().Os
820}
821
822func (m *ModuleBase) Host() bool {
823	return m.Os().Class == Host || m.Os().Class == HostCross
824}
825
826func (m *ModuleBase) Device() bool {
827	return m.Os().Class == Device
828}
829
830func (m *ModuleBase) Arch() Arch {
831	return m.Target().Arch
832}
833
834func (m *ModuleBase) ArchSpecific() bool {
835	return m.commonProperties.ArchSpecific
836}
837
838// True if the current variant is a CommonOS variant, false otherwise.
839func (m *ModuleBase) IsCommonOSVariant() bool {
840	return m.commonProperties.CommonOSVariant
841}
842
843func (m *ModuleBase) OsClassSupported() []OsClass {
844	switch m.commonProperties.HostOrDeviceSupported {
845	case HostSupported:
846		return []OsClass{Host, HostCross}
847	case HostSupportedNoCross:
848		return []OsClass{Host}
849	case DeviceSupported:
850		return []OsClass{Device}
851	case HostAndDeviceSupported, HostAndDeviceDefault:
852		var supported []OsClass
853		if Bool(m.hostAndDeviceProperties.Host_supported) ||
854			(m.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
855				m.hostAndDeviceProperties.Host_supported == nil) {
856			supported = append(supported, Host, HostCross)
857		}
858		if m.hostAndDeviceProperties.Device_supported == nil ||
859			*m.hostAndDeviceProperties.Device_supported {
860			supported = append(supported, Device)
861		}
862		return supported
863	default:
864		return nil
865	}
866}
867
868func (m *ModuleBase) DeviceSupported() bool {
869	return m.commonProperties.HostOrDeviceSupported == DeviceSupported ||
870		m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
871			(m.hostAndDeviceProperties.Device_supported == nil ||
872				*m.hostAndDeviceProperties.Device_supported)
873}
874
875func (m *ModuleBase) HostSupported() bool {
876	return m.commonProperties.HostOrDeviceSupported == HostSupported ||
877		m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
878			(m.hostAndDeviceProperties.Host_supported != nil &&
879				*m.hostAndDeviceProperties.Host_supported)
880}
881
882func (m *ModuleBase) Platform() bool {
883	return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
884}
885
886func (m *ModuleBase) DeviceSpecific() bool {
887	return Bool(m.commonProperties.Device_specific)
888}
889
890func (m *ModuleBase) SocSpecific() bool {
891	return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
892}
893
894func (m *ModuleBase) ProductSpecific() bool {
895	return Bool(m.commonProperties.Product_specific)
896}
897
898func (m *ModuleBase) SystemExtSpecific() bool {
899	return Bool(m.commonProperties.System_ext_specific)
900}
901
902// RequiresStableAPIs returns true if the module will be installed to a partition that may
903// be updated separately from the system image.
904func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
905	return m.SocSpecific() || m.DeviceSpecific() ||
906		(m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
907}
908
909func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
910	partition := "system"
911	if m.SocSpecific() {
912		// A SoC-specific module could be on the vendor partition at
913		// "vendor" or the system partition at "system/vendor".
914		if config.VendorPath() == "vendor" {
915			partition = "vendor"
916		}
917	} else if m.DeviceSpecific() {
918		// A device-specific module could be on the odm partition at
919		// "odm", the vendor partition at "vendor/odm", or the system
920		// partition at "system/vendor/odm".
921		if config.OdmPath() == "odm" {
922			partition = "odm"
923		} else if strings.HasPrefix(config.OdmPath(), "vendor/") {
924			partition = "vendor"
925		}
926	} else if m.ProductSpecific() {
927		// A product-specific module could be on the product partition
928		// at "product" or the system partition at "system/product".
929		if config.ProductPath() == "product" {
930			partition = "product"
931		}
932	} else if m.SystemExtSpecific() {
933		// A system_ext-specific module could be on the system_ext
934		// partition at "system_ext" or the system partition at
935		// "system/system_ext".
936		if config.SystemExtPath() == "system_ext" {
937			partition = "system_ext"
938		}
939	}
940	return partition
941}
942
943func (m *ModuleBase) Enabled() bool {
944	if m.commonProperties.Enabled == nil {
945		return !m.Os().DefaultDisabled
946	}
947	return *m.commonProperties.Enabled
948}
949
950func (m *ModuleBase) Disable() {
951	m.commonProperties.Enabled = proptools.BoolPtr(false)
952}
953
954func (m *ModuleBase) SkipInstall() {
955	m.commonProperties.SkipInstall = true
956}
957
958func (m *ModuleBase) IsSkipInstall() bool {
959	return m.commonProperties.SkipInstall == true
960}
961
962func (m *ModuleBase) ExportedToMake() bool {
963	return m.commonProperties.NamespaceExportedToMake
964}
965
966func (m *ModuleBase) computeInstallDeps(
967	ctx blueprint.ModuleContext) Paths {
968
969	result := Paths{}
970	// TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
971	ctx.VisitDepsDepthFirstIf(isFileInstaller,
972		func(m blueprint.Module) {
973			fileInstaller := m.(fileInstaller)
974			files := fileInstaller.filesToInstall()
975			result = append(result, files...)
976		})
977
978	return result
979}
980
981func (m *ModuleBase) filesToInstall() Paths {
982	return m.installFiles
983}
984
985func (m *ModuleBase) NoAddressSanitizer() bool {
986	return m.noAddressSanitizer
987}
988
989func (m *ModuleBase) InstallInData() bool {
990	return false
991}
992
993func (m *ModuleBase) InstallInTestcases() bool {
994	return false
995}
996
997func (m *ModuleBase) InstallInSanitizerDir() bool {
998	return false
999}
1000
1001func (m *ModuleBase) InstallInRamdisk() bool {
1002	return Bool(m.commonProperties.Ramdisk)
1003}
1004
1005func (m *ModuleBase) InstallInRecovery() bool {
1006	return Bool(m.commonProperties.Recovery)
1007}
1008
1009func (m *ModuleBase) InstallInRoot() bool {
1010	return false
1011}
1012
1013func (m *ModuleBase) InstallBypassMake() bool {
1014	return false
1015}
1016
1017func (m *ModuleBase) Owner() string {
1018	return String(m.commonProperties.Owner)
1019}
1020
1021func (m *ModuleBase) NoticeFile() OptionalPath {
1022	return m.noticeFile
1023}
1024
1025func (m *ModuleBase) setImageVariation(variant string) {
1026	m.commonProperties.ImageVariation = variant
1027}
1028
1029func (m *ModuleBase) ImageVariation() blueprint.Variation {
1030	return blueprint.Variation{
1031		Mutator:   "image",
1032		Variation: m.base().commonProperties.ImageVariation,
1033	}
1034}
1035
1036func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1037	for i, v := range m.commonProperties.DebugMutators {
1038		if v == mutator {
1039			return m.commonProperties.DebugVariations[i]
1040		}
1041	}
1042
1043	return ""
1044}
1045
1046func (m *ModuleBase) InRamdisk() bool {
1047	return m.base().commonProperties.ImageVariation == RamdiskVariation
1048}
1049
1050func (m *ModuleBase) InRecovery() bool {
1051	return m.base().commonProperties.ImageVariation == RecoveryVariation
1052}
1053
1054func (m *ModuleBase) RequiredModuleNames() []string {
1055	return m.base().commonProperties.Required
1056}
1057
1058func (m *ModuleBase) HostRequiredModuleNames() []string {
1059	return m.base().commonProperties.Host_required
1060}
1061
1062func (m *ModuleBase) TargetRequiredModuleNames() []string {
1063	return m.base().commonProperties.Target_required
1064}
1065
1066func (m *ModuleBase) InitRc() Paths {
1067	return append(Paths{}, m.initRcPaths...)
1068}
1069
1070func (m *ModuleBase) VintfFragments() Paths {
1071	return append(Paths{}, m.vintfFragmentsPaths...)
1072}
1073
1074func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
1075	allInstalledFiles := Paths{}
1076	allCheckbuildFiles := Paths{}
1077	ctx.VisitAllModuleVariants(func(module Module) {
1078		a := module.base()
1079		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
1080		allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
1081	})
1082
1083	var deps Paths
1084
1085	namespacePrefix := ctx.Namespace().(*Namespace).id
1086	if namespacePrefix != "" {
1087		namespacePrefix = namespacePrefix + "-"
1088	}
1089
1090	if len(allInstalledFiles) > 0 {
1091		name := namespacePrefix + ctx.ModuleName() + "-install"
1092		ctx.Phony(name, allInstalledFiles...)
1093		m.installTarget = PathForPhony(ctx, name)
1094		deps = append(deps, m.installTarget)
1095	}
1096
1097	if len(allCheckbuildFiles) > 0 {
1098		name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
1099		ctx.Phony(name, allCheckbuildFiles...)
1100		m.checkbuildTarget = PathForPhony(ctx, name)
1101		deps = append(deps, m.checkbuildTarget)
1102	}
1103
1104	if len(deps) > 0 {
1105		suffix := ""
1106		if ctx.Config().EmbeddedInMake() {
1107			suffix = "-soong"
1108		}
1109
1110		ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
1111
1112		m.blueprintDir = ctx.ModuleDir()
1113	}
1114}
1115
1116func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
1117	var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1118	var deviceSpecific = Bool(m.commonProperties.Device_specific)
1119	var productSpecific = Bool(m.commonProperties.Product_specific)
1120	var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
1121
1122	msg := "conflicting value set here"
1123	if socSpecific && deviceSpecific {
1124		ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
1125		if Bool(m.commonProperties.Vendor) {
1126			ctx.PropertyErrorf("vendor", msg)
1127		}
1128		if Bool(m.commonProperties.Proprietary) {
1129			ctx.PropertyErrorf("proprietary", msg)
1130		}
1131		if Bool(m.commonProperties.Soc_specific) {
1132			ctx.PropertyErrorf("soc_specific", msg)
1133		}
1134	}
1135
1136	if productSpecific && systemExtSpecific {
1137		ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1138		ctx.PropertyErrorf("system_ext_specific", msg)
1139	}
1140
1141	if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
1142		if productSpecific {
1143			ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1144		} else {
1145			ctx.PropertyErrorf("system_ext_specific", "a module cannot be specific to SoC or device and system_ext at the same time.")
1146		}
1147		if deviceSpecific {
1148			ctx.PropertyErrorf("device_specific", msg)
1149		} else {
1150			if Bool(m.commonProperties.Vendor) {
1151				ctx.PropertyErrorf("vendor", msg)
1152			}
1153			if Bool(m.commonProperties.Proprietary) {
1154				ctx.PropertyErrorf("proprietary", msg)
1155			}
1156			if Bool(m.commonProperties.Soc_specific) {
1157				ctx.PropertyErrorf("soc_specific", msg)
1158			}
1159		}
1160	}
1161
1162	if productSpecific {
1163		return productSpecificModule
1164	} else if systemExtSpecific {
1165		return systemExtSpecificModule
1166	} else if deviceSpecific {
1167		return deviceSpecificModule
1168	} else if socSpecific {
1169		return socSpecificModule
1170	} else {
1171		return platformModule
1172	}
1173}
1174
1175func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
1176	return earlyModuleContext{
1177		EarlyModuleContext: ctx,
1178		kind:               determineModuleKind(m, ctx),
1179		config:             ctx.Config().(Config),
1180	}
1181}
1182
1183func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1184	return baseModuleContext{
1185		bp:                 ctx,
1186		earlyModuleContext: m.earlyModuleContextFactory(ctx),
1187		os:                 m.commonProperties.CompileOS,
1188		target:             m.commonProperties.CompileTarget,
1189		targetPrimary:      m.commonProperties.CompilePrimary,
1190		multiTargets:       m.commonProperties.CompileMultiTargets,
1191	}
1192}
1193
1194func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
1195	ctx := &moduleContext{
1196		module:            m.module,
1197		bp:                blueprintCtx,
1198		baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
1199		installDeps:       m.computeInstallDeps(blueprintCtx),
1200		installFiles:      m.installFiles,
1201		variables:         make(map[string]string),
1202	}
1203
1204	// Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
1205	// reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
1206	// TODO: This will be removed once defaults modules handle missing dependency errors
1207	blueprintCtx.GetMissingDependencies()
1208
1209	// For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
1210	// are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
1211	// (because the dependencies are added before the modules are disabled). The
1212	// GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
1213	// ignored.
1214	ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
1215
1216	if ctx.config.captureBuild {
1217		ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
1218	}
1219
1220	desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
1221	var suffix []string
1222	if ctx.Os().Class != Device && ctx.Os().Class != Generic {
1223		suffix = append(suffix, ctx.Os().String())
1224	}
1225	if !ctx.PrimaryArch() {
1226		suffix = append(suffix, ctx.Arch().ArchType.String())
1227	}
1228	if apex, ok := m.module.(ApexModule); ok && !apex.IsForPlatform() {
1229		suffix = append(suffix, apex.ApexName())
1230	}
1231
1232	ctx.Variable(pctx, "moduleDesc", desc)
1233
1234	s := ""
1235	if len(suffix) > 0 {
1236		s = " [" + strings.Join(suffix, " ") + "]"
1237	}
1238	ctx.Variable(pctx, "moduleDescSuffix", s)
1239
1240	// Some common property checks for properties that will be used later in androidmk.go
1241	if m.commonProperties.Dist.Dest != nil {
1242		_, err := validateSafePath(*m.commonProperties.Dist.Dest)
1243		if err != nil {
1244			ctx.PropertyErrorf("dist.dest", "%s", err.Error())
1245		}
1246	}
1247	if m.commonProperties.Dist.Dir != nil {
1248		_, err := validateSafePath(*m.commonProperties.Dist.Dir)
1249		if err != nil {
1250			ctx.PropertyErrorf("dist.dir", "%s", err.Error())
1251		}
1252	}
1253	if m.commonProperties.Dist.Suffix != nil {
1254		if strings.Contains(*m.commonProperties.Dist.Suffix, "/") {
1255			ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.")
1256		}
1257	}
1258
1259	if m.Enabled() {
1260		// ensure all direct android.Module deps are enabled
1261		ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
1262			if _, ok := bm.(Module); ok {
1263				ctx.validateAndroidModule(bm, ctx.baseModuleContext.strictVisitDeps)
1264			}
1265		})
1266
1267		notice := proptools.StringDefault(m.commonProperties.Notice, "NOTICE")
1268		if module := SrcIsModule(notice); module != "" {
1269			m.noticeFile = ctx.ExpandOptionalSource(&notice, "notice")
1270		} else {
1271			noticePath := filepath.Join(ctx.ModuleDir(), notice)
1272			m.noticeFile = ExistentPathForSource(ctx, noticePath)
1273		}
1274
1275		m.module.GenerateAndroidBuildActions(ctx)
1276		if ctx.Failed() {
1277			return
1278		}
1279
1280		m.installFiles = append(m.installFiles, ctx.installFiles...)
1281		m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
1282		m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
1283		m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
1284		for k, v := range ctx.phonies {
1285			m.phonies[k] = append(m.phonies[k], v...)
1286		}
1287	} else if ctx.Config().AllowMissingDependencies() {
1288		// If the module is not enabled it will not create any build rules, nothing will call
1289		// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
1290		// and report them as an error even when AllowMissingDependencies = true.  Call
1291		// ctx.GetMissingDependencies() here to tell blueprint not to handle them.
1292		ctx.GetMissingDependencies()
1293	}
1294
1295	if m == ctx.FinalModule().(Module).base() {
1296		m.generateModuleTarget(ctx)
1297		if ctx.Failed() {
1298			return
1299		}
1300	}
1301
1302	m.buildParams = ctx.buildParams
1303	m.ruleParams = ctx.ruleParams
1304	m.variables = ctx.variables
1305}
1306
1307type earlyModuleContext struct {
1308	blueprint.EarlyModuleContext
1309
1310	kind   moduleKind
1311	config Config
1312}
1313
1314func (e *earlyModuleContext) Glob(globPattern string, excludes []string) Paths {
1315	ret, err := e.GlobWithDeps(globPattern, excludes)
1316	if err != nil {
1317		e.ModuleErrorf("glob: %s", err.Error())
1318	}
1319	return pathsForModuleSrcFromFullPath(e, ret, true)
1320}
1321
1322func (e *earlyModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
1323	ret, err := e.GlobWithDeps(globPattern, excludes)
1324	if err != nil {
1325		e.ModuleErrorf("glob: %s", err.Error())
1326	}
1327	return pathsForModuleSrcFromFullPath(e, ret, false)
1328}
1329
1330func (b *earlyModuleContext) IsSymlink(path Path) bool {
1331	fileInfo, err := b.config.fs.Lstat(path.String())
1332	if err != nil {
1333		b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
1334	}
1335	return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
1336}
1337
1338func (b *earlyModuleContext) Readlink(path Path) string {
1339	dest, err := b.config.fs.Readlink(path.String())
1340	if err != nil {
1341		b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
1342	}
1343	return dest
1344}
1345
1346func (e *earlyModuleContext) Module() Module {
1347	module, _ := e.EarlyModuleContext.Module().(Module)
1348	return module
1349}
1350
1351func (e *earlyModuleContext) Config() Config {
1352	return e.EarlyModuleContext.Config().(Config)
1353}
1354
1355func (e *earlyModuleContext) AConfig() Config {
1356	return e.config
1357}
1358
1359func (e *earlyModuleContext) DeviceConfig() DeviceConfig {
1360	return DeviceConfig{e.config.deviceConfig}
1361}
1362
1363func (e *earlyModuleContext) Platform() bool {
1364	return e.kind == platformModule
1365}
1366
1367func (e *earlyModuleContext) DeviceSpecific() bool {
1368	return e.kind == deviceSpecificModule
1369}
1370
1371func (e *earlyModuleContext) SocSpecific() bool {
1372	return e.kind == socSpecificModule
1373}
1374
1375func (e *earlyModuleContext) ProductSpecific() bool {
1376	return e.kind == productSpecificModule
1377}
1378
1379func (e *earlyModuleContext) SystemExtSpecific() bool {
1380	return e.kind == systemExtSpecificModule
1381}
1382
1383type baseModuleContext struct {
1384	bp blueprint.BaseModuleContext
1385	earlyModuleContext
1386	os            OsType
1387	target        Target
1388	multiTargets  []Target
1389	targetPrimary bool
1390	debug         bool
1391
1392	walkPath []Module
1393	tagPath  []blueprint.DependencyTag
1394
1395	strictVisitDeps bool // If true, enforce that all dependencies are enabled
1396}
1397
1398func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
1399	return b.bp.OtherModuleName(m)
1400}
1401func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) }
1402func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
1403	b.bp.OtherModuleErrorf(m, fmt, args...)
1404}
1405func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
1406	return b.bp.OtherModuleDependencyTag(m)
1407}
1408func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
1409func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
1410	return b.bp.OtherModuleType(m)
1411}
1412
1413func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
1414	return b.bp.GetDirectDepWithTag(name, tag)
1415}
1416
1417type moduleContext struct {
1418	bp blueprint.ModuleContext
1419	baseModuleContext
1420	installDeps     Paths
1421	installFiles    Paths
1422	checkbuildFiles Paths
1423	module          Module
1424	phonies         map[string]Paths
1425
1426	// For tests
1427	buildParams []BuildParams
1428	ruleParams  map[blueprint.Rule]blueprint.RuleParams
1429	variables   map[string]string
1430}
1431
1432func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
1433	return pctx, BuildParams{
1434		Rule:            ErrorRule,
1435		Description:     params.Description,
1436		Output:          params.Output,
1437		Outputs:         params.Outputs,
1438		ImplicitOutput:  params.ImplicitOutput,
1439		ImplicitOutputs: params.ImplicitOutputs,
1440		Args: map[string]string{
1441			"error": err.Error(),
1442		},
1443	}
1444}
1445
1446func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
1447	m.Build(pctx, BuildParams(params))
1448}
1449
1450func convertBuildParams(params BuildParams) blueprint.BuildParams {
1451	bparams := blueprint.BuildParams{
1452		Rule:            params.Rule,
1453		Description:     params.Description,
1454		Deps:            params.Deps,
1455		Outputs:         params.Outputs.Strings(),
1456		ImplicitOutputs: params.ImplicitOutputs.Strings(),
1457		Inputs:          params.Inputs.Strings(),
1458		Implicits:       params.Implicits.Strings(),
1459		OrderOnly:       params.OrderOnly.Strings(),
1460		Args:            params.Args,
1461		Optional:        !params.Default,
1462	}
1463
1464	if params.Depfile != nil {
1465		bparams.Depfile = params.Depfile.String()
1466	}
1467	if params.Output != nil {
1468		bparams.Outputs = append(bparams.Outputs, params.Output.String())
1469	}
1470	if params.ImplicitOutput != nil {
1471		bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
1472	}
1473	if params.Input != nil {
1474		bparams.Inputs = append(bparams.Inputs, params.Input.String())
1475	}
1476	if params.Implicit != nil {
1477		bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
1478	}
1479
1480	bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
1481	bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
1482	bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
1483	bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
1484	bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
1485	bparams.Depfile = proptools.NinjaEscapeList([]string{bparams.Depfile})[0]
1486
1487	return bparams
1488}
1489
1490func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
1491	if m.config.captureBuild {
1492		m.variables[name] = value
1493	}
1494
1495	m.bp.Variable(pctx.PackageContext, name, value)
1496}
1497
1498func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
1499	argNames ...string) blueprint.Rule {
1500
1501	if m.config.UseRemoteBuild() {
1502		if params.Pool == nil {
1503			// When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
1504			// jobs to the local parallelism value
1505			params.Pool = localPool
1506		} else if params.Pool == remotePool {
1507			// remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
1508			// pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
1509			// parallelism.
1510			params.Pool = nil
1511		}
1512	}
1513
1514	rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
1515
1516	if m.config.captureBuild {
1517		m.ruleParams[rule] = params
1518	}
1519
1520	return rule
1521}
1522
1523func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
1524	if params.Description != "" {
1525		params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
1526	}
1527
1528	if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 {
1529		pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n",
1530			m.ModuleName(), strings.Join(missingDeps, ", ")))
1531	}
1532
1533	if m.config.captureBuild {
1534		m.buildParams = append(m.buildParams, params)
1535	}
1536
1537	m.bp.Build(pctx.PackageContext, convertBuildParams(params))
1538}
1539
1540func (m *moduleContext) Phony(name string, deps ...Path) {
1541	addPhony(m.config, name, deps...)
1542}
1543
1544func (m *moduleContext) GetMissingDependencies() []string {
1545	var missingDeps []string
1546	missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
1547	missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...)
1548	missingDeps = FirstUniqueStrings(missingDeps)
1549	return missingDeps
1550}
1551
1552func (b *baseModuleContext) AddMissingDependencies(deps []string) {
1553	if deps != nil {
1554		missingDeps := &b.Module().base().commonProperties.MissingDeps
1555		*missingDeps = append(*missingDeps, deps...)
1556		*missingDeps = FirstUniqueStrings(*missingDeps)
1557	}
1558}
1559
1560func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, strict bool) Module {
1561	aModule, _ := module.(Module)
1562
1563	if !strict {
1564		return aModule
1565	}
1566
1567	if aModule == nil {
1568		b.ModuleErrorf("module %q not an android module", b.OtherModuleName(module))
1569		return nil
1570	}
1571
1572	if !aModule.Enabled() {
1573		if b.Config().AllowMissingDependencies() {
1574			b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
1575		} else {
1576			b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
1577		}
1578		return nil
1579	}
1580	return aModule
1581}
1582
1583func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
1584	type dep struct {
1585		mod blueprint.Module
1586		tag blueprint.DependencyTag
1587	}
1588	var deps []dep
1589	b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
1590		if aModule, _ := module.(Module); aModule != nil && aModule.base().BaseModuleName() == name {
1591			returnedTag := b.bp.OtherModuleDependencyTag(aModule)
1592			if tag == nil || returnedTag == tag {
1593				deps = append(deps, dep{aModule, returnedTag})
1594			}
1595		}
1596	})
1597	if len(deps) == 1 {
1598		return deps[0].mod, deps[0].tag
1599	} else if len(deps) >= 2 {
1600		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
1601			name, b.ModuleName()))
1602	} else {
1603		return nil, nil
1604	}
1605}
1606
1607func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
1608	var deps []Module
1609	b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
1610		if aModule, _ := module.(Module); aModule != nil {
1611			if b.bp.OtherModuleDependencyTag(aModule) == tag {
1612				deps = append(deps, aModule)
1613			}
1614		}
1615	})
1616	return deps
1617}
1618
1619func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
1620	module, _ := m.getDirectDepInternal(name, tag)
1621	return module
1622}
1623
1624func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
1625	return b.getDirectDepInternal(name, nil)
1626}
1627
1628func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
1629	b.bp.VisitDirectDeps(visit)
1630}
1631
1632func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
1633	b.bp.VisitDirectDeps(func(module blueprint.Module) {
1634		if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
1635			visit(aModule)
1636		}
1637	})
1638}
1639
1640func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
1641	b.bp.VisitDirectDeps(func(module blueprint.Module) {
1642		if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
1643			if b.bp.OtherModuleDependencyTag(aModule) == tag {
1644				visit(aModule)
1645			}
1646		}
1647	})
1648}
1649
1650func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
1651	b.bp.VisitDirectDepsIf(
1652		// pred
1653		func(module blueprint.Module) bool {
1654			if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
1655				return pred(aModule)
1656			} else {
1657				return false
1658			}
1659		},
1660		// visit
1661		func(module blueprint.Module) {
1662			visit(module.(Module))
1663		})
1664}
1665
1666func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
1667	b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
1668		if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
1669			visit(aModule)
1670		}
1671	})
1672}
1673
1674func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
1675	b.bp.VisitDepsDepthFirstIf(
1676		// pred
1677		func(module blueprint.Module) bool {
1678			if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
1679				return pred(aModule)
1680			} else {
1681				return false
1682			}
1683		},
1684		// visit
1685		func(module blueprint.Module) {
1686			visit(module.(Module))
1687		})
1688}
1689
1690func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
1691	b.bp.WalkDeps(visit)
1692}
1693
1694func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
1695	b.walkPath = []Module{b.Module()}
1696	b.tagPath = []blueprint.DependencyTag{}
1697	b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
1698		childAndroidModule, _ := child.(Module)
1699		parentAndroidModule, _ := parent.(Module)
1700		if childAndroidModule != nil && parentAndroidModule != nil {
1701			// record walkPath before visit
1702			for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
1703				b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
1704				b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
1705			}
1706			b.walkPath = append(b.walkPath, childAndroidModule)
1707			b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
1708			return visit(childAndroidModule, parentAndroidModule)
1709		} else {
1710			return false
1711		}
1712	})
1713}
1714
1715func (b *baseModuleContext) GetWalkPath() []Module {
1716	return b.walkPath
1717}
1718
1719func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
1720	return b.tagPath
1721}
1722
1723func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
1724	m.bp.VisitAllModuleVariants(func(module blueprint.Module) {
1725		visit(module.(Module))
1726	})
1727}
1728
1729func (m *moduleContext) PrimaryModule() Module {
1730	return m.bp.PrimaryModule().(Module)
1731}
1732
1733func (m *moduleContext) FinalModule() Module {
1734	return m.bp.FinalModule().(Module)
1735}
1736
1737func (m *moduleContext) ModuleSubDir() string {
1738	return m.bp.ModuleSubDir()
1739}
1740
1741func (b *baseModuleContext) Target() Target {
1742	return b.target
1743}
1744
1745func (b *baseModuleContext) TargetPrimary() bool {
1746	return b.targetPrimary
1747}
1748
1749func (b *baseModuleContext) MultiTargets() []Target {
1750	return b.multiTargets
1751}
1752
1753func (b *baseModuleContext) Arch() Arch {
1754	return b.target.Arch
1755}
1756
1757func (b *baseModuleContext) Os() OsType {
1758	return b.os
1759}
1760
1761func (b *baseModuleContext) Host() bool {
1762	return b.os.Class == Host || b.os.Class == HostCross
1763}
1764
1765func (b *baseModuleContext) Device() bool {
1766	return b.os.Class == Device
1767}
1768
1769func (b *baseModuleContext) Darwin() bool {
1770	return b.os == Darwin
1771}
1772
1773func (b *baseModuleContext) Fuchsia() bool {
1774	return b.os == Fuchsia
1775}
1776
1777func (b *baseModuleContext) Windows() bool {
1778	return b.os == Windows
1779}
1780
1781func (b *baseModuleContext) Debug() bool {
1782	return b.debug
1783}
1784
1785func (b *baseModuleContext) PrimaryArch() bool {
1786	if len(b.config.Targets[b.target.Os]) <= 1 {
1787		return true
1788	}
1789	return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType
1790}
1791
1792// Makes this module a platform module, i.e. not specific to soc, device,
1793// product, or system_ext.
1794func (m *ModuleBase) MakeAsPlatform() {
1795	m.commonProperties.Vendor = boolPtr(false)
1796	m.commonProperties.Proprietary = boolPtr(false)
1797	m.commonProperties.Soc_specific = boolPtr(false)
1798	m.commonProperties.Product_specific = boolPtr(false)
1799	m.commonProperties.System_ext_specific = boolPtr(false)
1800}
1801
1802func (m *ModuleBase) EnableNativeBridgeSupportByDefault() {
1803	m.commonProperties.Native_bridge_supported = boolPtr(true)
1804}
1805
1806func (m *ModuleBase) MakeAsSystemExt() {
1807	m.commonProperties.Vendor = boolPtr(false)
1808	m.commonProperties.Proprietary = boolPtr(false)
1809	m.commonProperties.Soc_specific = boolPtr(false)
1810	m.commonProperties.Product_specific = boolPtr(false)
1811	m.commonProperties.System_ext_specific = boolPtr(true)
1812}
1813
1814// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
1815func (m *ModuleBase) IsNativeBridgeSupported() bool {
1816	return proptools.Bool(m.commonProperties.Native_bridge_supported)
1817}
1818
1819func (m *moduleContext) InstallInData() bool {
1820	return m.module.InstallInData()
1821}
1822
1823func (m *moduleContext) InstallInTestcases() bool {
1824	return m.module.InstallInTestcases()
1825}
1826
1827func (m *moduleContext) InstallInSanitizerDir() bool {
1828	return m.module.InstallInSanitizerDir()
1829}
1830
1831func (m *moduleContext) InstallInRamdisk() bool {
1832	return m.module.InstallInRamdisk()
1833}
1834
1835func (m *moduleContext) InstallInRecovery() bool {
1836	return m.module.InstallInRecovery()
1837}
1838
1839func (m *moduleContext) InstallInRoot() bool {
1840	return m.module.InstallInRoot()
1841}
1842
1843func (m *moduleContext) InstallBypassMake() bool {
1844	return m.module.InstallBypassMake()
1845}
1846
1847func (m *moduleContext) skipInstall(fullInstallPath InstallPath) bool {
1848	if m.module.base().commonProperties.SkipInstall {
1849		return true
1850	}
1851
1852	// We'll need a solution for choosing which of modules with the same name in different
1853	// namespaces to install.  For now, reuse the list of namespaces exported to Make as the
1854	// list of namespaces to install in a Soong-only build.
1855	if !m.module.base().commonProperties.NamespaceExportedToMake {
1856		return true
1857	}
1858
1859	if m.Device() {
1860		if m.Config().EmbeddedInMake() && !m.InstallBypassMake() {
1861			return true
1862		}
1863
1864		if m.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
1865			return true
1866		}
1867	}
1868
1869	return false
1870}
1871
1872func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
1873	deps ...Path) InstallPath {
1874	return m.installFile(installPath, name, srcPath, Cp, deps)
1875}
1876
1877func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
1878	deps ...Path) InstallPath {
1879	return m.installFile(installPath, name, srcPath, CpExecutable, deps)
1880}
1881
1882func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path,
1883	rule blueprint.Rule, deps []Path) InstallPath {
1884
1885	fullInstallPath := installPath.Join(m, name)
1886	m.module.base().hooks.runInstallHooks(m, fullInstallPath, false)
1887
1888	if !m.skipInstall(fullInstallPath) {
1889
1890		deps = append(deps, m.installDeps...)
1891
1892		var implicitDeps, orderOnlyDeps Paths
1893
1894		if m.Host() {
1895			// Installed host modules might be used during the build, depend directly on their
1896			// dependencies so their timestamp is updated whenever their dependency is updated
1897			implicitDeps = deps
1898		} else {
1899			orderOnlyDeps = deps
1900		}
1901
1902		m.Build(pctx, BuildParams{
1903			Rule:        rule,
1904			Description: "install " + fullInstallPath.Base(),
1905			Output:      fullInstallPath,
1906			Input:       srcPath,
1907			Implicits:   implicitDeps,
1908			OrderOnly:   orderOnlyDeps,
1909			Default:     !m.Config().EmbeddedInMake(),
1910		})
1911
1912		m.installFiles = append(m.installFiles, fullInstallPath)
1913	}
1914	m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
1915	return fullInstallPath
1916}
1917
1918func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath {
1919	fullInstallPath := installPath.Join(m, name)
1920	m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
1921
1922	if !m.skipInstall(fullInstallPath) {
1923
1924		relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
1925		if err != nil {
1926			panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
1927		}
1928		m.Build(pctx, BuildParams{
1929			Rule:        Symlink,
1930			Description: "install symlink " + fullInstallPath.Base(),
1931			Output:      fullInstallPath,
1932			Input:       srcPath,
1933			Default:     !m.Config().EmbeddedInMake(),
1934			Args: map[string]string{
1935				"fromPath": relPath,
1936			},
1937		})
1938
1939		m.installFiles = append(m.installFiles, fullInstallPath)
1940		m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
1941	}
1942	return fullInstallPath
1943}
1944
1945// installPath/name -> absPath where absPath might be a path that is available only at runtime
1946// (e.g. /apex/...)
1947func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath {
1948	fullInstallPath := installPath.Join(m, name)
1949	m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
1950
1951	if !m.skipInstall(fullInstallPath) {
1952		m.Build(pctx, BuildParams{
1953			Rule:        Symlink,
1954			Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
1955			Output:      fullInstallPath,
1956			Default:     !m.Config().EmbeddedInMake(),
1957			Args: map[string]string{
1958				"fromPath": absPath,
1959			},
1960		})
1961
1962		m.installFiles = append(m.installFiles, fullInstallPath)
1963	}
1964	return fullInstallPath
1965}
1966
1967func (m *moduleContext) CheckbuildFile(srcPath Path) {
1968	m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
1969}
1970
1971type fileInstaller interface {
1972	filesToInstall() Paths
1973}
1974
1975func isFileInstaller(m blueprint.Module) bool {
1976	_, ok := m.(fileInstaller)
1977	return ok
1978}
1979
1980func isAndroidModule(m blueprint.Module) bool {
1981	_, ok := m.(Module)
1982	return ok
1983}
1984
1985func findStringInSlice(str string, slice []string) int {
1986	for i, s := range slice {
1987		if s == str {
1988			return i
1989		}
1990	}
1991	return -1
1992}
1993
1994// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
1995// was not a module reference.
1996func SrcIsModule(s string) (module string) {
1997	if len(s) > 1 && s[0] == ':' {
1998		return s[1:]
1999	}
2000	return ""
2001}
2002
2003// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
2004// module name and an empty string for the tag, or empty strings if the input was not a module reference.
2005func SrcIsModuleWithTag(s string) (module, tag string) {
2006	if len(s) > 1 && s[0] == ':' {
2007		module = s[1:]
2008		if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2009			if module[len(module)-1] == '}' {
2010				tag = module[tagStart+1 : len(module)-1]
2011				module = module[:tagStart]
2012				return module, tag
2013			}
2014		}
2015		return module, ""
2016	}
2017	return "", ""
2018}
2019
2020type sourceOrOutputDependencyTag struct {
2021	blueprint.BaseDependencyTag
2022	tag string
2023}
2024
2025func sourceOrOutputDepTag(tag string) blueprint.DependencyTag {
2026	return sourceOrOutputDependencyTag{tag: tag}
2027}
2028
2029var SourceDepTag = sourceOrOutputDepTag("")
2030
2031// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2032// using ":module" syntax, if any.
2033//
2034// Deprecated: tag the property with `android:"path"` instead.
2035func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
2036	set := make(map[string]bool)
2037
2038	for _, s := range srcFiles {
2039		if m, t := SrcIsModuleWithTag(s); m != "" {
2040			if _, found := set[s]; found {
2041				ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
2042			} else {
2043				set[s] = true
2044				ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
2045			}
2046		}
2047	}
2048}
2049
2050// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2051// using ":module" syntax, if any.
2052//
2053// Deprecated: tag the property with `android:"path"` instead.
2054func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2055	if s != nil {
2056		if m, t := SrcIsModuleWithTag(*s); m != "" {
2057			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
2058		}
2059	}
2060}
2061
2062// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2063// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property.
2064type SourceFileProducer interface {
2065	Srcs() Paths
2066}
2067
2068// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
2069// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were
2070// listed in the property.
2071type OutputFileProducer interface {
2072	OutputFiles(tag string) (Paths, error)
2073}
2074
2075// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag.  On error, including if the
2076// module produced zero paths, it reports errors to the ctx and returns nil.
2077func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
2078	paths, err := outputFilesForModule(ctx, module, tag)
2079	if err != nil {
2080		reportPathError(ctx, err)
2081		return nil
2082	}
2083	return paths
2084}
2085
2086// OutputFileForModule returns the path from an OutputFileProducer with the given tag.  On error, including if the
2087// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
2088func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
2089	paths, err := outputFilesForModule(ctx, module, tag)
2090	if err != nil {
2091		reportPathError(ctx, err)
2092		return nil
2093	}
2094	if len(paths) > 1 {
2095		reportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
2096			pathContextName(ctx, module))
2097		return nil
2098	}
2099	return paths[0]
2100}
2101
2102func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
2103	if outputFileProducer, ok := module.(OutputFileProducer); ok {
2104		paths, err := outputFileProducer.OutputFiles(tag)
2105		if err != nil {
2106			return nil, fmt.Errorf("failed to get output file from module %q: %s",
2107				pathContextName(ctx, module), err.Error())
2108		}
2109		if len(paths) == 0 {
2110			return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
2111		}
2112		return paths, nil
2113	} else {
2114		return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
2115	}
2116}
2117
2118type HostToolProvider interface {
2119	HostToolPath() OptionalPath
2120}
2121
2122// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.  The property must
2123// be tagged with `android:"path" to support automatic source module dependency resolution.
2124//
2125// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
2126func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
2127	return PathsForModuleSrcExcludes(m, srcFiles, excludes)
2128}
2129
2130// Returns a single path expanded from globs and modules referenced using ":module" syntax.  The property must
2131// be tagged with `android:"path" to support automatic source module dependency resolution.
2132//
2133// Deprecated: use PathForModuleSrc instead.
2134func (m *moduleContext) ExpandSource(srcFile, prop string) Path {
2135	return PathForModuleSrc(m, srcFile)
2136}
2137
2138// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
2139// the srcFile is non-nil.  The property must be tagged with `android:"path" to support automatic source module
2140// dependency resolution.
2141func (m *moduleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
2142	if srcFile != nil {
2143		return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
2144	}
2145	return OptionalPath{}
2146}
2147
2148func (m *moduleContext) RequiredModuleNames() []string {
2149	return m.module.RequiredModuleNames()
2150}
2151
2152func (m *moduleContext) HostRequiredModuleNames() []string {
2153	return m.module.HostRequiredModuleNames()
2154}
2155
2156func (m *moduleContext) TargetRequiredModuleNames() []string {
2157	return m.module.TargetRequiredModuleNames()
2158}
2159
2160func init() {
2161	RegisterSingletonType("buildtarget", BuildTargetSingleton)
2162}
2163
2164func BuildTargetSingleton() Singleton {
2165	return &buildTargetSingleton{}
2166}
2167
2168func parentDir(dir string) string {
2169	dir, _ = filepath.Split(dir)
2170	return filepath.Clean(dir)
2171}
2172
2173type buildTargetSingleton struct{}
2174
2175func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
2176	var checkbuildDeps Paths
2177
2178	mmTarget := func(dir string) string {
2179		return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
2180	}
2181
2182	modulesInDir := make(map[string]Paths)
2183
2184	ctx.VisitAllModules(func(module Module) {
2185		blueprintDir := module.base().blueprintDir
2186		installTarget := module.base().installTarget
2187		checkbuildTarget := module.base().checkbuildTarget
2188
2189		if checkbuildTarget != nil {
2190			checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
2191			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
2192		}
2193
2194		if installTarget != nil {
2195			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
2196		}
2197	})
2198
2199	suffix := ""
2200	if ctx.Config().EmbeddedInMake() {
2201		suffix = "-soong"
2202	}
2203
2204	// Create a top-level checkbuild target that depends on all modules
2205	ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
2206
2207	// Make will generate the MODULES-IN-* targets
2208	if ctx.Config().EmbeddedInMake() {
2209		return
2210	}
2211
2212	// Ensure ancestor directories are in modulesInDir
2213	dirs := SortedStringKeys(modulesInDir)
2214	for _, dir := range dirs {
2215		dir := parentDir(dir)
2216		for dir != "." && dir != "/" {
2217			if _, exists := modulesInDir[dir]; exists {
2218				break
2219			}
2220			modulesInDir[dir] = nil
2221			dir = parentDir(dir)
2222		}
2223	}
2224
2225	// Make directories build their direct subdirectories
2226	for _, dir := range dirs {
2227		p := parentDir(dir)
2228		if p != "." && p != "/" {
2229			modulesInDir[p] = append(modulesInDir[p], PathForPhony(ctx, mmTarget(dir)))
2230		}
2231	}
2232
2233	// Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
2234	// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
2235	// files.
2236	for _, dir := range dirs {
2237		ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
2238	}
2239
2240	// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
2241	osDeps := map[OsType]Paths{}
2242	ctx.VisitAllModules(func(module Module) {
2243		if module.Enabled() {
2244			os := module.Target().Os
2245			osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
2246		}
2247	})
2248
2249	osClass := make(map[string]Paths)
2250	for os, deps := range osDeps {
2251		var className string
2252
2253		switch os.Class {
2254		case Host:
2255			className = "host"
2256		case HostCross:
2257			className = "host-cross"
2258		case Device:
2259			className = "target"
2260		default:
2261			continue
2262		}
2263
2264		name := className + "-" + os.Name
2265		osClass[className] = append(osClass[className], PathForPhony(ctx, name))
2266
2267		ctx.Phony(name, deps...)
2268	}
2269
2270	// Wrap those into host|host-cross|target phony rules
2271	for _, class := range SortedStringKeys(osClass) {
2272		ctx.Phony(class, osClass[class]...)
2273	}
2274}
2275
2276// Collect information for opening IDE project files in java/jdeps.go.
2277type IDEInfo interface {
2278	IDEInfo(ideInfo *IdeInfo)
2279	BaseModuleName() string
2280}
2281
2282// Extract the base module name from the Import name.
2283// Often the Import name has a prefix "prebuilt_".
2284// Remove the prefix explicitly if needed
2285// until we find a better solution to get the Import name.
2286type IDECustomizedModuleName interface {
2287	IDECustomizedModuleName() string
2288}
2289
2290type IdeInfo struct {
2291	Deps              []string `json:"dependencies,omitempty"`
2292	Srcs              []string `json:"srcs,omitempty"`
2293	Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
2294	Jarjar_rules      []string `json:"jarjar_rules,omitempty"`
2295	Jars              []string `json:"jars,omitempty"`
2296	Classes           []string `json:"class,omitempty"`
2297	Installed_paths   []string `json:"installed,omitempty"`
2298	SrcJars           []string `json:"srcjars,omitempty"`
2299}
2300