blob: 7156e8c8fc2d686242897f24f244cb83e0ab4b74 [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 Cross6ff51382015-12-17 16:39:19 -080020 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070021
22 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070023 "github.com/google/blueprint/pathtools"
Colin Cross3f40fa42015-01-30 17:27:36 -080024)
25
26var (
27 DeviceSharedLibrary = "shared_library"
28 DeviceStaticLibrary = "static_library"
29 DeviceExecutable = "executable"
30 HostSharedLibrary = "host_shared_library"
31 HostStaticLibrary = "host_static_library"
32 HostExecutable = "host_executable"
33)
34
Dan Willemsen34cc69e2015-09-23 15:26:20 -070035type ModuleBuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070036 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080037 Deps blueprint.Deps
38 Depfile WritablePath
Dan Willemsen9f3c5742016-11-03 14:28:31 -070039 Output WritablePath
40 Outputs WritablePaths
41 ImplicitOutput WritablePath
42 ImplicitOutputs WritablePaths
43 Input Path
44 Inputs Paths
45 Implicit Path
46 Implicits Paths
47 OrderOnly Paths
48 Default bool
49 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070050}
51
Colin Crossf6566ed2015-03-24 11:13:38 -070052type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070053 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070054 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070055 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070056 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070057 Host() bool
58 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070059 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070061 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070062 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070063 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070064}
65
Colin Cross635c3b02016-05-18 15:37:25 -070066type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070067 blueprint.BaseModuleContext
68 androidBaseContext
69}
70
Colin Cross635c3b02016-05-18 15:37:25 -070071type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080072 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070073 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080074
Dan Willemsen34cc69e2015-09-23 15:26:20 -070075 // Similar to Build, but takes Paths instead of []string,
76 // and performs more verification.
77 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070078
Dan Willemsen34cc69e2015-09-23 15:26:20 -070079 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070080 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081
Colin Crossa2344662016-03-24 13:14:12 -070082 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
83 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080084 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070085 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080086
87 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070088
89 Proprietary() bool
90 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080091}
92
Colin Cross635c3b02016-05-18 15:37:25 -070093type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080094 blueprint.Module
95
Colin Cross635c3b02016-05-18 15:37:25 -070096 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -070097 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080098
Colin Cross635c3b02016-05-18 15:37:25 -070099 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800100 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700101 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800102 InstallInData() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800103 SkipInstall()
Colin Cross3f40fa42015-01-30 17:27:36 -0800104}
105
Colin Crossfc754582016-05-17 16:34:16 -0700106type nameProperties struct {
107 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700108 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700109}
110
111type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700112 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800113
Dan Willemsen0effe062015-11-30 16:06:01 -0800114 // emit build rules for this module
115 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800116
Colin Cross7d5136f2015-05-11 13:39:40 -0700117 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800118 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
119 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
120 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700121 Compile_multilib string `android:"arch_variant"`
122
123 Target struct {
124 Host struct {
125 Compile_multilib string
126 }
127 Android struct {
128 Compile_multilib string
129 }
130 }
131
132 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800133
Dan Willemsen782a2d12015-12-21 14:55:28 -0800134 // whether this is a proprietary vendor module, and should be installed into /vendor
135 Proprietary bool
136
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700137 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
138 // file
139 Logtags []string
140
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700141 // init.rc files to be installed if this module is installed
142 Init_rc []string
143
Chris Wolfe998306e2016-08-15 14:47:23 -0400144 // names of other modules to install if this module is installed
145 Required []string
146
Colin Crossa1ad8d12016-06-01 17:09:44 -0700147 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700148 CompileTarget Target `blueprint:"mutated"`
149 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800150
151 // Set by InitAndroidModule
152 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700153 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700154
155 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800156}
157
158type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700159 Host_supported *bool
160 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800161}
162
Colin Crossc472d572015-03-17 15:06:21 -0700163type Multilib string
164
165const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700166 MultilibBoth Multilib = "both"
167 MultilibFirst Multilib = "first"
168 MultilibCommon Multilib = "common"
169 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700170)
171
Colin Crossa1ad8d12016-06-01 17:09:44 -0700172type HostOrDeviceSupported int
173
174const (
175 _ HostOrDeviceSupported = iota
176 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700177 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700178 DeviceSupported
179 HostAndDeviceSupported
180 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700181 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700182)
183
Colin Cross635c3b02016-05-18 15:37:25 -0700184func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800185 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
186
187 base := m.base()
188 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700189
Colin Crossfc754582016-05-17 16:34:16 -0700190 propertyStructs = append(propertyStructs,
191 &base.nameProperties,
192 &base.commonProperties,
193 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700194
195 return m, propertyStructs
196}
197
Colin Cross635c3b02016-05-18 15:37:25 -0700198func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700199 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
200
201 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
202
203 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800204 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700205 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700206 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800207
Dan Willemsen218f6562015-07-08 18:13:11 -0700208 switch hod {
209 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800210 // Default to module to device supported, host not supported, can override in module
211 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700212 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700213 fallthrough
214 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800215 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
216 }
217
Colin Crosscfad1192015-11-02 16:43:11 -0800218 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800219}
220
221// A AndroidModuleBase object contains the properties that are common to all Android
222// modules. It should be included as an anonymous field in every module
223// struct definition. InitAndroidModule should then be called from the module's
224// factory function, and the return values from InitAndroidModule should be
225// returned from the factory function.
226//
227// The AndroidModuleBase type is responsible for implementing the
228// GenerateBuildActions method to support the blueprint.Module interface. This
229// method will then call the module's GenerateAndroidBuildActions method once
230// for each build variant that is to be built. GenerateAndroidBuildActions is
231// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
232// AndroidModuleContext exposes extra functionality specific to the Android build
233// system including details about the particular build variant that is to be
234// generated.
235//
236// For example:
237//
238// import (
239// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700240// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800241// )
242//
243// type myModule struct {
244// common.AndroidModuleBase
245// properties struct {
246// MyProperty string
247// }
248// }
249//
250// func NewMyModule() (blueprint.Module, []interface{}) {
251// m := &myModule{}
252// return common.InitAndroidModule(m, &m.properties)
253// }
254//
255// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
256// // Get the CPU architecture for the current build variant.
257// variantArch := ctx.Arch()
258//
259// // ...
260// }
Colin Cross635c3b02016-05-18 15:37:25 -0700261type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800262 // Putting the curiously recurring thing pointing to the thing that contains
263 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700264 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800265
Colin Crossfc754582016-05-17 16:34:16 -0700266 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800267 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700268 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800269 hostAndDeviceProperties hostAndDeviceProperties
270 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700271 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700272 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800273
274 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700275 installFiles Paths
276 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700277
278 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
279 // Only set on the final variant of each module
280 installTarget string
281 checkbuildTarget string
282 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700283
Colin Cross178a5092016-09-13 13:42:32 -0700284 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800285}
286
Colin Crossce75d2c2016-10-06 16:12:58 -0700287// Name returns the name of the module. It may be overridden by individual module types, for
288// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700289func (a *ModuleBase) Name() string {
290 return a.nameProperties.Name
291}
292
Colin Crossce75d2c2016-10-06 16:12:58 -0700293// BaseModuleName returns the name of the module as specified in the blueprints file.
294func (a *ModuleBase) BaseModuleName() string {
295 return a.nameProperties.Name
296}
297
Colin Cross635c3b02016-05-18 15:37:25 -0700298func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800299 return a
300}
301
Colin Cross8b74d172016-09-13 09:59:14 -0700302func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700303 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700304 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700305}
306
Colin Crossa1ad8d12016-06-01 17:09:44 -0700307func (a *ModuleBase) Target() Target {
308 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800309}
310
Colin Cross8b74d172016-09-13 09:59:14 -0700311func (a *ModuleBase) TargetPrimary() bool {
312 return a.commonProperties.CompilePrimary
313}
314
Colin Crossa1ad8d12016-06-01 17:09:44 -0700315func (a *ModuleBase) Os() OsType {
316 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800317}
318
Colin Cross635c3b02016-05-18 15:37:25 -0700319func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700320 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800321}
322
Colin Cross635c3b02016-05-18 15:37:25 -0700323func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700324 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800325}
326
Dan Willemsen0b24c742016-10-04 15:13:37 -0700327func (a *ModuleBase) ArchSpecific() bool {
328 return a.commonProperties.ArchSpecific
329}
330
Colin Crossa1ad8d12016-06-01 17:09:44 -0700331func (a *ModuleBase) OsClassSupported() []OsClass {
332 switch a.commonProperties.HostOrDeviceSupported {
333 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700334 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700335 case HostSupportedNoCross:
336 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700337 case DeviceSupported:
338 return []OsClass{Device}
339 case HostAndDeviceSupported:
340 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700341 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700342 supported = append(supported, Host, HostCross)
343 }
Colin Crossa4190c12016-07-12 13:11:25 -0700344 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700345 supported = append(supported, Device)
346 }
347 return supported
348 default:
349 return nil
350 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800351}
352
Colin Cross635c3b02016-05-18 15:37:25 -0700353func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800354 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
355 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700356 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800357}
358
Colin Cross635c3b02016-05-18 15:37:25 -0700359func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800360 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800361 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800362 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800363 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800364}
365
Colin Crossce75d2c2016-10-06 16:12:58 -0700366func (a *ModuleBase) SkipInstall() {
367 a.commonProperties.SkipInstall = true
368}
369
Colin Cross635c3b02016-05-18 15:37:25 -0700370func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700371 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800372
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700373 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800374 ctx.VisitDepsDepthFirstIf(isFileInstaller,
375 func(m blueprint.Module) {
376 fileInstaller := m.(fileInstaller)
377 files := fileInstaller.filesToInstall()
378 result = append(result, files...)
379 })
380
381 return result
382}
383
Colin Cross635c3b02016-05-18 15:37:25 -0700384func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800385 return a.installFiles
386}
387
Colin Cross635c3b02016-05-18 15:37:25 -0700388func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800389 return p.noAddressSanitizer
390}
391
Colin Cross635c3b02016-05-18 15:37:25 -0700392func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800393 return false
394}
395
Colin Cross635c3b02016-05-18 15:37:25 -0700396func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700397 allInstalledFiles := Paths{}
398 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800399 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700400 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700401 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
402 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800403 })
404
Colin Cross9454bfa2015-03-17 13:24:18 -0700405 deps := []string{}
406
Colin Cross3f40fa42015-01-30 17:27:36 -0800407 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700408 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800409 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700410 Rule: blueprint.Phony,
411 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700412 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800413 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700414 })
415 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700416 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700417 }
418
419 if len(allCheckbuildFiles) > 0 {
420 name := ctx.ModuleName() + "-checkbuild"
421 ctx.Build(pctx, blueprint.BuildParams{
422 Rule: blueprint.Phony,
423 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700424 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700425 Optional: true,
426 })
427 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700428 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700429 }
430
431 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800432 suffix := ""
433 if ctx.Config().(Config).EmbeddedInMake() {
434 suffix = "-soong"
435 }
436
Colin Cross9454bfa2015-03-17 13:24:18 -0700437 ctx.Build(pctx, blueprint.BuildParams{
438 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800439 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700440 Implicits: deps,
441 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800442 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700443
444 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800445 }
446}
447
Colin Cross635c3b02016-05-18 15:37:25 -0700448func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700449 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700450 target: a.commonProperties.CompileTarget,
451 targetPrimary: a.commonProperties.CompilePrimary,
452 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800453 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800454}
455
Colin Cross635c3b02016-05-18 15:37:25 -0700456func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800457 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700458 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700459 ModuleContext: ctx,
460 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
461 installDeps: a.computeInstallDeps(ctx),
462 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800463 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800464 }
465
Colin Cross9b1d13d2016-09-19 15:18:11 -0700466 if a.Enabled() {
467 a.module.GenerateAndroidBuildActions(androidCtx)
468 if ctx.Failed() {
469 return
470 }
471
472 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
473 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800474 }
475
Colin Cross9b1d13d2016-09-19 15:18:11 -0700476 if a == ctx.FinalModule().(Module).base() {
477 a.generateModuleTarget(ctx)
478 if ctx.Failed() {
479 return
480 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800481 }
482}
483
Colin Crossf6566ed2015-03-24 11:13:38 -0700484type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700485 target Target
486 targetPrimary bool
487 debug bool
488 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700489}
490
Colin Cross3f40fa42015-01-30 17:27:36 -0800491type androidModuleContext struct {
492 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700493 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700494 installDeps Paths
495 installFiles Paths
496 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800497 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700498 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800499}
500
501func (a *androidModuleContext) ninjaError(outputs []string, err error) {
502 a.ModuleContext.Build(pctx, blueprint.BuildParams{
503 Rule: ErrorRule,
504 Outputs: outputs,
505 Optional: true,
506 Args: map[string]string{
507 "error": err.Error(),
508 },
509 })
510 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800511}
512
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800513func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700514 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800515 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
516 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
517 return
518 }
519
Colin Cross3f40fa42015-01-30 17:27:36 -0800520 params.Optional = true
521 a.ModuleContext.Build(pctx, params)
522}
523
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700524func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
525 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700526 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800527 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700528 Outputs: params.Outputs.Strings(),
529 ImplicitOutputs: params.ImplicitOutputs.Strings(),
530 Inputs: params.Inputs.Strings(),
531 Implicits: params.Implicits.Strings(),
532 OrderOnly: params.OrderOnly.Strings(),
533 Args: params.Args,
534 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700535 }
536
Colin Cross33bfb0a2016-11-21 17:23:08 -0800537 if params.Depfile != nil {
538 bparams.Depfile = params.Depfile.String()
539 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700540 if params.Output != nil {
541 bparams.Outputs = append(bparams.Outputs, params.Output.String())
542 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700543 if params.ImplicitOutput != nil {
544 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
545 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700546 if params.Input != nil {
547 bparams.Inputs = append(bparams.Inputs, params.Input.String())
548 }
549 if params.Implicit != nil {
550 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
551 }
552
Colin Cross6ff51382015-12-17 16:39:19 -0800553 if a.missingDeps != nil {
554 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
555 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
556 return
557 }
558
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700559 a.ModuleContext.Build(pctx, bparams)
560}
561
Colin Cross6ff51382015-12-17 16:39:19 -0800562func (a *androidModuleContext) GetMissingDependencies() []string {
563 return a.missingDeps
564}
565
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800566func (a *androidModuleContext) AddMissingDependencies(deps []string) {
567 if deps != nil {
568 a.missingDeps = append(a.missingDeps, deps...)
569 }
570}
571
Colin Crossa1ad8d12016-06-01 17:09:44 -0700572func (a *androidBaseContextImpl) Target() Target {
573 return a.target
574}
575
Colin Cross8b74d172016-09-13 09:59:14 -0700576func (a *androidBaseContextImpl) TargetPrimary() bool {
577 return a.targetPrimary
578}
579
Colin Crossf6566ed2015-03-24 11:13:38 -0700580func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700581 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800582}
583
Colin Crossa1ad8d12016-06-01 17:09:44 -0700584func (a *androidBaseContextImpl) Os() OsType {
585 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800586}
587
Colin Crossf6566ed2015-03-24 11:13:38 -0700588func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700589 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700590}
591
592func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700593 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700594}
595
Colin Cross0af4b842015-04-30 16:36:18 -0700596func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700597 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700598}
599
Colin Crossf6566ed2015-03-24 11:13:38 -0700600func (a *androidBaseContextImpl) Debug() bool {
601 return a.debug
602}
603
Colin Cross1e7d3702016-08-24 15:25:47 -0700604func (a *androidBaseContextImpl) PrimaryArch() bool {
605 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
606}
607
Colin Cross1332b002015-04-07 17:11:30 -0700608func (a *androidBaseContextImpl) AConfig() Config {
609 return a.config
610}
611
Colin Cross9272ade2016-08-17 15:24:12 -0700612func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
613 return DeviceConfig{a.config.deviceConfig}
614}
615
Colin Cross8d8f8e22016-08-03 11:57:50 -0700616func (a *androidModuleContext) Proprietary() bool {
617 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800618}
619
Colin Cross8d8f8e22016-08-03 11:57:50 -0700620func (a *androidModuleContext) InstallInData() bool {
621 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800622}
623
624func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700625 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700626
Dan Willemsen782a2d12015-12-21 14:55:28 -0800627 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700628 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800629
Colin Crossce75d2c2016-10-06 16:12:58 -0700630 if !a.module.base().commonProperties.SkipInstall &&
631 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
632
Dan Willemsen322acaf2016-01-12 23:07:05 -0800633 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700634
Colin Cross89562dc2016-10-03 17:47:19 -0700635 var implicitDeps, orderOnlyDeps Paths
636
637 if a.Host() {
638 // Installed host modules might be used during the build, depend directly on their
639 // dependencies so their timestamp is updated whenever their dependency is updated
640 implicitDeps = deps
641 } else {
642 orderOnlyDeps = deps
643 }
644
Dan Willemsen322acaf2016-01-12 23:07:05 -0800645 a.ModuleBuild(pctx, ModuleBuildParams{
646 Rule: Cp,
647 Output: fullInstallPath,
648 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700649 Implicits: implicitDeps,
650 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800651 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800652 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800653
Dan Willemsen322acaf2016-01-12 23:07:05 -0800654 a.installFiles = append(a.installFiles, fullInstallPath)
655 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700656 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700657 return fullInstallPath
658}
659
Colin Crossa2344662016-03-24 13:14:12 -0700660func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700661 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800662}
663
Colin Cross3854a602016-01-11 12:49:11 -0800664func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
665 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700666 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800667
Colin Crossce75d2c2016-10-06 16:12:58 -0700668 if !a.module.base().commonProperties.SkipInstall &&
669 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
670
Colin Cross12fc4972016-01-11 12:49:11 -0800671 a.ModuleBuild(pctx, ModuleBuildParams{
672 Rule: Symlink,
673 Output: fullInstallPath,
674 OrderOnly: Paths{srcPath},
675 Default: !a.AConfig().EmbeddedInMake(),
676 Args: map[string]string{
677 "fromPath": srcPath.String(),
678 },
679 })
Colin Cross3854a602016-01-11 12:49:11 -0800680
Colin Cross12fc4972016-01-11 12:49:11 -0800681 a.installFiles = append(a.installFiles, fullInstallPath)
682 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
683 }
Colin Cross3854a602016-01-11 12:49:11 -0800684 return fullInstallPath
685}
686
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700687func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800688 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
689}
690
Colin Cross3f40fa42015-01-30 17:27:36 -0800691type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700692 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800693}
694
695func isFileInstaller(m blueprint.Module) bool {
696 _, ok := m.(fileInstaller)
697 return ok
698}
699
700func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700701 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800702 return ok
703}
Colin Crossfce53272015-04-08 11:21:40 -0700704
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700705func findStringInSlice(str string, slice []string) int {
706 for i, s := range slice {
707 if s == str {
708 return i
Colin Crossfce53272015-04-08 11:21:40 -0700709 }
710 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700711 return -1
712}
713
Colin Cross068e0fe2016-12-13 15:23:47 -0800714func SrcIsModule(s string) string {
715 if len(s) > 1 && s[0] == ':' {
716 return s[1:]
717 }
718 return ""
719}
720
721type sourceDependencyTag struct {
722 blueprint.BaseDependencyTag
723}
724
725var SourceDepTag sourceDependencyTag
726
727// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
728// modules listed in srcFiles using ":module" syntax
729func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
730 var deps []string
731 for _, s := range srcFiles {
732 if m := SrcIsModule(s); m != "" {
733 deps = append(deps, m)
734 }
735 }
736
737 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
738}
739
740type SourceFileProducer interface {
741 Srcs() Paths
742}
743
744// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
745// ExpandSourceDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700746func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
747 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700748 for i, e := range excludes {
749 j := findStringInSlice(e, srcFiles)
750 if j != -1 {
751 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
752 }
753
754 excludes[i] = filepath.Join(prefix, e)
755 }
756
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700757 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700758 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800759 if m := SrcIsModule(s); m != "" {
760 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
761 if srcProducer, ok := module.(SourceFileProducer); ok {
762 globbedSrcFiles = append(globbedSrcFiles, srcProducer.Srcs()...)
763 } else {
764 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
765 }
766 } else if pathtools.IsGlob(s) {
Colin Cross7f19f372016-11-01 11:10:25 -0700767 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700768 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700769 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700770 }
771 }
772
773 return globbedSrcFiles
774}
775
Colin Cross7f19f372016-11-01 11:10:25 -0700776func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
777 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700778 if err != nil {
779 ctx.ModuleErrorf("glob: %s", err.Error())
780 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700781 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700782}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700783
Colin Cross463a90e2015-06-17 14:20:06 -0700784func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700785 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700786}
787
Colin Cross1f8c52b2015-06-16 16:38:17 -0700788func BuildTargetSingleton() blueprint.Singleton {
789 return &buildTargetSingleton{}
790}
791
792type buildTargetSingleton struct{}
793
794func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
795 checkbuildDeps := []string{}
796
797 dirModules := make(map[string][]string)
798
799 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700800 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700801 blueprintDir := a.base().blueprintDir
802 installTarget := a.base().installTarget
803 checkbuildTarget := a.base().checkbuildTarget
804
805 if checkbuildTarget != "" {
806 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
807 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
808 }
809
810 if installTarget != "" {
811 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
812 }
813 }
814 })
815
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800816 suffix := ""
817 if ctx.Config().(Config).EmbeddedInMake() {
818 suffix = "-soong"
819 }
820
Colin Cross1f8c52b2015-06-16 16:38:17 -0700821 // Create a top-level checkbuild target that depends on all modules
822 ctx.Build(pctx, blueprint.BuildParams{
823 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800824 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700825 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700826 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700827 })
828
829 // Create a mm/<directory> target that depends on all modules in a directory
830 dirs := sortedKeys(dirModules)
831 for _, dir := range dirs {
832 ctx.Build(pctx, blueprint.BuildParams{
833 Rule: blueprint.Phony,
834 Outputs: []string{filepath.Join("mm", dir)},
835 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800836 // HACK: checkbuild should be an optional build, but force it
837 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800838 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700839 })
840 }
841}
Colin Crossd779da42015-12-17 18:00:23 -0800842
843type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700844 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800845 ctx interface {
846 ModuleName(blueprint.Module) string
847 ModuleSubDir(blueprint.Module) string
848 }
849}
850
851func (s AndroidModulesByName) Len() int { return len(s.slice) }
852func (s AndroidModulesByName) Less(i, j int) bool {
853 mi, mj := s.slice[i], s.slice[j]
854 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
855
856 if ni != nj {
857 return ni < nj
858 } else {
859 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
860 }
861}
862func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }