blob: 6d7bb438336be4268551f403631e41475c324d11 [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 Willemsen2277bcb2016-07-25 20:27:39 -0700217 // init.rc files to be installed if this module is installed
218 Init_rc []string
219
Chris Wolfe998306e2016-08-15 14:47:23 -0400220 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700221 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400222
Colin Cross5aac3622017-08-31 15:07:09 -0700223 // relative path to a file to include in the list of notices for the device
224 Notice *string
225
Colin Crossa1ad8d12016-06-01 17:09:44 -0700226 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700227 CompileTarget Target `blueprint:"mutated"`
228 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800229
230 // Set by InitAndroidModule
231 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700232 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700233
234 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800235
236 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800237}
238
239type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700240 Host_supported *bool
241 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800242}
243
Colin Crossc472d572015-03-17 15:06:21 -0700244type Multilib string
245
246const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800247 MultilibBoth Multilib = "both"
248 MultilibFirst Multilib = "first"
249 MultilibCommon Multilib = "common"
250 MultilibCommonFirst Multilib = "common_first"
251 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700252)
253
Colin Crossa1ad8d12016-06-01 17:09:44 -0700254type HostOrDeviceSupported int
255
256const (
257 _ HostOrDeviceSupported = iota
258 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700259 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700260 DeviceSupported
261 HostAndDeviceSupported
262 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700263 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700264)
265
Colin Cross36242852017-06-23 15:06:31 -0700266func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800267 base := m.base()
268 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700269
Colin Cross36242852017-06-23 15:06:31 -0700270 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700271 &base.nameProperties,
272 &base.commonProperties,
273 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700274}
275
Colin Cross36242852017-06-23 15:06:31 -0700276func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
277 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700278
279 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800280 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700281 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700282 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800283
Dan Willemsen218f6562015-07-08 18:13:11 -0700284 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700285 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700286 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800287 }
288
Colin Cross36242852017-06-23 15:06:31 -0700289 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800290}
291
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800292// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800293// modules. It should be included as an anonymous field in every module
294// struct definition. InitAndroidModule should then be called from the module's
295// factory function, and the return values from InitAndroidModule should be
296// returned from the factory function.
297//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800298// The ModuleBase type is responsible for implementing the GenerateBuildActions
299// method to support the blueprint.Module interface. This method will then call
300// the module's GenerateAndroidBuildActions method once for each build variant
301// that is to be built. GenerateAndroidBuildActions is passed a
302// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800303// AndroidModuleContext exposes extra functionality specific to the Android build
304// system including details about the particular build variant that is to be
305// generated.
306//
307// For example:
308//
309// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800310// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800311// )
312//
313// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800314// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800315// properties struct {
316// MyProperty string
317// }
318// }
319//
Colin Cross36242852017-06-23 15:06:31 -0700320// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800321// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700322// m.AddProperties(&m.properties)
323// android.InitAndroidModule(m)
324// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800325// }
326//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800327// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800328// // Get the CPU architecture for the current build variant.
329// variantArch := ctx.Arch()
330//
331// // ...
332// }
Colin Cross635c3b02016-05-18 15:37:25 -0700333type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800334 // Putting the curiously recurring thing pointing to the thing that contains
335 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700336 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700337 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800338
Colin Crossfc754582016-05-17 16:34:16 -0700339 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800340 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700341 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800342 hostAndDeviceProperties hostAndDeviceProperties
343 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700344 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700345 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800346
347 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700348 installFiles Paths
349 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700350
351 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
352 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800353 installTarget WritablePath
354 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700355 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700356
Colin Cross178a5092016-09-13 13:42:32 -0700357 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700358
359 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700360
361 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700362 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700363}
364
365func (a *ModuleBase) AddProperties(props ...interface{}) {
366 a.registerProps = append(a.registerProps, props...)
367}
368
369func (a *ModuleBase) GetProperties() []interface{} {
370 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800371}
372
Colin Crossae887032017-10-23 17:16:14 -0700373func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700374 return a.buildParams
375}
376
Colin Crossce75d2c2016-10-06 16:12:58 -0700377// Name returns the name of the module. It may be overridden by individual module types, for
378// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700379func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800380 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700381}
382
Colin Crossce75d2c2016-10-06 16:12:58 -0700383// BaseModuleName returns the name of the module as specified in the blueprints file.
384func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800385 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700386}
387
Colin Cross635c3b02016-05-18 15:37:25 -0700388func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800389 return a
390}
391
Colin Cross8b74d172016-09-13 09:59:14 -0700392func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700393 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700394 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700395}
396
Colin Crossa1ad8d12016-06-01 17:09:44 -0700397func (a *ModuleBase) Target() Target {
398 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800399}
400
Colin Cross8b74d172016-09-13 09:59:14 -0700401func (a *ModuleBase) TargetPrimary() bool {
402 return a.commonProperties.CompilePrimary
403}
404
Colin Crossa1ad8d12016-06-01 17:09:44 -0700405func (a *ModuleBase) Os() OsType {
406 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800407}
408
Colin Cross635c3b02016-05-18 15:37:25 -0700409func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700410 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800411}
412
Colin Cross635c3b02016-05-18 15:37:25 -0700413func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700414 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800415}
416
Dan Willemsen0b24c742016-10-04 15:13:37 -0700417func (a *ModuleBase) ArchSpecific() bool {
418 return a.commonProperties.ArchSpecific
419}
420
Colin Crossa1ad8d12016-06-01 17:09:44 -0700421func (a *ModuleBase) OsClassSupported() []OsClass {
422 switch a.commonProperties.HostOrDeviceSupported {
423 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700424 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700425 case HostSupportedNoCross:
426 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700427 case DeviceSupported:
428 return []OsClass{Device}
429 case HostAndDeviceSupported:
430 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700431 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700432 supported = append(supported, Host, HostCross)
433 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700434 if a.hostAndDeviceProperties.Device_supported == nil ||
435 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700436 supported = append(supported, Device)
437 }
438 return supported
439 default:
440 return nil
441 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800442}
443
Colin Cross635c3b02016-05-18 15:37:25 -0700444func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800445 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
446 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700447 (a.hostAndDeviceProperties.Device_supported == nil ||
448 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800449}
450
Colin Cross635c3b02016-05-18 15:37:25 -0700451func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800452 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800453 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800454 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800455 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800456}
457
Colin Crossce75d2c2016-10-06 16:12:58 -0700458func (a *ModuleBase) SkipInstall() {
459 a.commonProperties.SkipInstall = true
460}
461
Colin Cross635c3b02016-05-18 15:37:25 -0700462func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700463 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800464
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700465 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800466 ctx.VisitDepsDepthFirstIf(isFileInstaller,
467 func(m blueprint.Module) {
468 fileInstaller := m.(fileInstaller)
469 files := fileInstaller.filesToInstall()
470 result = append(result, files...)
471 })
472
473 return result
474}
475
Colin Cross635c3b02016-05-18 15:37:25 -0700476func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 return a.installFiles
478}
479
Colin Cross635c3b02016-05-18 15:37:25 -0700480func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800481 return p.noAddressSanitizer
482}
483
Colin Cross635c3b02016-05-18 15:37:25 -0700484func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800485 return false
486}
487
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700488func (p *ModuleBase) InstallInSanitizerDir() bool {
489 return false
490}
491
Colin Cross0875c522017-11-28 17:34:01 -0800492func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700493 allInstalledFiles := Paths{}
494 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800495 ctx.VisitAllModuleVariants(func(module Module) {
496 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700497 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
498 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800499 })
500
Colin Cross0875c522017-11-28 17:34:01 -0800501 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700502
Jeff Gaston088e29e2017-11-29 16:47:17 -0800503 namespacePrefix := ctx.Namespace().(*Namespace).id
504 if namespacePrefix != "" {
505 namespacePrefix = namespacePrefix + "-"
506 }
507
Colin Cross3f40fa42015-01-30 17:27:36 -0800508 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800509 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800510 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700511 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800512 Output: name,
513 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800514 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700515 })
516 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700517 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700518 }
519
520 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800521 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800522 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700523 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800524 Output: name,
525 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700526 })
527 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700528 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700529 }
530
531 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800532 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800533 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800534 suffix = "-soong"
535 }
536
Jeff Gaston088e29e2017-11-29 16:47:17 -0800537 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800538 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700539 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800540 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700541 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800542 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700543
544 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800545 }
546}
547
Colin Cross635c3b02016-05-18 15:37:25 -0700548func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700549 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700550 target: a.commonProperties.CompileTarget,
551 targetPrimary: a.commonProperties.CompilePrimary,
Colin Cross7d716ba2017-11-01 10:38:29 -0700552 vendor: Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Vendor),
Colin Cross8b74d172016-09-13 09:59:14 -0700553 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800554 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800555}
556
Colin Cross0875c522017-11-28 17:34:01 -0800557func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
558 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700559 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800560 ModuleContext: blueprintCtx,
561 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
562 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700563 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800564 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800565 }
566
Colin Cross67a5c132017-05-09 13:45:28 -0700567 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
568 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800569 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
570 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700571 }
Colin Cross0875c522017-11-28 17:34:01 -0800572 if !ctx.PrimaryArch() {
573 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700574 }
575
576 ctx.Variable(pctx, "moduleDesc", desc)
577
578 s := ""
579 if len(suffix) > 0 {
580 s = " [" + strings.Join(suffix, " ") + "]"
581 }
582 ctx.Variable(pctx, "moduleDescSuffix", s)
583
Colin Cross9b1d13d2016-09-19 15:18:11 -0700584 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800585 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700586 if ctx.Failed() {
587 return
588 }
589
Colin Cross0875c522017-11-28 17:34:01 -0800590 a.installFiles = append(a.installFiles, ctx.installFiles...)
591 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800592 }
593
Colin Cross9b1d13d2016-09-19 15:18:11 -0700594 if a == ctx.FinalModule().(Module).base() {
595 a.generateModuleTarget(ctx)
596 if ctx.Failed() {
597 return
598 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800599 }
Colin Crosscec81712017-07-13 14:43:27 -0700600
Colin Cross0875c522017-11-28 17:34:01 -0800601 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800602}
603
Colin Crossf6566ed2015-03-24 11:13:38 -0700604type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700605 target Target
606 targetPrimary bool
607 debug bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700608 vendor bool
Colin Cross8b74d172016-09-13 09:59:14 -0700609 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700610}
611
Colin Cross3f40fa42015-01-30 17:27:36 -0800612type androidModuleContext struct {
613 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700614 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700615 installDeps Paths
616 installFiles Paths
617 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800618 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700619 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700620
621 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700622 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800623}
624
Colin Cross67a5c132017-05-09 13:45:28 -0700625func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800626 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700627 Rule: ErrorRule,
628 Description: desc,
629 Outputs: outputs,
630 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800631 Args: map[string]string{
632 "error": err.Error(),
633 },
634 })
635 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800636}
637
Colin Crossaabf6792017-11-29 00:27:14 -0800638func (a *androidModuleContext) Config() Config {
639 return a.ModuleContext.Config().(Config)
640}
641
Colin Cross0875c522017-11-28 17:34:01 -0800642func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700643 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800644}
645
Colin Cross0875c522017-11-28 17:34:01 -0800646func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700647 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700648 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800649 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800650 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700651 Outputs: params.Outputs.Strings(),
652 ImplicitOutputs: params.ImplicitOutputs.Strings(),
653 Inputs: params.Inputs.Strings(),
654 Implicits: params.Implicits.Strings(),
655 OrderOnly: params.OrderOnly.Strings(),
656 Args: params.Args,
657 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700658 }
659
Colin Cross33bfb0a2016-11-21 17:23:08 -0800660 if params.Depfile != nil {
661 bparams.Depfile = params.Depfile.String()
662 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700663 if params.Output != nil {
664 bparams.Outputs = append(bparams.Outputs, params.Output.String())
665 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700666 if params.ImplicitOutput != nil {
667 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
668 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700669 if params.Input != nil {
670 bparams.Inputs = append(bparams.Inputs, params.Input.String())
671 }
672 if params.Implicit != nil {
673 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
674 }
675
Colin Cross0875c522017-11-28 17:34:01 -0800676 return bparams
677}
678
679func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
680 a.ModuleContext.Variable(pctx.PackageContext, name, value)
681}
682
683func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
684 argNames ...string) blueprint.Rule {
685
686 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
687}
688
689func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
690 if a.config.captureBuild {
691 a.buildParams = append(a.buildParams, params)
692 }
693
694 bparams := convertBuildParams(params)
695
696 if bparams.Description != "" {
697 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
698 }
699
Colin Cross6ff51382015-12-17 16:39:19 -0800700 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700701 a.ninjaError(bparams.Description, bparams.Outputs,
702 fmt.Errorf("module %s missing dependencies: %s\n",
703 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800704 return
705 }
706
Colin Cross0875c522017-11-28 17:34:01 -0800707 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700708}
709
Colin Cross6ff51382015-12-17 16:39:19 -0800710func (a *androidModuleContext) GetMissingDependencies() []string {
711 return a.missingDeps
712}
713
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800714func (a *androidModuleContext) AddMissingDependencies(deps []string) {
715 if deps != nil {
716 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700717 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800718 }
719}
720
Colin Crossd11fcda2017-10-23 17:59:01 -0700721func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
722 aModule, _ := module.(Module)
723 if aModule == nil {
724 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
725 return nil
726 }
727
728 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800729 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700730 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
731 } else {
732 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
733 }
734 return nil
735 }
736
737 return aModule
738}
739
Colin Cross35143d02017-11-16 00:11:20 -0800740func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
741 a.ModuleContext.VisitDirectDeps(visit)
742}
743
Colin Crossd11fcda2017-10-23 17:59:01 -0700744func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
745 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
746 if aModule := a.validateAndroidModule(module); aModule != nil {
747 visit(aModule)
748 }
749 })
750}
751
752func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
753 a.ModuleContext.VisitDirectDepsIf(
754 // pred
755 func(module blueprint.Module) bool {
756 if aModule := a.validateAndroidModule(module); aModule != nil {
757 return pred(aModule)
758 } else {
759 return false
760 }
761 },
762 // visit
763 func(module blueprint.Module) {
764 visit(module.(Module))
765 })
766}
767
768func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
769 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
770 if aModule := a.validateAndroidModule(module); aModule != nil {
771 visit(aModule)
772 }
773 })
774}
775
776func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
777 a.ModuleContext.VisitDepsDepthFirstIf(
778 // pred
779 func(module blueprint.Module) bool {
780 if aModule := a.validateAndroidModule(module); aModule != nil {
781 return pred(aModule)
782 } else {
783 return false
784 }
785 },
786 // visit
787 func(module blueprint.Module) {
788 visit(module.(Module))
789 })
790}
791
792func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
793 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
794 childAndroidModule := a.validateAndroidModule(child)
795 parentAndroidModule := a.validateAndroidModule(parent)
796 if childAndroidModule != nil && parentAndroidModule != nil {
797 return visit(childAndroidModule, parentAndroidModule)
798 } else {
799 return false
800 }
801 })
802}
803
Colin Cross0875c522017-11-28 17:34:01 -0800804func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
805 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
806 visit(module.(Module))
807 })
808}
809
810func (a *androidModuleContext) PrimaryModule() Module {
811 return a.ModuleContext.PrimaryModule().(Module)
812}
813
814func (a *androidModuleContext) FinalModule() Module {
815 return a.ModuleContext.FinalModule().(Module)
816}
817
Colin Crossa1ad8d12016-06-01 17:09:44 -0700818func (a *androidBaseContextImpl) Target() Target {
819 return a.target
820}
821
Colin Cross8b74d172016-09-13 09:59:14 -0700822func (a *androidBaseContextImpl) TargetPrimary() bool {
823 return a.targetPrimary
824}
825
Colin Crossf6566ed2015-03-24 11:13:38 -0700826func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700827 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800828}
829
Colin Crossa1ad8d12016-06-01 17:09:44 -0700830func (a *androidBaseContextImpl) Os() OsType {
831 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800832}
833
Colin Crossf6566ed2015-03-24 11:13:38 -0700834func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700835 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700836}
837
838func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700839 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700840}
841
Colin Cross0af4b842015-04-30 16:36:18 -0700842func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700843 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700844}
845
Colin Cross3edeee12017-04-04 12:59:48 -0700846func (a *androidBaseContextImpl) Windows() bool {
847 return a.target.Os == Windows
848}
849
Colin Crossf6566ed2015-03-24 11:13:38 -0700850func (a *androidBaseContextImpl) Debug() bool {
851 return a.debug
852}
853
Colin Cross1e7d3702016-08-24 15:25:47 -0700854func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700855 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
856 return true
857 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700858 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
859}
860
Colin Cross1332b002015-04-07 17:11:30 -0700861func (a *androidBaseContextImpl) AConfig() Config {
862 return a.config
863}
864
Colin Cross9272ade2016-08-17 15:24:12 -0700865func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
866 return DeviceConfig{a.config.deviceConfig}
867}
868
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700869func (a *androidBaseContextImpl) InstallOnVendorPartition() bool {
Dan Willemsenaa118f92017-04-06 12:49:58 -0700870 return a.vendor
Dan Willemsen782a2d12015-12-21 14:55:28 -0800871}
872
Colin Cross8d8f8e22016-08-03 11:57:50 -0700873func (a *androidModuleContext) InstallInData() bool {
874 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800875}
876
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700877func (a *androidModuleContext) InstallInSanitizerDir() bool {
878 return a.module.InstallInSanitizerDir()
879}
880
Colin Cross893d8162017-04-26 17:34:03 -0700881func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
882 if a.module.base().commonProperties.SkipInstall {
883 return true
884 }
885
886 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -0800887 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -0700888 return true
889 }
890
Colin Cross6510f912017-11-29 00:27:14 -0800891 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -0700892 return true
893 }
894 }
895
896 return false
897}
898
Colin Cross5c517922017-08-31 12:29:17 -0700899func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700900 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -0700901 return a.installFile(installPath, name, srcPath, Cp, deps)
902}
903
904func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
905 deps ...Path) OutputPath {
906 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
907}
908
909func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
910 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700911
Dan Willemsen782a2d12015-12-21 14:55:28 -0800912 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700913 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800914
Colin Cross893d8162017-04-26 17:34:03 -0700915 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700916
Dan Willemsen322acaf2016-01-12 23:07:05 -0800917 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700918
Colin Cross89562dc2016-10-03 17:47:19 -0700919 var implicitDeps, orderOnlyDeps Paths
920
921 if a.Host() {
922 // Installed host modules might be used during the build, depend directly on their
923 // dependencies so their timestamp is updated whenever their dependency is updated
924 implicitDeps = deps
925 } else {
926 orderOnlyDeps = deps
927 }
928
Colin Crossae887032017-10-23 17:16:14 -0700929 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -0700930 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -0700931 Description: "install " + fullInstallPath.Base(),
932 Output: fullInstallPath,
933 Input: srcPath,
934 Implicits: implicitDeps,
935 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -0800936 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800937 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800938
Dan Willemsen322acaf2016-01-12 23:07:05 -0800939 a.installFiles = append(a.installFiles, fullInstallPath)
940 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700941 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700942 return fullInstallPath
943}
944
Colin Cross3854a602016-01-11 12:49:11 -0800945func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
946 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700947 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800948
Colin Cross893d8162017-04-26 17:34:03 -0700949 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700950
Colin Crossae887032017-10-23 17:16:14 -0700951 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700952 Rule: Symlink,
953 Description: "install symlink " + fullInstallPath.Base(),
954 Output: fullInstallPath,
955 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -0800956 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -0800957 Args: map[string]string{
958 "fromPath": srcPath.String(),
959 },
960 })
Colin Cross3854a602016-01-11 12:49:11 -0800961
Colin Cross12fc4972016-01-11 12:49:11 -0800962 a.installFiles = append(a.installFiles, fullInstallPath)
963 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
964 }
Colin Cross3854a602016-01-11 12:49:11 -0800965 return fullInstallPath
966}
967
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700968func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800969 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
970}
971
Colin Cross3f40fa42015-01-30 17:27:36 -0800972type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700973 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800974}
975
976func isFileInstaller(m blueprint.Module) bool {
977 _, ok := m.(fileInstaller)
978 return ok
979}
980
981func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700982 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800983 return ok
984}
Colin Crossfce53272015-04-08 11:21:40 -0700985
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700986func findStringInSlice(str string, slice []string) int {
987 for i, s := range slice {
988 if s == str {
989 return i
Colin Crossfce53272015-04-08 11:21:40 -0700990 }
991 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700992 return -1
993}
994
Colin Cross068e0fe2016-12-13 15:23:47 -0800995func SrcIsModule(s string) string {
996 if len(s) > 1 && s[0] == ':' {
997 return s[1:]
998 }
999 return ""
1000}
1001
1002type sourceDependencyTag struct {
1003 blueprint.BaseDependencyTag
1004}
1005
1006var SourceDepTag sourceDependencyTag
1007
1008// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
1009// modules listed in srcFiles using ":module" syntax
1010func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1011 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001012 set := make(map[string]bool)
1013
Colin Cross068e0fe2016-12-13 15:23:47 -08001014 for _, s := range srcFiles {
1015 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001016 if _, found := set[m]; found {
1017 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1018 } else {
1019 set[m] = true
1020 deps = append(deps, m)
1021 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001022 }
1023 }
1024
1025 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1026}
1027
1028type SourceFileProducer interface {
1029 Srcs() Paths
1030}
1031
1032// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001033// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001034func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001035 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1036}
1037
1038func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001039 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001040
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001041 for i, e := range excludes {
1042 j := findStringInSlice(e, srcFiles)
1043 if j != -1 {
1044 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
1045 }
1046
1047 excludes[i] = filepath.Join(prefix, e)
1048 }
1049
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001050 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001051 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001052 if m := SrcIsModule(s); m != "" {
1053 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001054 if module == nil {
1055 // Error will have been handled by ExtractSourcesDeps
1056 continue
1057 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001058 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001059 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001060 } else {
1061 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1062 }
1063 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001064 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001065 for i, s := range globbedSrcFiles {
1066 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001067 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001068 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001069 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001070 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1071 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -07001072 }
1073 }
1074
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001075 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001076}
1077
Nan Zhang6d34b302017-02-04 17:47:46 -08001078func (ctx *androidModuleContext) RequiredModuleNames() []string {
1079 return ctx.module.base().commonProperties.Required
1080}
1081
Colin Cross7f19f372016-11-01 11:10:25 -07001082func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1083 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001084 if err != nil {
1085 ctx.ModuleErrorf("glob: %s", err.Error())
1086 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001087 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -07001088}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001089
Colin Cross463a90e2015-06-17 14:20:06 -07001090func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001091 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001092}
1093
Colin Cross0875c522017-11-28 17:34:01 -08001094func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001095 return &buildTargetSingleton{}
1096}
1097
Colin Cross87d8b562017-04-25 10:01:55 -07001098func parentDir(dir string) string {
1099 dir, _ = filepath.Split(dir)
1100 return filepath.Clean(dir)
1101}
1102
Colin Cross1f8c52b2015-06-16 16:38:17 -07001103type buildTargetSingleton struct{}
1104
Colin Cross0875c522017-11-28 17:34:01 -08001105func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1106 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001107
Colin Cross0875c522017-11-28 17:34:01 -08001108 mmTarget := func(dir string) WritablePath {
1109 return PathForPhony(ctx,
1110 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001111 }
1112
Colin Cross0875c522017-11-28 17:34:01 -08001113 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001114
Colin Cross0875c522017-11-28 17:34:01 -08001115 ctx.VisitAllModules(func(module Module) {
1116 blueprintDir := module.base().blueprintDir
1117 installTarget := module.base().installTarget
1118 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001119
Colin Cross0875c522017-11-28 17:34:01 -08001120 if checkbuildTarget != nil {
1121 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1122 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1123 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001124
Colin Cross0875c522017-11-28 17:34:01 -08001125 if installTarget != nil {
1126 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001127 }
1128 })
1129
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001130 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001131 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001132 suffix = "-soong"
1133 }
1134
Colin Cross1f8c52b2015-06-16 16:38:17 -07001135 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001136 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001137 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001138 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001139 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001140 })
1141
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001142 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001143 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001144 return
1145 }
1146
Colin Cross0875c522017-11-28 17:34:01 -08001147 sortedKeys := func(m map[string]Paths) []string {
1148 s := make([]string, 0, len(m))
1149 for k := range m {
1150 s = append(s, k)
1151 }
1152 sort.Strings(s)
1153 return s
1154 }
1155
Colin Cross87d8b562017-04-25 10:01:55 -07001156 // Ensure ancestor directories are in modulesInDir
1157 dirs := sortedKeys(modulesInDir)
1158 for _, dir := range dirs {
1159 dir := parentDir(dir)
1160 for dir != "." && dir != "/" {
1161 if _, exists := modulesInDir[dir]; exists {
1162 break
1163 }
1164 modulesInDir[dir] = nil
1165 dir = parentDir(dir)
1166 }
1167 }
1168
1169 // Make directories build their direct subdirectories
1170 dirs = sortedKeys(modulesInDir)
1171 for _, dir := range dirs {
1172 p := parentDir(dir)
1173 if p != "." && p != "/" {
1174 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1175 }
1176 }
1177
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001178 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1179 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1180 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001181 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001182 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001183 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001184 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001185 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001186 // HACK: checkbuild should be an optional build, but force it
1187 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001188 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001189 })
1190 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001191
1192 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1193 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001194 ctx.VisitAllModules(func(module Module) {
1195 if module.Enabled() {
1196 os := module.Target().Os
1197 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001198 }
1199 })
1200
Colin Cross0875c522017-11-28 17:34:01 -08001201 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001202 for os, deps := range osDeps {
1203 var className string
1204
1205 switch os.Class {
1206 case Host:
1207 className = "host"
1208 case HostCross:
1209 className = "host-cross"
1210 case Device:
1211 className = "target"
1212 default:
1213 continue
1214 }
1215
Colin Cross0875c522017-11-28 17:34:01 -08001216 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001217 osClass[className] = append(osClass[className], name)
1218
Colin Cross0875c522017-11-28 17:34:01 -08001219 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001220 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001221 Output: name,
1222 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001223 })
1224 }
1225
1226 // Wrap those into host|host-cross|target phony rules
1227 osClasses := sortedKeys(osClass)
1228 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001229 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001230 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001231 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001232 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001233 })
1234 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001235}
Colin Crossd779da42015-12-17 18:00:23 -08001236
1237type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001238 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001239 ctx interface {
1240 ModuleName(blueprint.Module) string
1241 ModuleSubDir(blueprint.Module) string
1242 }
1243}
1244
1245func (s AndroidModulesByName) Len() int { return len(s.slice) }
1246func (s AndroidModulesByName) Less(i, j int) bool {
1247 mi, mj := s.slice[i], s.slice[j]
1248 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1249
1250 if ni != nj {
1251 return ni < nj
1252 } else {
1253 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1254 }
1255}
1256func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }