blob: 1e544700635ca1fc52f6de0143cce23f1fe279f8 [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()
Jiyong Park374510b2018-03-19 18:23:01 +0900180 ExportedToMake() bool
Colin Cross36242852017-06-23 15:06:31 -0700181
182 AddProperties(props ...interface{})
183 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700184
Colin Crossae887032017-10-23 17:16:14 -0700185 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800186}
187
Colin Crossfc754582016-05-17 16:34:16 -0700188type nameProperties struct {
189 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800190 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700191}
192
193type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700194 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800195
Dan Willemsen0effe062015-11-30 16:06:01 -0800196 // emit build rules for this module
197 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800198
Colin Cross7d5136f2015-05-11 13:39:40 -0700199 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800200 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
201 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
202 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700203 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700204
205 Target struct {
206 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700207 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700208 }
209 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700210 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700211 }
212 }
213
214 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800215
Dan Willemsen782a2d12015-12-21 14:55:28 -0800216 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700217 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800218
Colin Cross55708f32017-03-20 13:23:34 -0700219 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700220 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700221
Jiyong Park2db76922017-11-08 16:03:48 +0900222 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
223 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
224 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700225 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700226
Jiyong Park2db76922017-11-08 16:03:48 +0900227 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
228 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
229 Soc_specific *bool
230
231 // whether this module is specific to a device, not only for SoC, but also for off-chip
232 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
233 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
234 // This implies `soc_specific:true`.
235 Device_specific *bool
236
237 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900238 // network operator, etc). When set to true, it is installed into /product (or
239 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900240 Product_specific *bool
241
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700242 // init.rc files to be installed if this module is installed
243 Init_rc []string
244
Chris Wolfe998306e2016-08-15 14:47:23 -0400245 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700246 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400247
Colin Cross5aac3622017-08-31 15:07:09 -0700248 // relative path to a file to include in the list of notices for the device
249 Notice *string
250
Colin Crossa1ad8d12016-06-01 17:09:44 -0700251 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700252 CompileTarget Target `blueprint:"mutated"`
253 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800254
255 // Set by InitAndroidModule
256 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700257 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700258
259 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800260
261 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800262}
263
264type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700265 Host_supported *bool
266 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800267}
268
Colin Crossc472d572015-03-17 15:06:21 -0700269type Multilib string
270
271const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800272 MultilibBoth Multilib = "both"
273 MultilibFirst Multilib = "first"
274 MultilibCommon Multilib = "common"
275 MultilibCommonFirst Multilib = "common_first"
276 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700277)
278
Colin Crossa1ad8d12016-06-01 17:09:44 -0700279type HostOrDeviceSupported int
280
281const (
282 _ HostOrDeviceSupported = iota
283 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700284 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700285 DeviceSupported
286 HostAndDeviceSupported
287 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700288 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700289)
290
Jiyong Park2db76922017-11-08 16:03:48 +0900291type moduleKind int
292
293const (
294 platformModule moduleKind = iota
295 deviceSpecificModule
296 socSpecificModule
297 productSpecificModule
298)
299
300func (k moduleKind) String() string {
301 switch k {
302 case platformModule:
303 return "platform"
304 case deviceSpecificModule:
305 return "device-specific"
306 case socSpecificModule:
307 return "soc-specific"
308 case productSpecificModule:
309 return "product-specific"
310 default:
311 panic(fmt.Errorf("unknown module kind %d", k))
312 }
313}
314
Colin Cross36242852017-06-23 15:06:31 -0700315func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800316 base := m.base()
317 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700318
Colin Cross36242852017-06-23 15:06:31 -0700319 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700320 &base.nameProperties,
321 &base.commonProperties,
322 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700323}
324
Colin Cross36242852017-06-23 15:06:31 -0700325func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
326 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700327
328 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800329 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700330 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700331 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800332
Dan Willemsen218f6562015-07-08 18:13:11 -0700333 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700334 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700335 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800336 }
337
Colin Cross36242852017-06-23 15:06:31 -0700338 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800339}
340
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800341// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800342// modules. It should be included as an anonymous field in every module
343// struct definition. InitAndroidModule should then be called from the module's
344// factory function, and the return values from InitAndroidModule should be
345// returned from the factory function.
346//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800347// The ModuleBase type is responsible for implementing the GenerateBuildActions
348// method to support the blueprint.Module interface. This method will then call
349// the module's GenerateAndroidBuildActions method once for each build variant
350// that is to be built. GenerateAndroidBuildActions is passed a
351// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800352// AndroidModuleContext exposes extra functionality specific to the Android build
353// system including details about the particular build variant that is to be
354// generated.
355//
356// For example:
357//
358// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800359// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800360// )
361//
362// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800363// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800364// properties struct {
365// MyProperty string
366// }
367// }
368//
Colin Cross36242852017-06-23 15:06:31 -0700369// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800370// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700371// m.AddProperties(&m.properties)
372// android.InitAndroidModule(m)
373// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800374// }
375//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800376// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800377// // Get the CPU architecture for the current build variant.
378// variantArch := ctx.Arch()
379//
380// // ...
381// }
Colin Cross635c3b02016-05-18 15:37:25 -0700382type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800383 // Putting the curiously recurring thing pointing to the thing that contains
384 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700385 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700386 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800387
Colin Crossfc754582016-05-17 16:34:16 -0700388 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800389 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700390 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800391 hostAndDeviceProperties hostAndDeviceProperties
392 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700393 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700394 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800395
396 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700397 installFiles Paths
398 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700399
400 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
401 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800402 installTarget WritablePath
403 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700404 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700405
Colin Cross178a5092016-09-13 13:42:32 -0700406 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700407
408 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700409
410 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700411 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700412}
413
414func (a *ModuleBase) AddProperties(props ...interface{}) {
415 a.registerProps = append(a.registerProps, props...)
416}
417
418func (a *ModuleBase) GetProperties() []interface{} {
419 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800420}
421
Colin Crossae887032017-10-23 17:16:14 -0700422func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700423 return a.buildParams
424}
425
Colin Crossce75d2c2016-10-06 16:12:58 -0700426// Name returns the name of the module. It may be overridden by individual module types, for
427// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700428func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800429 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700430}
431
Colin Crossce75d2c2016-10-06 16:12:58 -0700432// BaseModuleName returns the name of the module as specified in the blueprints file.
433func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800434 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700435}
436
Colin Cross635c3b02016-05-18 15:37:25 -0700437func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 return a
439}
440
Colin Cross8b74d172016-09-13 09:59:14 -0700441func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700442 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700443 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700444}
445
Colin Crossa1ad8d12016-06-01 17:09:44 -0700446func (a *ModuleBase) Target() Target {
447 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800448}
449
Colin Cross8b74d172016-09-13 09:59:14 -0700450func (a *ModuleBase) TargetPrimary() bool {
451 return a.commonProperties.CompilePrimary
452}
453
Colin Crossa1ad8d12016-06-01 17:09:44 -0700454func (a *ModuleBase) Os() OsType {
455 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800456}
457
Colin Cross635c3b02016-05-18 15:37:25 -0700458func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700459 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800460}
461
Colin Cross635c3b02016-05-18 15:37:25 -0700462func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700463 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800464}
465
Dan Willemsen0b24c742016-10-04 15:13:37 -0700466func (a *ModuleBase) ArchSpecific() bool {
467 return a.commonProperties.ArchSpecific
468}
469
Colin Crossa1ad8d12016-06-01 17:09:44 -0700470func (a *ModuleBase) OsClassSupported() []OsClass {
471 switch a.commonProperties.HostOrDeviceSupported {
472 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700473 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700474 case HostSupportedNoCross:
475 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700476 case DeviceSupported:
477 return []OsClass{Device}
478 case HostAndDeviceSupported:
479 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700480 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700481 supported = append(supported, Host, HostCross)
482 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700483 if a.hostAndDeviceProperties.Device_supported == nil ||
484 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700485 supported = append(supported, Device)
486 }
487 return supported
488 default:
489 return nil
490 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800491}
492
Colin Cross635c3b02016-05-18 15:37:25 -0700493func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800494 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
495 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700496 (a.hostAndDeviceProperties.Device_supported == nil ||
497 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800498}
499
Colin Cross635c3b02016-05-18 15:37:25 -0700500func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800501 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800502 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800503 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800504 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800505}
506
Colin Crossce75d2c2016-10-06 16:12:58 -0700507func (a *ModuleBase) SkipInstall() {
508 a.commonProperties.SkipInstall = true
509}
510
Jiyong Park374510b2018-03-19 18:23:01 +0900511func (a *ModuleBase) ExportedToMake() bool {
512 return a.commonProperties.NamespaceExportedToMake
513}
514
Colin Cross635c3b02016-05-18 15:37:25 -0700515func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700516 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800517
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700518 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800519 ctx.VisitDepsDepthFirstIf(isFileInstaller,
520 func(m blueprint.Module) {
521 fileInstaller := m.(fileInstaller)
522 files := fileInstaller.filesToInstall()
523 result = append(result, files...)
524 })
525
526 return result
527}
528
Colin Cross635c3b02016-05-18 15:37:25 -0700529func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800530 return a.installFiles
531}
532
Colin Cross635c3b02016-05-18 15:37:25 -0700533func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800534 return p.noAddressSanitizer
535}
536
Colin Cross635c3b02016-05-18 15:37:25 -0700537func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800538 return false
539}
540
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700541func (p *ModuleBase) InstallInSanitizerDir() bool {
542 return false
543}
544
Colin Cross0875c522017-11-28 17:34:01 -0800545func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700546 allInstalledFiles := Paths{}
547 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800548 ctx.VisitAllModuleVariants(func(module Module) {
549 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700550 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
551 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800552 })
553
Colin Cross0875c522017-11-28 17:34:01 -0800554 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700555
Jeff Gaston088e29e2017-11-29 16:47:17 -0800556 namespacePrefix := ctx.Namespace().(*Namespace).id
557 if namespacePrefix != "" {
558 namespacePrefix = namespacePrefix + "-"
559 }
560
Colin Cross3f40fa42015-01-30 17:27:36 -0800561 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800562 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800563 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700564 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800565 Output: name,
566 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800567 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700568 })
569 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700570 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700571 }
572
573 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800574 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800575 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700576 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800577 Output: name,
578 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700579 })
580 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700581 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700582 }
583
584 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800585 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800586 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800587 suffix = "-soong"
588 }
589
Jeff Gaston088e29e2017-11-29 16:47:17 -0800590 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800591 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700592 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800593 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700594 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800595 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700596
597 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800598 }
599}
600
Jiyong Park2db76922017-11-08 16:03:48 +0900601func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
602 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
603 var deviceSpecific = Bool(a.commonProperties.Device_specific)
604 var productSpecific = Bool(a.commonProperties.Product_specific)
605
606 if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
607 msg := "conflicting value set here"
608 if productSpecific {
609 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
610 if deviceSpecific {
611 ctx.PropertyErrorf("device_specific", msg)
612 }
613 } else {
614 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
615 }
616 if Bool(a.commonProperties.Vendor) {
617 ctx.PropertyErrorf("vendor", msg)
618 }
619 if Bool(a.commonProperties.Proprietary) {
620 ctx.PropertyErrorf("proprietary", msg)
621 }
622 if Bool(a.commonProperties.Soc_specific) {
623 ctx.PropertyErrorf("soc_specific", msg)
624 }
625 }
626
627 if productSpecific {
628 return productSpecificModule
629 } else if deviceSpecific {
630 return deviceSpecificModule
631 } else if socSpecific {
632 return socSpecificModule
633 } else {
634 return platformModule
635 }
636}
637
Colin Cross635c3b02016-05-18 15:37:25 -0700638func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700639 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700640 target: a.commonProperties.CompileTarget,
641 targetPrimary: a.commonProperties.CompilePrimary,
Jiyong Park2db76922017-11-08 16:03:48 +0900642 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700643 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800644 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800645}
646
Colin Cross0875c522017-11-28 17:34:01 -0800647func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
648 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700649 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800650 ModuleContext: blueprintCtx,
651 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
652 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700653 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800654 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800655 }
656
Colin Cross67a5c132017-05-09 13:45:28 -0700657 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
658 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800659 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
660 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700661 }
Colin Cross0875c522017-11-28 17:34:01 -0800662 if !ctx.PrimaryArch() {
663 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700664 }
665
666 ctx.Variable(pctx, "moduleDesc", desc)
667
668 s := ""
669 if len(suffix) > 0 {
670 s = " [" + strings.Join(suffix, " ") + "]"
671 }
672 ctx.Variable(pctx, "moduleDescSuffix", s)
673
Colin Cross9b1d13d2016-09-19 15:18:11 -0700674 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800675 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700676 if ctx.Failed() {
677 return
678 }
679
Colin Cross0875c522017-11-28 17:34:01 -0800680 a.installFiles = append(a.installFiles, ctx.installFiles...)
681 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800682 }
683
Colin Cross9b1d13d2016-09-19 15:18:11 -0700684 if a == ctx.FinalModule().(Module).base() {
685 a.generateModuleTarget(ctx)
686 if ctx.Failed() {
687 return
688 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800689 }
Colin Crosscec81712017-07-13 14:43:27 -0700690
Colin Cross0875c522017-11-28 17:34:01 -0800691 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800692}
693
Colin Crossf6566ed2015-03-24 11:13:38 -0700694type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700695 target Target
696 targetPrimary bool
697 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900698 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700699 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700700}
701
Colin Cross3f40fa42015-01-30 17:27:36 -0800702type androidModuleContext struct {
703 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700704 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700705 installDeps Paths
706 installFiles Paths
707 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800708 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700709 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700710
711 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700712 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800713}
714
Colin Cross67a5c132017-05-09 13:45:28 -0700715func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800716 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700717 Rule: ErrorRule,
718 Description: desc,
719 Outputs: outputs,
720 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800721 Args: map[string]string{
722 "error": err.Error(),
723 },
724 })
725 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800726}
727
Colin Crossaabf6792017-11-29 00:27:14 -0800728func (a *androidModuleContext) Config() Config {
729 return a.ModuleContext.Config().(Config)
730}
731
Colin Cross0875c522017-11-28 17:34:01 -0800732func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700733 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800734}
735
Colin Cross0875c522017-11-28 17:34:01 -0800736func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700737 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700738 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800739 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800740 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700741 Outputs: params.Outputs.Strings(),
742 ImplicitOutputs: params.ImplicitOutputs.Strings(),
743 Inputs: params.Inputs.Strings(),
744 Implicits: params.Implicits.Strings(),
745 OrderOnly: params.OrderOnly.Strings(),
746 Args: params.Args,
747 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700748 }
749
Colin Cross33bfb0a2016-11-21 17:23:08 -0800750 if params.Depfile != nil {
751 bparams.Depfile = params.Depfile.String()
752 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700753 if params.Output != nil {
754 bparams.Outputs = append(bparams.Outputs, params.Output.String())
755 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700756 if params.ImplicitOutput != nil {
757 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
758 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700759 if params.Input != nil {
760 bparams.Inputs = append(bparams.Inputs, params.Input.String())
761 }
762 if params.Implicit != nil {
763 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
764 }
765
Colin Cross0875c522017-11-28 17:34:01 -0800766 return bparams
767}
768
769func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
770 a.ModuleContext.Variable(pctx.PackageContext, name, value)
771}
772
773func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
774 argNames ...string) blueprint.Rule {
775
776 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
777}
778
779func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
780 if a.config.captureBuild {
781 a.buildParams = append(a.buildParams, params)
782 }
783
784 bparams := convertBuildParams(params)
785
786 if bparams.Description != "" {
787 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
788 }
789
Colin Cross6ff51382015-12-17 16:39:19 -0800790 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700791 a.ninjaError(bparams.Description, bparams.Outputs,
792 fmt.Errorf("module %s missing dependencies: %s\n",
793 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800794 return
795 }
796
Colin Cross0875c522017-11-28 17:34:01 -0800797 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700798}
799
Colin Cross6ff51382015-12-17 16:39:19 -0800800func (a *androidModuleContext) GetMissingDependencies() []string {
801 return a.missingDeps
802}
803
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800804func (a *androidModuleContext) AddMissingDependencies(deps []string) {
805 if deps != nil {
806 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700807 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800808 }
809}
810
Colin Crossd11fcda2017-10-23 17:59:01 -0700811func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
812 aModule, _ := module.(Module)
813 if aModule == nil {
814 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
815 return nil
816 }
817
818 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800819 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700820 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
821 } else {
822 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
823 }
824 return nil
825 }
826
827 return aModule
828}
829
Colin Cross35143d02017-11-16 00:11:20 -0800830func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
831 a.ModuleContext.VisitDirectDeps(visit)
832}
833
Colin Crossd11fcda2017-10-23 17:59:01 -0700834func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
835 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
836 if aModule := a.validateAndroidModule(module); aModule != nil {
837 visit(aModule)
838 }
839 })
840}
841
Colin Crossee6143c2017-12-30 17:54:27 -0800842func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
843 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
844 if aModule := a.validateAndroidModule(module); aModule != nil {
845 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
846 visit(aModule)
847 }
848 }
849 })
850}
851
Colin Crossd11fcda2017-10-23 17:59:01 -0700852func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
853 a.ModuleContext.VisitDirectDepsIf(
854 // pred
855 func(module blueprint.Module) bool {
856 if aModule := a.validateAndroidModule(module); aModule != nil {
857 return pred(aModule)
858 } else {
859 return false
860 }
861 },
862 // visit
863 func(module blueprint.Module) {
864 visit(module.(Module))
865 })
866}
867
868func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
869 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
870 if aModule := a.validateAndroidModule(module); aModule != nil {
871 visit(aModule)
872 }
873 })
874}
875
876func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
877 a.ModuleContext.VisitDepsDepthFirstIf(
878 // pred
879 func(module blueprint.Module) bool {
880 if aModule := a.validateAndroidModule(module); aModule != nil {
881 return pred(aModule)
882 } else {
883 return false
884 }
885 },
886 // visit
887 func(module blueprint.Module) {
888 visit(module.(Module))
889 })
890}
891
892func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
893 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
894 childAndroidModule := a.validateAndroidModule(child)
895 parentAndroidModule := a.validateAndroidModule(parent)
896 if childAndroidModule != nil && parentAndroidModule != nil {
897 return visit(childAndroidModule, parentAndroidModule)
898 } else {
899 return false
900 }
901 })
902}
903
Colin Cross0875c522017-11-28 17:34:01 -0800904func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
905 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
906 visit(module.(Module))
907 })
908}
909
910func (a *androidModuleContext) PrimaryModule() Module {
911 return a.ModuleContext.PrimaryModule().(Module)
912}
913
914func (a *androidModuleContext) FinalModule() Module {
915 return a.ModuleContext.FinalModule().(Module)
916}
917
Colin Crossa1ad8d12016-06-01 17:09:44 -0700918func (a *androidBaseContextImpl) Target() Target {
919 return a.target
920}
921
Colin Cross8b74d172016-09-13 09:59:14 -0700922func (a *androidBaseContextImpl) TargetPrimary() bool {
923 return a.targetPrimary
924}
925
Colin Crossf6566ed2015-03-24 11:13:38 -0700926func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700927 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800928}
929
Colin Crossa1ad8d12016-06-01 17:09:44 -0700930func (a *androidBaseContextImpl) Os() OsType {
931 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800932}
933
Colin Crossf6566ed2015-03-24 11:13:38 -0700934func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700935 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700936}
937
938func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700939 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700940}
941
Colin Cross0af4b842015-04-30 16:36:18 -0700942func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700943 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700944}
945
Colin Cross3edeee12017-04-04 12:59:48 -0700946func (a *androidBaseContextImpl) Windows() bool {
947 return a.target.Os == Windows
948}
949
Colin Crossf6566ed2015-03-24 11:13:38 -0700950func (a *androidBaseContextImpl) Debug() bool {
951 return a.debug
952}
953
Colin Cross1e7d3702016-08-24 15:25:47 -0700954func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700955 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
956 return true
957 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700958 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
959}
960
Colin Cross1332b002015-04-07 17:11:30 -0700961func (a *androidBaseContextImpl) AConfig() Config {
962 return a.config
963}
964
Colin Cross9272ade2016-08-17 15:24:12 -0700965func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
966 return DeviceConfig{a.config.deviceConfig}
967}
968
Jiyong Park2db76922017-11-08 16:03:48 +0900969func (a *androidBaseContextImpl) Platform() bool {
970 return a.kind == platformModule
971}
972
973func (a *androidBaseContextImpl) DeviceSpecific() bool {
974 return a.kind == deviceSpecificModule
975}
976
977func (a *androidBaseContextImpl) SocSpecific() bool {
978 return a.kind == socSpecificModule
979}
980
981func (a *androidBaseContextImpl) ProductSpecific() bool {
982 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -0800983}
984
Colin Cross8d8f8e22016-08-03 11:57:50 -0700985func (a *androidModuleContext) InstallInData() bool {
986 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800987}
988
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700989func (a *androidModuleContext) InstallInSanitizerDir() bool {
990 return a.module.InstallInSanitizerDir()
991}
992
Colin Cross893d8162017-04-26 17:34:03 -0700993func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
994 if a.module.base().commonProperties.SkipInstall {
995 return true
996 }
997
998 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -0800999 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001000 return true
1001 }
1002
Colin Cross6510f912017-11-29 00:27:14 -08001003 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001004 return true
1005 }
1006 }
1007
1008 return false
1009}
1010
Colin Cross5c517922017-08-31 12:29:17 -07001011func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001012 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001013 return a.installFile(installPath, name, srcPath, Cp, deps)
1014}
1015
1016func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1017 deps ...Path) OutputPath {
1018 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1019}
1020
1021func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1022 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001023
Dan Willemsen782a2d12015-12-21 14:55:28 -08001024 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001025 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001026
Colin Cross893d8162017-04-26 17:34:03 -07001027 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001028
Dan Willemsen322acaf2016-01-12 23:07:05 -08001029 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001030
Colin Cross89562dc2016-10-03 17:47:19 -07001031 var implicitDeps, orderOnlyDeps Paths
1032
1033 if a.Host() {
1034 // Installed host modules might be used during the build, depend directly on their
1035 // dependencies so their timestamp is updated whenever their dependency is updated
1036 implicitDeps = deps
1037 } else {
1038 orderOnlyDeps = deps
1039 }
1040
Colin Crossae887032017-10-23 17:16:14 -07001041 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001042 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001043 Description: "install " + fullInstallPath.Base(),
1044 Output: fullInstallPath,
1045 Input: srcPath,
1046 Implicits: implicitDeps,
1047 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001048 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001049 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001050
Dan Willemsen322acaf2016-01-12 23:07:05 -08001051 a.installFiles = append(a.installFiles, fullInstallPath)
1052 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001053 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001054 return fullInstallPath
1055}
1056
Colin Cross3854a602016-01-11 12:49:11 -08001057func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1058 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001059 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001060
Colin Cross893d8162017-04-26 17:34:03 -07001061 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001062
Colin Crossae887032017-10-23 17:16:14 -07001063 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001064 Rule: Symlink,
1065 Description: "install symlink " + fullInstallPath.Base(),
1066 Output: fullInstallPath,
1067 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001068 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001069 Args: map[string]string{
1070 "fromPath": srcPath.String(),
1071 },
1072 })
Colin Cross3854a602016-01-11 12:49:11 -08001073
Colin Cross12fc4972016-01-11 12:49:11 -08001074 a.installFiles = append(a.installFiles, fullInstallPath)
1075 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1076 }
Colin Cross3854a602016-01-11 12:49:11 -08001077 return fullInstallPath
1078}
1079
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001080func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001081 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1082}
1083
Colin Cross3f40fa42015-01-30 17:27:36 -08001084type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001085 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001086}
1087
1088func isFileInstaller(m blueprint.Module) bool {
1089 _, ok := m.(fileInstaller)
1090 return ok
1091}
1092
1093func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001094 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001095 return ok
1096}
Colin Crossfce53272015-04-08 11:21:40 -07001097
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001098func findStringInSlice(str string, slice []string) int {
1099 for i, s := range slice {
1100 if s == str {
1101 return i
Colin Crossfce53272015-04-08 11:21:40 -07001102 }
1103 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001104 return -1
1105}
1106
Colin Cross068e0fe2016-12-13 15:23:47 -08001107func SrcIsModule(s string) string {
1108 if len(s) > 1 && s[0] == ':' {
1109 return s[1:]
1110 }
1111 return ""
1112}
1113
1114type sourceDependencyTag struct {
1115 blueprint.BaseDependencyTag
1116}
1117
1118var SourceDepTag sourceDependencyTag
1119
Colin Cross366938f2017-12-11 16:29:02 -08001120// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1121// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001122func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1123 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001124 set := make(map[string]bool)
1125
Colin Cross068e0fe2016-12-13 15:23:47 -08001126 for _, s := range srcFiles {
1127 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001128 if _, found := set[m]; found {
1129 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1130 } else {
1131 set[m] = true
1132 deps = append(deps, m)
1133 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001134 }
1135 }
1136
1137 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1138}
1139
Colin Cross366938f2017-12-11 16:29:02 -08001140// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1141// using ":module" syntax, if any.
1142func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1143 if s != nil {
1144 if m := SrcIsModule(*s); m != "" {
1145 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1146 }
1147 }
1148}
1149
Colin Cross068e0fe2016-12-13 15:23:47 -08001150type SourceFileProducer interface {
1151 Srcs() Paths
1152}
1153
1154// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001155// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001156func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001157 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1158}
1159
Colin Cross366938f2017-12-11 16:29:02 -08001160// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1161// ExtractSourceDeps must have already been called during the dependency resolution phase.
1162func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1163 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1164 if len(srcFiles) == 1 {
1165 return srcFiles[0]
1166 } else {
1167 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1168 return nil
1169 }
1170}
1171
Colin Cross2383f3b2018-02-06 14:40:13 -08001172// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1173// the srcFile is non-nil.
1174// ExtractSourceDeps must have already been called during the dependency resolution phase.
1175func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1176 if srcFile != nil {
1177 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1178 }
1179 return OptionalPath{}
1180}
1181
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001182func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001183 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001184
Colin Cross461b4452018-02-23 09:22:42 -08001185 var expandedExcludes []string
1186 if excludes != nil {
1187 expandedExcludes = make([]string, 0, len(excludes))
1188 }
Nan Zhang27e284d2018-02-09 21:03:53 +00001189
1190 for _, e := range excludes {
1191 if m := SrcIsModule(e); m != "" {
1192 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1193 if module == nil {
1194 // Error will have been handled by ExtractSourcesDeps
1195 continue
1196 }
1197 if srcProducer, ok := module.(SourceFileProducer); ok {
1198 expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1199 } else {
1200 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1201 }
1202 } else {
1203 expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001204 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001205 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001206 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001207 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001208 if m := SrcIsModule(s); m != "" {
1209 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001210 if module == nil {
1211 // Error will have been handled by ExtractSourcesDeps
1212 continue
1213 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001214 if srcProducer, ok := module.(SourceFileProducer); ok {
Nan Zhang27e284d2018-02-09 21:03:53 +00001215 moduleSrcs := srcProducer.Srcs()
1216 for _, e := range expandedExcludes {
1217 for j, ms := range moduleSrcs {
1218 if ms.String() == e {
1219 moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1220 }
1221 }
1222 }
1223 expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001224 } else {
1225 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1226 }
1227 } else if pathtools.IsGlob(s) {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001228 globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001229 for i, s := range globbedSrcFiles {
1230 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001231 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001232 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001233 } else {
Nan Zhang27e284d2018-02-09 21:03:53 +00001234 p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1235 j := findStringInSlice(p.String(), expandedExcludes)
1236 if j == -1 {
1237 expandedSrcFiles = append(expandedSrcFiles, p)
1238 }
1239
Colin Cross8f101b42015-06-17 15:09:06 -07001240 }
1241 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001242 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001243}
1244
Nan Zhang6d34b302017-02-04 17:47:46 -08001245func (ctx *androidModuleContext) RequiredModuleNames() []string {
1246 return ctx.module.base().commonProperties.Required
1247}
1248
Colin Cross7f19f372016-11-01 11:10:25 -07001249func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1250 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001251 if err != nil {
1252 ctx.ModuleErrorf("glob: %s", err.Error())
1253 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001254 return pathsForModuleSrcFromFullPath(ctx, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001255}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001256
Nan Zhang581fd212018-01-10 16:06:12 -08001257func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001258 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001259 if err != nil {
1260 ctx.ModuleErrorf("glob: %s", err.Error())
1261 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001262 return pathsForModuleSrcFromFullPath(ctx, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001263}
1264
Colin Cross463a90e2015-06-17 14:20:06 -07001265func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001266 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001267}
1268
Colin Cross0875c522017-11-28 17:34:01 -08001269func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001270 return &buildTargetSingleton{}
1271}
1272
Colin Cross87d8b562017-04-25 10:01:55 -07001273func parentDir(dir string) string {
1274 dir, _ = filepath.Split(dir)
1275 return filepath.Clean(dir)
1276}
1277
Colin Cross1f8c52b2015-06-16 16:38:17 -07001278type buildTargetSingleton struct{}
1279
Colin Cross0875c522017-11-28 17:34:01 -08001280func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1281 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001282
Colin Cross0875c522017-11-28 17:34:01 -08001283 mmTarget := func(dir string) WritablePath {
1284 return PathForPhony(ctx,
1285 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001286 }
1287
Colin Cross0875c522017-11-28 17:34:01 -08001288 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001289
Colin Cross0875c522017-11-28 17:34:01 -08001290 ctx.VisitAllModules(func(module Module) {
1291 blueprintDir := module.base().blueprintDir
1292 installTarget := module.base().installTarget
1293 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001294
Colin Cross0875c522017-11-28 17:34:01 -08001295 if checkbuildTarget != nil {
1296 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1297 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1298 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001299
Colin Cross0875c522017-11-28 17:34:01 -08001300 if installTarget != nil {
1301 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001302 }
1303 })
1304
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001305 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001306 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001307 suffix = "-soong"
1308 }
1309
Colin Cross1f8c52b2015-06-16 16:38:17 -07001310 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001311 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001312 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001313 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001314 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001315 })
1316
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001317 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001318 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001319 return
1320 }
1321
Colin Cross0875c522017-11-28 17:34:01 -08001322 sortedKeys := func(m map[string]Paths) []string {
1323 s := make([]string, 0, len(m))
1324 for k := range m {
1325 s = append(s, k)
1326 }
1327 sort.Strings(s)
1328 return s
1329 }
1330
Colin Cross87d8b562017-04-25 10:01:55 -07001331 // Ensure ancestor directories are in modulesInDir
1332 dirs := sortedKeys(modulesInDir)
1333 for _, dir := range dirs {
1334 dir := parentDir(dir)
1335 for dir != "." && dir != "/" {
1336 if _, exists := modulesInDir[dir]; exists {
1337 break
1338 }
1339 modulesInDir[dir] = nil
1340 dir = parentDir(dir)
1341 }
1342 }
1343
1344 // Make directories build their direct subdirectories
1345 dirs = sortedKeys(modulesInDir)
1346 for _, dir := range dirs {
1347 p := parentDir(dir)
1348 if p != "." && p != "/" {
1349 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1350 }
1351 }
1352
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001353 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1354 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1355 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001356 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001357 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001358 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001359 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001360 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001361 // HACK: checkbuild should be an optional build, but force it
1362 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001363 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001364 })
1365 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001366
1367 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1368 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001369 ctx.VisitAllModules(func(module Module) {
1370 if module.Enabled() {
1371 os := module.Target().Os
1372 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001373 }
1374 })
1375
Colin Cross0875c522017-11-28 17:34:01 -08001376 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001377 for os, deps := range osDeps {
1378 var className string
1379
1380 switch os.Class {
1381 case Host:
1382 className = "host"
1383 case HostCross:
1384 className = "host-cross"
1385 case Device:
1386 className = "target"
1387 default:
1388 continue
1389 }
1390
Colin Cross0875c522017-11-28 17:34:01 -08001391 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001392 osClass[className] = append(osClass[className], name)
1393
Colin Cross0875c522017-11-28 17:34:01 -08001394 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001395 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001396 Output: name,
1397 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001398 })
1399 }
1400
1401 // Wrap those into host|host-cross|target phony rules
1402 osClasses := sortedKeys(osClass)
1403 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001404 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001405 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001406 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001407 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001408 })
1409 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001410}
Colin Crossd779da42015-12-17 18:00:23 -08001411
1412type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001413 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001414 ctx interface {
1415 ModuleName(blueprint.Module) string
1416 ModuleSubDir(blueprint.Module) string
1417 }
1418}
1419
1420func (s AndroidModulesByName) Len() int { return len(s.slice) }
1421func (s AndroidModulesByName) Less(i, j int) bool {
1422 mi, mj := s.slice[i], s.slice[j]
1423 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1424
1425 if ni != nj {
1426 return ni < nj
1427 } else {
1428 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1429 }
1430}
1431func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }