blob: e6766a346524eccbeb74c9ada2776f5603c72f14 [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 (
Dan Willemsen218f6562015-07-08 18:13:11 -0700251 MultilibBoth Multilib = "both"
252 MultilibFirst Multilib = "first"
253 MultilibCommon Multilib = "common"
254 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700255)
256
Colin Crossa1ad8d12016-06-01 17:09:44 -0700257type HostOrDeviceSupported int
258
259const (
260 _ HostOrDeviceSupported = iota
261 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700262 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700263 DeviceSupported
264 HostAndDeviceSupported
265 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700266 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700267)
268
Colin Cross36242852017-06-23 15:06:31 -0700269func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800270 base := m.base()
271 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700272
Colin Cross36242852017-06-23 15:06:31 -0700273 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700274 &base.nameProperties,
275 &base.commonProperties,
276 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700277}
278
Colin Cross36242852017-06-23 15:06:31 -0700279func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
280 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700281
282 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800283 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700284 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700285 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800286
Dan Willemsen218f6562015-07-08 18:13:11 -0700287 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700288 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700289 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800290 }
291
Colin Cross36242852017-06-23 15:06:31 -0700292 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800293}
294
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800295// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800296// modules. It should be included as an anonymous field in every module
297// struct definition. InitAndroidModule should then be called from the module's
298// factory function, and the return values from InitAndroidModule should be
299// returned from the factory function.
300//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800301// The ModuleBase type is responsible for implementing the GenerateBuildActions
302// method to support the blueprint.Module interface. This method will then call
303// the module's GenerateAndroidBuildActions method once for each build variant
304// that is to be built. GenerateAndroidBuildActions is passed a
305// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800306// AndroidModuleContext exposes extra functionality specific to the Android build
307// system including details about the particular build variant that is to be
308// generated.
309//
310// For example:
311//
312// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800313// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800314// )
315//
316// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800317// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800318// properties struct {
319// MyProperty string
320// }
321// }
322//
Colin Cross36242852017-06-23 15:06:31 -0700323// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800324// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700325// m.AddProperties(&m.properties)
326// android.InitAndroidModule(m)
327// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800328// }
329//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800330// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800331// // Get the CPU architecture for the current build variant.
332// variantArch := ctx.Arch()
333//
334// // ...
335// }
Colin Cross635c3b02016-05-18 15:37:25 -0700336type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800337 // Putting the curiously recurring thing pointing to the thing that contains
338 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700339 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700340 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800341
Colin Crossfc754582016-05-17 16:34:16 -0700342 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800343 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700344 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800345 hostAndDeviceProperties hostAndDeviceProperties
346 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700347 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700348 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800349
350 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700351 installFiles Paths
352 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700353
354 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
355 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800356 installTarget WritablePath
357 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700358 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700359
Colin Cross178a5092016-09-13 13:42:32 -0700360 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700361
362 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700363
364 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700365 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700366}
367
368func (a *ModuleBase) AddProperties(props ...interface{}) {
369 a.registerProps = append(a.registerProps, props...)
370}
371
372func (a *ModuleBase) GetProperties() []interface{} {
373 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800374}
375
Colin Crossae887032017-10-23 17:16:14 -0700376func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700377 return a.buildParams
378}
379
Colin Crossce75d2c2016-10-06 16:12:58 -0700380// Name returns the name of the module. It may be overridden by individual module types, for
381// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700382func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800383 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700384}
385
Colin Crossce75d2c2016-10-06 16:12:58 -0700386// BaseModuleName returns the name of the module as specified in the blueprints file.
387func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800388 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700389}
390
Colin Cross635c3b02016-05-18 15:37:25 -0700391func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800392 return a
393}
394
Colin Cross8b74d172016-09-13 09:59:14 -0700395func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700396 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700397 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700398}
399
Colin Crossa1ad8d12016-06-01 17:09:44 -0700400func (a *ModuleBase) Target() Target {
401 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800402}
403
Colin Cross8b74d172016-09-13 09:59:14 -0700404func (a *ModuleBase) TargetPrimary() bool {
405 return a.commonProperties.CompilePrimary
406}
407
Colin Crossa1ad8d12016-06-01 17:09:44 -0700408func (a *ModuleBase) Os() OsType {
409 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800410}
411
Colin Cross635c3b02016-05-18 15:37:25 -0700412func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700413 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800414}
415
Colin Cross635c3b02016-05-18 15:37:25 -0700416func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700417 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800418}
419
Dan Willemsen0b24c742016-10-04 15:13:37 -0700420func (a *ModuleBase) ArchSpecific() bool {
421 return a.commonProperties.ArchSpecific
422}
423
Colin Crossa1ad8d12016-06-01 17:09:44 -0700424func (a *ModuleBase) OsClassSupported() []OsClass {
425 switch a.commonProperties.HostOrDeviceSupported {
426 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700427 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700428 case HostSupportedNoCross:
429 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700430 case DeviceSupported:
431 return []OsClass{Device}
432 case HostAndDeviceSupported:
433 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700434 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700435 supported = append(supported, Host, HostCross)
436 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700437 if a.hostAndDeviceProperties.Device_supported == nil ||
438 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700439 supported = append(supported, Device)
440 }
441 return supported
442 default:
443 return nil
444 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800445}
446
Colin Cross635c3b02016-05-18 15:37:25 -0700447func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800448 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
449 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700450 (a.hostAndDeviceProperties.Device_supported == nil ||
451 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800452}
453
Colin Cross635c3b02016-05-18 15:37:25 -0700454func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800455 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800456 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800457 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800458 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800459}
460
Colin Crossce75d2c2016-10-06 16:12:58 -0700461func (a *ModuleBase) SkipInstall() {
462 a.commonProperties.SkipInstall = true
463}
464
Colin Cross635c3b02016-05-18 15:37:25 -0700465func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700466 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800467
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700468 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800469 ctx.VisitDepsDepthFirstIf(isFileInstaller,
470 func(m blueprint.Module) {
471 fileInstaller := m.(fileInstaller)
472 files := fileInstaller.filesToInstall()
473 result = append(result, files...)
474 })
475
476 return result
477}
478
Colin Cross635c3b02016-05-18 15:37:25 -0700479func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800480 return a.installFiles
481}
482
Colin Cross635c3b02016-05-18 15:37:25 -0700483func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800484 return p.noAddressSanitizer
485}
486
Colin Cross635c3b02016-05-18 15:37:25 -0700487func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800488 return false
489}
490
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700491func (p *ModuleBase) InstallInSanitizerDir() bool {
492 return false
493}
494
Colin Cross0875c522017-11-28 17:34:01 -0800495func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700496 allInstalledFiles := Paths{}
497 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800498 ctx.VisitAllModuleVariants(func(module Module) {
499 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700500 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
501 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800502 })
503
Colin Cross0875c522017-11-28 17:34:01 -0800504 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700505
Jeff Gaston088e29e2017-11-29 16:47:17 -0800506 namespacePrefix := ctx.Namespace().(*Namespace).id
507 if namespacePrefix != "" {
508 namespacePrefix = namespacePrefix + "-"
509 }
510
Colin Cross3f40fa42015-01-30 17:27:36 -0800511 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800512 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800513 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700514 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800515 Output: name,
516 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800517 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700518 })
519 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700520 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700521 }
522
523 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800524 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800525 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700526 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800527 Output: name,
528 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700529 })
530 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700531 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700532 }
533
534 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800535 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800536 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800537 suffix = "-soong"
538 }
539
Jeff Gaston088e29e2017-11-29 16:47:17 -0800540 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800541 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700542 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800543 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700544 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800545 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700546
547 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800548 }
549}
550
Colin Cross635c3b02016-05-18 15:37:25 -0700551func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700552 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700553 target: a.commonProperties.CompileTarget,
554 targetPrimary: a.commonProperties.CompilePrimary,
Colin Cross7d716ba2017-11-01 10:38:29 -0700555 vendor: Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Vendor),
Colin Cross8b74d172016-09-13 09:59:14 -0700556 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800557 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800558}
559
Colin Cross0875c522017-11-28 17:34:01 -0800560func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
561 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700562 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800563 ModuleContext: blueprintCtx,
564 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
565 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700566 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800567 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800568 }
569
Colin Cross67a5c132017-05-09 13:45:28 -0700570 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
571 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800572 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
573 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700574 }
Colin Cross0875c522017-11-28 17:34:01 -0800575 if !ctx.PrimaryArch() {
576 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700577 }
578
579 ctx.Variable(pctx, "moduleDesc", desc)
580
581 s := ""
582 if len(suffix) > 0 {
583 s = " [" + strings.Join(suffix, " ") + "]"
584 }
585 ctx.Variable(pctx, "moduleDescSuffix", s)
586
Colin Cross9b1d13d2016-09-19 15:18:11 -0700587 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800588 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700589 if ctx.Failed() {
590 return
591 }
592
Colin Cross0875c522017-11-28 17:34:01 -0800593 a.installFiles = append(a.installFiles, ctx.installFiles...)
594 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800595 }
596
Colin Cross9b1d13d2016-09-19 15:18:11 -0700597 if a == ctx.FinalModule().(Module).base() {
598 a.generateModuleTarget(ctx)
599 if ctx.Failed() {
600 return
601 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800602 }
Colin Crosscec81712017-07-13 14:43:27 -0700603
Colin Cross0875c522017-11-28 17:34:01 -0800604 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800605}
606
Colin Crossf6566ed2015-03-24 11:13:38 -0700607type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700608 target Target
609 targetPrimary bool
610 debug bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700611 vendor bool
Colin Cross8b74d172016-09-13 09:59:14 -0700612 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700613}
614
Colin Cross3f40fa42015-01-30 17:27:36 -0800615type androidModuleContext struct {
616 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700617 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700618 installDeps Paths
619 installFiles Paths
620 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800621 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700622 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700623
624 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700625 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800626}
627
Colin Cross67a5c132017-05-09 13:45:28 -0700628func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800629 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700630 Rule: ErrorRule,
631 Description: desc,
632 Outputs: outputs,
633 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800634 Args: map[string]string{
635 "error": err.Error(),
636 },
637 })
638 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800639}
640
Colin Crossaabf6792017-11-29 00:27:14 -0800641func (a *androidModuleContext) Config() Config {
642 return a.ModuleContext.Config().(Config)
643}
644
Colin Cross0875c522017-11-28 17:34:01 -0800645func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700646 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800647}
648
Colin Cross0875c522017-11-28 17:34:01 -0800649func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700650 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700651 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800652 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800653 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700654 Outputs: params.Outputs.Strings(),
655 ImplicitOutputs: params.ImplicitOutputs.Strings(),
656 Inputs: params.Inputs.Strings(),
657 Implicits: params.Implicits.Strings(),
658 OrderOnly: params.OrderOnly.Strings(),
659 Args: params.Args,
660 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700661 }
662
Colin Cross33bfb0a2016-11-21 17:23:08 -0800663 if params.Depfile != nil {
664 bparams.Depfile = params.Depfile.String()
665 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700666 if params.Output != nil {
667 bparams.Outputs = append(bparams.Outputs, params.Output.String())
668 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700669 if params.ImplicitOutput != nil {
670 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
671 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700672 if params.Input != nil {
673 bparams.Inputs = append(bparams.Inputs, params.Input.String())
674 }
675 if params.Implicit != nil {
676 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
677 }
678
Colin Cross0875c522017-11-28 17:34:01 -0800679 return bparams
680}
681
682func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
683 a.ModuleContext.Variable(pctx.PackageContext, name, value)
684}
685
686func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
687 argNames ...string) blueprint.Rule {
688
689 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
690}
691
692func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
693 if a.config.captureBuild {
694 a.buildParams = append(a.buildParams, params)
695 }
696
697 bparams := convertBuildParams(params)
698
699 if bparams.Description != "" {
700 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
701 }
702
Colin Cross6ff51382015-12-17 16:39:19 -0800703 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700704 a.ninjaError(bparams.Description, bparams.Outputs,
705 fmt.Errorf("module %s missing dependencies: %s\n",
706 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800707 return
708 }
709
Colin Cross0875c522017-11-28 17:34:01 -0800710 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700711}
712
Colin Cross6ff51382015-12-17 16:39:19 -0800713func (a *androidModuleContext) GetMissingDependencies() []string {
714 return a.missingDeps
715}
716
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800717func (a *androidModuleContext) AddMissingDependencies(deps []string) {
718 if deps != nil {
719 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700720 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800721 }
722}
723
Colin Crossd11fcda2017-10-23 17:59:01 -0700724func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
725 aModule, _ := module.(Module)
726 if aModule == nil {
727 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
728 return nil
729 }
730
731 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800732 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700733 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
734 } else {
735 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
736 }
737 return nil
738 }
739
740 return aModule
741}
742
Colin Cross35143d02017-11-16 00:11:20 -0800743func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
744 a.ModuleContext.VisitDirectDeps(visit)
745}
746
Colin Crossd11fcda2017-10-23 17:59:01 -0700747func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
748 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
749 if aModule := a.validateAndroidModule(module); aModule != nil {
750 visit(aModule)
751 }
752 })
753}
754
755func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
756 a.ModuleContext.VisitDirectDepsIf(
757 // pred
758 func(module blueprint.Module) bool {
759 if aModule := a.validateAndroidModule(module); aModule != nil {
760 return pred(aModule)
761 } else {
762 return false
763 }
764 },
765 // visit
766 func(module blueprint.Module) {
767 visit(module.(Module))
768 })
769}
770
771func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
772 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
773 if aModule := a.validateAndroidModule(module); aModule != nil {
774 visit(aModule)
775 }
776 })
777}
778
779func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
780 a.ModuleContext.VisitDepsDepthFirstIf(
781 // pred
782 func(module blueprint.Module) bool {
783 if aModule := a.validateAndroidModule(module); aModule != nil {
784 return pred(aModule)
785 } else {
786 return false
787 }
788 },
789 // visit
790 func(module blueprint.Module) {
791 visit(module.(Module))
792 })
793}
794
795func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
796 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
797 childAndroidModule := a.validateAndroidModule(child)
798 parentAndroidModule := a.validateAndroidModule(parent)
799 if childAndroidModule != nil && parentAndroidModule != nil {
800 return visit(childAndroidModule, parentAndroidModule)
801 } else {
802 return false
803 }
804 })
805}
806
Colin Cross0875c522017-11-28 17:34:01 -0800807func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
808 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
809 visit(module.(Module))
810 })
811}
812
813func (a *androidModuleContext) PrimaryModule() Module {
814 return a.ModuleContext.PrimaryModule().(Module)
815}
816
817func (a *androidModuleContext) FinalModule() Module {
818 return a.ModuleContext.FinalModule().(Module)
819}
820
Colin Crossa1ad8d12016-06-01 17:09:44 -0700821func (a *androidBaseContextImpl) Target() Target {
822 return a.target
823}
824
Colin Cross8b74d172016-09-13 09:59:14 -0700825func (a *androidBaseContextImpl) TargetPrimary() bool {
826 return a.targetPrimary
827}
828
Colin Crossf6566ed2015-03-24 11:13:38 -0700829func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700830 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800831}
832
Colin Crossa1ad8d12016-06-01 17:09:44 -0700833func (a *androidBaseContextImpl) Os() OsType {
834 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800835}
836
Colin Crossf6566ed2015-03-24 11:13:38 -0700837func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700838 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700839}
840
841func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700842 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700843}
844
Colin Cross0af4b842015-04-30 16:36:18 -0700845func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700846 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700847}
848
Colin Cross3edeee12017-04-04 12:59:48 -0700849func (a *androidBaseContextImpl) Windows() bool {
850 return a.target.Os == Windows
851}
852
Colin Crossf6566ed2015-03-24 11:13:38 -0700853func (a *androidBaseContextImpl) Debug() bool {
854 return a.debug
855}
856
Colin Cross1e7d3702016-08-24 15:25:47 -0700857func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700858 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
859 return true
860 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700861 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
862}
863
Colin Cross1332b002015-04-07 17:11:30 -0700864func (a *androidBaseContextImpl) AConfig() Config {
865 return a.config
866}
867
Colin Cross9272ade2016-08-17 15:24:12 -0700868func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
869 return DeviceConfig{a.config.deviceConfig}
870}
871
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700872func (a *androidBaseContextImpl) InstallOnVendorPartition() bool {
Dan Willemsenaa118f92017-04-06 12:49:58 -0700873 return a.vendor
Dan Willemsen782a2d12015-12-21 14:55:28 -0800874}
875
Colin Cross8d8f8e22016-08-03 11:57:50 -0700876func (a *androidModuleContext) InstallInData() bool {
877 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800878}
879
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700880func (a *androidModuleContext) InstallInSanitizerDir() bool {
881 return a.module.InstallInSanitizerDir()
882}
883
Colin Cross893d8162017-04-26 17:34:03 -0700884func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
885 if a.module.base().commonProperties.SkipInstall {
886 return true
887 }
888
889 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -0800890 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -0700891 return true
892 }
893
Colin Cross6510f912017-11-29 00:27:14 -0800894 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -0700895 return true
896 }
897 }
898
899 return false
900}
901
Colin Cross5c517922017-08-31 12:29:17 -0700902func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700903 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -0700904 return a.installFile(installPath, name, srcPath, Cp, deps)
905}
906
907func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
908 deps ...Path) OutputPath {
909 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
910}
911
912func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
913 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700914
Dan Willemsen782a2d12015-12-21 14:55:28 -0800915 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700916 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800917
Colin Cross893d8162017-04-26 17:34:03 -0700918 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700919
Dan Willemsen322acaf2016-01-12 23:07:05 -0800920 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700921
Colin Cross89562dc2016-10-03 17:47:19 -0700922 var implicitDeps, orderOnlyDeps Paths
923
924 if a.Host() {
925 // Installed host modules might be used during the build, depend directly on their
926 // dependencies so their timestamp is updated whenever their dependency is updated
927 implicitDeps = deps
928 } else {
929 orderOnlyDeps = deps
930 }
931
Colin Crossae887032017-10-23 17:16:14 -0700932 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -0700933 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -0700934 Description: "install " + fullInstallPath.Base(),
935 Output: fullInstallPath,
936 Input: srcPath,
937 Implicits: implicitDeps,
938 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -0800939 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800940 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800941
Dan Willemsen322acaf2016-01-12 23:07:05 -0800942 a.installFiles = append(a.installFiles, fullInstallPath)
943 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700944 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700945 return fullInstallPath
946}
947
Colin Cross3854a602016-01-11 12:49:11 -0800948func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
949 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700950 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800951
Colin Cross893d8162017-04-26 17:34:03 -0700952 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700953
Colin Crossae887032017-10-23 17:16:14 -0700954 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700955 Rule: Symlink,
956 Description: "install symlink " + fullInstallPath.Base(),
957 Output: fullInstallPath,
958 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -0800959 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -0800960 Args: map[string]string{
961 "fromPath": srcPath.String(),
962 },
963 })
Colin Cross3854a602016-01-11 12:49:11 -0800964
Colin Cross12fc4972016-01-11 12:49:11 -0800965 a.installFiles = append(a.installFiles, fullInstallPath)
966 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
967 }
Colin Cross3854a602016-01-11 12:49:11 -0800968 return fullInstallPath
969}
970
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700971func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800972 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
973}
974
Colin Cross3f40fa42015-01-30 17:27:36 -0800975type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700976 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800977}
978
979func isFileInstaller(m blueprint.Module) bool {
980 _, ok := m.(fileInstaller)
981 return ok
982}
983
984func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700985 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800986 return ok
987}
Colin Crossfce53272015-04-08 11:21:40 -0700988
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700989func findStringInSlice(str string, slice []string) int {
990 for i, s := range slice {
991 if s == str {
992 return i
Colin Crossfce53272015-04-08 11:21:40 -0700993 }
994 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700995 return -1
996}
997
Colin Cross068e0fe2016-12-13 15:23:47 -0800998func SrcIsModule(s string) string {
999 if len(s) > 1 && s[0] == ':' {
1000 return s[1:]
1001 }
1002 return ""
1003}
1004
1005type sourceDependencyTag struct {
1006 blueprint.BaseDependencyTag
1007}
1008
1009var SourceDepTag sourceDependencyTag
1010
1011// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
1012// modules listed in srcFiles using ":module" syntax
1013func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1014 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001015 set := make(map[string]bool)
1016
Colin Cross068e0fe2016-12-13 15:23:47 -08001017 for _, s := range srcFiles {
1018 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001019 if _, found := set[m]; found {
1020 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1021 } else {
1022 set[m] = true
1023 deps = append(deps, m)
1024 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001025 }
1026 }
1027
1028 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1029}
1030
1031type SourceFileProducer interface {
1032 Srcs() Paths
1033}
1034
1035// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001036// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001037func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001038 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1039}
1040
1041func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001042 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001043
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001044 for i, e := range excludes {
1045 j := findStringInSlice(e, srcFiles)
1046 if j != -1 {
1047 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
1048 }
1049
1050 excludes[i] = filepath.Join(prefix, e)
1051 }
1052
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001053 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001054 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001055 if m := SrcIsModule(s); m != "" {
1056 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001057 if module == nil {
1058 // Error will have been handled by ExtractSourcesDeps
1059 continue
1060 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001061 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001062 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001063 } else {
1064 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1065 }
1066 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001067 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001068 for i, s := range globbedSrcFiles {
1069 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001070 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001071 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001072 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001073 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1074 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -07001075 }
1076 }
1077
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001078 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001079}
1080
Nan Zhang6d34b302017-02-04 17:47:46 -08001081func (ctx *androidModuleContext) RequiredModuleNames() []string {
1082 return ctx.module.base().commonProperties.Required
1083}
1084
Colin Cross7f19f372016-11-01 11:10:25 -07001085func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1086 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001087 if err != nil {
1088 ctx.ModuleErrorf("glob: %s", err.Error())
1089 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001090 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -07001091}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001092
Colin Cross463a90e2015-06-17 14:20:06 -07001093func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001094 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001095}
1096
Colin Cross0875c522017-11-28 17:34:01 -08001097func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001098 return &buildTargetSingleton{}
1099}
1100
Colin Cross87d8b562017-04-25 10:01:55 -07001101func parentDir(dir string) string {
1102 dir, _ = filepath.Split(dir)
1103 return filepath.Clean(dir)
1104}
1105
Colin Cross1f8c52b2015-06-16 16:38:17 -07001106type buildTargetSingleton struct{}
1107
Colin Cross0875c522017-11-28 17:34:01 -08001108func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1109 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001110
Colin Cross0875c522017-11-28 17:34:01 -08001111 mmTarget := func(dir string) WritablePath {
1112 return PathForPhony(ctx,
1113 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001114 }
1115
Colin Cross0875c522017-11-28 17:34:01 -08001116 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001117
Colin Cross0875c522017-11-28 17:34:01 -08001118 ctx.VisitAllModules(func(module Module) {
1119 blueprintDir := module.base().blueprintDir
1120 installTarget := module.base().installTarget
1121 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001122
Colin Cross0875c522017-11-28 17:34:01 -08001123 if checkbuildTarget != nil {
1124 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1125 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1126 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001127
Colin Cross0875c522017-11-28 17:34:01 -08001128 if installTarget != nil {
1129 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001130 }
1131 })
1132
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001133 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001134 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001135 suffix = "-soong"
1136 }
1137
Colin Cross1f8c52b2015-06-16 16:38:17 -07001138 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001139 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001140 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001141 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001142 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001143 })
1144
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001145 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001146 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001147 return
1148 }
1149
Colin Cross0875c522017-11-28 17:34:01 -08001150 sortedKeys := func(m map[string]Paths) []string {
1151 s := make([]string, 0, len(m))
1152 for k := range m {
1153 s = append(s, k)
1154 }
1155 sort.Strings(s)
1156 return s
1157 }
1158
Colin Cross87d8b562017-04-25 10:01:55 -07001159 // Ensure ancestor directories are in modulesInDir
1160 dirs := sortedKeys(modulesInDir)
1161 for _, dir := range dirs {
1162 dir := parentDir(dir)
1163 for dir != "." && dir != "/" {
1164 if _, exists := modulesInDir[dir]; exists {
1165 break
1166 }
1167 modulesInDir[dir] = nil
1168 dir = parentDir(dir)
1169 }
1170 }
1171
1172 // Make directories build their direct subdirectories
1173 dirs = sortedKeys(modulesInDir)
1174 for _, dir := range dirs {
1175 p := parentDir(dir)
1176 if p != "." && p != "/" {
1177 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1178 }
1179 }
1180
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001181 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1182 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1183 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001184 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001185 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001186 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001187 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001188 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001189 // HACK: checkbuild should be an optional build, but force it
1190 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001191 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001192 })
1193 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001194
1195 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1196 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001197 ctx.VisitAllModules(func(module Module) {
1198 if module.Enabled() {
1199 os := module.Target().Os
1200 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001201 }
1202 })
1203
Colin Cross0875c522017-11-28 17:34:01 -08001204 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001205 for os, deps := range osDeps {
1206 var className string
1207
1208 switch os.Class {
1209 case Host:
1210 className = "host"
1211 case HostCross:
1212 className = "host-cross"
1213 case Device:
1214 className = "target"
1215 default:
1216 continue
1217 }
1218
Colin Cross0875c522017-11-28 17:34:01 -08001219 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001220 osClass[className] = append(osClass[className], name)
1221
Colin Cross0875c522017-11-28 17:34:01 -08001222 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001223 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001224 Output: name,
1225 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001226 })
1227 }
1228
1229 // Wrap those into host|host-cross|target phony rules
1230 osClasses := sortedKeys(osClass)
1231 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001232 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001233 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001234 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001235 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001236 })
1237 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001238}
Colin Crossd779da42015-12-17 18:00:23 -08001239
1240type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001241 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001242 ctx interface {
1243 ModuleName(blueprint.Module) string
1244 ModuleSubDir(blueprint.Module) string
1245 }
1246}
1247
1248func (s AndroidModulesByName) Len() int { return len(s.slice) }
1249func (s AndroidModulesByName) Less(i, j int) bool {
1250 mi, mj := s.slice[i], s.slice[j]
1251 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1252
1253 if ni != nj {
1254 return ni < nj
1255 } else {
1256 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1257 }
1258}
1259func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }