blob: 865764f58fca384f328e0a4c9cf44b5251985bde [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross6ff51382015-12-17 16:39:19 -080018 "fmt"
Colin Cross3f40fa42015-01-30 17:27:36 -080019 "path/filepath"
Colin Cross0875c522017-11-28 17:34:01 -080020 "sort"
Colin Cross6ff51382015-12-17 16:39:19 -080021 "strings"
Colin Crossaabf6792017-11-29 00:27:14 -080022 "text/scanner"
Colin Crossf6566ed2015-03-24 11:13:38 -070023
24 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070025 "github.com/google/blueprint/pathtools"
Colin Cross3f40fa42015-01-30 17:27:36 -080026)
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
Colin Crossae887032017-10-23 17:16:14 -070037type BuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070038 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080039 Deps blueprint.Deps
40 Depfile WritablePath
Colin Cross67a5c132017-05-09 13:45:28 -070041 Description string
Dan Willemsen9f3c5742016-11-03 14:28:31 -070042 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
Dan Willemsen34cc69e2015-09-23 15:26:20 -070053}
54
Colin Crossae887032017-10-23 17:16:14 -070055type ModuleBuildParams BuildParams
56
Colin Crossf6566ed2015-03-24 11:13:38 -070057type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070058 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070059 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070061 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070062 Host() bool
63 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070064 Darwin() bool
Colin Cross3edeee12017-04-04 12:59:48 -070065 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070066 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070067 PrimaryArch() bool
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070068 InstallOnVendorPartition() bool
Colin Cross1332b002015-04-07 17:11:30 -070069 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070070 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070071}
72
Colin Cross635c3b02016-05-18 15:37:25 -070073type BaseContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -080074 BaseModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070075 androidBaseContext
76}
77
Colin Crossaabf6792017-11-29 00:27:14 -080078// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
79// a Config instead of an interface{}.
80type BaseModuleContext interface {
81 ModuleName() string
82 ModuleDir() string
83 Config() Config
84
85 ContainsProperty(name string) bool
86 Errorf(pos scanner.Position, fmt string, args ...interface{})
87 ModuleErrorf(fmt string, args ...interface{})
88 PropertyErrorf(property, fmt string, args ...interface{})
89 Failed() bool
90
91 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
92 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
93 // builder whenever a file matching the pattern as added or removed, without rerunning if a
94 // file that does not match the pattern is added to a searched directory.
95 GlobWithDeps(pattern string, excludes []string) ([]string, error)
96
97 Fs() pathtools.FileSystem
98 AddNinjaFileDeps(deps ...string)
99}
100
Colin Cross635c3b02016-05-18 15:37:25 -0700101type ModuleContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -0700102 androidBaseContext
Colin Crossaabf6792017-11-29 00:27:14 -0800103 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800104
Colin Crossae887032017-10-23 17:16:14 -0700105 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800106 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700107
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700108 ExpandSources(srcFiles, excludes []string) Paths
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800109 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -0700110 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700111
Colin Cross5c517922017-08-31 12:29:17 -0700112 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
113 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800114 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700115 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800116
117 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700118
Colin Cross8d8f8e22016-08-03 11:57:50 -0700119 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700120 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800121
122 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700123
124 // android.ModuleContext methods
125 // These are duplicated instead of embedded so that can eventually be wrapped to take an
126 // android.Module instead of a blueprint.Module
127 OtherModuleName(m blueprint.Module) string
128 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
129 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
130
131 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
132 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
133
134 ModuleSubDir() string
135
Colin Cross35143d02017-11-16 00:11:20 -0800136 VisitDirectDepsBlueprint(visit func(blueprint.Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700137 VisitDirectDeps(visit func(Module))
138 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
139 VisitDepsDepthFirst(visit func(Module))
140 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
141 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700142
Colin Cross0875c522017-11-28 17:34:01 -0800143 Variable(pctx PackageContext, name, value string)
144 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700145 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
146 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800147 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700148
Colin Cross0875c522017-11-28 17:34:01 -0800149 PrimaryModule() Module
150 FinalModule() Module
151 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700152
153 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800154 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800155}
156
Colin Cross635c3b02016-05-18 15:37:25 -0700157type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800158 blueprint.Module
159
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700160 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
161 // but GenerateAndroidBuildActions also has access to Android-specific information.
162 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700163 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700164
Colin Cross1e676be2016-10-12 14:38:15 -0700165 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800166
Colin Cross635c3b02016-05-18 15:37:25 -0700167 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800168 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700169 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800170 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700171 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800172 SkipInstall()
Colin Cross36242852017-06-23 15:06:31 -0700173
174 AddProperties(props ...interface{})
175 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700176
Colin Crossae887032017-10-23 17:16:14 -0700177 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800178}
179
Colin Crossfc754582016-05-17 16:34:16 -0700180type nameProperties struct {
181 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800182 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700183}
184
185type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700186 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800187
Dan Willemsen0effe062015-11-30 16:06:01 -0800188 // emit build rules for this module
189 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800190
Colin Cross7d5136f2015-05-11 13:39:40 -0700191 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800192 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
193 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
194 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700195 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700196
197 Target struct {
198 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700199 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700200 }
201 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700202 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700203 }
204 }
205
206 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800207
Dan Willemsen782a2d12015-12-21 14:55:28 -0800208 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700209 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800210
Colin Cross55708f32017-03-20 13:23:34 -0700211 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700212 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700213
Dan Willemsenaa118f92017-04-06 12:49:58 -0700214 // whether this module is device specific and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700215 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700216
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700217 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
218 // file
219 Logtags []string
220
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700221 // init.rc files to be installed if this module is installed
222 Init_rc []string
223
Chris Wolfe998306e2016-08-15 14:47:23 -0400224 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700225 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400226
Colin Cross5aac3622017-08-31 15:07:09 -0700227 // relative path to a file to include in the list of notices for the device
228 Notice *string
229
Colin Crossa1ad8d12016-06-01 17:09:44 -0700230 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700231 CompileTarget Target `blueprint:"mutated"`
232 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800233
234 // Set by InitAndroidModule
235 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700236 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700237
238 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800239
240 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800241}
242
243type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700244 Host_supported *bool
245 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800246}
247
Colin Crossc472d572015-03-17 15:06:21 -0700248type Multilib string
249
250const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800251 MultilibBoth Multilib = "both"
252 MultilibFirst Multilib = "first"
253 MultilibCommon Multilib = "common"
254 MultilibCommonFirst Multilib = "common_first"
255 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700256)
257
Colin Crossa1ad8d12016-06-01 17:09:44 -0700258type HostOrDeviceSupported int
259
260const (
261 _ HostOrDeviceSupported = iota
262 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700263 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700264 DeviceSupported
265 HostAndDeviceSupported
266 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700267 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700268)
269
Colin Cross36242852017-06-23 15:06:31 -0700270func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800271 base := m.base()
272 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700273
Colin Cross36242852017-06-23 15:06:31 -0700274 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700275 &base.nameProperties,
276 &base.commonProperties,
277 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700278}
279
Colin Cross36242852017-06-23 15:06:31 -0700280func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
281 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700282
283 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800284 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700285 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700286 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800287
Dan Willemsen218f6562015-07-08 18:13:11 -0700288 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700289 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700290 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800291 }
292
Colin Cross36242852017-06-23 15:06:31 -0700293 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800294}
295
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800296// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800297// modules. It should be included as an anonymous field in every module
298// struct definition. InitAndroidModule should then be called from the module's
299// factory function, and the return values from InitAndroidModule should be
300// returned from the factory function.
301//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800302// The ModuleBase type is responsible for implementing the GenerateBuildActions
303// method to support the blueprint.Module interface. This method will then call
304// the module's GenerateAndroidBuildActions method once for each build variant
305// that is to be built. GenerateAndroidBuildActions is passed a
306// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800307// AndroidModuleContext exposes extra functionality specific to the Android build
308// system including details about the particular build variant that is to be
309// generated.
310//
311// For example:
312//
313// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800314// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800315// )
316//
317// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800318// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800319// properties struct {
320// MyProperty string
321// }
322// }
323//
Colin Cross36242852017-06-23 15:06:31 -0700324// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800325// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700326// m.AddProperties(&m.properties)
327// android.InitAndroidModule(m)
328// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800329// }
330//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800331// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800332// // Get the CPU architecture for the current build variant.
333// variantArch := ctx.Arch()
334//
335// // ...
336// }
Colin Cross635c3b02016-05-18 15:37:25 -0700337type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800338 // Putting the curiously recurring thing pointing to the thing that contains
339 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700340 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700341 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800342
Colin Crossfc754582016-05-17 16:34:16 -0700343 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800344 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700345 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800346 hostAndDeviceProperties hostAndDeviceProperties
347 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700348 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700349 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800350
351 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700352 installFiles Paths
353 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700354
355 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
356 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800357 installTarget WritablePath
358 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700359 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700360
Colin Cross178a5092016-09-13 13:42:32 -0700361 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700362
363 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700364
365 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700366 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700367}
368
369func (a *ModuleBase) AddProperties(props ...interface{}) {
370 a.registerProps = append(a.registerProps, props...)
371}
372
373func (a *ModuleBase) GetProperties() []interface{} {
374 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800375}
376
Colin Crossae887032017-10-23 17:16:14 -0700377func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700378 return a.buildParams
379}
380
Colin Crossce75d2c2016-10-06 16:12:58 -0700381// Name returns the name of the module. It may be overridden by individual module types, for
382// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700383func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800384 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700385}
386
Colin Crossce75d2c2016-10-06 16:12:58 -0700387// BaseModuleName returns the name of the module as specified in the blueprints file.
388func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800389 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700390}
391
Colin Cross635c3b02016-05-18 15:37:25 -0700392func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800393 return a
394}
395
Colin Cross8b74d172016-09-13 09:59:14 -0700396func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700397 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700398 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700399}
400
Colin Crossa1ad8d12016-06-01 17:09:44 -0700401func (a *ModuleBase) Target() Target {
402 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800403}
404
Colin Cross8b74d172016-09-13 09:59:14 -0700405func (a *ModuleBase) TargetPrimary() bool {
406 return a.commonProperties.CompilePrimary
407}
408
Colin Crossa1ad8d12016-06-01 17:09:44 -0700409func (a *ModuleBase) Os() OsType {
410 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800411}
412
Colin Cross635c3b02016-05-18 15:37:25 -0700413func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700414 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800415}
416
Colin Cross635c3b02016-05-18 15:37:25 -0700417func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700418 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800419}
420
Dan Willemsen0b24c742016-10-04 15:13:37 -0700421func (a *ModuleBase) ArchSpecific() bool {
422 return a.commonProperties.ArchSpecific
423}
424
Colin Crossa1ad8d12016-06-01 17:09:44 -0700425func (a *ModuleBase) OsClassSupported() []OsClass {
426 switch a.commonProperties.HostOrDeviceSupported {
427 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700428 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700429 case HostSupportedNoCross:
430 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700431 case DeviceSupported:
432 return []OsClass{Device}
433 case HostAndDeviceSupported:
434 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700435 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700436 supported = append(supported, Host, HostCross)
437 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700438 if a.hostAndDeviceProperties.Device_supported == nil ||
439 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700440 supported = append(supported, Device)
441 }
442 return supported
443 default:
444 return nil
445 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800446}
447
Colin Cross635c3b02016-05-18 15:37:25 -0700448func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800449 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
450 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700451 (a.hostAndDeviceProperties.Device_supported == nil ||
452 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800453}
454
Colin Cross635c3b02016-05-18 15:37:25 -0700455func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800456 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800457 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800458 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800459 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800460}
461
Colin Crossce75d2c2016-10-06 16:12:58 -0700462func (a *ModuleBase) SkipInstall() {
463 a.commonProperties.SkipInstall = true
464}
465
Colin Cross635c3b02016-05-18 15:37:25 -0700466func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700467 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800468
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700469 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800470 ctx.VisitDepsDepthFirstIf(isFileInstaller,
471 func(m blueprint.Module) {
472 fileInstaller := m.(fileInstaller)
473 files := fileInstaller.filesToInstall()
474 result = append(result, files...)
475 })
476
477 return result
478}
479
Colin Cross635c3b02016-05-18 15:37:25 -0700480func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800481 return a.installFiles
482}
483
Colin Cross635c3b02016-05-18 15:37:25 -0700484func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800485 return p.noAddressSanitizer
486}
487
Colin Cross635c3b02016-05-18 15:37:25 -0700488func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800489 return false
490}
491
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700492func (p *ModuleBase) InstallInSanitizerDir() bool {
493 return false
494}
495
Colin Cross0875c522017-11-28 17:34:01 -0800496func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700497 allInstalledFiles := Paths{}
498 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800499 ctx.VisitAllModuleVariants(func(module Module) {
500 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700501 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
502 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800503 })
504
Colin Cross0875c522017-11-28 17:34:01 -0800505 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700506
Jeff Gaston088e29e2017-11-29 16:47:17 -0800507 namespacePrefix := ctx.Namespace().(*Namespace).id
508 if namespacePrefix != "" {
509 namespacePrefix = namespacePrefix + "-"
510 }
511
Colin Cross3f40fa42015-01-30 17:27:36 -0800512 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800513 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800514 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700515 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800516 Output: name,
517 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800518 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700519 })
520 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700521 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700522 }
523
524 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800525 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800526 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700527 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800528 Output: name,
529 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700530 })
531 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700532 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700533 }
534
535 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800536 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800537 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800538 suffix = "-soong"
539 }
540
Jeff Gaston088e29e2017-11-29 16:47:17 -0800541 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800542 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700543 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800544 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700545 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800546 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700547
548 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800549 }
550}
551
Colin Cross635c3b02016-05-18 15:37:25 -0700552func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700553 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700554 target: a.commonProperties.CompileTarget,
555 targetPrimary: a.commonProperties.CompilePrimary,
Colin Cross7d716ba2017-11-01 10:38:29 -0700556 vendor: Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Vendor),
Colin Cross8b74d172016-09-13 09:59:14 -0700557 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800558 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800559}
560
Colin Cross0875c522017-11-28 17:34:01 -0800561func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
562 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700563 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800564 ModuleContext: blueprintCtx,
565 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
566 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700567 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800568 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800569 }
570
Colin Cross67a5c132017-05-09 13:45:28 -0700571 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
572 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800573 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
574 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700575 }
Colin Cross0875c522017-11-28 17:34:01 -0800576 if !ctx.PrimaryArch() {
577 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700578 }
579
580 ctx.Variable(pctx, "moduleDesc", desc)
581
582 s := ""
583 if len(suffix) > 0 {
584 s = " [" + strings.Join(suffix, " ") + "]"
585 }
586 ctx.Variable(pctx, "moduleDescSuffix", s)
587
Colin Cross9b1d13d2016-09-19 15:18:11 -0700588 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800589 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700590 if ctx.Failed() {
591 return
592 }
593
Colin Cross0875c522017-11-28 17:34:01 -0800594 a.installFiles = append(a.installFiles, ctx.installFiles...)
595 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800596 }
597
Colin Cross9b1d13d2016-09-19 15:18:11 -0700598 if a == ctx.FinalModule().(Module).base() {
599 a.generateModuleTarget(ctx)
600 if ctx.Failed() {
601 return
602 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800603 }
Colin Crosscec81712017-07-13 14:43:27 -0700604
Colin Cross0875c522017-11-28 17:34:01 -0800605 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800606}
607
Colin Crossf6566ed2015-03-24 11:13:38 -0700608type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700609 target Target
610 targetPrimary bool
611 debug bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700612 vendor bool
Colin Cross8b74d172016-09-13 09:59:14 -0700613 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700614}
615
Colin Cross3f40fa42015-01-30 17:27:36 -0800616type androidModuleContext struct {
617 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700618 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700619 installDeps Paths
620 installFiles Paths
621 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800622 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700623 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700624
625 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700626 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800627}
628
Colin Cross67a5c132017-05-09 13:45:28 -0700629func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800630 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700631 Rule: ErrorRule,
632 Description: desc,
633 Outputs: outputs,
634 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800635 Args: map[string]string{
636 "error": err.Error(),
637 },
638 })
639 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800640}
641
Colin Crossaabf6792017-11-29 00:27:14 -0800642func (a *androidModuleContext) Config() Config {
643 return a.ModuleContext.Config().(Config)
644}
645
Colin Cross0875c522017-11-28 17:34:01 -0800646func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700647 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800648}
649
Colin Cross0875c522017-11-28 17:34:01 -0800650func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700651 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700652 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800653 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800654 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700655 Outputs: params.Outputs.Strings(),
656 ImplicitOutputs: params.ImplicitOutputs.Strings(),
657 Inputs: params.Inputs.Strings(),
658 Implicits: params.Implicits.Strings(),
659 OrderOnly: params.OrderOnly.Strings(),
660 Args: params.Args,
661 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700662 }
663
Colin Cross33bfb0a2016-11-21 17:23:08 -0800664 if params.Depfile != nil {
665 bparams.Depfile = params.Depfile.String()
666 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700667 if params.Output != nil {
668 bparams.Outputs = append(bparams.Outputs, params.Output.String())
669 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700670 if params.ImplicitOutput != nil {
671 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
672 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700673 if params.Input != nil {
674 bparams.Inputs = append(bparams.Inputs, params.Input.String())
675 }
676 if params.Implicit != nil {
677 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
678 }
679
Colin Cross0875c522017-11-28 17:34:01 -0800680 return bparams
681}
682
683func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
684 a.ModuleContext.Variable(pctx.PackageContext, name, value)
685}
686
687func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
688 argNames ...string) blueprint.Rule {
689
690 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
691}
692
693func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
694 if a.config.captureBuild {
695 a.buildParams = append(a.buildParams, params)
696 }
697
698 bparams := convertBuildParams(params)
699
700 if bparams.Description != "" {
701 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
702 }
703
Colin Cross6ff51382015-12-17 16:39:19 -0800704 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700705 a.ninjaError(bparams.Description, bparams.Outputs,
706 fmt.Errorf("module %s missing dependencies: %s\n",
707 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800708 return
709 }
710
Colin Cross0875c522017-11-28 17:34:01 -0800711 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700712}
713
Colin Cross6ff51382015-12-17 16:39:19 -0800714func (a *androidModuleContext) GetMissingDependencies() []string {
715 return a.missingDeps
716}
717
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800718func (a *androidModuleContext) AddMissingDependencies(deps []string) {
719 if deps != nil {
720 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700721 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800722 }
723}
724
Colin Crossd11fcda2017-10-23 17:59:01 -0700725func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
726 aModule, _ := module.(Module)
727 if aModule == nil {
728 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
729 return nil
730 }
731
732 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800733 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700734 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
735 } else {
736 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
737 }
738 return nil
739 }
740
741 return aModule
742}
743
Colin Cross35143d02017-11-16 00:11:20 -0800744func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
745 a.ModuleContext.VisitDirectDeps(visit)
746}
747
Colin Crossd11fcda2017-10-23 17:59:01 -0700748func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
749 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
750 if aModule := a.validateAndroidModule(module); aModule != nil {
751 visit(aModule)
752 }
753 })
754}
755
756func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
757 a.ModuleContext.VisitDirectDepsIf(
758 // pred
759 func(module blueprint.Module) bool {
760 if aModule := a.validateAndroidModule(module); aModule != nil {
761 return pred(aModule)
762 } else {
763 return false
764 }
765 },
766 // visit
767 func(module blueprint.Module) {
768 visit(module.(Module))
769 })
770}
771
772func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
773 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
774 if aModule := a.validateAndroidModule(module); aModule != nil {
775 visit(aModule)
776 }
777 })
778}
779
780func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
781 a.ModuleContext.VisitDepsDepthFirstIf(
782 // pred
783 func(module blueprint.Module) bool {
784 if aModule := a.validateAndroidModule(module); aModule != nil {
785 return pred(aModule)
786 } else {
787 return false
788 }
789 },
790 // visit
791 func(module blueprint.Module) {
792 visit(module.(Module))
793 })
794}
795
796func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
797 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
798 childAndroidModule := a.validateAndroidModule(child)
799 parentAndroidModule := a.validateAndroidModule(parent)
800 if childAndroidModule != nil && parentAndroidModule != nil {
801 return visit(childAndroidModule, parentAndroidModule)
802 } else {
803 return false
804 }
805 })
806}
807
Colin Cross0875c522017-11-28 17:34:01 -0800808func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
809 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
810 visit(module.(Module))
811 })
812}
813
814func (a *androidModuleContext) PrimaryModule() Module {
815 return a.ModuleContext.PrimaryModule().(Module)
816}
817
818func (a *androidModuleContext) FinalModule() Module {
819 return a.ModuleContext.FinalModule().(Module)
820}
821
Colin Crossa1ad8d12016-06-01 17:09:44 -0700822func (a *androidBaseContextImpl) Target() Target {
823 return a.target
824}
825
Colin Cross8b74d172016-09-13 09:59:14 -0700826func (a *androidBaseContextImpl) TargetPrimary() bool {
827 return a.targetPrimary
828}
829
Colin Crossf6566ed2015-03-24 11:13:38 -0700830func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700831 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800832}
833
Colin Crossa1ad8d12016-06-01 17:09:44 -0700834func (a *androidBaseContextImpl) Os() OsType {
835 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800836}
837
Colin Crossf6566ed2015-03-24 11:13:38 -0700838func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700839 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700840}
841
842func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700843 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700844}
845
Colin Cross0af4b842015-04-30 16:36:18 -0700846func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700847 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700848}
849
Colin Cross3edeee12017-04-04 12:59:48 -0700850func (a *androidBaseContextImpl) Windows() bool {
851 return a.target.Os == Windows
852}
853
Colin Crossf6566ed2015-03-24 11:13:38 -0700854func (a *androidBaseContextImpl) Debug() bool {
855 return a.debug
856}
857
Colin Cross1e7d3702016-08-24 15:25:47 -0700858func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700859 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
860 return true
861 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700862 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
863}
864
Colin Cross1332b002015-04-07 17:11:30 -0700865func (a *androidBaseContextImpl) AConfig() Config {
866 return a.config
867}
868
Colin Cross9272ade2016-08-17 15:24:12 -0700869func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
870 return DeviceConfig{a.config.deviceConfig}
871}
872
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700873func (a *androidBaseContextImpl) InstallOnVendorPartition() bool {
Dan Willemsenaa118f92017-04-06 12:49:58 -0700874 return a.vendor
Dan Willemsen782a2d12015-12-21 14:55:28 -0800875}
876
Colin Cross8d8f8e22016-08-03 11:57:50 -0700877func (a *androidModuleContext) InstallInData() bool {
878 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800879}
880
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700881func (a *androidModuleContext) InstallInSanitizerDir() bool {
882 return a.module.InstallInSanitizerDir()
883}
884
Colin Cross893d8162017-04-26 17:34:03 -0700885func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
886 if a.module.base().commonProperties.SkipInstall {
887 return true
888 }
889
890 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -0800891 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -0700892 return true
893 }
894
Colin Cross6510f912017-11-29 00:27:14 -0800895 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -0700896 return true
897 }
898 }
899
900 return false
901}
902
Colin Cross5c517922017-08-31 12:29:17 -0700903func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700904 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -0700905 return a.installFile(installPath, name, srcPath, Cp, deps)
906}
907
908func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
909 deps ...Path) OutputPath {
910 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
911}
912
913func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
914 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700915
Dan Willemsen782a2d12015-12-21 14:55:28 -0800916 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700917 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800918
Colin Cross893d8162017-04-26 17:34:03 -0700919 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700920
Dan Willemsen322acaf2016-01-12 23:07:05 -0800921 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700922
Colin Cross89562dc2016-10-03 17:47:19 -0700923 var implicitDeps, orderOnlyDeps Paths
924
925 if a.Host() {
926 // Installed host modules might be used during the build, depend directly on their
927 // dependencies so their timestamp is updated whenever their dependency is updated
928 implicitDeps = deps
929 } else {
930 orderOnlyDeps = deps
931 }
932
Colin Crossae887032017-10-23 17:16:14 -0700933 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -0700934 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -0700935 Description: "install " + fullInstallPath.Base(),
936 Output: fullInstallPath,
937 Input: srcPath,
938 Implicits: implicitDeps,
939 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -0800940 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800941 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800942
Dan Willemsen322acaf2016-01-12 23:07:05 -0800943 a.installFiles = append(a.installFiles, fullInstallPath)
944 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700945 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700946 return fullInstallPath
947}
948
Colin Cross3854a602016-01-11 12:49:11 -0800949func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
950 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700951 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800952
Colin Cross893d8162017-04-26 17:34:03 -0700953 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700954
Colin Crossae887032017-10-23 17:16:14 -0700955 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700956 Rule: Symlink,
957 Description: "install symlink " + fullInstallPath.Base(),
958 Output: fullInstallPath,
959 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -0800960 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -0800961 Args: map[string]string{
962 "fromPath": srcPath.String(),
963 },
964 })
Colin Cross3854a602016-01-11 12:49:11 -0800965
Colin Cross12fc4972016-01-11 12:49:11 -0800966 a.installFiles = append(a.installFiles, fullInstallPath)
967 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
968 }
Colin Cross3854a602016-01-11 12:49:11 -0800969 return fullInstallPath
970}
971
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700972func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800973 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
974}
975
Colin Cross3f40fa42015-01-30 17:27:36 -0800976type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700977 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800978}
979
980func isFileInstaller(m blueprint.Module) bool {
981 _, ok := m.(fileInstaller)
982 return ok
983}
984
985func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700986 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800987 return ok
988}
Colin Crossfce53272015-04-08 11:21:40 -0700989
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700990func findStringInSlice(str string, slice []string) int {
991 for i, s := range slice {
992 if s == str {
993 return i
Colin Crossfce53272015-04-08 11:21:40 -0700994 }
995 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700996 return -1
997}
998
Colin Cross068e0fe2016-12-13 15:23:47 -0800999func SrcIsModule(s string) string {
1000 if len(s) > 1 && s[0] == ':' {
1001 return s[1:]
1002 }
1003 return ""
1004}
1005
1006type sourceDependencyTag struct {
1007 blueprint.BaseDependencyTag
1008}
1009
1010var SourceDepTag sourceDependencyTag
1011
1012// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
1013// modules listed in srcFiles using ":module" syntax
1014func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1015 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001016 set := make(map[string]bool)
1017
Colin Cross068e0fe2016-12-13 15:23:47 -08001018 for _, s := range srcFiles {
1019 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001020 if _, found := set[m]; found {
1021 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1022 } else {
1023 set[m] = true
1024 deps = append(deps, m)
1025 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001026 }
1027 }
1028
1029 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1030}
1031
1032type SourceFileProducer interface {
1033 Srcs() Paths
1034}
1035
1036// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001037// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001038func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001039 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1040}
1041
1042func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001043 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001044
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001045 for i, e := range excludes {
1046 j := findStringInSlice(e, srcFiles)
1047 if j != -1 {
1048 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
1049 }
1050
1051 excludes[i] = filepath.Join(prefix, e)
1052 }
1053
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001054 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001055 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001056 if m := SrcIsModule(s); m != "" {
1057 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001058 if module == nil {
1059 // Error will have been handled by ExtractSourcesDeps
1060 continue
1061 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001062 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001063 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001064 } else {
1065 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1066 }
1067 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001068 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001069 for i, s := range globbedSrcFiles {
1070 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001071 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001072 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001073 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001074 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1075 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -07001076 }
1077 }
1078
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001079 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001080}
1081
Nan Zhang6d34b302017-02-04 17:47:46 -08001082func (ctx *androidModuleContext) RequiredModuleNames() []string {
1083 return ctx.module.base().commonProperties.Required
1084}
1085
Colin Cross7f19f372016-11-01 11:10:25 -07001086func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1087 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001088 if err != nil {
1089 ctx.ModuleErrorf("glob: %s", err.Error())
1090 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001091 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -07001092}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001093
Colin Cross463a90e2015-06-17 14:20:06 -07001094func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001095 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001096}
1097
Colin Cross0875c522017-11-28 17:34:01 -08001098func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001099 return &buildTargetSingleton{}
1100}
1101
Colin Cross87d8b562017-04-25 10:01:55 -07001102func parentDir(dir string) string {
1103 dir, _ = filepath.Split(dir)
1104 return filepath.Clean(dir)
1105}
1106
Colin Cross1f8c52b2015-06-16 16:38:17 -07001107type buildTargetSingleton struct{}
1108
Colin Cross0875c522017-11-28 17:34:01 -08001109func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1110 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001111
Colin Cross0875c522017-11-28 17:34:01 -08001112 mmTarget := func(dir string) WritablePath {
1113 return PathForPhony(ctx,
1114 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001115 }
1116
Colin Cross0875c522017-11-28 17:34:01 -08001117 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001118
Colin Cross0875c522017-11-28 17:34:01 -08001119 ctx.VisitAllModules(func(module Module) {
1120 blueprintDir := module.base().blueprintDir
1121 installTarget := module.base().installTarget
1122 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001123
Colin Cross0875c522017-11-28 17:34:01 -08001124 if checkbuildTarget != nil {
1125 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1126 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1127 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001128
Colin Cross0875c522017-11-28 17:34:01 -08001129 if installTarget != nil {
1130 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001131 }
1132 })
1133
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001134 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001135 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001136 suffix = "-soong"
1137 }
1138
Colin Cross1f8c52b2015-06-16 16:38:17 -07001139 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001140 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001141 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001142 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001143 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001144 })
1145
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001146 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001147 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001148 return
1149 }
1150
Colin Cross0875c522017-11-28 17:34:01 -08001151 sortedKeys := func(m map[string]Paths) []string {
1152 s := make([]string, 0, len(m))
1153 for k := range m {
1154 s = append(s, k)
1155 }
1156 sort.Strings(s)
1157 return s
1158 }
1159
Colin Cross87d8b562017-04-25 10:01:55 -07001160 // Ensure ancestor directories are in modulesInDir
1161 dirs := sortedKeys(modulesInDir)
1162 for _, dir := range dirs {
1163 dir := parentDir(dir)
1164 for dir != "." && dir != "/" {
1165 if _, exists := modulesInDir[dir]; exists {
1166 break
1167 }
1168 modulesInDir[dir] = nil
1169 dir = parentDir(dir)
1170 }
1171 }
1172
1173 // Make directories build their direct subdirectories
1174 dirs = sortedKeys(modulesInDir)
1175 for _, dir := range dirs {
1176 p := parentDir(dir)
1177 if p != "." && p != "/" {
1178 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1179 }
1180 }
1181
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001182 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1183 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1184 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001185 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001186 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001187 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001188 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001189 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001190 // HACK: checkbuild should be an optional build, but force it
1191 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001192 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001193 })
1194 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001195
1196 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1197 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001198 ctx.VisitAllModules(func(module Module) {
1199 if module.Enabled() {
1200 os := module.Target().Os
1201 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001202 }
1203 })
1204
Colin Cross0875c522017-11-28 17:34:01 -08001205 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001206 for os, deps := range osDeps {
1207 var className string
1208
1209 switch os.Class {
1210 case Host:
1211 className = "host"
1212 case HostCross:
1213 className = "host-cross"
1214 case Device:
1215 className = "target"
1216 default:
1217 continue
1218 }
1219
Colin Cross0875c522017-11-28 17:34:01 -08001220 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001221 osClass[className] = append(osClass[className], name)
1222
Colin Cross0875c522017-11-28 17:34:01 -08001223 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001224 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001225 Output: name,
1226 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001227 })
1228 }
1229
1230 // Wrap those into host|host-cross|target phony rules
1231 osClasses := sortedKeys(osClass)
1232 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001233 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001234 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001235 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001236 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001237 })
1238 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001239}
Colin Crossd779da42015-12-17 18:00:23 -08001240
1241type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001242 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001243 ctx interface {
1244 ModuleName(blueprint.Module) string
1245 ModuleSubDir(blueprint.Module) string
1246 }
1247}
1248
1249func (s AndroidModulesByName) Len() int { return len(s.slice) }
1250func (s AndroidModulesByName) Less(i, j int) bool {
1251 mi, mj := s.slice[i], s.slice[j]
1252 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1253
1254 if ni != nj {
1255 return ni < nj
1256 } else {
1257 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1258 }
1259}
1260func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }