blob: 9de5294a0433a45d14775de1cb5b4b4380a7ed27 [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
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700116
Colin Cross5c517922017-08-31 12:29:17 -0700117 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
118 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800119 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700120 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800121
122 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700123
Colin Cross8d8f8e22016-08-03 11:57:50 -0700124 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700125 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800126
127 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700128
129 // android.ModuleContext methods
130 // These are duplicated instead of embedded so that can eventually be wrapped to take an
131 // android.Module instead of a blueprint.Module
132 OtherModuleName(m blueprint.Module) string
133 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
134 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
135
136 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
137 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
138
139 ModuleSubDir() string
140
Colin Cross35143d02017-11-16 00:11:20 -0800141 VisitDirectDepsBlueprint(visit func(blueprint.Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700142 VisitDirectDeps(visit func(Module))
Colin Crossee6143c2017-12-30 17:54:27 -0800143 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700144 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
145 VisitDepsDepthFirst(visit func(Module))
146 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
147 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700148
Colin Cross0875c522017-11-28 17:34:01 -0800149 Variable(pctx PackageContext, name, value string)
150 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700151 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
152 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800153 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700154
Colin Cross0875c522017-11-28 17:34:01 -0800155 PrimaryModule() Module
156 FinalModule() Module
157 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700158
159 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800160 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800161}
162
Colin Cross635c3b02016-05-18 15:37:25 -0700163type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800164 blueprint.Module
165
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700166 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
167 // but GenerateAndroidBuildActions also has access to Android-specific information.
168 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700169 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700170
Colin Cross1e676be2016-10-12 14:38:15 -0700171 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800172
Colin Cross635c3b02016-05-18 15:37:25 -0700173 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800174 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700175 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800176 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700177 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800178 SkipInstall()
Colin Cross36242852017-06-23 15:06:31 -0700179
180 AddProperties(props ...interface{})
181 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700182
Colin Crossae887032017-10-23 17:16:14 -0700183 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800184}
185
Colin Crossfc754582016-05-17 16:34:16 -0700186type nameProperties struct {
187 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800188 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700189}
190
191type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700192 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800193
Dan Willemsen0effe062015-11-30 16:06:01 -0800194 // emit build rules for this module
195 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800196
Colin Cross7d5136f2015-05-11 13:39:40 -0700197 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800198 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
199 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
200 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700201 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700202
203 Target struct {
204 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700205 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700206 }
207 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700208 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700209 }
210 }
211
212 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800213
Dan Willemsen782a2d12015-12-21 14:55:28 -0800214 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700215 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800216
Colin Cross55708f32017-03-20 13:23:34 -0700217 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700218 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700219
Jiyong Park2db76922017-11-08 16:03:48 +0900220 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
221 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
222 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700223 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700224
Jiyong Park2db76922017-11-08 16:03:48 +0900225 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
226 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
227 Soc_specific *bool
228
229 // whether this module is specific to a device, not only for SoC, but also for off-chip
230 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
231 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
232 // This implies `soc_specific:true`.
233 Device_specific *bool
234
235 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900236 // network operator, etc). When set to true, it is installed into /product (or
237 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900238 Product_specific *bool
239
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700240 // init.rc files to be installed if this module is installed
241 Init_rc []string
242
Chris Wolfe998306e2016-08-15 14:47:23 -0400243 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700244 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400245
Colin Cross5aac3622017-08-31 15:07:09 -0700246 // relative path to a file to include in the list of notices for the device
247 Notice *string
248
Colin Crossa1ad8d12016-06-01 17:09:44 -0700249 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700250 CompileTarget Target `blueprint:"mutated"`
251 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800252
253 // Set by InitAndroidModule
254 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700255 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700256
257 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800258
259 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800260}
261
262type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700263 Host_supported *bool
264 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800265}
266
Colin Crossc472d572015-03-17 15:06:21 -0700267type Multilib string
268
269const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800270 MultilibBoth Multilib = "both"
271 MultilibFirst Multilib = "first"
272 MultilibCommon Multilib = "common"
273 MultilibCommonFirst Multilib = "common_first"
274 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700275)
276
Colin Crossa1ad8d12016-06-01 17:09:44 -0700277type HostOrDeviceSupported int
278
279const (
280 _ HostOrDeviceSupported = iota
281 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700282 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700283 DeviceSupported
284 HostAndDeviceSupported
285 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700286 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700287)
288
Jiyong Park2db76922017-11-08 16:03:48 +0900289type moduleKind int
290
291const (
292 platformModule moduleKind = iota
293 deviceSpecificModule
294 socSpecificModule
295 productSpecificModule
296)
297
298func (k moduleKind) String() string {
299 switch k {
300 case platformModule:
301 return "platform"
302 case deviceSpecificModule:
303 return "device-specific"
304 case socSpecificModule:
305 return "soc-specific"
306 case productSpecificModule:
307 return "product-specific"
308 default:
309 panic(fmt.Errorf("unknown module kind %d", k))
310 }
311}
312
Colin Cross36242852017-06-23 15:06:31 -0700313func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800314 base := m.base()
315 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700316
Colin Cross36242852017-06-23 15:06:31 -0700317 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700318 &base.nameProperties,
319 &base.commonProperties,
320 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700321}
322
Colin Cross36242852017-06-23 15:06:31 -0700323func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
324 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700325
326 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800327 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700328 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700329 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800330
Dan Willemsen218f6562015-07-08 18:13:11 -0700331 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700332 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700333 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800334 }
335
Colin Cross36242852017-06-23 15:06:31 -0700336 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800337}
338
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800339// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800340// modules. It should be included as an anonymous field in every module
341// struct definition. InitAndroidModule should then be called from the module's
342// factory function, and the return values from InitAndroidModule should be
343// returned from the factory function.
344//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800345// The ModuleBase type is responsible for implementing the GenerateBuildActions
346// method to support the blueprint.Module interface. This method will then call
347// the module's GenerateAndroidBuildActions method once for each build variant
348// that is to be built. GenerateAndroidBuildActions is passed a
349// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800350// AndroidModuleContext exposes extra functionality specific to the Android build
351// system including details about the particular build variant that is to be
352// generated.
353//
354// For example:
355//
356// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800357// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800358// )
359//
360// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800361// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800362// properties struct {
363// MyProperty string
364// }
365// }
366//
Colin Cross36242852017-06-23 15:06:31 -0700367// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800368// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700369// m.AddProperties(&m.properties)
370// android.InitAndroidModule(m)
371// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800372// }
373//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800374// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800375// // Get the CPU architecture for the current build variant.
376// variantArch := ctx.Arch()
377//
378// // ...
379// }
Colin Cross635c3b02016-05-18 15:37:25 -0700380type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800381 // Putting the curiously recurring thing pointing to the thing that contains
382 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700383 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700384 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800385
Colin Crossfc754582016-05-17 16:34:16 -0700386 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800387 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700388 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800389 hostAndDeviceProperties hostAndDeviceProperties
390 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700391 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700392 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800393
394 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700395 installFiles Paths
396 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700397
398 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
399 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800400 installTarget WritablePath
401 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700402 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700403
Colin Cross178a5092016-09-13 13:42:32 -0700404 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700405
406 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700407
408 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700409 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700410}
411
412func (a *ModuleBase) AddProperties(props ...interface{}) {
413 a.registerProps = append(a.registerProps, props...)
414}
415
416func (a *ModuleBase) GetProperties() []interface{} {
417 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800418}
419
Colin Crossae887032017-10-23 17:16:14 -0700420func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700421 return a.buildParams
422}
423
Colin Crossce75d2c2016-10-06 16:12:58 -0700424// Name returns the name of the module. It may be overridden by individual module types, for
425// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700426func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800427 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700428}
429
Colin Crossce75d2c2016-10-06 16:12:58 -0700430// BaseModuleName returns the name of the module as specified in the blueprints file.
431func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800432 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700433}
434
Colin Cross635c3b02016-05-18 15:37:25 -0700435func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800436 return a
437}
438
Colin Cross8b74d172016-09-13 09:59:14 -0700439func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700440 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700441 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700442}
443
Colin Crossa1ad8d12016-06-01 17:09:44 -0700444func (a *ModuleBase) Target() Target {
445 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800446}
447
Colin Cross8b74d172016-09-13 09:59:14 -0700448func (a *ModuleBase) TargetPrimary() bool {
449 return a.commonProperties.CompilePrimary
450}
451
Colin Crossa1ad8d12016-06-01 17:09:44 -0700452func (a *ModuleBase) Os() OsType {
453 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800454}
455
Colin Cross635c3b02016-05-18 15:37:25 -0700456func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700457 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800458}
459
Colin Cross635c3b02016-05-18 15:37:25 -0700460func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700461 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800462}
463
Dan Willemsen0b24c742016-10-04 15:13:37 -0700464func (a *ModuleBase) ArchSpecific() bool {
465 return a.commonProperties.ArchSpecific
466}
467
Colin Crossa1ad8d12016-06-01 17:09:44 -0700468func (a *ModuleBase) OsClassSupported() []OsClass {
469 switch a.commonProperties.HostOrDeviceSupported {
470 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700471 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700472 case HostSupportedNoCross:
473 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700474 case DeviceSupported:
475 return []OsClass{Device}
476 case HostAndDeviceSupported:
477 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700478 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700479 supported = append(supported, Host, HostCross)
480 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700481 if a.hostAndDeviceProperties.Device_supported == nil ||
482 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700483 supported = append(supported, Device)
484 }
485 return supported
486 default:
487 return nil
488 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800489}
490
Colin Cross635c3b02016-05-18 15:37:25 -0700491func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800492 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
493 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700494 (a.hostAndDeviceProperties.Device_supported == nil ||
495 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800496}
497
Colin Cross635c3b02016-05-18 15:37:25 -0700498func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800499 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800500 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800501 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800502 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800503}
504
Colin Crossce75d2c2016-10-06 16:12:58 -0700505func (a *ModuleBase) SkipInstall() {
506 a.commonProperties.SkipInstall = true
507}
508
Colin Cross635c3b02016-05-18 15:37:25 -0700509func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700510 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800511
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700512 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800513 ctx.VisitDepsDepthFirstIf(isFileInstaller,
514 func(m blueprint.Module) {
515 fileInstaller := m.(fileInstaller)
516 files := fileInstaller.filesToInstall()
517 result = append(result, files...)
518 })
519
520 return result
521}
522
Colin Cross635c3b02016-05-18 15:37:25 -0700523func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800524 return a.installFiles
525}
526
Colin Cross635c3b02016-05-18 15:37:25 -0700527func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800528 return p.noAddressSanitizer
529}
530
Colin Cross635c3b02016-05-18 15:37:25 -0700531func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800532 return false
533}
534
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700535func (p *ModuleBase) InstallInSanitizerDir() bool {
536 return false
537}
538
Colin Cross0875c522017-11-28 17:34:01 -0800539func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700540 allInstalledFiles := Paths{}
541 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800542 ctx.VisitAllModuleVariants(func(module Module) {
543 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700544 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
545 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800546 })
547
Colin Cross0875c522017-11-28 17:34:01 -0800548 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700549
Jeff Gaston088e29e2017-11-29 16:47:17 -0800550 namespacePrefix := ctx.Namespace().(*Namespace).id
551 if namespacePrefix != "" {
552 namespacePrefix = namespacePrefix + "-"
553 }
554
Colin Cross3f40fa42015-01-30 17:27:36 -0800555 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800556 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800557 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700558 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800559 Output: name,
560 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800561 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700562 })
563 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700564 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700565 }
566
567 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800568 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800569 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700570 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800571 Output: name,
572 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700573 })
574 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700575 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700576 }
577
578 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800579 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800580 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800581 suffix = "-soong"
582 }
583
Jeff Gaston088e29e2017-11-29 16:47:17 -0800584 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800585 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700586 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800587 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700588 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800589 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700590
591 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800592 }
593}
594
Jiyong Park2db76922017-11-08 16:03:48 +0900595func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
596 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
597 var deviceSpecific = Bool(a.commonProperties.Device_specific)
598 var productSpecific = Bool(a.commonProperties.Product_specific)
599
600 if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
601 msg := "conflicting value set here"
602 if productSpecific {
603 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
604 if deviceSpecific {
605 ctx.PropertyErrorf("device_specific", msg)
606 }
607 } else {
608 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
609 }
610 if Bool(a.commonProperties.Vendor) {
611 ctx.PropertyErrorf("vendor", msg)
612 }
613 if Bool(a.commonProperties.Proprietary) {
614 ctx.PropertyErrorf("proprietary", msg)
615 }
616 if Bool(a.commonProperties.Soc_specific) {
617 ctx.PropertyErrorf("soc_specific", msg)
618 }
619 }
620
621 if productSpecific {
622 return productSpecificModule
623 } else if deviceSpecific {
624 return deviceSpecificModule
625 } else if socSpecific {
626 return socSpecificModule
627 } else {
628 return platformModule
629 }
630}
631
Colin Cross635c3b02016-05-18 15:37:25 -0700632func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700633 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700634 target: a.commonProperties.CompileTarget,
635 targetPrimary: a.commonProperties.CompilePrimary,
Jiyong Park2db76922017-11-08 16:03:48 +0900636 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700637 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800638 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800639}
640
Colin Cross0875c522017-11-28 17:34:01 -0800641func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
642 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700643 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800644 ModuleContext: blueprintCtx,
645 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
646 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700647 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800648 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800649 }
650
Colin Cross67a5c132017-05-09 13:45:28 -0700651 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
652 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800653 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
654 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700655 }
Colin Cross0875c522017-11-28 17:34:01 -0800656 if !ctx.PrimaryArch() {
657 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700658 }
659
660 ctx.Variable(pctx, "moduleDesc", desc)
661
662 s := ""
663 if len(suffix) > 0 {
664 s = " [" + strings.Join(suffix, " ") + "]"
665 }
666 ctx.Variable(pctx, "moduleDescSuffix", s)
667
Colin Cross9b1d13d2016-09-19 15:18:11 -0700668 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800669 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700670 if ctx.Failed() {
671 return
672 }
673
Colin Cross0875c522017-11-28 17:34:01 -0800674 a.installFiles = append(a.installFiles, ctx.installFiles...)
675 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800676 }
677
Colin Cross9b1d13d2016-09-19 15:18:11 -0700678 if a == ctx.FinalModule().(Module).base() {
679 a.generateModuleTarget(ctx)
680 if ctx.Failed() {
681 return
682 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800683 }
Colin Crosscec81712017-07-13 14:43:27 -0700684
Colin Cross0875c522017-11-28 17:34:01 -0800685 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800686}
687
Colin Crossf6566ed2015-03-24 11:13:38 -0700688type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700689 target Target
690 targetPrimary bool
691 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900692 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700693 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700694}
695
Colin Cross3f40fa42015-01-30 17:27:36 -0800696type androidModuleContext struct {
697 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700698 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700699 installDeps Paths
700 installFiles Paths
701 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800702 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700703 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700704
705 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700706 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800707}
708
Colin Cross67a5c132017-05-09 13:45:28 -0700709func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800710 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700711 Rule: ErrorRule,
712 Description: desc,
713 Outputs: outputs,
714 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800715 Args: map[string]string{
716 "error": err.Error(),
717 },
718 })
719 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800720}
721
Colin Crossaabf6792017-11-29 00:27:14 -0800722func (a *androidModuleContext) Config() Config {
723 return a.ModuleContext.Config().(Config)
724}
725
Colin Cross0875c522017-11-28 17:34:01 -0800726func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700727 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800728}
729
Colin Cross0875c522017-11-28 17:34:01 -0800730func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700731 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700732 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800733 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800734 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700735 Outputs: params.Outputs.Strings(),
736 ImplicitOutputs: params.ImplicitOutputs.Strings(),
737 Inputs: params.Inputs.Strings(),
738 Implicits: params.Implicits.Strings(),
739 OrderOnly: params.OrderOnly.Strings(),
740 Args: params.Args,
741 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700742 }
743
Colin Cross33bfb0a2016-11-21 17:23:08 -0800744 if params.Depfile != nil {
745 bparams.Depfile = params.Depfile.String()
746 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700747 if params.Output != nil {
748 bparams.Outputs = append(bparams.Outputs, params.Output.String())
749 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700750 if params.ImplicitOutput != nil {
751 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
752 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700753 if params.Input != nil {
754 bparams.Inputs = append(bparams.Inputs, params.Input.String())
755 }
756 if params.Implicit != nil {
757 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
758 }
759
Colin Cross0875c522017-11-28 17:34:01 -0800760 return bparams
761}
762
763func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
764 a.ModuleContext.Variable(pctx.PackageContext, name, value)
765}
766
767func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
768 argNames ...string) blueprint.Rule {
769
770 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
771}
772
773func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
774 if a.config.captureBuild {
775 a.buildParams = append(a.buildParams, params)
776 }
777
778 bparams := convertBuildParams(params)
779
780 if bparams.Description != "" {
781 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
782 }
783
Colin Cross6ff51382015-12-17 16:39:19 -0800784 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700785 a.ninjaError(bparams.Description, bparams.Outputs,
786 fmt.Errorf("module %s missing dependencies: %s\n",
787 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800788 return
789 }
790
Colin Cross0875c522017-11-28 17:34:01 -0800791 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700792}
793
Colin Cross6ff51382015-12-17 16:39:19 -0800794func (a *androidModuleContext) GetMissingDependencies() []string {
795 return a.missingDeps
796}
797
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800798func (a *androidModuleContext) AddMissingDependencies(deps []string) {
799 if deps != nil {
800 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700801 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800802 }
803}
804
Colin Crossd11fcda2017-10-23 17:59:01 -0700805func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
806 aModule, _ := module.(Module)
807 if aModule == nil {
808 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
809 return nil
810 }
811
812 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800813 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700814 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
815 } else {
816 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
817 }
818 return nil
819 }
820
821 return aModule
822}
823
Colin Cross35143d02017-11-16 00:11:20 -0800824func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
825 a.ModuleContext.VisitDirectDeps(visit)
826}
827
Colin Crossd11fcda2017-10-23 17:59:01 -0700828func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
829 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
830 if aModule := a.validateAndroidModule(module); aModule != nil {
831 visit(aModule)
832 }
833 })
834}
835
Colin Crossee6143c2017-12-30 17:54:27 -0800836func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
837 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
838 if aModule := a.validateAndroidModule(module); aModule != nil {
839 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
840 visit(aModule)
841 }
842 }
843 })
844}
845
Colin Crossd11fcda2017-10-23 17:59:01 -0700846func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
847 a.ModuleContext.VisitDirectDepsIf(
848 // pred
849 func(module blueprint.Module) bool {
850 if aModule := a.validateAndroidModule(module); aModule != nil {
851 return pred(aModule)
852 } else {
853 return false
854 }
855 },
856 // visit
857 func(module blueprint.Module) {
858 visit(module.(Module))
859 })
860}
861
862func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
863 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
864 if aModule := a.validateAndroidModule(module); aModule != nil {
865 visit(aModule)
866 }
867 })
868}
869
870func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
871 a.ModuleContext.VisitDepsDepthFirstIf(
872 // pred
873 func(module blueprint.Module) bool {
874 if aModule := a.validateAndroidModule(module); aModule != nil {
875 return pred(aModule)
876 } else {
877 return false
878 }
879 },
880 // visit
881 func(module blueprint.Module) {
882 visit(module.(Module))
883 })
884}
885
886func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
887 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
888 childAndroidModule := a.validateAndroidModule(child)
889 parentAndroidModule := a.validateAndroidModule(parent)
890 if childAndroidModule != nil && parentAndroidModule != nil {
891 return visit(childAndroidModule, parentAndroidModule)
892 } else {
893 return false
894 }
895 })
896}
897
Colin Cross0875c522017-11-28 17:34:01 -0800898func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
899 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
900 visit(module.(Module))
901 })
902}
903
904func (a *androidModuleContext) PrimaryModule() Module {
905 return a.ModuleContext.PrimaryModule().(Module)
906}
907
908func (a *androidModuleContext) FinalModule() Module {
909 return a.ModuleContext.FinalModule().(Module)
910}
911
Colin Crossa1ad8d12016-06-01 17:09:44 -0700912func (a *androidBaseContextImpl) Target() Target {
913 return a.target
914}
915
Colin Cross8b74d172016-09-13 09:59:14 -0700916func (a *androidBaseContextImpl) TargetPrimary() bool {
917 return a.targetPrimary
918}
919
Colin Crossf6566ed2015-03-24 11:13:38 -0700920func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700921 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800922}
923
Colin Crossa1ad8d12016-06-01 17:09:44 -0700924func (a *androidBaseContextImpl) Os() OsType {
925 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800926}
927
Colin Crossf6566ed2015-03-24 11:13:38 -0700928func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700929 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700930}
931
932func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700933 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700934}
935
Colin Cross0af4b842015-04-30 16:36:18 -0700936func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700937 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700938}
939
Colin Cross3edeee12017-04-04 12:59:48 -0700940func (a *androidBaseContextImpl) Windows() bool {
941 return a.target.Os == Windows
942}
943
Colin Crossf6566ed2015-03-24 11:13:38 -0700944func (a *androidBaseContextImpl) Debug() bool {
945 return a.debug
946}
947
Colin Cross1e7d3702016-08-24 15:25:47 -0700948func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700949 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
950 return true
951 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700952 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
953}
954
Colin Cross1332b002015-04-07 17:11:30 -0700955func (a *androidBaseContextImpl) AConfig() Config {
956 return a.config
957}
958
Colin Cross9272ade2016-08-17 15:24:12 -0700959func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
960 return DeviceConfig{a.config.deviceConfig}
961}
962
Jiyong Park2db76922017-11-08 16:03:48 +0900963func (a *androidBaseContextImpl) Platform() bool {
964 return a.kind == platformModule
965}
966
967func (a *androidBaseContextImpl) DeviceSpecific() bool {
968 return a.kind == deviceSpecificModule
969}
970
971func (a *androidBaseContextImpl) SocSpecific() bool {
972 return a.kind == socSpecificModule
973}
974
975func (a *androidBaseContextImpl) ProductSpecific() bool {
976 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -0800977}
978
Colin Cross8d8f8e22016-08-03 11:57:50 -0700979func (a *androidModuleContext) InstallInData() bool {
980 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800981}
982
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700983func (a *androidModuleContext) InstallInSanitizerDir() bool {
984 return a.module.InstallInSanitizerDir()
985}
986
Colin Cross893d8162017-04-26 17:34:03 -0700987func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
988 if a.module.base().commonProperties.SkipInstall {
989 return true
990 }
991
992 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -0800993 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -0700994 return true
995 }
996
Colin Cross6510f912017-11-29 00:27:14 -0800997 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -0700998 return true
999 }
1000 }
1001
1002 return false
1003}
1004
Colin Cross5c517922017-08-31 12:29:17 -07001005func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001006 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001007 return a.installFile(installPath, name, srcPath, Cp, deps)
1008}
1009
1010func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1011 deps ...Path) OutputPath {
1012 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1013}
1014
1015func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1016 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001017
Dan Willemsen782a2d12015-12-21 14:55:28 -08001018 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001019 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001020
Colin Cross893d8162017-04-26 17:34:03 -07001021 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001022
Dan Willemsen322acaf2016-01-12 23:07:05 -08001023 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001024
Colin Cross89562dc2016-10-03 17:47:19 -07001025 var implicitDeps, orderOnlyDeps Paths
1026
1027 if a.Host() {
1028 // Installed host modules might be used during the build, depend directly on their
1029 // dependencies so their timestamp is updated whenever their dependency is updated
1030 implicitDeps = deps
1031 } else {
1032 orderOnlyDeps = deps
1033 }
1034
Colin Crossae887032017-10-23 17:16:14 -07001035 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001036 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001037 Description: "install " + fullInstallPath.Base(),
1038 Output: fullInstallPath,
1039 Input: srcPath,
1040 Implicits: implicitDeps,
1041 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001042 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001043 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001044
Dan Willemsen322acaf2016-01-12 23:07:05 -08001045 a.installFiles = append(a.installFiles, fullInstallPath)
1046 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001047 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001048 return fullInstallPath
1049}
1050
Colin Cross3854a602016-01-11 12:49:11 -08001051func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1052 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001053 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001054
Colin Cross893d8162017-04-26 17:34:03 -07001055 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001056
Colin Crossae887032017-10-23 17:16:14 -07001057 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001058 Rule: Symlink,
1059 Description: "install symlink " + fullInstallPath.Base(),
1060 Output: fullInstallPath,
1061 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001062 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001063 Args: map[string]string{
1064 "fromPath": srcPath.String(),
1065 },
1066 })
Colin Cross3854a602016-01-11 12:49:11 -08001067
Colin Cross12fc4972016-01-11 12:49:11 -08001068 a.installFiles = append(a.installFiles, fullInstallPath)
1069 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1070 }
Colin Cross3854a602016-01-11 12:49:11 -08001071 return fullInstallPath
1072}
1073
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001074func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001075 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1076}
1077
Colin Cross3f40fa42015-01-30 17:27:36 -08001078type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001079 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001080}
1081
1082func isFileInstaller(m blueprint.Module) bool {
1083 _, ok := m.(fileInstaller)
1084 return ok
1085}
1086
1087func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001088 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001089 return ok
1090}
Colin Crossfce53272015-04-08 11:21:40 -07001091
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001092func findStringInSlice(str string, slice []string) int {
1093 for i, s := range slice {
1094 if s == str {
1095 return i
Colin Crossfce53272015-04-08 11:21:40 -07001096 }
1097 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001098 return -1
1099}
1100
Colin Cross068e0fe2016-12-13 15:23:47 -08001101func SrcIsModule(s string) string {
1102 if len(s) > 1 && s[0] == ':' {
1103 return s[1:]
1104 }
1105 return ""
1106}
1107
1108type sourceDependencyTag struct {
1109 blueprint.BaseDependencyTag
1110}
1111
1112var SourceDepTag sourceDependencyTag
1113
Colin Cross366938f2017-12-11 16:29:02 -08001114// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1115// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001116func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1117 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001118 set := make(map[string]bool)
1119
Colin Cross068e0fe2016-12-13 15:23:47 -08001120 for _, s := range srcFiles {
1121 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001122 if _, found := set[m]; found {
1123 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1124 } else {
1125 set[m] = true
1126 deps = append(deps, m)
1127 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001128 }
1129 }
1130
1131 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1132}
1133
Colin Cross366938f2017-12-11 16:29:02 -08001134// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1135// using ":module" syntax, if any.
1136func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1137 if s != nil {
1138 if m := SrcIsModule(*s); m != "" {
1139 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1140 }
1141 }
1142}
1143
Colin Cross068e0fe2016-12-13 15:23:47 -08001144type SourceFileProducer interface {
1145 Srcs() Paths
1146}
1147
1148// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001149// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001150func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001151 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1152}
1153
Colin Cross366938f2017-12-11 16:29:02 -08001154// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1155// ExtractSourceDeps must have already been called during the dependency resolution phase.
1156func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1157 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1158 if len(srcFiles) == 1 {
1159 return srcFiles[0]
1160 } else {
1161 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1162 return nil
1163 }
1164}
1165
Colin Cross2383f3b2018-02-06 14:40:13 -08001166// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1167// the srcFile is non-nil.
1168// ExtractSourceDeps must have already been called during the dependency resolution phase.
1169func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1170 if srcFile != nil {
1171 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1172 }
1173 return OptionalPath{}
1174}
1175
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001176func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001177 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001178
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001179 for i, e := range excludes {
1180 j := findStringInSlice(e, srcFiles)
1181 if j != -1 {
1182 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
1183 }
1184
1185 excludes[i] = filepath.Join(prefix, e)
1186 }
1187
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001188 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001189 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001190 if m := SrcIsModule(s); m != "" {
1191 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001192 if module == nil {
1193 // Error will have been handled by ExtractSourcesDeps
1194 continue
1195 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001196 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001197 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001198 } else {
1199 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1200 }
1201 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001202 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001203 for i, s := range globbedSrcFiles {
1204 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001205 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001206 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001207 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001208 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1209 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -07001210 }
1211 }
1212
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001213 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001214}
1215
Nan Zhang6d34b302017-02-04 17:47:46 -08001216func (ctx *androidModuleContext) RequiredModuleNames() []string {
1217 return ctx.module.base().commonProperties.Required
1218}
1219
Colin Cross7f19f372016-11-01 11:10:25 -07001220func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1221 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001222 if err != nil {
1223 ctx.ModuleErrorf("glob: %s", err.Error())
1224 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001225 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -07001226}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001227
Colin Cross463a90e2015-06-17 14:20:06 -07001228func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001229 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001230}
1231
Colin Cross0875c522017-11-28 17:34:01 -08001232func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001233 return &buildTargetSingleton{}
1234}
1235
Colin Cross87d8b562017-04-25 10:01:55 -07001236func parentDir(dir string) string {
1237 dir, _ = filepath.Split(dir)
1238 return filepath.Clean(dir)
1239}
1240
Colin Cross1f8c52b2015-06-16 16:38:17 -07001241type buildTargetSingleton struct{}
1242
Colin Cross0875c522017-11-28 17:34:01 -08001243func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1244 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001245
Colin Cross0875c522017-11-28 17:34:01 -08001246 mmTarget := func(dir string) WritablePath {
1247 return PathForPhony(ctx,
1248 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001249 }
1250
Colin Cross0875c522017-11-28 17:34:01 -08001251 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001252
Colin Cross0875c522017-11-28 17:34:01 -08001253 ctx.VisitAllModules(func(module Module) {
1254 blueprintDir := module.base().blueprintDir
1255 installTarget := module.base().installTarget
1256 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001257
Colin Cross0875c522017-11-28 17:34:01 -08001258 if checkbuildTarget != nil {
1259 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1260 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1261 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001262
Colin Cross0875c522017-11-28 17:34:01 -08001263 if installTarget != nil {
1264 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001265 }
1266 })
1267
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001268 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001269 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001270 suffix = "-soong"
1271 }
1272
Colin Cross1f8c52b2015-06-16 16:38:17 -07001273 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001274 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001275 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001276 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001277 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001278 })
1279
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001280 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001281 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001282 return
1283 }
1284
Colin Cross0875c522017-11-28 17:34:01 -08001285 sortedKeys := func(m map[string]Paths) []string {
1286 s := make([]string, 0, len(m))
1287 for k := range m {
1288 s = append(s, k)
1289 }
1290 sort.Strings(s)
1291 return s
1292 }
1293
Colin Cross87d8b562017-04-25 10:01:55 -07001294 // Ensure ancestor directories are in modulesInDir
1295 dirs := sortedKeys(modulesInDir)
1296 for _, dir := range dirs {
1297 dir := parentDir(dir)
1298 for dir != "." && dir != "/" {
1299 if _, exists := modulesInDir[dir]; exists {
1300 break
1301 }
1302 modulesInDir[dir] = nil
1303 dir = parentDir(dir)
1304 }
1305 }
1306
1307 // Make directories build their direct subdirectories
1308 dirs = sortedKeys(modulesInDir)
1309 for _, dir := range dirs {
1310 p := parentDir(dir)
1311 if p != "." && p != "/" {
1312 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1313 }
1314 }
1315
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001316 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1317 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1318 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001319 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001320 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001321 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001322 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001323 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001324 // HACK: checkbuild should be an optional build, but force it
1325 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001326 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001327 })
1328 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001329
1330 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1331 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001332 ctx.VisitAllModules(func(module Module) {
1333 if module.Enabled() {
1334 os := module.Target().Os
1335 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001336 }
1337 })
1338
Colin Cross0875c522017-11-28 17:34:01 -08001339 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001340 for os, deps := range osDeps {
1341 var className string
1342
1343 switch os.Class {
1344 case Host:
1345 className = "host"
1346 case HostCross:
1347 className = "host-cross"
1348 case Device:
1349 className = "target"
1350 default:
1351 continue
1352 }
1353
Colin Cross0875c522017-11-28 17:34:01 -08001354 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001355 osClass[className] = append(osClass[className], name)
1356
Colin Cross0875c522017-11-28 17:34:01 -08001357 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001358 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001359 Output: name,
1360 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001361 })
1362 }
1363
1364 // Wrap those into host|host-cross|target phony rules
1365 osClasses := sortedKeys(osClass)
1366 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001367 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001368 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001369 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001370 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001371 })
1372 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001373}
Colin Crossd779da42015-12-17 18:00:23 -08001374
1375type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001376 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001377 ctx interface {
1378 ModuleName(blueprint.Module) string
1379 ModuleSubDir(blueprint.Module) string
1380 }
1381}
1382
1383func (s AndroidModulesByName) Len() int { return len(s.slice) }
1384func (s AndroidModulesByName) Less(i, j int) bool {
1385 mi, mj := s.slice[i], s.slice[j]
1386 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1387
1388 if ni != nj {
1389 return ni < nj
1390 } else {
1391 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1392 }
1393}
1394func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }