blob: 4a8e8acf65f7fbba8eb9a881437d8cfdf75cb9cb [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
Jiyong Park2db76922017-11-08 16:03:48 +090068 Platform() bool
69 DeviceSpecific() bool
70 SocSpecific() bool
71 ProductSpecific() bool
Colin Cross1332b002015-04-07 17:11:30 -070072 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070073 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070074}
75
Colin Cross635c3b02016-05-18 15:37:25 -070076type BaseContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -080077 BaseModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070078 androidBaseContext
79}
80
Colin Crossaabf6792017-11-29 00:27:14 -080081// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
82// a Config instead of an interface{}.
83type BaseModuleContext interface {
84 ModuleName() string
85 ModuleDir() string
86 Config() Config
87
88 ContainsProperty(name string) bool
89 Errorf(pos scanner.Position, fmt string, args ...interface{})
90 ModuleErrorf(fmt string, args ...interface{})
91 PropertyErrorf(property, fmt string, args ...interface{})
92 Failed() bool
93
94 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
95 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
96 // builder whenever a file matching the pattern as added or removed, without rerunning if a
97 // file that does not match the pattern is added to a searched directory.
98 GlobWithDeps(pattern string, excludes []string) ([]string, error)
99
100 Fs() pathtools.FileSystem
101 AddNinjaFileDeps(deps ...string)
102}
103
Colin Cross635c3b02016-05-18 15:37:25 -0700104type ModuleContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -0700105 androidBaseContext
Colin Crossaabf6792017-11-29 00:27:14 -0800106 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800107
Colin Crossae887032017-10-23 17:16:14 -0700108 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800109 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700110
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700111 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross366938f2017-12-11 16:29:02 -0800112 ExpandSource(srcFile, prop string) Path
Colin Cross2383f3b2018-02-06 14:40:13 -0800113 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800114 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -0700115 Glob(globPattern string, excludes []string) Paths
Nan Zhang581fd212018-01-10 16:06:12 -0800116 GlobFiles(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700117
Colin Cross5c517922017-08-31 12:29:17 -0700118 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
119 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800120 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700121 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800122
123 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700124
Colin Cross8d8f8e22016-08-03 11:57:50 -0700125 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700126 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800127
128 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700129
130 // android.ModuleContext methods
131 // These are duplicated instead of embedded so that can eventually be wrapped to take an
132 // android.Module instead of a blueprint.Module
133 OtherModuleName(m blueprint.Module) string
134 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
135 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
136
137 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
138 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
139
140 ModuleSubDir() string
141
Colin Cross35143d02017-11-16 00:11:20 -0800142 VisitDirectDepsBlueprint(visit func(blueprint.Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700143 VisitDirectDeps(visit func(Module))
Colin Crossee6143c2017-12-30 17:54:27 -0800144 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700145 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
146 VisitDepsDepthFirst(visit func(Module))
147 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
148 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700149
Colin Cross0875c522017-11-28 17:34:01 -0800150 Variable(pctx PackageContext, name, value string)
151 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700152 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
153 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800154 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700155
Colin Cross0875c522017-11-28 17:34:01 -0800156 PrimaryModule() Module
157 FinalModule() Module
158 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700159
160 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800161 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800162}
163
Colin Cross635c3b02016-05-18 15:37:25 -0700164type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800165 blueprint.Module
166
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700167 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
168 // but GenerateAndroidBuildActions also has access to Android-specific information.
169 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700170 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700171
Colin Cross1e676be2016-10-12 14:38:15 -0700172 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800173
Colin Cross635c3b02016-05-18 15:37:25 -0700174 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800175 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700176 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800177 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700178 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800179 SkipInstall()
Colin Cross36242852017-06-23 15:06:31 -0700180
181 AddProperties(props ...interface{})
182 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700183
Colin Crossae887032017-10-23 17:16:14 -0700184 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800185}
186
Colin Crossfc754582016-05-17 16:34:16 -0700187type nameProperties struct {
188 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800189 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700190}
191
192type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700193 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800194
Dan Willemsen0effe062015-11-30 16:06:01 -0800195 // emit build rules for this module
196 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800197
Colin Cross7d5136f2015-05-11 13:39:40 -0700198 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800199 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
200 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
201 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700202 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700203
204 Target struct {
205 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700206 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700207 }
208 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700209 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700210 }
211 }
212
213 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800214
Dan Willemsen782a2d12015-12-21 14:55:28 -0800215 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700216 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800217
Colin Cross55708f32017-03-20 13:23:34 -0700218 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700219 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700220
Jiyong Park2db76922017-11-08 16:03:48 +0900221 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
222 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
223 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700224 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700225
Jiyong Park2db76922017-11-08 16:03:48 +0900226 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
227 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
228 Soc_specific *bool
229
230 // whether this module is specific to a device, not only for SoC, but also for off-chip
231 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
232 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
233 // This implies `soc_specific:true`.
234 Device_specific *bool
235
236 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900237 // network operator, etc). When set to true, it is installed into /product (or
238 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900239 Product_specific *bool
240
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700241 // init.rc files to be installed if this module is installed
242 Init_rc []string
243
Chris Wolfe998306e2016-08-15 14:47:23 -0400244 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700245 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400246
Colin Cross5aac3622017-08-31 15:07:09 -0700247 // relative path to a file to include in the list of notices for the device
248 Notice *string
249
Colin Crossa1ad8d12016-06-01 17:09:44 -0700250 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700251 CompileTarget Target `blueprint:"mutated"`
252 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800253
254 // Set by InitAndroidModule
255 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700256 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700257
258 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800259
260 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800261}
262
263type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700264 Host_supported *bool
265 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800266}
267
Colin Crossc472d572015-03-17 15:06:21 -0700268type Multilib string
269
270const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800271 MultilibBoth Multilib = "both"
272 MultilibFirst Multilib = "first"
273 MultilibCommon Multilib = "common"
274 MultilibCommonFirst Multilib = "common_first"
275 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700276)
277
Colin Crossa1ad8d12016-06-01 17:09:44 -0700278type HostOrDeviceSupported int
279
280const (
281 _ HostOrDeviceSupported = iota
282 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700283 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700284 DeviceSupported
285 HostAndDeviceSupported
286 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700287 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700288)
289
Jiyong Park2db76922017-11-08 16:03:48 +0900290type moduleKind int
291
292const (
293 platformModule moduleKind = iota
294 deviceSpecificModule
295 socSpecificModule
296 productSpecificModule
297)
298
299func (k moduleKind) String() string {
300 switch k {
301 case platformModule:
302 return "platform"
303 case deviceSpecificModule:
304 return "device-specific"
305 case socSpecificModule:
306 return "soc-specific"
307 case productSpecificModule:
308 return "product-specific"
309 default:
310 panic(fmt.Errorf("unknown module kind %d", k))
311 }
312}
313
Colin Cross36242852017-06-23 15:06:31 -0700314func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800315 base := m.base()
316 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700317
Colin Cross36242852017-06-23 15:06:31 -0700318 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700319 &base.nameProperties,
320 &base.commonProperties,
321 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700322}
323
Colin Cross36242852017-06-23 15:06:31 -0700324func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
325 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700326
327 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800328 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700329 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700330 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800331
Dan Willemsen218f6562015-07-08 18:13:11 -0700332 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700333 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700334 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800335 }
336
Colin Cross36242852017-06-23 15:06:31 -0700337 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800338}
339
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800340// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800341// modules. It should be included as an anonymous field in every module
342// struct definition. InitAndroidModule should then be called from the module's
343// factory function, and the return values from InitAndroidModule should be
344// returned from the factory function.
345//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800346// The ModuleBase type is responsible for implementing the GenerateBuildActions
347// method to support the blueprint.Module interface. This method will then call
348// the module's GenerateAndroidBuildActions method once for each build variant
349// that is to be built. GenerateAndroidBuildActions is passed a
350// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800351// AndroidModuleContext exposes extra functionality specific to the Android build
352// system including details about the particular build variant that is to be
353// generated.
354//
355// For example:
356//
357// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800358// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800359// )
360//
361// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800362// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800363// properties struct {
364// MyProperty string
365// }
366// }
367//
Colin Cross36242852017-06-23 15:06:31 -0700368// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800369// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700370// m.AddProperties(&m.properties)
371// android.InitAndroidModule(m)
372// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800373// }
374//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800375// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800376// // Get the CPU architecture for the current build variant.
377// variantArch := ctx.Arch()
378//
379// // ...
380// }
Colin Cross635c3b02016-05-18 15:37:25 -0700381type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 // Putting the curiously recurring thing pointing to the thing that contains
383 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700384 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700385 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800386
Colin Crossfc754582016-05-17 16:34:16 -0700387 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800388 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700389 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800390 hostAndDeviceProperties hostAndDeviceProperties
391 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700392 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700393 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800394
395 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700396 installFiles Paths
397 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700398
399 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
400 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800401 installTarget WritablePath
402 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700403 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700404
Colin Cross178a5092016-09-13 13:42:32 -0700405 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700406
407 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700408
409 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700410 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700411}
412
413func (a *ModuleBase) AddProperties(props ...interface{}) {
414 a.registerProps = append(a.registerProps, props...)
415}
416
417func (a *ModuleBase) GetProperties() []interface{} {
418 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800419}
420
Colin Crossae887032017-10-23 17:16:14 -0700421func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700422 return a.buildParams
423}
424
Colin Crossce75d2c2016-10-06 16:12:58 -0700425// Name returns the name of the module. It may be overridden by individual module types, for
426// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700427func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800428 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700429}
430
Colin Crossce75d2c2016-10-06 16:12:58 -0700431// BaseModuleName returns the name of the module as specified in the blueprints file.
432func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800433 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700434}
435
Colin Cross635c3b02016-05-18 15:37:25 -0700436func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800437 return a
438}
439
Colin Cross8b74d172016-09-13 09:59:14 -0700440func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700441 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700442 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700443}
444
Colin Crossa1ad8d12016-06-01 17:09:44 -0700445func (a *ModuleBase) Target() Target {
446 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800447}
448
Colin Cross8b74d172016-09-13 09:59:14 -0700449func (a *ModuleBase) TargetPrimary() bool {
450 return a.commonProperties.CompilePrimary
451}
452
Colin Crossa1ad8d12016-06-01 17:09:44 -0700453func (a *ModuleBase) Os() OsType {
454 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800455}
456
Colin Cross635c3b02016-05-18 15:37:25 -0700457func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700458 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800459}
460
Colin Cross635c3b02016-05-18 15:37:25 -0700461func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700462 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800463}
464
Dan Willemsen0b24c742016-10-04 15:13:37 -0700465func (a *ModuleBase) ArchSpecific() bool {
466 return a.commonProperties.ArchSpecific
467}
468
Colin Crossa1ad8d12016-06-01 17:09:44 -0700469func (a *ModuleBase) OsClassSupported() []OsClass {
470 switch a.commonProperties.HostOrDeviceSupported {
471 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700472 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700473 case HostSupportedNoCross:
474 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700475 case DeviceSupported:
476 return []OsClass{Device}
477 case HostAndDeviceSupported:
478 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700479 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700480 supported = append(supported, Host, HostCross)
481 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700482 if a.hostAndDeviceProperties.Device_supported == nil ||
483 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700484 supported = append(supported, Device)
485 }
486 return supported
487 default:
488 return nil
489 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800490}
491
Colin Cross635c3b02016-05-18 15:37:25 -0700492func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800493 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
494 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700495 (a.hostAndDeviceProperties.Device_supported == nil ||
496 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800497}
498
Colin Cross635c3b02016-05-18 15:37:25 -0700499func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800500 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800501 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800502 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800503 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800504}
505
Colin Crossce75d2c2016-10-06 16:12:58 -0700506func (a *ModuleBase) SkipInstall() {
507 a.commonProperties.SkipInstall = true
508}
509
Colin Cross635c3b02016-05-18 15:37:25 -0700510func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700511 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800512
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700513 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800514 ctx.VisitDepsDepthFirstIf(isFileInstaller,
515 func(m blueprint.Module) {
516 fileInstaller := m.(fileInstaller)
517 files := fileInstaller.filesToInstall()
518 result = append(result, files...)
519 })
520
521 return result
522}
523
Colin Cross635c3b02016-05-18 15:37:25 -0700524func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800525 return a.installFiles
526}
527
Colin Cross635c3b02016-05-18 15:37:25 -0700528func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800529 return p.noAddressSanitizer
530}
531
Colin Cross635c3b02016-05-18 15:37:25 -0700532func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800533 return false
534}
535
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700536func (p *ModuleBase) InstallInSanitizerDir() bool {
537 return false
538}
539
Colin Cross0875c522017-11-28 17:34:01 -0800540func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700541 allInstalledFiles := Paths{}
542 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800543 ctx.VisitAllModuleVariants(func(module Module) {
544 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700545 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
546 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800547 })
548
Colin Cross0875c522017-11-28 17:34:01 -0800549 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700550
Jeff Gaston088e29e2017-11-29 16:47:17 -0800551 namespacePrefix := ctx.Namespace().(*Namespace).id
552 if namespacePrefix != "" {
553 namespacePrefix = namespacePrefix + "-"
554 }
555
Colin Cross3f40fa42015-01-30 17:27:36 -0800556 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800557 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800558 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700559 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800560 Output: name,
561 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800562 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700563 })
564 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700565 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700566 }
567
568 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800569 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800570 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700571 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800572 Output: name,
573 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700574 })
575 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700576 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700577 }
578
579 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800580 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800581 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800582 suffix = "-soong"
583 }
584
Jeff Gaston088e29e2017-11-29 16:47:17 -0800585 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800586 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700587 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800588 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700589 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800590 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700591
592 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800593 }
594}
595
Jiyong Park2db76922017-11-08 16:03:48 +0900596func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
597 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
598 var deviceSpecific = Bool(a.commonProperties.Device_specific)
599 var productSpecific = Bool(a.commonProperties.Product_specific)
600
601 if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
602 msg := "conflicting value set here"
603 if productSpecific {
604 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
605 if deviceSpecific {
606 ctx.PropertyErrorf("device_specific", msg)
607 }
608 } else {
609 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
610 }
611 if Bool(a.commonProperties.Vendor) {
612 ctx.PropertyErrorf("vendor", msg)
613 }
614 if Bool(a.commonProperties.Proprietary) {
615 ctx.PropertyErrorf("proprietary", msg)
616 }
617 if Bool(a.commonProperties.Soc_specific) {
618 ctx.PropertyErrorf("soc_specific", msg)
619 }
620 }
621
622 if productSpecific {
623 return productSpecificModule
624 } else if deviceSpecific {
625 return deviceSpecificModule
626 } else if socSpecific {
627 return socSpecificModule
628 } else {
629 return platformModule
630 }
631}
632
Colin Cross635c3b02016-05-18 15:37:25 -0700633func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700634 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700635 target: a.commonProperties.CompileTarget,
636 targetPrimary: a.commonProperties.CompilePrimary,
Jiyong Park2db76922017-11-08 16:03:48 +0900637 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700638 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800639 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800640}
641
Colin Cross0875c522017-11-28 17:34:01 -0800642func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
643 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700644 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800645 ModuleContext: blueprintCtx,
646 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
647 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700648 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800649 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800650 }
651
Colin Cross67a5c132017-05-09 13:45:28 -0700652 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
653 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800654 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
655 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700656 }
Colin Cross0875c522017-11-28 17:34:01 -0800657 if !ctx.PrimaryArch() {
658 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700659 }
660
661 ctx.Variable(pctx, "moduleDesc", desc)
662
663 s := ""
664 if len(suffix) > 0 {
665 s = " [" + strings.Join(suffix, " ") + "]"
666 }
667 ctx.Variable(pctx, "moduleDescSuffix", s)
668
Colin Cross9b1d13d2016-09-19 15:18:11 -0700669 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800670 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700671 if ctx.Failed() {
672 return
673 }
674
Colin Cross0875c522017-11-28 17:34:01 -0800675 a.installFiles = append(a.installFiles, ctx.installFiles...)
676 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800677 }
678
Colin Cross9b1d13d2016-09-19 15:18:11 -0700679 if a == ctx.FinalModule().(Module).base() {
680 a.generateModuleTarget(ctx)
681 if ctx.Failed() {
682 return
683 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800684 }
Colin Crosscec81712017-07-13 14:43:27 -0700685
Colin Cross0875c522017-11-28 17:34:01 -0800686 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800687}
688
Colin Crossf6566ed2015-03-24 11:13:38 -0700689type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700690 target Target
691 targetPrimary bool
692 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900693 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700694 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700695}
696
Colin Cross3f40fa42015-01-30 17:27:36 -0800697type androidModuleContext struct {
698 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700699 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700700 installDeps Paths
701 installFiles Paths
702 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800703 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700704 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700705
706 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700707 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800708}
709
Colin Cross67a5c132017-05-09 13:45:28 -0700710func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800711 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700712 Rule: ErrorRule,
713 Description: desc,
714 Outputs: outputs,
715 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800716 Args: map[string]string{
717 "error": err.Error(),
718 },
719 })
720 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800721}
722
Colin Crossaabf6792017-11-29 00:27:14 -0800723func (a *androidModuleContext) Config() Config {
724 return a.ModuleContext.Config().(Config)
725}
726
Colin Cross0875c522017-11-28 17:34:01 -0800727func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700728 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800729}
730
Colin Cross0875c522017-11-28 17:34:01 -0800731func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700732 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700733 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800734 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800735 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700736 Outputs: params.Outputs.Strings(),
737 ImplicitOutputs: params.ImplicitOutputs.Strings(),
738 Inputs: params.Inputs.Strings(),
739 Implicits: params.Implicits.Strings(),
740 OrderOnly: params.OrderOnly.Strings(),
741 Args: params.Args,
742 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700743 }
744
Colin Cross33bfb0a2016-11-21 17:23:08 -0800745 if params.Depfile != nil {
746 bparams.Depfile = params.Depfile.String()
747 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700748 if params.Output != nil {
749 bparams.Outputs = append(bparams.Outputs, params.Output.String())
750 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700751 if params.ImplicitOutput != nil {
752 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
753 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700754 if params.Input != nil {
755 bparams.Inputs = append(bparams.Inputs, params.Input.String())
756 }
757 if params.Implicit != nil {
758 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
759 }
760
Colin Cross0875c522017-11-28 17:34:01 -0800761 return bparams
762}
763
764func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
765 a.ModuleContext.Variable(pctx.PackageContext, name, value)
766}
767
768func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
769 argNames ...string) blueprint.Rule {
770
771 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
772}
773
774func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
775 if a.config.captureBuild {
776 a.buildParams = append(a.buildParams, params)
777 }
778
779 bparams := convertBuildParams(params)
780
781 if bparams.Description != "" {
782 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
783 }
784
Colin Cross6ff51382015-12-17 16:39:19 -0800785 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700786 a.ninjaError(bparams.Description, bparams.Outputs,
787 fmt.Errorf("module %s missing dependencies: %s\n",
788 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800789 return
790 }
791
Colin Cross0875c522017-11-28 17:34:01 -0800792 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700793}
794
Colin Cross6ff51382015-12-17 16:39:19 -0800795func (a *androidModuleContext) GetMissingDependencies() []string {
796 return a.missingDeps
797}
798
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800799func (a *androidModuleContext) AddMissingDependencies(deps []string) {
800 if deps != nil {
801 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700802 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800803 }
804}
805
Colin Crossd11fcda2017-10-23 17:59:01 -0700806func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
807 aModule, _ := module.(Module)
808 if aModule == nil {
809 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
810 return nil
811 }
812
813 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800814 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700815 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
816 } else {
817 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
818 }
819 return nil
820 }
821
822 return aModule
823}
824
Colin Cross35143d02017-11-16 00:11:20 -0800825func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
826 a.ModuleContext.VisitDirectDeps(visit)
827}
828
Colin Crossd11fcda2017-10-23 17:59:01 -0700829func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
830 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
831 if aModule := a.validateAndroidModule(module); aModule != nil {
832 visit(aModule)
833 }
834 })
835}
836
Colin Crossee6143c2017-12-30 17:54:27 -0800837func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
838 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
839 if aModule := a.validateAndroidModule(module); aModule != nil {
840 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
841 visit(aModule)
842 }
843 }
844 })
845}
846
Colin Crossd11fcda2017-10-23 17:59:01 -0700847func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
848 a.ModuleContext.VisitDirectDepsIf(
849 // pred
850 func(module blueprint.Module) bool {
851 if aModule := a.validateAndroidModule(module); aModule != nil {
852 return pred(aModule)
853 } else {
854 return false
855 }
856 },
857 // visit
858 func(module blueprint.Module) {
859 visit(module.(Module))
860 })
861}
862
863func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
864 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
865 if aModule := a.validateAndroidModule(module); aModule != nil {
866 visit(aModule)
867 }
868 })
869}
870
871func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
872 a.ModuleContext.VisitDepsDepthFirstIf(
873 // pred
874 func(module blueprint.Module) bool {
875 if aModule := a.validateAndroidModule(module); aModule != nil {
876 return pred(aModule)
877 } else {
878 return false
879 }
880 },
881 // visit
882 func(module blueprint.Module) {
883 visit(module.(Module))
884 })
885}
886
887func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
888 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
889 childAndroidModule := a.validateAndroidModule(child)
890 parentAndroidModule := a.validateAndroidModule(parent)
891 if childAndroidModule != nil && parentAndroidModule != nil {
892 return visit(childAndroidModule, parentAndroidModule)
893 } else {
894 return false
895 }
896 })
897}
898
Colin Cross0875c522017-11-28 17:34:01 -0800899func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
900 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
901 visit(module.(Module))
902 })
903}
904
905func (a *androidModuleContext) PrimaryModule() Module {
906 return a.ModuleContext.PrimaryModule().(Module)
907}
908
909func (a *androidModuleContext) FinalModule() Module {
910 return a.ModuleContext.FinalModule().(Module)
911}
912
Colin Crossa1ad8d12016-06-01 17:09:44 -0700913func (a *androidBaseContextImpl) Target() Target {
914 return a.target
915}
916
Colin Cross8b74d172016-09-13 09:59:14 -0700917func (a *androidBaseContextImpl) TargetPrimary() bool {
918 return a.targetPrimary
919}
920
Colin Crossf6566ed2015-03-24 11:13:38 -0700921func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700922 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800923}
924
Colin Crossa1ad8d12016-06-01 17:09:44 -0700925func (a *androidBaseContextImpl) Os() OsType {
926 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800927}
928
Colin Crossf6566ed2015-03-24 11:13:38 -0700929func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700930 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700931}
932
933func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700934 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700935}
936
Colin Cross0af4b842015-04-30 16:36:18 -0700937func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700938 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700939}
940
Colin Cross3edeee12017-04-04 12:59:48 -0700941func (a *androidBaseContextImpl) Windows() bool {
942 return a.target.Os == Windows
943}
944
Colin Crossf6566ed2015-03-24 11:13:38 -0700945func (a *androidBaseContextImpl) Debug() bool {
946 return a.debug
947}
948
Colin Cross1e7d3702016-08-24 15:25:47 -0700949func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700950 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
951 return true
952 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700953 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
954}
955
Colin Cross1332b002015-04-07 17:11:30 -0700956func (a *androidBaseContextImpl) AConfig() Config {
957 return a.config
958}
959
Colin Cross9272ade2016-08-17 15:24:12 -0700960func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
961 return DeviceConfig{a.config.deviceConfig}
962}
963
Jiyong Park2db76922017-11-08 16:03:48 +0900964func (a *androidBaseContextImpl) Platform() bool {
965 return a.kind == platformModule
966}
967
968func (a *androidBaseContextImpl) DeviceSpecific() bool {
969 return a.kind == deviceSpecificModule
970}
971
972func (a *androidBaseContextImpl) SocSpecific() bool {
973 return a.kind == socSpecificModule
974}
975
976func (a *androidBaseContextImpl) ProductSpecific() bool {
977 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -0800978}
979
Colin Cross8d8f8e22016-08-03 11:57:50 -0700980func (a *androidModuleContext) InstallInData() bool {
981 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800982}
983
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700984func (a *androidModuleContext) InstallInSanitizerDir() bool {
985 return a.module.InstallInSanitizerDir()
986}
987
Colin Cross893d8162017-04-26 17:34:03 -0700988func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
989 if a.module.base().commonProperties.SkipInstall {
990 return true
991 }
992
993 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -0800994 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -0700995 return true
996 }
997
Colin Cross6510f912017-11-29 00:27:14 -0800998 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -0700999 return true
1000 }
1001 }
1002
1003 return false
1004}
1005
Colin Cross5c517922017-08-31 12:29:17 -07001006func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001007 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001008 return a.installFile(installPath, name, srcPath, Cp, deps)
1009}
1010
1011func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1012 deps ...Path) OutputPath {
1013 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1014}
1015
1016func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1017 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001018
Dan Willemsen782a2d12015-12-21 14:55:28 -08001019 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001020 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001021
Colin Cross893d8162017-04-26 17:34:03 -07001022 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001023
Dan Willemsen322acaf2016-01-12 23:07:05 -08001024 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001025
Colin Cross89562dc2016-10-03 17:47:19 -07001026 var implicitDeps, orderOnlyDeps Paths
1027
1028 if a.Host() {
1029 // Installed host modules might be used during the build, depend directly on their
1030 // dependencies so their timestamp is updated whenever their dependency is updated
1031 implicitDeps = deps
1032 } else {
1033 orderOnlyDeps = deps
1034 }
1035
Colin Crossae887032017-10-23 17:16:14 -07001036 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001037 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001038 Description: "install " + fullInstallPath.Base(),
1039 Output: fullInstallPath,
1040 Input: srcPath,
1041 Implicits: implicitDeps,
1042 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001043 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001044 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001045
Dan Willemsen322acaf2016-01-12 23:07:05 -08001046 a.installFiles = append(a.installFiles, fullInstallPath)
1047 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001048 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001049 return fullInstallPath
1050}
1051
Colin Cross3854a602016-01-11 12:49:11 -08001052func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1053 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001054 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001055
Colin Cross893d8162017-04-26 17:34:03 -07001056 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001057
Colin Crossae887032017-10-23 17:16:14 -07001058 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001059 Rule: Symlink,
1060 Description: "install symlink " + fullInstallPath.Base(),
1061 Output: fullInstallPath,
1062 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001063 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001064 Args: map[string]string{
1065 "fromPath": srcPath.String(),
1066 },
1067 })
Colin Cross3854a602016-01-11 12:49:11 -08001068
Colin Cross12fc4972016-01-11 12:49:11 -08001069 a.installFiles = append(a.installFiles, fullInstallPath)
1070 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1071 }
Colin Cross3854a602016-01-11 12:49:11 -08001072 return fullInstallPath
1073}
1074
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001075func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001076 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1077}
1078
Colin Cross3f40fa42015-01-30 17:27:36 -08001079type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001080 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001081}
1082
1083func isFileInstaller(m blueprint.Module) bool {
1084 _, ok := m.(fileInstaller)
1085 return ok
1086}
1087
1088func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001089 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001090 return ok
1091}
Colin Crossfce53272015-04-08 11:21:40 -07001092
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001093func findStringInSlice(str string, slice []string) int {
1094 for i, s := range slice {
1095 if s == str {
1096 return i
Colin Crossfce53272015-04-08 11:21:40 -07001097 }
1098 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001099 return -1
1100}
1101
Colin Cross068e0fe2016-12-13 15:23:47 -08001102func SrcIsModule(s string) string {
1103 if len(s) > 1 && s[0] == ':' {
1104 return s[1:]
1105 }
1106 return ""
1107}
1108
1109type sourceDependencyTag struct {
1110 blueprint.BaseDependencyTag
1111}
1112
1113var SourceDepTag sourceDependencyTag
1114
Colin Cross366938f2017-12-11 16:29:02 -08001115// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1116// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001117func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1118 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001119 set := make(map[string]bool)
1120
Colin Cross068e0fe2016-12-13 15:23:47 -08001121 for _, s := range srcFiles {
1122 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001123 if _, found := set[m]; found {
1124 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1125 } else {
1126 set[m] = true
1127 deps = append(deps, m)
1128 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001129 }
1130 }
1131
1132 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1133}
1134
Colin Cross366938f2017-12-11 16:29:02 -08001135// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1136// using ":module" syntax, if any.
1137func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1138 if s != nil {
1139 if m := SrcIsModule(*s); m != "" {
1140 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1141 }
1142 }
1143}
1144
Colin Cross068e0fe2016-12-13 15:23:47 -08001145type SourceFileProducer interface {
1146 Srcs() Paths
1147}
1148
1149// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001150// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001151func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001152 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1153}
1154
Colin Cross366938f2017-12-11 16:29:02 -08001155// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1156// ExtractSourceDeps must have already been called during the dependency resolution phase.
1157func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1158 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1159 if len(srcFiles) == 1 {
1160 return srcFiles[0]
1161 } else {
1162 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1163 return nil
1164 }
1165}
1166
Colin Cross2383f3b2018-02-06 14:40:13 -08001167// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1168// the srcFile is non-nil.
1169// ExtractSourceDeps must have already been called during the dependency resolution phase.
1170func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1171 if srcFile != nil {
1172 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1173 }
1174 return OptionalPath{}
1175}
1176
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001177func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001178 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001179
Colin Cross461b4452018-02-23 09:22:42 -08001180 var expandedExcludes []string
1181 if excludes != nil {
1182 expandedExcludes = make([]string, 0, len(excludes))
1183 }
Nan Zhang27e284d2018-02-09 21:03:53 +00001184
1185 for _, e := range excludes {
1186 if m := SrcIsModule(e); m != "" {
1187 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1188 if module == nil {
1189 // Error will have been handled by ExtractSourcesDeps
1190 continue
1191 }
1192 if srcProducer, ok := module.(SourceFileProducer); ok {
1193 expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1194 } else {
1195 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1196 }
1197 } else {
1198 expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001199 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001200 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001201 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001202 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001203 if m := SrcIsModule(s); m != "" {
1204 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001205 if module == nil {
1206 // Error will have been handled by ExtractSourcesDeps
1207 continue
1208 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001209 if srcProducer, ok := module.(SourceFileProducer); ok {
Nan Zhang27e284d2018-02-09 21:03:53 +00001210 moduleSrcs := srcProducer.Srcs()
1211 for _, e := range expandedExcludes {
1212 for j, ms := range moduleSrcs {
1213 if ms.String() == e {
1214 moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1215 }
1216 }
1217 }
1218 expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001219 } else {
1220 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1221 }
1222 } else if pathtools.IsGlob(s) {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001223 globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001224 for i, s := range globbedSrcFiles {
1225 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001226 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001227 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001228 } else {
Nan Zhang27e284d2018-02-09 21:03:53 +00001229 p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1230 j := findStringInSlice(p.String(), expandedExcludes)
1231 if j == -1 {
1232 expandedSrcFiles = append(expandedSrcFiles, p)
1233 }
1234
Colin Cross8f101b42015-06-17 15:09:06 -07001235 }
1236 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001237 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001238}
1239
Nan Zhang6d34b302017-02-04 17:47:46 -08001240func (ctx *androidModuleContext) RequiredModuleNames() []string {
1241 return ctx.module.base().commonProperties.Required
1242}
1243
Colin Cross7f19f372016-11-01 11:10:25 -07001244func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1245 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001246 if err != nil {
1247 ctx.ModuleErrorf("glob: %s", err.Error())
1248 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001249 return pathsForModuleSrcFromFullPath(ctx, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001250}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001251
Nan Zhang581fd212018-01-10 16:06:12 -08001252func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001253 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001254 if err != nil {
1255 ctx.ModuleErrorf("glob: %s", err.Error())
1256 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001257 return pathsForModuleSrcFromFullPath(ctx, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001258}
1259
Colin Cross463a90e2015-06-17 14:20:06 -07001260func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001261 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001262}
1263
Colin Cross0875c522017-11-28 17:34:01 -08001264func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001265 return &buildTargetSingleton{}
1266}
1267
Colin Cross87d8b562017-04-25 10:01:55 -07001268func parentDir(dir string) string {
1269 dir, _ = filepath.Split(dir)
1270 return filepath.Clean(dir)
1271}
1272
Colin Cross1f8c52b2015-06-16 16:38:17 -07001273type buildTargetSingleton struct{}
1274
Colin Cross0875c522017-11-28 17:34:01 -08001275func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1276 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001277
Colin Cross0875c522017-11-28 17:34:01 -08001278 mmTarget := func(dir string) WritablePath {
1279 return PathForPhony(ctx,
1280 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001281 }
1282
Colin Cross0875c522017-11-28 17:34:01 -08001283 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001284
Colin Cross0875c522017-11-28 17:34:01 -08001285 ctx.VisitAllModules(func(module Module) {
1286 blueprintDir := module.base().blueprintDir
1287 installTarget := module.base().installTarget
1288 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001289
Colin Cross0875c522017-11-28 17:34:01 -08001290 if checkbuildTarget != nil {
1291 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1292 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1293 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001294
Colin Cross0875c522017-11-28 17:34:01 -08001295 if installTarget != nil {
1296 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001297 }
1298 })
1299
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001300 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001301 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001302 suffix = "-soong"
1303 }
1304
Colin Cross1f8c52b2015-06-16 16:38:17 -07001305 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001306 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001307 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001308 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001309 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001310 })
1311
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001312 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001313 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001314 return
1315 }
1316
Colin Cross0875c522017-11-28 17:34:01 -08001317 sortedKeys := func(m map[string]Paths) []string {
1318 s := make([]string, 0, len(m))
1319 for k := range m {
1320 s = append(s, k)
1321 }
1322 sort.Strings(s)
1323 return s
1324 }
1325
Colin Cross87d8b562017-04-25 10:01:55 -07001326 // Ensure ancestor directories are in modulesInDir
1327 dirs := sortedKeys(modulesInDir)
1328 for _, dir := range dirs {
1329 dir := parentDir(dir)
1330 for dir != "." && dir != "/" {
1331 if _, exists := modulesInDir[dir]; exists {
1332 break
1333 }
1334 modulesInDir[dir] = nil
1335 dir = parentDir(dir)
1336 }
1337 }
1338
1339 // Make directories build their direct subdirectories
1340 dirs = sortedKeys(modulesInDir)
1341 for _, dir := range dirs {
1342 p := parentDir(dir)
1343 if p != "." && p != "/" {
1344 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1345 }
1346 }
1347
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001348 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1349 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1350 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001351 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001352 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001353 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001354 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001355 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001356 // HACK: checkbuild should be an optional build, but force it
1357 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001358 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001359 })
1360 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001361
1362 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1363 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001364 ctx.VisitAllModules(func(module Module) {
1365 if module.Enabled() {
1366 os := module.Target().Os
1367 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001368 }
1369 })
1370
Colin Cross0875c522017-11-28 17:34:01 -08001371 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001372 for os, deps := range osDeps {
1373 var className string
1374
1375 switch os.Class {
1376 case Host:
1377 className = "host"
1378 case HostCross:
1379 className = "host-cross"
1380 case Device:
1381 className = "target"
1382 default:
1383 continue
1384 }
1385
Colin Cross0875c522017-11-28 17:34:01 -08001386 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001387 osClass[className] = append(osClass[className], name)
1388
Colin Cross0875c522017-11-28 17:34:01 -08001389 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001390 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001391 Output: name,
1392 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001393 })
1394 }
1395
1396 // Wrap those into host|host-cross|target phony rules
1397 osClasses := sortedKeys(osClass)
1398 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001399 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001400 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001401 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001402 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001403 })
1404 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001405}
Colin Crossd779da42015-12-17 18:00:23 -08001406
1407type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001408 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001409 ctx interface {
1410 ModuleName(blueprint.Module) string
1411 ModuleSubDir(blueprint.Module) string
1412 }
1413}
1414
1415func (s AndroidModulesByName) Len() int { return len(s.slice) }
1416func (s AndroidModulesByName) Less(i, j int) bool {
1417 mi, mj := s.slice[i], s.slice[j]
1418 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1419
1420 if ni != nj {
1421 return ni < nj
1422 } else {
1423 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1424 }
1425}
1426func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }