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	"path/filepath"
20	"sort"
21	"strings"
22	"text/scanner"
23
24	"github.com/google/blueprint"
25	"github.com/google/blueprint/pathtools"
26)
27
28var (
29	DeviceSharedLibrary = "shared_library"
30	DeviceStaticLibrary = "static_library"
31	DeviceExecutable    = "executable"
32	HostSharedLibrary   = "host_shared_library"
33	HostStaticLibrary   = "host_static_library"
34	HostExecutable      = "host_executable"
35)
36
37type BuildParams struct {
38	Rule            blueprint.Rule
39	Deps            blueprint.Deps
40	Depfile         WritablePath
41	Description     string
42	Output          WritablePath
43	Outputs         WritablePaths
44	ImplicitOutput  WritablePath
45	ImplicitOutputs WritablePaths
46	Input           Path
47	Inputs          Paths
48	Implicit        Path
49	Implicits       Paths
50	OrderOnly       Paths
51	Default         bool
52	Args            map[string]string
53}
54
55type ModuleBuildParams BuildParams
56
57type androidBaseContext interface {
58	Target() Target
59	TargetPrimary() bool
60	Arch() Arch
61	Os() OsType
62	Host() bool
63	Device() bool
64	Darwin() bool
65	Windows() bool
66	Debug() bool
67	PrimaryArch() bool
68	Platform() bool
69	DeviceSpecific() bool
70	SocSpecific() bool
71	ProductSpecific() bool
72	AConfig() Config
73	DeviceConfig() DeviceConfig
74}
75
76type BaseContext interface {
77	BaseModuleContext
78	androidBaseContext
79}
80
81// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
82// a Config instead of an interface{}.
83type BaseModuleContext interface {
84	ModuleName() string
85	ModuleDir() string
86	Config() Config
87
88	ContainsProperty(name string) bool
89	Errorf(pos scanner.Position, fmt string, args ...interface{})
90	ModuleErrorf(fmt string, args ...interface{})
91	PropertyErrorf(property, fmt string, args ...interface{})
92	Failed() bool
93
94	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
95	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
96	// builder whenever a file matching the pattern as added or removed, without rerunning if a
97	// file that does not match the pattern is added to a searched directory.
98	GlobWithDeps(pattern string, excludes []string) ([]string, error)
99
100	Fs() pathtools.FileSystem
101	AddNinjaFileDeps(deps ...string)
102}
103
104type ModuleContext interface {
105	androidBaseContext
106	BaseModuleContext
107
108	// Deprecated: use ModuleContext.Build instead.
109	ModuleBuild(pctx PackageContext, params ModuleBuildParams)
110
111	ExpandSources(srcFiles, excludes []string) Paths
112	ExpandSource(srcFile, prop string) Path
113	ExpandOptionalSource(srcFile *string, prop string) OptionalPath
114	ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
115	Glob(globPattern string, excludes []string) Paths
116	GlobFiles(globPattern string, excludes []string) Paths
117
118	InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
119	InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
120	InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
121	CheckbuildFile(srcPath Path)
122
123	AddMissingDependencies(deps []string)
124
125	InstallInData() bool
126	InstallInSanitizerDir() bool
127
128	RequiredModuleNames() []string
129
130	// android.ModuleContext methods
131	// These are duplicated instead of embedded so that can eventually be wrapped to take an
132	// android.Module instead of a blueprint.Module
133	OtherModuleName(m blueprint.Module) string
134	OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
135	OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
136
137	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
138	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
139
140	ModuleSubDir() string
141
142	VisitDirectDepsBlueprint(visit func(blueprint.Module))
143	VisitDirectDeps(visit func(Module))
144	VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
145	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
146	VisitDepsDepthFirst(visit func(Module))
147	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
148	WalkDeps(visit func(Module, Module) bool)
149
150	Variable(pctx PackageContext, name, value string)
151	Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
152	// Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
153	// and performs more verification.
154	Build(pctx PackageContext, params BuildParams)
155
156	PrimaryModule() Module
157	FinalModule() Module
158	VisitAllModuleVariants(visit func(Module))
159
160	GetMissingDependencies() []string
161	Namespace() blueprint.Namespace
162}
163
164type Module interface {
165	blueprint.Module
166
167	// GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
168	// but GenerateAndroidBuildActions also has access to Android-specific information.
169	// For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
170	GenerateAndroidBuildActions(ModuleContext)
171
172	DepsMutator(BottomUpMutatorContext)
173
174	base() *ModuleBase
175	Enabled() bool
176	Target() Target
177	InstallInData() bool
178	InstallInSanitizerDir() bool
179	SkipInstall()
180	ExportedToMake() bool
181
182	AddProperties(props ...interface{})
183	GetProperties() []interface{}
184
185	BuildParamsForTests() []BuildParams
186}
187
188type nameProperties struct {
189	// The name of the module.  Must be unique across all modules.
190	Name *string
191}
192
193type commonProperties struct {
194	Tags []string
195
196	// emit build rules for this module
197	Enabled *bool `android:"arch_variant"`
198
199	// control whether this module compiles for 32-bit, 64-bit, or both.  Possible values
200	// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
201	// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
202	// platform
203	Compile_multilib *string `android:"arch_variant"`
204
205	Target struct {
206		Host struct {
207			Compile_multilib *string
208		}
209		Android struct {
210			Compile_multilib *string
211		}
212	}
213
214	Default_multilib string `blueprint:"mutated"`
215
216	// whether this is a proprietary vendor module, and should be installed into /vendor
217	Proprietary *bool
218
219	// vendor who owns this module
220	Owner *string
221
222	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
223	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
224	// Use `soc_specific` instead for better meaning.
225	Vendor *bool
226
227	// whether this module is specific to an SoC (System-On-a-Chip). When set to true,
228	// it is installed into /vendor (or /system/vendor if vendor partition does not exist).
229	Soc_specific *bool
230
231	// whether this module is specific to a device, not only for SoC, but also for off-chip
232	// peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
233	// does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
234	// This implies `soc_specific:true`.
235	Device_specific *bool
236
237	// whether this module is specific to a software configuration of a product (e.g. country,
238	// network operator, etc). When set to true, it is installed into /product (or
239	// /system/product if product partition does not exist).
240	Product_specific *bool
241
242	// init.rc files to be installed if this module is installed
243	Init_rc []string
244
245	// names of other modules to install if this module is installed
246	Required []string `android:"arch_variant"`
247
248	// relative path to a file to include in the list of notices for the device
249	Notice *string
250
251	// Set by TargetMutator
252	CompileTarget  Target `blueprint:"mutated"`
253	CompilePrimary bool   `blueprint:"mutated"`
254
255	// Set by InitAndroidModule
256	HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
257	ArchSpecific          bool                  `blueprint:"mutated"`
258
259	SkipInstall bool `blueprint:"mutated"`
260
261	NamespaceExportedToMake bool `blueprint:"mutated"`
262}
263
264type hostAndDeviceProperties struct {
265	Host_supported   *bool
266	Device_supported *bool
267}
268
269type Multilib string
270
271const (
272	MultilibBoth        Multilib = "both"
273	MultilibFirst       Multilib = "first"
274	MultilibCommon      Multilib = "common"
275	MultilibCommonFirst Multilib = "common_first"
276	MultilibDefault     Multilib = ""
277)
278
279type HostOrDeviceSupported int
280
281const (
282	_ HostOrDeviceSupported = iota
283	HostSupported
284	HostSupportedNoCross
285	DeviceSupported
286	HostAndDeviceSupported
287	HostAndDeviceDefault
288	NeitherHostNorDeviceSupported
289)
290
291type moduleKind int
292
293const (
294	platformModule moduleKind = iota
295	deviceSpecificModule
296	socSpecificModule
297	productSpecificModule
298)
299
300func (k moduleKind) String() string {
301	switch k {
302	case platformModule:
303		return "platform"
304	case deviceSpecificModule:
305		return "device-specific"
306	case socSpecificModule:
307		return "soc-specific"
308	case productSpecificModule:
309		return "product-specific"
310	default:
311		panic(fmt.Errorf("unknown module kind %d", k))
312	}
313}
314
315func InitAndroidModule(m Module) {
316	base := m.base()
317	base.module = m
318
319	m.AddProperties(
320		&base.nameProperties,
321		&base.commonProperties,
322		&base.variableProperties)
323}
324
325func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
326	InitAndroidModule(m)
327
328	base := m.base()
329	base.commonProperties.HostOrDeviceSupported = hod
330	base.commonProperties.Default_multilib = string(defaultMultilib)
331	base.commonProperties.ArchSpecific = true
332
333	switch hod {
334	case HostAndDeviceSupported, HostAndDeviceDefault:
335		m.AddProperties(&base.hostAndDeviceProperties)
336	}
337
338	InitArchModule(m)
339}
340
341// A ModuleBase object contains the properties that are common to all Android
342// modules.  It should be included as an anonymous field in every module
343// struct definition.  InitAndroidModule should then be called from the module's
344// factory function, and the return values from InitAndroidModule should be
345// returned from the factory function.
346//
347// The ModuleBase type is responsible for implementing the GenerateBuildActions
348// method to support the blueprint.Module interface. This method will then call
349// the module's GenerateAndroidBuildActions method once for each build variant
350// that is to be built. GenerateAndroidBuildActions is passed a
351// AndroidModuleContext rather than the usual blueprint.ModuleContext.
352// AndroidModuleContext exposes extra functionality specific to the Android build
353// system including details about the particular build variant that is to be
354// generated.
355//
356// For example:
357//
358//     import (
359//         "android/soong/android"
360//     )
361//
362//     type myModule struct {
363//         android.ModuleBase
364//         properties struct {
365//             MyProperty string
366//         }
367//     }
368//
369//     func NewMyModule() android.Module) {
370//         m := &myModule{}
371//         m.AddProperties(&m.properties)
372//         android.InitAndroidModule(m)
373//         return m
374//     }
375//
376//     func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
377//         // Get the CPU architecture for the current build variant.
378//         variantArch := ctx.Arch()
379//
380//         // ...
381//     }
382type ModuleBase struct {
383	// Putting the curiously recurring thing pointing to the thing that contains
384	// the thing pattern to good use.
385	// TODO: remove this
386	module Module
387
388	nameProperties          nameProperties
389	commonProperties        commonProperties
390	variableProperties      variableProperties
391	hostAndDeviceProperties hostAndDeviceProperties
392	generalProperties       []interface{}
393	archProperties          []interface{}
394	customizableProperties  []interface{}
395
396	noAddressSanitizer bool
397	installFiles       Paths
398	checkbuildFiles    Paths
399
400	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
401	// Only set on the final variant of each module
402	installTarget    WritablePath
403	checkbuildTarget WritablePath
404	blueprintDir     string
405
406	hooks hooks
407
408	registerProps []interface{}
409
410	// For tests
411	buildParams []BuildParams
412}
413
414func (a *ModuleBase) AddProperties(props ...interface{}) {
415	a.registerProps = append(a.registerProps, props...)
416}
417
418func (a *ModuleBase) GetProperties() []interface{} {
419	return a.registerProps
420}
421
422func (a *ModuleBase) BuildParamsForTests() []BuildParams {
423	return a.buildParams
424}
425
426// Name returns the name of the module.  It may be overridden by individual module types, for
427// example prebuilts will prepend prebuilt_ to the name.
428func (a *ModuleBase) Name() string {
429	return String(a.nameProperties.Name)
430}
431
432// BaseModuleName returns the name of the module as specified in the blueprints file.
433func (a *ModuleBase) BaseModuleName() string {
434	return String(a.nameProperties.Name)
435}
436
437func (a *ModuleBase) base() *ModuleBase {
438	return a
439}
440
441func (a *ModuleBase) SetTarget(target Target, primary bool) {
442	a.commonProperties.CompileTarget = target
443	a.commonProperties.CompilePrimary = primary
444}
445
446func (a *ModuleBase) Target() Target {
447	return a.commonProperties.CompileTarget
448}
449
450func (a *ModuleBase) TargetPrimary() bool {
451	return a.commonProperties.CompilePrimary
452}
453
454func (a *ModuleBase) Os() OsType {
455	return a.Target().Os
456}
457
458func (a *ModuleBase) Host() bool {
459	return a.Os().Class == Host || a.Os().Class == HostCross
460}
461
462func (a *ModuleBase) Arch() Arch {
463	return a.Target().Arch
464}
465
466func (a *ModuleBase) ArchSpecific() bool {
467	return a.commonProperties.ArchSpecific
468}
469
470func (a *ModuleBase) OsClassSupported() []OsClass {
471	switch a.commonProperties.HostOrDeviceSupported {
472	case HostSupported:
473		return []OsClass{Host, HostCross}
474	case HostSupportedNoCross:
475		return []OsClass{Host}
476	case DeviceSupported:
477		return []OsClass{Device}
478	case HostAndDeviceSupported:
479		var supported []OsClass
480		if Bool(a.hostAndDeviceProperties.Host_supported) {
481			supported = append(supported, Host, HostCross)
482		}
483		if a.hostAndDeviceProperties.Device_supported == nil ||
484			*a.hostAndDeviceProperties.Device_supported {
485			supported = append(supported, Device)
486		}
487		return supported
488	default:
489		return nil
490	}
491}
492
493func (a *ModuleBase) DeviceSupported() bool {
494	return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
495		a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
496			(a.hostAndDeviceProperties.Device_supported == nil ||
497				*a.hostAndDeviceProperties.Device_supported)
498}
499
500func (a *ModuleBase) Enabled() bool {
501	if a.commonProperties.Enabled == nil {
502		return !a.Os().DefaultDisabled
503	}
504	return *a.commonProperties.Enabled
505}
506
507func (a *ModuleBase) SkipInstall() {
508	a.commonProperties.SkipInstall = true
509}
510
511func (a *ModuleBase) ExportedToMake() bool {
512	return a.commonProperties.NamespaceExportedToMake
513}
514
515func (a *ModuleBase) computeInstallDeps(
516	ctx blueprint.ModuleContext) Paths {
517
518	result := Paths{}
519	ctx.VisitDepsDepthFirstIf(isFileInstaller,
520		func(m blueprint.Module) {
521			fileInstaller := m.(fileInstaller)
522			files := fileInstaller.filesToInstall()
523			result = append(result, files...)
524		})
525
526	return result
527}
528
529func (a *ModuleBase) filesToInstall() Paths {
530	return a.installFiles
531}
532
533func (p *ModuleBase) NoAddressSanitizer() bool {
534	return p.noAddressSanitizer
535}
536
537func (p *ModuleBase) InstallInData() bool {
538	return false
539}
540
541func (p *ModuleBase) InstallInSanitizerDir() bool {
542	return false
543}
544
545func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
546	allInstalledFiles := Paths{}
547	allCheckbuildFiles := Paths{}
548	ctx.VisitAllModuleVariants(func(module Module) {
549		a := module.base()
550		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
551		allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
552	})
553
554	var deps Paths
555
556	namespacePrefix := ctx.Namespace().(*Namespace).id
557	if namespacePrefix != "" {
558		namespacePrefix = namespacePrefix + "-"
559	}
560
561	if len(allInstalledFiles) > 0 {
562		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
563		ctx.Build(pctx, BuildParams{
564			Rule:      blueprint.Phony,
565			Output:    name,
566			Implicits: allInstalledFiles,
567			Default:   !ctx.Config().EmbeddedInMake(),
568		})
569		deps = append(deps, name)
570		a.installTarget = name
571	}
572
573	if len(allCheckbuildFiles) > 0 {
574		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
575		ctx.Build(pctx, BuildParams{
576			Rule:      blueprint.Phony,
577			Output:    name,
578			Implicits: allCheckbuildFiles,
579		})
580		deps = append(deps, name)
581		a.checkbuildTarget = name
582	}
583
584	if len(deps) > 0 {
585		suffix := ""
586		if ctx.Config().EmbeddedInMake() {
587			suffix = "-soong"
588		}
589
590		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
591		ctx.Build(pctx, BuildParams{
592			Rule:      blueprint.Phony,
593			Outputs:   []WritablePath{name},
594			Implicits: deps,
595		})
596
597		a.blueprintDir = ctx.ModuleDir()
598	}
599}
600
601func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
602	var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
603	var deviceSpecific = Bool(a.commonProperties.Device_specific)
604	var productSpecific = Bool(a.commonProperties.Product_specific)
605
606	if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
607		msg := "conflicting value set here"
608		if productSpecific {
609			ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
610			if deviceSpecific {
611				ctx.PropertyErrorf("device_specific", msg)
612			}
613		} else {
614			ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
615		}
616		if Bool(a.commonProperties.Vendor) {
617			ctx.PropertyErrorf("vendor", msg)
618		}
619		if Bool(a.commonProperties.Proprietary) {
620			ctx.PropertyErrorf("proprietary", msg)
621		}
622		if Bool(a.commonProperties.Soc_specific) {
623			ctx.PropertyErrorf("soc_specific", msg)
624		}
625	}
626
627	if productSpecific {
628		return productSpecificModule
629	} else if deviceSpecific {
630		return deviceSpecificModule
631	} else if socSpecific {
632		return socSpecificModule
633	} else {
634		return platformModule
635	}
636}
637
638func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
639	return androidBaseContextImpl{
640		target:        a.commonProperties.CompileTarget,
641		targetPrimary: a.commonProperties.CompilePrimary,
642		kind:          determineModuleKind(a, ctx),
643		config:        ctx.Config().(Config),
644	}
645}
646
647func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
648	ctx := &androidModuleContext{
649		module:                 a.module,
650		ModuleContext:          blueprintCtx,
651		androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
652		installDeps:            a.computeInstallDeps(blueprintCtx),
653		installFiles:           a.installFiles,
654		missingDeps:            blueprintCtx.GetMissingDependencies(),
655	}
656
657	desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
658	var suffix []string
659	if ctx.Os().Class != Device && ctx.Os().Class != Generic {
660		suffix = append(suffix, ctx.Os().String())
661	}
662	if !ctx.PrimaryArch() {
663		suffix = append(suffix, ctx.Arch().ArchType.String())
664	}
665
666	ctx.Variable(pctx, "moduleDesc", desc)
667
668	s := ""
669	if len(suffix) > 0 {
670		s = " [" + strings.Join(suffix, " ") + "]"
671	}
672	ctx.Variable(pctx, "moduleDescSuffix", s)
673
674	if a.Enabled() {
675		a.module.GenerateAndroidBuildActions(ctx)
676		if ctx.Failed() {
677			return
678		}
679
680		a.installFiles = append(a.installFiles, ctx.installFiles...)
681		a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
682	}
683
684	if a == ctx.FinalModule().(Module).base() {
685		a.generateModuleTarget(ctx)
686		if ctx.Failed() {
687			return
688		}
689	}
690
691	a.buildParams = ctx.buildParams
692}
693
694type androidBaseContextImpl struct {
695	target        Target
696	targetPrimary bool
697	debug         bool
698	kind          moduleKind
699	config        Config
700}
701
702type androidModuleContext struct {
703	blueprint.ModuleContext
704	androidBaseContextImpl
705	installDeps     Paths
706	installFiles    Paths
707	checkbuildFiles Paths
708	missingDeps     []string
709	module          Module
710
711	// For tests
712	buildParams []BuildParams
713}
714
715func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
716	a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
717		Rule:        ErrorRule,
718		Description: desc,
719		Outputs:     outputs,
720		Optional:    true,
721		Args: map[string]string{
722			"error": err.Error(),
723		},
724	})
725	return
726}
727
728func (a *androidModuleContext) Config() Config {
729	return a.ModuleContext.Config().(Config)
730}
731
732func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
733	a.Build(pctx, BuildParams(params))
734}
735
736func convertBuildParams(params BuildParams) blueprint.BuildParams {
737	bparams := blueprint.BuildParams{
738		Rule:            params.Rule,
739		Description:     params.Description,
740		Deps:            params.Deps,
741		Outputs:         params.Outputs.Strings(),
742		ImplicitOutputs: params.ImplicitOutputs.Strings(),
743		Inputs:          params.Inputs.Strings(),
744		Implicits:       params.Implicits.Strings(),
745		OrderOnly:       params.OrderOnly.Strings(),
746		Args:            params.Args,
747		Optional:        !params.Default,
748	}
749
750	if params.Depfile != nil {
751		bparams.Depfile = params.Depfile.String()
752	}
753	if params.Output != nil {
754		bparams.Outputs = append(bparams.Outputs, params.Output.String())
755	}
756	if params.ImplicitOutput != nil {
757		bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
758	}
759	if params.Input != nil {
760		bparams.Inputs = append(bparams.Inputs, params.Input.String())
761	}
762	if params.Implicit != nil {
763		bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
764	}
765
766	return bparams
767}
768
769func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
770	a.ModuleContext.Variable(pctx.PackageContext, name, value)
771}
772
773func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
774	argNames ...string) blueprint.Rule {
775
776	return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
777}
778
779func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
780	if a.config.captureBuild {
781		a.buildParams = append(a.buildParams, params)
782	}
783
784	bparams := convertBuildParams(params)
785
786	if bparams.Description != "" {
787		bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
788	}
789
790	if a.missingDeps != nil {
791		a.ninjaError(bparams.Description, bparams.Outputs,
792			fmt.Errorf("module %s missing dependencies: %s\n",
793				a.ModuleName(), strings.Join(a.missingDeps, ", ")))
794		return
795	}
796
797	a.ModuleContext.Build(pctx.PackageContext, bparams)
798}
799
800func (a *androidModuleContext) GetMissingDependencies() []string {
801	return a.missingDeps
802}
803
804func (a *androidModuleContext) AddMissingDependencies(deps []string) {
805	if deps != nil {
806		a.missingDeps = append(a.missingDeps, deps...)
807		a.missingDeps = FirstUniqueStrings(a.missingDeps)
808	}
809}
810
811func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
812	aModule, _ := module.(Module)
813	if aModule == nil {
814		a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
815		return nil
816	}
817
818	if !aModule.Enabled() {
819		if a.Config().AllowMissingDependencies() {
820			a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
821		} else {
822			a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
823		}
824		return nil
825	}
826
827	return aModule
828}
829
830func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
831	a.ModuleContext.VisitDirectDeps(visit)
832}
833
834func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
835	a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
836		if aModule := a.validateAndroidModule(module); aModule != nil {
837			visit(aModule)
838		}
839	})
840}
841
842func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
843	a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
844		if aModule := a.validateAndroidModule(module); aModule != nil {
845			if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
846				visit(aModule)
847			}
848		}
849	})
850}
851
852func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
853	a.ModuleContext.VisitDirectDepsIf(
854		// pred
855		func(module blueprint.Module) bool {
856			if aModule := a.validateAndroidModule(module); aModule != nil {
857				return pred(aModule)
858			} else {
859				return false
860			}
861		},
862		// visit
863		func(module blueprint.Module) {
864			visit(module.(Module))
865		})
866}
867
868func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
869	a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
870		if aModule := a.validateAndroidModule(module); aModule != nil {
871			visit(aModule)
872		}
873	})
874}
875
876func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
877	a.ModuleContext.VisitDepsDepthFirstIf(
878		// pred
879		func(module blueprint.Module) bool {
880			if aModule := a.validateAndroidModule(module); aModule != nil {
881				return pred(aModule)
882			} else {
883				return false
884			}
885		},
886		// visit
887		func(module blueprint.Module) {
888			visit(module.(Module))
889		})
890}
891
892func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
893	a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
894		childAndroidModule := a.validateAndroidModule(child)
895		parentAndroidModule := a.validateAndroidModule(parent)
896		if childAndroidModule != nil && parentAndroidModule != nil {
897			return visit(childAndroidModule, parentAndroidModule)
898		} else {
899			return false
900		}
901	})
902}
903
904func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
905	a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
906		visit(module.(Module))
907	})
908}
909
910func (a *androidModuleContext) PrimaryModule() Module {
911	return a.ModuleContext.PrimaryModule().(Module)
912}
913
914func (a *androidModuleContext) FinalModule() Module {
915	return a.ModuleContext.FinalModule().(Module)
916}
917
918func (a *androidBaseContextImpl) Target() Target {
919	return a.target
920}
921
922func (a *androidBaseContextImpl) TargetPrimary() bool {
923	return a.targetPrimary
924}
925
926func (a *androidBaseContextImpl) Arch() Arch {
927	return a.target.Arch
928}
929
930func (a *androidBaseContextImpl) Os() OsType {
931	return a.target.Os
932}
933
934func (a *androidBaseContextImpl) Host() bool {
935	return a.target.Os.Class == Host || a.target.Os.Class == HostCross
936}
937
938func (a *androidBaseContextImpl) Device() bool {
939	return a.target.Os.Class == Device
940}
941
942func (a *androidBaseContextImpl) Darwin() bool {
943	return a.target.Os == Darwin
944}
945
946func (a *androidBaseContextImpl) Windows() bool {
947	return a.target.Os == Windows
948}
949
950func (a *androidBaseContextImpl) Debug() bool {
951	return a.debug
952}
953
954func (a *androidBaseContextImpl) PrimaryArch() bool {
955	if len(a.config.Targets[a.target.Os.Class]) <= 1 {
956		return true
957	}
958	return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
959}
960
961func (a *androidBaseContextImpl) AConfig() Config {
962	return a.config
963}
964
965func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
966	return DeviceConfig{a.config.deviceConfig}
967}
968
969func (a *androidBaseContextImpl) Platform() bool {
970	return a.kind == platformModule
971}
972
973func (a *androidBaseContextImpl) DeviceSpecific() bool {
974	return a.kind == deviceSpecificModule
975}
976
977func (a *androidBaseContextImpl) SocSpecific() bool {
978	return a.kind == socSpecificModule
979}
980
981func (a *androidBaseContextImpl) ProductSpecific() bool {
982	return a.kind == productSpecificModule
983}
984
985func (a *androidModuleContext) InstallInData() bool {
986	return a.module.InstallInData()
987}
988
989func (a *androidModuleContext) InstallInSanitizerDir() bool {
990	return a.module.InstallInSanitizerDir()
991}
992
993func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
994	if a.module.base().commonProperties.SkipInstall {
995		return true
996	}
997
998	if a.Device() {
999		if a.Config().SkipDeviceInstall() {
1000			return true
1001		}
1002
1003		if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
1004			return true
1005		}
1006	}
1007
1008	return false
1009}
1010
1011func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
1012	deps ...Path) OutputPath {
1013	return a.installFile(installPath, name, srcPath, Cp, deps)
1014}
1015
1016func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1017	deps ...Path) OutputPath {
1018	return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1019}
1020
1021func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1022	rule blueprint.Rule, deps []Path) OutputPath {
1023
1024	fullInstallPath := installPath.Join(a, name)
1025	a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
1026
1027	if !a.skipInstall(fullInstallPath) {
1028
1029		deps = append(deps, a.installDeps...)
1030
1031		var implicitDeps, orderOnlyDeps Paths
1032
1033		if a.Host() {
1034			// Installed host modules might be used during the build, depend directly on their
1035			// dependencies so their timestamp is updated whenever their dependency is updated
1036			implicitDeps = deps
1037		} else {
1038			orderOnlyDeps = deps
1039		}
1040
1041		a.Build(pctx, BuildParams{
1042			Rule:        rule,
1043			Description: "install " + fullInstallPath.Base(),
1044			Output:      fullInstallPath,
1045			Input:       srcPath,
1046			Implicits:   implicitDeps,
1047			OrderOnly:   orderOnlyDeps,
1048			Default:     !a.Config().EmbeddedInMake(),
1049		})
1050
1051		a.installFiles = append(a.installFiles, fullInstallPath)
1052	}
1053	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1054	return fullInstallPath
1055}
1056
1057func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1058	fullInstallPath := installPath.Join(a, name)
1059	a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
1060
1061	if !a.skipInstall(fullInstallPath) {
1062
1063		a.Build(pctx, BuildParams{
1064			Rule:        Symlink,
1065			Description: "install symlink " + fullInstallPath.Base(),
1066			Output:      fullInstallPath,
1067			OrderOnly:   Paths{srcPath},
1068			Default:     !a.Config().EmbeddedInMake(),
1069			Args: map[string]string{
1070				"fromPath": srcPath.String(),
1071			},
1072		})
1073
1074		a.installFiles = append(a.installFiles, fullInstallPath)
1075		a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1076	}
1077	return fullInstallPath
1078}
1079
1080func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
1081	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1082}
1083
1084type fileInstaller interface {
1085	filesToInstall() Paths
1086}
1087
1088func isFileInstaller(m blueprint.Module) bool {
1089	_, ok := m.(fileInstaller)
1090	return ok
1091}
1092
1093func isAndroidModule(m blueprint.Module) bool {
1094	_, ok := m.(Module)
1095	return ok
1096}
1097
1098func findStringInSlice(str string, slice []string) int {
1099	for i, s := range slice {
1100		if s == str {
1101			return i
1102		}
1103	}
1104	return -1
1105}
1106
1107func SrcIsModule(s string) string {
1108	if len(s) > 1 && s[0] == ':' {
1109		return s[1:]
1110	}
1111	return ""
1112}
1113
1114type sourceDependencyTag struct {
1115	blueprint.BaseDependencyTag
1116}
1117
1118var SourceDepTag sourceDependencyTag
1119
1120// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1121// using ":module" syntax, if any.
1122func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1123	var deps []string
1124	set := make(map[string]bool)
1125
1126	for _, s := range srcFiles {
1127		if m := SrcIsModule(s); m != "" {
1128			if _, found := set[m]; found {
1129				ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1130			} else {
1131				set[m] = true
1132				deps = append(deps, m)
1133			}
1134		}
1135	}
1136
1137	ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1138}
1139
1140// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1141// using ":module" syntax, if any.
1142func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1143	if s != nil {
1144		if m := SrcIsModule(*s); m != "" {
1145			ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1146		}
1147	}
1148}
1149
1150type SourceFileProducer interface {
1151	Srcs() Paths
1152}
1153
1154// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
1155// ExtractSourcesDeps must have already been called during the dependency resolution phase.
1156func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
1157	return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1158}
1159
1160// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1161// ExtractSourceDeps must have already been called during the dependency resolution phase.
1162func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1163	srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1164	if len(srcFiles) == 1 {
1165		return srcFiles[0]
1166	} else {
1167		ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1168		return nil
1169	}
1170}
1171
1172// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1173// the srcFile is non-nil.
1174// ExtractSourceDeps must have already been called during the dependency resolution phase.
1175func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1176	if srcFile != nil {
1177		return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1178	}
1179	return OptionalPath{}
1180}
1181
1182func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
1183	prefix := PathForModuleSrc(ctx).String()
1184
1185	var expandedExcludes []string
1186	if excludes != nil {
1187		expandedExcludes = make([]string, 0, len(excludes))
1188	}
1189
1190	for _, e := range excludes {
1191		if m := SrcIsModule(e); m != "" {
1192			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1193			if module == nil {
1194				// Error will have been handled by ExtractSourcesDeps
1195				continue
1196			}
1197			if srcProducer, ok := module.(SourceFileProducer); ok {
1198				expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1199			} else {
1200				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1201			}
1202		} else {
1203			expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
1204		}
1205	}
1206	expandedSrcFiles := make(Paths, 0, len(srcFiles))
1207	for _, s := range srcFiles {
1208		if m := SrcIsModule(s); m != "" {
1209			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1210			if module == nil {
1211				// Error will have been handled by ExtractSourcesDeps
1212				continue
1213			}
1214			if srcProducer, ok := module.(SourceFileProducer); ok {
1215				moduleSrcs := srcProducer.Srcs()
1216				for _, e := range expandedExcludes {
1217					for j, ms := range moduleSrcs {
1218						if ms.String() == e {
1219							moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1220						}
1221					}
1222				}
1223				expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
1224			} else {
1225				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1226			}
1227		} else if pathtools.IsGlob(s) {
1228			globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
1229			for i, s := range globbedSrcFiles {
1230				globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
1231			}
1232			expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
1233		} else {
1234			p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1235			j := findStringInSlice(p.String(), expandedExcludes)
1236			if j == -1 {
1237				expandedSrcFiles = append(expandedSrcFiles, p)
1238			}
1239
1240		}
1241	}
1242	return expandedSrcFiles
1243}
1244
1245func (ctx *androidModuleContext) RequiredModuleNames() []string {
1246	return ctx.module.base().commonProperties.Required
1247}
1248
1249func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1250	ret, err := ctx.GlobWithDeps(globPattern, excludes)
1251	if err != nil {
1252		ctx.ModuleErrorf("glob: %s", err.Error())
1253	}
1254	return pathsForModuleSrcFromFullPath(ctx, ret, true)
1255}
1256
1257func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
1258	ret, err := ctx.GlobWithDeps(globPattern, excludes)
1259	if err != nil {
1260		ctx.ModuleErrorf("glob: %s", err.Error())
1261	}
1262	return pathsForModuleSrcFromFullPath(ctx, ret, false)
1263}
1264
1265func init() {
1266	RegisterSingletonType("buildtarget", BuildTargetSingleton)
1267}
1268
1269func BuildTargetSingleton() Singleton {
1270	return &buildTargetSingleton{}
1271}
1272
1273func parentDir(dir string) string {
1274	dir, _ = filepath.Split(dir)
1275	return filepath.Clean(dir)
1276}
1277
1278type buildTargetSingleton struct{}
1279
1280func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1281	var checkbuildDeps Paths
1282
1283	mmTarget := func(dir string) WritablePath {
1284		return PathForPhony(ctx,
1285			"MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
1286	}
1287
1288	modulesInDir := make(map[string]Paths)
1289
1290	ctx.VisitAllModules(func(module Module) {
1291		blueprintDir := module.base().blueprintDir
1292		installTarget := module.base().installTarget
1293		checkbuildTarget := module.base().checkbuildTarget
1294
1295		if checkbuildTarget != nil {
1296			checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1297			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1298		}
1299
1300		if installTarget != nil {
1301			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
1302		}
1303	})
1304
1305	suffix := ""
1306	if ctx.Config().EmbeddedInMake() {
1307		suffix = "-soong"
1308	}
1309
1310	// Create a top-level checkbuild target that depends on all modules
1311	ctx.Build(pctx, BuildParams{
1312		Rule:      blueprint.Phony,
1313		Output:    PathForPhony(ctx, "checkbuild"+suffix),
1314		Implicits: checkbuildDeps,
1315	})
1316
1317	// Make will generate the MODULES-IN-* targets
1318	if ctx.Config().EmbeddedInMake() {
1319		return
1320	}
1321
1322	sortedKeys := func(m map[string]Paths) []string {
1323		s := make([]string, 0, len(m))
1324		for k := range m {
1325			s = append(s, k)
1326		}
1327		sort.Strings(s)
1328		return s
1329	}
1330
1331	// Ensure ancestor directories are in modulesInDir
1332	dirs := sortedKeys(modulesInDir)
1333	for _, dir := range dirs {
1334		dir := parentDir(dir)
1335		for dir != "." && dir != "/" {
1336			if _, exists := modulesInDir[dir]; exists {
1337				break
1338			}
1339			modulesInDir[dir] = nil
1340			dir = parentDir(dir)
1341		}
1342	}
1343
1344	// Make directories build their direct subdirectories
1345	dirs = sortedKeys(modulesInDir)
1346	for _, dir := range dirs {
1347		p := parentDir(dir)
1348		if p != "." && p != "/" {
1349			modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1350		}
1351	}
1352
1353	// Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1354	// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1355	// files.
1356	for _, dir := range dirs {
1357		ctx.Build(pctx, BuildParams{
1358			Rule:      blueprint.Phony,
1359			Output:    mmTarget(dir),
1360			Implicits: modulesInDir[dir],
1361			// HACK: checkbuild should be an optional build, but force it
1362			// enabled for now in standalone builds
1363			Default: !ctx.Config().EmbeddedInMake(),
1364		})
1365	}
1366
1367	// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1368	osDeps := map[OsType]Paths{}
1369	ctx.VisitAllModules(func(module Module) {
1370		if module.Enabled() {
1371			os := module.Target().Os
1372			osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
1373		}
1374	})
1375
1376	osClass := make(map[string]Paths)
1377	for os, deps := range osDeps {
1378		var className string
1379
1380		switch os.Class {
1381		case Host:
1382			className = "host"
1383		case HostCross:
1384			className = "host-cross"
1385		case Device:
1386			className = "target"
1387		default:
1388			continue
1389		}
1390
1391		name := PathForPhony(ctx, className+"-"+os.Name)
1392		osClass[className] = append(osClass[className], name)
1393
1394		ctx.Build(pctx, BuildParams{
1395			Rule:      blueprint.Phony,
1396			Output:    name,
1397			Implicits: deps,
1398		})
1399	}
1400
1401	// Wrap those into host|host-cross|target phony rules
1402	osClasses := sortedKeys(osClass)
1403	for _, class := range osClasses {
1404		ctx.Build(pctx, BuildParams{
1405			Rule:      blueprint.Phony,
1406			Output:    PathForPhony(ctx, class),
1407			Implicits: osClass[class],
1408		})
1409	}
1410}
1411
1412type AndroidModulesByName struct {
1413	slice []Module
1414	ctx   interface {
1415		ModuleName(blueprint.Module) string
1416		ModuleSubDir(blueprint.Module) string
1417	}
1418}
1419
1420func (s AndroidModulesByName) Len() int { return len(s.slice) }
1421func (s AndroidModulesByName) Less(i, j int) bool {
1422	mi, mj := s.slice[i], s.slice[j]
1423	ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1424
1425	if ni != nj {
1426		return ni < nj
1427	} else {
1428		return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1429	}
1430}
1431func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }
1432