blob: b6220dc31f8b02f66be51cac8a1b900595d0fd4d [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
Jiyong Parkf9332f12018-02-01 00:54:12 +0900127 InstallInRecovery() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800128
129 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700130
131 // android.ModuleContext methods
132 // These are duplicated instead of embedded so that can eventually be wrapped to take an
133 // android.Module instead of a blueprint.Module
134 OtherModuleName(m blueprint.Module) string
135 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
136 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
137
138 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
139 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
140
141 ModuleSubDir() string
142
Colin Cross35143d02017-11-16 00:11:20 -0800143 VisitDirectDepsBlueprint(visit func(blueprint.Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700144 VisitDirectDeps(visit func(Module))
Colin Crossee6143c2017-12-30 17:54:27 -0800145 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700146 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
Colin Cross6b753602018-06-21 13:03:07 -0700147 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Crossd11fcda2017-10-23 17:59:01 -0700148 VisitDepsDepthFirst(visit func(Module))
Colin Cross6b753602018-06-21 13:03:07 -0700149 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Crossd11fcda2017-10-23 17:59:01 -0700150 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
151 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700152
Colin Cross0875c522017-11-28 17:34:01 -0800153 Variable(pctx PackageContext, name, value string)
154 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700155 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
156 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800157 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700158
Colin Cross0875c522017-11-28 17:34:01 -0800159 PrimaryModule() Module
160 FinalModule() Module
161 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700162
163 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800164 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800165}
166
Colin Cross635c3b02016-05-18 15:37:25 -0700167type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800168 blueprint.Module
169
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700170 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
171 // but GenerateAndroidBuildActions also has access to Android-specific information.
172 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700173 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700174
Colin Cross1e676be2016-10-12 14:38:15 -0700175 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800176
Colin Cross635c3b02016-05-18 15:37:25 -0700177 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800178 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700179 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800180 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700181 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900182 InstallInRecovery() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800183 SkipInstall()
Jiyong Park374510b2018-03-19 18:23:01 +0900184 ExportedToMake() bool
Colin Cross36242852017-06-23 15:06:31 -0700185
186 AddProperties(props ...interface{})
187 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700188
Colin Crossae887032017-10-23 17:16:14 -0700189 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800190}
191
Colin Crossfc754582016-05-17 16:34:16 -0700192type nameProperties struct {
193 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800194 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700195}
196
197type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800198 // emit build rules for this module
199 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800200
Colin Cross7d5136f2015-05-11 13:39:40 -0700201 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800202 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
203 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
204 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700205 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700206
207 Target struct {
208 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700209 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700210 }
211 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700212 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700213 }
214 }
215
216 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800217
Dan Willemsen782a2d12015-12-21 14:55:28 -0800218 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700219 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800220
Colin Cross55708f32017-03-20 13:23:34 -0700221 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700222 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700223
Jiyong Park2db76922017-11-08 16:03:48 +0900224 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
225 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
226 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700227 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700228
Jiyong Park2db76922017-11-08 16:03:48 +0900229 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
230 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
231 Soc_specific *bool
232
233 // whether this module is specific to a device, not only for SoC, but also for off-chip
234 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
235 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
236 // This implies `soc_specific:true`.
237 Device_specific *bool
238
239 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900240 // network operator, etc). When set to true, it is installed into /product (or
241 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900242 Product_specific *bool
243
Jiyong Parkf9332f12018-02-01 00:54:12 +0900244 // Whether this module is installed to recovery partition
245 Recovery *bool
246
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700247 // init.rc files to be installed if this module is installed
248 Init_rc []string
249
Steven Moreland57a23d22018-04-04 15:42:19 -0700250 // VINTF manifest fragments to be installed if this module is installed
251 Vintf_fragments []string
252
Chris Wolfe998306e2016-08-15 14:47:23 -0400253 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700254 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400255
Colin Cross5aac3622017-08-31 15:07:09 -0700256 // relative path to a file to include in the list of notices for the device
257 Notice *string
258
Colin Crossa1ad8d12016-06-01 17:09:44 -0700259 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700260 CompileTarget Target `blueprint:"mutated"`
261 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800262
263 // Set by InitAndroidModule
264 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700265 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700266
267 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800268
269 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800270}
271
272type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700273 Host_supported *bool
274 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800275}
276
Colin Crossc472d572015-03-17 15:06:21 -0700277type Multilib string
278
279const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800280 MultilibBoth Multilib = "both"
281 MultilibFirst Multilib = "first"
282 MultilibCommon Multilib = "common"
283 MultilibCommonFirst Multilib = "common_first"
284 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700285)
286
Colin Crossa1ad8d12016-06-01 17:09:44 -0700287type HostOrDeviceSupported int
288
289const (
290 _ HostOrDeviceSupported = iota
291 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700292 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700293 DeviceSupported
294 HostAndDeviceSupported
295 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700296 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700297)
298
Jiyong Park2db76922017-11-08 16:03:48 +0900299type moduleKind int
300
301const (
302 platformModule moduleKind = iota
303 deviceSpecificModule
304 socSpecificModule
305 productSpecificModule
306)
307
308func (k moduleKind) String() string {
309 switch k {
310 case platformModule:
311 return "platform"
312 case deviceSpecificModule:
313 return "device-specific"
314 case socSpecificModule:
315 return "soc-specific"
316 case productSpecificModule:
317 return "product-specific"
318 default:
319 panic(fmt.Errorf("unknown module kind %d", k))
320 }
321}
322
Colin Cross36242852017-06-23 15:06:31 -0700323func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800324 base := m.base()
325 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700326
Colin Cross36242852017-06-23 15:06:31 -0700327 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700328 &base.nameProperties,
329 &base.commonProperties,
330 &base.variableProperties)
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700331 base.customizableProperties = m.GetProperties()
Colin Cross5049f022015-03-18 13:28:46 -0700332}
333
Colin Cross36242852017-06-23 15:06:31 -0700334func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
335 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700336
337 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800338 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700339 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700340 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800341
Dan Willemsen218f6562015-07-08 18:13:11 -0700342 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700343 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700344 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800345 }
346
Colin Cross36242852017-06-23 15:06:31 -0700347 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800348}
349
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800350// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800351// modules. It should be included as an anonymous field in every module
352// struct definition. InitAndroidModule should then be called from the module's
353// factory function, and the return values from InitAndroidModule should be
354// returned from the factory function.
355//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800356// The ModuleBase type is responsible for implementing the GenerateBuildActions
357// method to support the blueprint.Module interface. This method will then call
358// the module's GenerateAndroidBuildActions method once for each build variant
359// that is to be built. GenerateAndroidBuildActions is passed a
360// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800361// AndroidModuleContext exposes extra functionality specific to the Android build
362// system including details about the particular build variant that is to be
363// generated.
364//
365// For example:
366//
367// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800368// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800369// )
370//
371// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800372// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800373// properties struct {
374// MyProperty string
375// }
376// }
377//
Colin Cross36242852017-06-23 15:06:31 -0700378// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800379// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700380// m.AddProperties(&m.properties)
381// android.InitAndroidModule(m)
382// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800383// }
384//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800385// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800386// // Get the CPU architecture for the current build variant.
387// variantArch := ctx.Arch()
388//
389// // ...
390// }
Colin Cross635c3b02016-05-18 15:37:25 -0700391type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800392 // Putting the curiously recurring thing pointing to the thing that contains
393 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700394 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700395 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800396
Colin Crossfc754582016-05-17 16:34:16 -0700397 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800398 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700399 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800400 hostAndDeviceProperties hostAndDeviceProperties
401 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700402 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700403 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800404
405 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700406 installFiles Paths
407 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700408
409 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
410 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800411 installTarget WritablePath
412 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700413 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700414
Colin Cross178a5092016-09-13 13:42:32 -0700415 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700416
417 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700418
419 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700420 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700421}
422
423func (a *ModuleBase) AddProperties(props ...interface{}) {
424 a.registerProps = append(a.registerProps, props...)
425}
426
427func (a *ModuleBase) GetProperties() []interface{} {
428 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800429}
430
Colin Crossae887032017-10-23 17:16:14 -0700431func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700432 return a.buildParams
433}
434
Colin Crossce75d2c2016-10-06 16:12:58 -0700435// Name returns the name of the module. It may be overridden by individual module types, for
436// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700437func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800438 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700439}
440
Colin Crossce75d2c2016-10-06 16:12:58 -0700441// BaseModuleName returns the name of the module as specified in the blueprints file.
442func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800443 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700444}
445
Colin Cross635c3b02016-05-18 15:37:25 -0700446func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800447 return a
448}
449
Colin Cross8b74d172016-09-13 09:59:14 -0700450func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700451 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700452 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700453}
454
Colin Crossa1ad8d12016-06-01 17:09:44 -0700455func (a *ModuleBase) Target() Target {
456 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800457}
458
Colin Cross8b74d172016-09-13 09:59:14 -0700459func (a *ModuleBase) TargetPrimary() bool {
460 return a.commonProperties.CompilePrimary
461}
462
Colin Crossa1ad8d12016-06-01 17:09:44 -0700463func (a *ModuleBase) Os() OsType {
464 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800465}
466
Colin Cross635c3b02016-05-18 15:37:25 -0700467func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700468 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800469}
470
Colin Cross635c3b02016-05-18 15:37:25 -0700471func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700472 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800473}
474
Dan Willemsen0b24c742016-10-04 15:13:37 -0700475func (a *ModuleBase) ArchSpecific() bool {
476 return a.commonProperties.ArchSpecific
477}
478
Colin Crossa1ad8d12016-06-01 17:09:44 -0700479func (a *ModuleBase) OsClassSupported() []OsClass {
480 switch a.commonProperties.HostOrDeviceSupported {
481 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700482 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700483 case HostSupportedNoCross:
484 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700485 case DeviceSupported:
486 return []OsClass{Device}
487 case HostAndDeviceSupported:
488 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700489 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700490 supported = append(supported, Host, HostCross)
491 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700492 if a.hostAndDeviceProperties.Device_supported == nil ||
493 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700494 supported = append(supported, Device)
495 }
496 return supported
497 default:
498 return nil
499 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800500}
501
Colin Cross635c3b02016-05-18 15:37:25 -0700502func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800503 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
504 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700505 (a.hostAndDeviceProperties.Device_supported == nil ||
506 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800507}
508
Jiyong Parkc678ad32018-04-10 13:07:10 +0900509func (a *ModuleBase) Platform() bool {
510 return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific()
511}
512
513func (a *ModuleBase) DeviceSpecific() bool {
514 return Bool(a.commonProperties.Device_specific)
515}
516
517func (a *ModuleBase) SocSpecific() bool {
518 return Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
519}
520
521func (a *ModuleBase) ProductSpecific() bool {
522 return Bool(a.commonProperties.Product_specific)
523}
524
Colin Cross635c3b02016-05-18 15:37:25 -0700525func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800526 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800527 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800528 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800529 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800530}
531
Colin Crossce75d2c2016-10-06 16:12:58 -0700532func (a *ModuleBase) SkipInstall() {
533 a.commonProperties.SkipInstall = true
534}
535
Jiyong Park374510b2018-03-19 18:23:01 +0900536func (a *ModuleBase) ExportedToMake() bool {
537 return a.commonProperties.NamespaceExportedToMake
538}
539
Colin Cross635c3b02016-05-18 15:37:25 -0700540func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700541 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800542
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700543 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700544 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800545 ctx.VisitDepsDepthFirstIf(isFileInstaller,
546 func(m blueprint.Module) {
547 fileInstaller := m.(fileInstaller)
548 files := fileInstaller.filesToInstall()
549 result = append(result, files...)
550 })
551
552 return result
553}
554
Colin Cross635c3b02016-05-18 15:37:25 -0700555func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800556 return a.installFiles
557}
558
Colin Cross635c3b02016-05-18 15:37:25 -0700559func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800560 return p.noAddressSanitizer
561}
562
Colin Cross635c3b02016-05-18 15:37:25 -0700563func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800564 return false
565}
566
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700567func (p *ModuleBase) InstallInSanitizerDir() bool {
568 return false
569}
570
Jiyong Parkf9332f12018-02-01 00:54:12 +0900571func (p *ModuleBase) InstallInRecovery() bool {
572 return Bool(p.commonProperties.Recovery)
573}
574
Colin Cross0875c522017-11-28 17:34:01 -0800575func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700576 allInstalledFiles := Paths{}
577 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800578 ctx.VisitAllModuleVariants(func(module Module) {
579 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700580 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
581 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800582 })
583
Colin Cross0875c522017-11-28 17:34:01 -0800584 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700585
Jeff Gaston088e29e2017-11-29 16:47:17 -0800586 namespacePrefix := ctx.Namespace().(*Namespace).id
587 if namespacePrefix != "" {
588 namespacePrefix = namespacePrefix + "-"
589 }
590
Colin Cross3f40fa42015-01-30 17:27:36 -0800591 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800592 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800593 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700594 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800595 Output: name,
596 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800597 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700598 })
599 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700600 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700601 }
602
603 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800604 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800605 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700606 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800607 Output: name,
608 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700609 })
610 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700611 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700612 }
613
614 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800615 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800616 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800617 suffix = "-soong"
618 }
619
Jeff Gaston088e29e2017-11-29 16:47:17 -0800620 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800621 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700622 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800623 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700624 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800625 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700626
627 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800628 }
629}
630
Jiyong Park2db76922017-11-08 16:03:48 +0900631func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
632 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
633 var deviceSpecific = Bool(a.commonProperties.Device_specific)
634 var productSpecific = Bool(a.commonProperties.Product_specific)
635
636 if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
637 msg := "conflicting value set here"
638 if productSpecific {
639 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
640 if deviceSpecific {
641 ctx.PropertyErrorf("device_specific", msg)
642 }
643 } else {
644 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
645 }
646 if Bool(a.commonProperties.Vendor) {
647 ctx.PropertyErrorf("vendor", msg)
648 }
649 if Bool(a.commonProperties.Proprietary) {
650 ctx.PropertyErrorf("proprietary", msg)
651 }
652 if Bool(a.commonProperties.Soc_specific) {
653 ctx.PropertyErrorf("soc_specific", msg)
654 }
655 }
656
657 if productSpecific {
658 return productSpecificModule
659 } else if deviceSpecific {
660 return deviceSpecificModule
661 } else if socSpecific {
662 return socSpecificModule
663 } else {
664 return platformModule
665 }
666}
667
Colin Cross635c3b02016-05-18 15:37:25 -0700668func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700669 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700670 target: a.commonProperties.CompileTarget,
671 targetPrimary: a.commonProperties.CompilePrimary,
Jiyong Park2db76922017-11-08 16:03:48 +0900672 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700673 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800674 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800675}
676
Colin Cross0875c522017-11-28 17:34:01 -0800677func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
678 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700679 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800680 ModuleContext: blueprintCtx,
681 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
682 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700683 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800684 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800685 }
686
Colin Cross67a5c132017-05-09 13:45:28 -0700687 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
688 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800689 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
690 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700691 }
Colin Cross0875c522017-11-28 17:34:01 -0800692 if !ctx.PrimaryArch() {
693 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700694 }
695
696 ctx.Variable(pctx, "moduleDesc", desc)
697
698 s := ""
699 if len(suffix) > 0 {
700 s = " [" + strings.Join(suffix, " ") + "]"
701 }
702 ctx.Variable(pctx, "moduleDescSuffix", s)
703
Colin Cross9b1d13d2016-09-19 15:18:11 -0700704 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800705 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700706 if ctx.Failed() {
707 return
708 }
709
Colin Cross0875c522017-11-28 17:34:01 -0800710 a.installFiles = append(a.installFiles, ctx.installFiles...)
711 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800712 }
713
Colin Cross9b1d13d2016-09-19 15:18:11 -0700714 if a == ctx.FinalModule().(Module).base() {
715 a.generateModuleTarget(ctx)
716 if ctx.Failed() {
717 return
718 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800719 }
Colin Crosscec81712017-07-13 14:43:27 -0700720
Colin Cross0875c522017-11-28 17:34:01 -0800721 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800722}
723
Colin Crossf6566ed2015-03-24 11:13:38 -0700724type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700725 target Target
726 targetPrimary bool
727 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900728 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700729 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700730}
731
Colin Cross3f40fa42015-01-30 17:27:36 -0800732type androidModuleContext struct {
733 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700734 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700735 installDeps Paths
736 installFiles Paths
737 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800738 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700739 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700740
741 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700742 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800743}
744
Colin Cross67a5c132017-05-09 13:45:28 -0700745func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800746 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700747 Rule: ErrorRule,
748 Description: desc,
749 Outputs: outputs,
750 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800751 Args: map[string]string{
752 "error": err.Error(),
753 },
754 })
755 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800756}
757
Colin Crossaabf6792017-11-29 00:27:14 -0800758func (a *androidModuleContext) Config() Config {
759 return a.ModuleContext.Config().(Config)
760}
761
Colin Cross0875c522017-11-28 17:34:01 -0800762func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700763 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800764}
765
Colin Cross0875c522017-11-28 17:34:01 -0800766func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700767 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700768 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800769 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800770 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700771 Outputs: params.Outputs.Strings(),
772 ImplicitOutputs: params.ImplicitOutputs.Strings(),
773 Inputs: params.Inputs.Strings(),
774 Implicits: params.Implicits.Strings(),
775 OrderOnly: params.OrderOnly.Strings(),
776 Args: params.Args,
777 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700778 }
779
Colin Cross33bfb0a2016-11-21 17:23:08 -0800780 if params.Depfile != nil {
781 bparams.Depfile = params.Depfile.String()
782 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700783 if params.Output != nil {
784 bparams.Outputs = append(bparams.Outputs, params.Output.String())
785 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700786 if params.ImplicitOutput != nil {
787 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
788 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700789 if params.Input != nil {
790 bparams.Inputs = append(bparams.Inputs, params.Input.String())
791 }
792 if params.Implicit != nil {
793 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
794 }
795
Colin Cross0875c522017-11-28 17:34:01 -0800796 return bparams
797}
798
799func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
800 a.ModuleContext.Variable(pctx.PackageContext, name, value)
801}
802
803func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
804 argNames ...string) blueprint.Rule {
805
806 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
807}
808
809func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
810 if a.config.captureBuild {
811 a.buildParams = append(a.buildParams, params)
812 }
813
814 bparams := convertBuildParams(params)
815
816 if bparams.Description != "" {
817 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
818 }
819
Colin Cross6ff51382015-12-17 16:39:19 -0800820 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700821 a.ninjaError(bparams.Description, bparams.Outputs,
822 fmt.Errorf("module %s missing dependencies: %s\n",
823 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800824 return
825 }
826
Colin Cross0875c522017-11-28 17:34:01 -0800827 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700828}
829
Colin Cross6ff51382015-12-17 16:39:19 -0800830func (a *androidModuleContext) GetMissingDependencies() []string {
831 return a.missingDeps
832}
833
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800834func (a *androidModuleContext) AddMissingDependencies(deps []string) {
835 if deps != nil {
836 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700837 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800838 }
839}
840
Colin Crossd11fcda2017-10-23 17:59:01 -0700841func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
842 aModule, _ := module.(Module)
843 if aModule == nil {
844 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
845 return nil
846 }
847
848 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800849 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700850 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
851 } else {
852 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
853 }
854 return nil
855 }
856
857 return aModule
858}
859
Colin Cross35143d02017-11-16 00:11:20 -0800860func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
861 a.ModuleContext.VisitDirectDeps(visit)
862}
863
Colin Crossd11fcda2017-10-23 17:59:01 -0700864func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
865 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
866 if aModule := a.validateAndroidModule(module); aModule != nil {
867 visit(aModule)
868 }
869 })
870}
871
Colin Crossee6143c2017-12-30 17:54:27 -0800872func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
873 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
874 if aModule := a.validateAndroidModule(module); aModule != nil {
875 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
876 visit(aModule)
877 }
878 }
879 })
880}
881
Colin Crossd11fcda2017-10-23 17:59:01 -0700882func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
883 a.ModuleContext.VisitDirectDepsIf(
884 // pred
885 func(module blueprint.Module) bool {
886 if aModule := a.validateAndroidModule(module); aModule != nil {
887 return pred(aModule)
888 } else {
889 return false
890 }
891 },
892 // visit
893 func(module blueprint.Module) {
894 visit(module.(Module))
895 })
896}
897
898func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
899 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
900 if aModule := a.validateAndroidModule(module); aModule != nil {
901 visit(aModule)
902 }
903 })
904}
905
906func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
907 a.ModuleContext.VisitDepsDepthFirstIf(
908 // pred
909 func(module blueprint.Module) bool {
910 if aModule := a.validateAndroidModule(module); aModule != nil {
911 return pred(aModule)
912 } else {
913 return false
914 }
915 },
916 // visit
917 func(module blueprint.Module) {
918 visit(module.(Module))
919 })
920}
921
922func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
923 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
924 childAndroidModule := a.validateAndroidModule(child)
925 parentAndroidModule := a.validateAndroidModule(parent)
926 if childAndroidModule != nil && parentAndroidModule != nil {
927 return visit(childAndroidModule, parentAndroidModule)
928 } else {
929 return false
930 }
931 })
932}
933
Colin Cross0875c522017-11-28 17:34:01 -0800934func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
935 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
936 visit(module.(Module))
937 })
938}
939
940func (a *androidModuleContext) PrimaryModule() Module {
941 return a.ModuleContext.PrimaryModule().(Module)
942}
943
944func (a *androidModuleContext) FinalModule() Module {
945 return a.ModuleContext.FinalModule().(Module)
946}
947
Colin Crossa1ad8d12016-06-01 17:09:44 -0700948func (a *androidBaseContextImpl) Target() Target {
949 return a.target
950}
951
Colin Cross8b74d172016-09-13 09:59:14 -0700952func (a *androidBaseContextImpl) TargetPrimary() bool {
953 return a.targetPrimary
954}
955
Colin Crossf6566ed2015-03-24 11:13:38 -0700956func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700957 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800958}
959
Colin Crossa1ad8d12016-06-01 17:09:44 -0700960func (a *androidBaseContextImpl) Os() OsType {
961 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800962}
963
Colin Crossf6566ed2015-03-24 11:13:38 -0700964func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700965 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700966}
967
968func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700969 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700970}
971
Colin Cross0af4b842015-04-30 16:36:18 -0700972func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700973 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700974}
975
Colin Cross3edeee12017-04-04 12:59:48 -0700976func (a *androidBaseContextImpl) Windows() bool {
977 return a.target.Os == Windows
978}
979
Colin Crossf6566ed2015-03-24 11:13:38 -0700980func (a *androidBaseContextImpl) Debug() bool {
981 return a.debug
982}
983
Colin Cross1e7d3702016-08-24 15:25:47 -0700984func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700985 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
986 return true
987 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700988 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
989}
990
Colin Cross1332b002015-04-07 17:11:30 -0700991func (a *androidBaseContextImpl) AConfig() Config {
992 return a.config
993}
994
Colin Cross9272ade2016-08-17 15:24:12 -0700995func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
996 return DeviceConfig{a.config.deviceConfig}
997}
998
Jiyong Park2db76922017-11-08 16:03:48 +0900999func (a *androidBaseContextImpl) Platform() bool {
1000 return a.kind == platformModule
1001}
1002
1003func (a *androidBaseContextImpl) DeviceSpecific() bool {
1004 return a.kind == deviceSpecificModule
1005}
1006
1007func (a *androidBaseContextImpl) SocSpecific() bool {
1008 return a.kind == socSpecificModule
1009}
1010
1011func (a *androidBaseContextImpl) ProductSpecific() bool {
1012 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -08001013}
1014
Colin Cross8d8f8e22016-08-03 11:57:50 -07001015func (a *androidModuleContext) InstallInData() bool {
1016 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001017}
1018
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001019func (a *androidModuleContext) InstallInSanitizerDir() bool {
1020 return a.module.InstallInSanitizerDir()
1021}
1022
Jiyong Parkf9332f12018-02-01 00:54:12 +09001023func (a *androidModuleContext) InstallInRecovery() bool {
1024 return a.module.InstallInRecovery()
1025}
1026
Colin Cross893d8162017-04-26 17:34:03 -07001027func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
1028 if a.module.base().commonProperties.SkipInstall {
1029 return true
1030 }
1031
Colin Cross3607f212018-05-07 15:28:05 -07001032 // We'll need a solution for choosing which of modules with the same name in different
1033 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1034 // list of namespaces to install in a Soong-only build.
1035 if !a.module.base().commonProperties.NamespaceExportedToMake {
1036 return true
1037 }
1038
Colin Cross893d8162017-04-26 17:34:03 -07001039 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -08001040 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001041 return true
1042 }
1043
Colin Cross6510f912017-11-29 00:27:14 -08001044 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001045 return true
1046 }
1047 }
1048
1049 return false
1050}
1051
Colin Cross5c517922017-08-31 12:29:17 -07001052func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001053 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001054 return a.installFile(installPath, name, srcPath, Cp, deps)
1055}
1056
1057func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1058 deps ...Path) OutputPath {
1059 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1060}
1061
1062func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1063 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001064
Dan Willemsen782a2d12015-12-21 14:55:28 -08001065 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001066 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001067
Colin Cross893d8162017-04-26 17:34:03 -07001068 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001069
Dan Willemsen322acaf2016-01-12 23:07:05 -08001070 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001071
Colin Cross89562dc2016-10-03 17:47:19 -07001072 var implicitDeps, orderOnlyDeps Paths
1073
1074 if a.Host() {
1075 // Installed host modules might be used during the build, depend directly on their
1076 // dependencies so their timestamp is updated whenever their dependency is updated
1077 implicitDeps = deps
1078 } else {
1079 orderOnlyDeps = deps
1080 }
1081
Colin Crossae887032017-10-23 17:16:14 -07001082 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001083 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001084 Description: "install " + fullInstallPath.Base(),
1085 Output: fullInstallPath,
1086 Input: srcPath,
1087 Implicits: implicitDeps,
1088 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001089 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001090 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001091
Dan Willemsen322acaf2016-01-12 23:07:05 -08001092 a.installFiles = append(a.installFiles, fullInstallPath)
1093 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001094 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001095 return fullInstallPath
1096}
1097
Colin Cross3854a602016-01-11 12:49:11 -08001098func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1099 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001100 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001101
Colin Cross893d8162017-04-26 17:34:03 -07001102 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001103
Colin Crossae887032017-10-23 17:16:14 -07001104 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001105 Rule: Symlink,
1106 Description: "install symlink " + fullInstallPath.Base(),
1107 Output: fullInstallPath,
1108 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001109 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001110 Args: map[string]string{
1111 "fromPath": srcPath.String(),
1112 },
1113 })
Colin Cross3854a602016-01-11 12:49:11 -08001114
Colin Cross12fc4972016-01-11 12:49:11 -08001115 a.installFiles = append(a.installFiles, fullInstallPath)
1116 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1117 }
Colin Cross3854a602016-01-11 12:49:11 -08001118 return fullInstallPath
1119}
1120
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001121func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001122 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1123}
1124
Colin Cross3f40fa42015-01-30 17:27:36 -08001125type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001126 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001127}
1128
1129func isFileInstaller(m blueprint.Module) bool {
1130 _, ok := m.(fileInstaller)
1131 return ok
1132}
1133
1134func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001135 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001136 return ok
1137}
Colin Crossfce53272015-04-08 11:21:40 -07001138
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001139func findStringInSlice(str string, slice []string) int {
1140 for i, s := range slice {
1141 if s == str {
1142 return i
Colin Crossfce53272015-04-08 11:21:40 -07001143 }
1144 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001145 return -1
1146}
1147
Colin Cross068e0fe2016-12-13 15:23:47 -08001148func SrcIsModule(s string) string {
1149 if len(s) > 1 && s[0] == ':' {
1150 return s[1:]
1151 }
1152 return ""
1153}
1154
1155type sourceDependencyTag struct {
1156 blueprint.BaseDependencyTag
1157}
1158
1159var SourceDepTag sourceDependencyTag
1160
Colin Cross366938f2017-12-11 16:29:02 -08001161// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1162// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001163func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1164 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001165 set := make(map[string]bool)
1166
Colin Cross068e0fe2016-12-13 15:23:47 -08001167 for _, s := range srcFiles {
1168 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001169 if _, found := set[m]; found {
1170 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1171 } else {
1172 set[m] = true
1173 deps = append(deps, m)
1174 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001175 }
1176 }
1177
1178 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1179}
1180
Colin Cross366938f2017-12-11 16:29:02 -08001181// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1182// using ":module" syntax, if any.
1183func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1184 if s != nil {
1185 if m := SrcIsModule(*s); m != "" {
1186 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1187 }
1188 }
1189}
1190
Colin Cross068e0fe2016-12-13 15:23:47 -08001191type SourceFileProducer interface {
1192 Srcs() Paths
1193}
1194
1195// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001196// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001197func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001198 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1199}
1200
Colin Cross366938f2017-12-11 16:29:02 -08001201// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1202// ExtractSourceDeps must have already been called during the dependency resolution phase.
1203func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1204 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1205 if len(srcFiles) == 1 {
1206 return srcFiles[0]
1207 } else {
1208 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1209 return nil
1210 }
1211}
1212
Colin Cross2383f3b2018-02-06 14:40:13 -08001213// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1214// the srcFile is non-nil.
1215// ExtractSourceDeps must have already been called during the dependency resolution phase.
1216func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1217 if srcFile != nil {
1218 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1219 }
1220 return OptionalPath{}
1221}
1222
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001223func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001224 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001225
Colin Cross461b4452018-02-23 09:22:42 -08001226 var expandedExcludes []string
1227 if excludes != nil {
1228 expandedExcludes = make([]string, 0, len(excludes))
1229 }
Nan Zhang27e284d2018-02-09 21:03:53 +00001230
1231 for _, e := range excludes {
1232 if m := SrcIsModule(e); m != "" {
1233 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1234 if module == nil {
1235 // Error will have been handled by ExtractSourcesDeps
1236 continue
1237 }
1238 if srcProducer, ok := module.(SourceFileProducer); ok {
1239 expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1240 } else {
1241 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1242 }
1243 } else {
1244 expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001245 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001246 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001247 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001248 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001249 if m := SrcIsModule(s); m != "" {
1250 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001251 if module == nil {
1252 // Error will have been handled by ExtractSourcesDeps
1253 continue
1254 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001255 if srcProducer, ok := module.(SourceFileProducer); ok {
Nan Zhang27e284d2018-02-09 21:03:53 +00001256 moduleSrcs := srcProducer.Srcs()
1257 for _, e := range expandedExcludes {
1258 for j, ms := range moduleSrcs {
1259 if ms.String() == e {
1260 moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1261 }
1262 }
1263 }
1264 expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001265 } else {
1266 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1267 }
1268 } else if pathtools.IsGlob(s) {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001269 globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001270 for i, s := range globbedSrcFiles {
1271 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001272 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001273 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001274 } else {
Nan Zhang27e284d2018-02-09 21:03:53 +00001275 p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1276 j := findStringInSlice(p.String(), expandedExcludes)
1277 if j == -1 {
1278 expandedSrcFiles = append(expandedSrcFiles, p)
1279 }
1280
Colin Cross8f101b42015-06-17 15:09:06 -07001281 }
1282 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001283 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001284}
1285
Nan Zhang6d34b302017-02-04 17:47:46 -08001286func (ctx *androidModuleContext) RequiredModuleNames() []string {
1287 return ctx.module.base().commonProperties.Required
1288}
1289
Colin Cross7f19f372016-11-01 11:10:25 -07001290func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1291 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001292 if err != nil {
1293 ctx.ModuleErrorf("glob: %s", err.Error())
1294 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001295 return pathsForModuleSrcFromFullPath(ctx, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001296}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001297
Nan Zhang581fd212018-01-10 16:06:12 -08001298func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001299 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001300 if err != nil {
1301 ctx.ModuleErrorf("glob: %s", err.Error())
1302 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001303 return pathsForModuleSrcFromFullPath(ctx, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001304}
1305
Colin Cross463a90e2015-06-17 14:20:06 -07001306func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001307 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001308}
1309
Colin Cross0875c522017-11-28 17:34:01 -08001310func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001311 return &buildTargetSingleton{}
1312}
1313
Colin Cross87d8b562017-04-25 10:01:55 -07001314func parentDir(dir string) string {
1315 dir, _ = filepath.Split(dir)
1316 return filepath.Clean(dir)
1317}
1318
Colin Cross1f8c52b2015-06-16 16:38:17 -07001319type buildTargetSingleton struct{}
1320
Colin Cross0875c522017-11-28 17:34:01 -08001321func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1322 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001323
Colin Cross0875c522017-11-28 17:34:01 -08001324 mmTarget := func(dir string) WritablePath {
1325 return PathForPhony(ctx,
1326 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001327 }
1328
Colin Cross0875c522017-11-28 17:34:01 -08001329 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001330
Colin Cross0875c522017-11-28 17:34:01 -08001331 ctx.VisitAllModules(func(module Module) {
1332 blueprintDir := module.base().blueprintDir
1333 installTarget := module.base().installTarget
1334 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001335
Colin Cross0875c522017-11-28 17:34:01 -08001336 if checkbuildTarget != nil {
1337 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1338 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1339 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001340
Colin Cross0875c522017-11-28 17:34:01 -08001341 if installTarget != nil {
1342 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001343 }
1344 })
1345
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001346 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001347 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001348 suffix = "-soong"
1349 }
1350
Colin Cross1f8c52b2015-06-16 16:38:17 -07001351 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001352 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001353 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001354 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001355 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001356 })
1357
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001358 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001359 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001360 return
1361 }
1362
Colin Cross0875c522017-11-28 17:34:01 -08001363 sortedKeys := func(m map[string]Paths) []string {
1364 s := make([]string, 0, len(m))
1365 for k := range m {
1366 s = append(s, k)
1367 }
1368 sort.Strings(s)
1369 return s
1370 }
1371
Colin Cross87d8b562017-04-25 10:01:55 -07001372 // Ensure ancestor directories are in modulesInDir
1373 dirs := sortedKeys(modulesInDir)
1374 for _, dir := range dirs {
1375 dir := parentDir(dir)
1376 for dir != "." && dir != "/" {
1377 if _, exists := modulesInDir[dir]; exists {
1378 break
1379 }
1380 modulesInDir[dir] = nil
1381 dir = parentDir(dir)
1382 }
1383 }
1384
1385 // Make directories build their direct subdirectories
1386 dirs = sortedKeys(modulesInDir)
1387 for _, dir := range dirs {
1388 p := parentDir(dir)
1389 if p != "." && p != "/" {
1390 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1391 }
1392 }
1393
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001394 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1395 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1396 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001397 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001398 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001399 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001400 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001401 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001402 // HACK: checkbuild should be an optional build, but force it
1403 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001404 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001405 })
1406 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001407
1408 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1409 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001410 ctx.VisitAllModules(func(module Module) {
1411 if module.Enabled() {
1412 os := module.Target().Os
1413 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001414 }
1415 })
1416
Colin Cross0875c522017-11-28 17:34:01 -08001417 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001418 for os, deps := range osDeps {
1419 var className string
1420
1421 switch os.Class {
1422 case Host:
1423 className = "host"
1424 case HostCross:
1425 className = "host-cross"
1426 case Device:
1427 className = "target"
1428 default:
1429 continue
1430 }
1431
Colin Cross0875c522017-11-28 17:34:01 -08001432 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001433 osClass[className] = append(osClass[className], name)
1434
Colin Cross0875c522017-11-28 17:34:01 -08001435 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001436 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001437 Output: name,
1438 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001439 })
1440 }
1441
1442 // Wrap those into host|host-cross|target phony rules
1443 osClasses := sortedKeys(osClass)
1444 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001445 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001446 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001447 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001448 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001449 })
1450 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001451}
Colin Crossd779da42015-12-17 18:00:23 -08001452
1453type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001454 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001455 ctx interface {
1456 ModuleName(blueprint.Module) string
1457 ModuleSubDir(blueprint.Module) string
1458 }
1459}
1460
1461func (s AndroidModulesByName) Len() int { return len(s.slice) }
1462func (s AndroidModulesByName) Less(i, j int) bool {
1463 mi, mj := s.slice[i], s.slice[j]
1464 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1465
1466 if ni != nj {
1467 return ni < nj
1468 } else {
1469 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1470 }
1471}
1472func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }