blob: 1cdc2dd8b5ad4b0279b00b030e8e3b14a32fa64a [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross6ff51382015-12-17 16:39:19 -080018 "fmt"
Colin Cross3f40fa42015-01-30 17:27:36 -080019 "path/filepath"
Colin Cross6ff51382015-12-17 16:39:19 -080020 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070021
22 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070023 "github.com/google/blueprint/pathtools"
Colin Cross3f40fa42015-01-30 17:27:36 -080024)
25
26var (
27 DeviceSharedLibrary = "shared_library"
28 DeviceStaticLibrary = "static_library"
29 DeviceExecutable = "executable"
30 HostSharedLibrary = "host_shared_library"
31 HostStaticLibrary = "host_static_library"
32 HostExecutable = "host_executable"
33)
34
Colin Crossae887032017-10-23 17:16:14 -070035type BuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070036 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080037 Deps blueprint.Deps
38 Depfile WritablePath
Colin Cross67a5c132017-05-09 13:45:28 -070039 Description string
Dan Willemsen9f3c5742016-11-03 14:28:31 -070040 Output WritablePath
41 Outputs WritablePaths
42 ImplicitOutput WritablePath
43 ImplicitOutputs WritablePaths
44 Input Path
45 Inputs Paths
46 Implicit Path
47 Implicits Paths
48 OrderOnly Paths
49 Default bool
50 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070051}
52
Colin Crossae887032017-10-23 17:16:14 -070053type ModuleBuildParams BuildParams
54
Colin Crossf6566ed2015-03-24 11:13:38 -070055type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070056 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070057 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070058 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070059 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Host() bool
61 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070062 Darwin() bool
Colin Cross3edeee12017-04-04 12:59:48 -070063 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070064 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070065 PrimaryArch() bool
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070066 InstallOnVendorPartition() bool
Colin Cross1332b002015-04-07 17:11:30 -070067 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070068 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070069}
70
Colin Cross635c3b02016-05-18 15:37:25 -070071type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070072 blueprint.BaseModuleContext
73 androidBaseContext
74}
75
Colin Cross635c3b02016-05-18 15:37:25 -070076type ModuleContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070077 androidBaseContext
Colin Cross3f68a132017-10-23 17:10:29 -070078 blueprint.BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -080079
Colin Crossae887032017-10-23 17:16:14 -070080 // Deprecated: use ModuleContext.Build instead.
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070082
Dan Willemsen34cc69e2015-09-23 15:26:20 -070083 ExpandSources(srcFiles, excludes []string) Paths
Colin Crossfaeb7aa2017-02-01 14:12:44 -080084 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070085 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070086
Colin Cross5c517922017-08-31 12:29:17 -070087 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
88 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080089 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070090 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080091
92 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070093
Colin Cross8d8f8e22016-08-03 11:57:50 -070094 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070095 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -080096
97 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -070098
99 // android.ModuleContext methods
100 // These are duplicated instead of embedded so that can eventually be wrapped to take an
101 // android.Module instead of a blueprint.Module
102 OtherModuleName(m blueprint.Module) string
103 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
104 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
105
106 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
107 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
108
109 ModuleSubDir() string
110
Colin Crossd11fcda2017-10-23 17:59:01 -0700111 VisitDirectDeps(visit func(Module))
112 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
113 VisitDepsDepthFirst(visit func(Module))
114 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
115 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700116
117 Variable(pctx blueprint.PackageContext, name, value string)
118 Rule(pctx blueprint.PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700119 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
120 // and performs more verification.
121 Build(pctx blueprint.PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700122
123 PrimaryModule() blueprint.Module
124 FinalModule() blueprint.Module
125 VisitAllModuleVariants(visit func(blueprint.Module))
126
127 GetMissingDependencies() []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800128}
129
Colin Cross635c3b02016-05-18 15:37:25 -0700130type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800131 blueprint.Module
132
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700133 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
134 // but GenerateAndroidBuildActions also has access to Android-specific information.
135 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700136 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700137
Colin Cross1e676be2016-10-12 14:38:15 -0700138 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800139
Colin Cross635c3b02016-05-18 15:37:25 -0700140 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800141 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700142 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800143 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700144 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800145 SkipInstall()
Colin Cross36242852017-06-23 15:06:31 -0700146
147 AddProperties(props ...interface{})
148 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700149
Colin Crossae887032017-10-23 17:16:14 -0700150 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800151}
152
Colin Crossfc754582016-05-17 16:34:16 -0700153type nameProperties struct {
154 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700155 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700156}
157
158type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700159 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800160
Dan Willemsen0effe062015-11-30 16:06:01 -0800161 // emit build rules for this module
162 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800163
Colin Cross7d5136f2015-05-11 13:39:40 -0700164 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800165 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
166 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
167 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700168 Compile_multilib string `android:"arch_variant"`
169
170 Target struct {
171 Host struct {
172 Compile_multilib string
173 }
174 Android struct {
175 Compile_multilib string
176 }
177 }
178
179 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800180
Dan Willemsen782a2d12015-12-21 14:55:28 -0800181 // whether this is a proprietary vendor module, and should be installed into /vendor
182 Proprietary bool
183
Colin Cross55708f32017-03-20 13:23:34 -0700184 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700185 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700186
Dan Willemsenaa118f92017-04-06 12:49:58 -0700187 // whether this module is device specific and should be installed into /vendor
188 Vendor bool
189
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700190 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
191 // file
192 Logtags []string
193
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700194 // init.rc files to be installed if this module is installed
195 Init_rc []string
196
Chris Wolfe998306e2016-08-15 14:47:23 -0400197 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700198 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400199
Colin Cross5aac3622017-08-31 15:07:09 -0700200 // relative path to a file to include in the list of notices for the device
201 Notice *string
202
Colin Crossa1ad8d12016-06-01 17:09:44 -0700203 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700204 CompileTarget Target `blueprint:"mutated"`
205 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800206
207 // Set by InitAndroidModule
208 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700209 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700210
211 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800212}
213
214type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700215 Host_supported *bool
216 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800217}
218
Colin Crossc472d572015-03-17 15:06:21 -0700219type Multilib string
220
221const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700222 MultilibBoth Multilib = "both"
223 MultilibFirst Multilib = "first"
224 MultilibCommon Multilib = "common"
225 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700226)
227
Colin Crossa1ad8d12016-06-01 17:09:44 -0700228type HostOrDeviceSupported int
229
230const (
231 _ HostOrDeviceSupported = iota
232 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700233 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700234 DeviceSupported
235 HostAndDeviceSupported
236 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700237 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700238)
239
Colin Cross36242852017-06-23 15:06:31 -0700240func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800241 base := m.base()
242 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700243
Colin Cross36242852017-06-23 15:06:31 -0700244 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700245 &base.nameProperties,
246 &base.commonProperties,
247 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700248}
249
Colin Cross36242852017-06-23 15:06:31 -0700250func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
251 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700252
253 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800254 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700255 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700256 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800257
Dan Willemsen218f6562015-07-08 18:13:11 -0700258 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700259 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700260 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800261 }
262
Colin Cross36242852017-06-23 15:06:31 -0700263 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800264}
265
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800266// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800267// modules. It should be included as an anonymous field in every module
268// struct definition. InitAndroidModule should then be called from the module's
269// factory function, and the return values from InitAndroidModule should be
270// returned from the factory function.
271//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800272// The ModuleBase type is responsible for implementing the GenerateBuildActions
273// method to support the blueprint.Module interface. This method will then call
274// the module's GenerateAndroidBuildActions method once for each build variant
275// that is to be built. GenerateAndroidBuildActions is passed a
276// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800277// AndroidModuleContext exposes extra functionality specific to the Android build
278// system including details about the particular build variant that is to be
279// generated.
280//
281// For example:
282//
283// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800284// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800285// )
286//
287// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800288// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800289// properties struct {
290// MyProperty string
291// }
292// }
293//
Colin Cross36242852017-06-23 15:06:31 -0700294// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800295// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700296// m.AddProperties(&m.properties)
297// android.InitAndroidModule(m)
298// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800299// }
300//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800301// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800302// // Get the CPU architecture for the current build variant.
303// variantArch := ctx.Arch()
304//
305// // ...
306// }
Colin Cross635c3b02016-05-18 15:37:25 -0700307type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800308 // Putting the curiously recurring thing pointing to the thing that contains
309 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700310 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700311 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800312
Colin Crossfc754582016-05-17 16:34:16 -0700313 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800314 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700315 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800316 hostAndDeviceProperties hostAndDeviceProperties
317 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700318 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700319 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800320
321 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700322 installFiles Paths
323 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700324
325 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
326 // Only set on the final variant of each module
327 installTarget string
328 checkbuildTarget string
329 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700330
Colin Cross178a5092016-09-13 13:42:32 -0700331 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700332
333 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700334
335 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700336 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700337}
338
339func (a *ModuleBase) AddProperties(props ...interface{}) {
340 a.registerProps = append(a.registerProps, props...)
341}
342
343func (a *ModuleBase) GetProperties() []interface{} {
344 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800345}
346
Colin Crossae887032017-10-23 17:16:14 -0700347func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700348 return a.buildParams
349}
350
Colin Crossce75d2c2016-10-06 16:12:58 -0700351// Name returns the name of the module. It may be overridden by individual module types, for
352// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700353func (a *ModuleBase) Name() string {
354 return a.nameProperties.Name
355}
356
Colin Crossce75d2c2016-10-06 16:12:58 -0700357// BaseModuleName returns the name of the module as specified in the blueprints file.
358func (a *ModuleBase) BaseModuleName() string {
359 return a.nameProperties.Name
360}
361
Colin Cross635c3b02016-05-18 15:37:25 -0700362func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800363 return a
364}
365
Colin Cross8b74d172016-09-13 09:59:14 -0700366func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700367 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700368 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700369}
370
Colin Crossa1ad8d12016-06-01 17:09:44 -0700371func (a *ModuleBase) Target() Target {
372 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800373}
374
Colin Cross8b74d172016-09-13 09:59:14 -0700375func (a *ModuleBase) TargetPrimary() bool {
376 return a.commonProperties.CompilePrimary
377}
378
Colin Crossa1ad8d12016-06-01 17:09:44 -0700379func (a *ModuleBase) Os() OsType {
380 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800381}
382
Colin Cross635c3b02016-05-18 15:37:25 -0700383func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700384 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800385}
386
Colin Cross635c3b02016-05-18 15:37:25 -0700387func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700388 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800389}
390
Dan Willemsen0b24c742016-10-04 15:13:37 -0700391func (a *ModuleBase) ArchSpecific() bool {
392 return a.commonProperties.ArchSpecific
393}
394
Colin Crossa1ad8d12016-06-01 17:09:44 -0700395func (a *ModuleBase) OsClassSupported() []OsClass {
396 switch a.commonProperties.HostOrDeviceSupported {
397 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700398 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700399 case HostSupportedNoCross:
400 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700401 case DeviceSupported:
402 return []OsClass{Device}
403 case HostAndDeviceSupported:
404 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700405 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700406 supported = append(supported, Host, HostCross)
407 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700408 if a.hostAndDeviceProperties.Device_supported == nil ||
409 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700410 supported = append(supported, Device)
411 }
412 return supported
413 default:
414 return nil
415 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800416}
417
Colin Cross635c3b02016-05-18 15:37:25 -0700418func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800419 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
420 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700421 (a.hostAndDeviceProperties.Device_supported == nil ||
422 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800423}
424
Colin Cross635c3b02016-05-18 15:37:25 -0700425func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800426 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800427 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800428 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800429 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800430}
431
Colin Crossce75d2c2016-10-06 16:12:58 -0700432func (a *ModuleBase) SkipInstall() {
433 a.commonProperties.SkipInstall = true
434}
435
Colin Cross635c3b02016-05-18 15:37:25 -0700436func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700437 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800438
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700439 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800440 ctx.VisitDepsDepthFirstIf(isFileInstaller,
441 func(m blueprint.Module) {
442 fileInstaller := m.(fileInstaller)
443 files := fileInstaller.filesToInstall()
444 result = append(result, files...)
445 })
446
447 return result
448}
449
Colin Cross635c3b02016-05-18 15:37:25 -0700450func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800451 return a.installFiles
452}
453
Colin Cross635c3b02016-05-18 15:37:25 -0700454func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800455 return p.noAddressSanitizer
456}
457
Colin Cross635c3b02016-05-18 15:37:25 -0700458func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800459 return false
460}
461
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700462func (p *ModuleBase) InstallInSanitizerDir() bool {
463 return false
464}
465
Colin Cross635c3b02016-05-18 15:37:25 -0700466func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700467 allInstalledFiles := Paths{}
468 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800469 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700470 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700471 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
472 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800473 })
474
Colin Cross9454bfa2015-03-17 13:24:18 -0700475 deps := []string{}
476
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700478 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800479 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700480 Rule: blueprint.Phony,
481 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700482 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800483 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700484 })
485 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700486 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700487 }
488
489 if len(allCheckbuildFiles) > 0 {
490 name := ctx.ModuleName() + "-checkbuild"
491 ctx.Build(pctx, blueprint.BuildParams{
492 Rule: blueprint.Phony,
493 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700494 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700495 Optional: true,
496 })
497 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700498 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700499 }
500
501 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800502 suffix := ""
503 if ctx.Config().(Config).EmbeddedInMake() {
504 suffix = "-soong"
505 }
506
Colin Cross9454bfa2015-03-17 13:24:18 -0700507 ctx.Build(pctx, blueprint.BuildParams{
508 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800509 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700510 Implicits: deps,
511 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800512 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700513
514 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800515 }
516}
517
Colin Cross635c3b02016-05-18 15:37:25 -0700518func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700519 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700520 target: a.commonProperties.CompileTarget,
521 targetPrimary: a.commonProperties.CompilePrimary,
Dan Willemsenaa118f92017-04-06 12:49:58 -0700522 vendor: a.commonProperties.Proprietary || a.commonProperties.Vendor,
Colin Cross8b74d172016-09-13 09:59:14 -0700523 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800524 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800525}
526
Colin Cross635c3b02016-05-18 15:37:25 -0700527func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800528 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700529 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700530 ModuleContext: ctx,
531 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
532 installDeps: a.computeInstallDeps(ctx),
533 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800534 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800535 }
536
Colin Cross67a5c132017-05-09 13:45:28 -0700537 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
538 var suffix []string
539 if androidCtx.Os().Class != Device && androidCtx.Os().Class != Generic {
540 suffix = append(suffix, androidCtx.Os().String())
541 }
542 if !androidCtx.PrimaryArch() {
543 suffix = append(suffix, androidCtx.Arch().ArchType.String())
544 }
545
546 ctx.Variable(pctx, "moduleDesc", desc)
547
548 s := ""
549 if len(suffix) > 0 {
550 s = " [" + strings.Join(suffix, " ") + "]"
551 }
552 ctx.Variable(pctx, "moduleDescSuffix", s)
553
Colin Cross9b1d13d2016-09-19 15:18:11 -0700554 if a.Enabled() {
555 a.module.GenerateAndroidBuildActions(androidCtx)
556 if ctx.Failed() {
557 return
558 }
559
560 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
561 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800562 }
563
Colin Cross9b1d13d2016-09-19 15:18:11 -0700564 if a == ctx.FinalModule().(Module).base() {
565 a.generateModuleTarget(ctx)
566 if ctx.Failed() {
567 return
568 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800569 }
Colin Crosscec81712017-07-13 14:43:27 -0700570
571 a.buildParams = androidCtx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800572}
573
Colin Crossf6566ed2015-03-24 11:13:38 -0700574type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700575 target Target
576 targetPrimary bool
577 debug bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700578 vendor bool
Colin Cross8b74d172016-09-13 09:59:14 -0700579 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700580}
581
Colin Cross3f40fa42015-01-30 17:27:36 -0800582type androidModuleContext struct {
583 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700584 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700585 installDeps Paths
586 installFiles Paths
587 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800588 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700589 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700590
591 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700592 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800593}
594
Colin Cross67a5c132017-05-09 13:45:28 -0700595func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross6ff51382015-12-17 16:39:19 -0800596 a.ModuleContext.Build(pctx, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700597 Rule: ErrorRule,
598 Description: desc,
599 Outputs: outputs,
600 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800601 Args: map[string]string{
602 "error": err.Error(),
603 },
604 })
605 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800606}
607
Colin Crossae887032017-10-23 17:16:14 -0700608func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
609 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800610}
611
Colin Crossae887032017-10-23 17:16:14 -0700612func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params BuildParams) {
Colin Crosscec81712017-07-13 14:43:27 -0700613 if a.config.captureBuild {
614 a.buildParams = append(a.buildParams, params)
615 }
616
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700617 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700618 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800619 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700620 Outputs: params.Outputs.Strings(),
621 ImplicitOutputs: params.ImplicitOutputs.Strings(),
622 Inputs: params.Inputs.Strings(),
623 Implicits: params.Implicits.Strings(),
624 OrderOnly: params.OrderOnly.Strings(),
625 Args: params.Args,
626 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700627 }
628
Colin Cross67a5c132017-05-09 13:45:28 -0700629 if params.Description != "" {
630 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
631 }
632
Colin Cross33bfb0a2016-11-21 17:23:08 -0800633 if params.Depfile != nil {
634 bparams.Depfile = params.Depfile.String()
635 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700636 if params.Output != nil {
637 bparams.Outputs = append(bparams.Outputs, params.Output.String())
638 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700639 if params.ImplicitOutput != nil {
640 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
641 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700642 if params.Input != nil {
643 bparams.Inputs = append(bparams.Inputs, params.Input.String())
644 }
645 if params.Implicit != nil {
646 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
647 }
648
Colin Cross6ff51382015-12-17 16:39:19 -0800649 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700650 a.ninjaError(bparams.Description, bparams.Outputs,
651 fmt.Errorf("module %s missing dependencies: %s\n",
652 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800653 return
654 }
655
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700656 a.ModuleContext.Build(pctx, bparams)
657}
658
Colin Cross6ff51382015-12-17 16:39:19 -0800659func (a *androidModuleContext) GetMissingDependencies() []string {
660 return a.missingDeps
661}
662
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800663func (a *androidModuleContext) AddMissingDependencies(deps []string) {
664 if deps != nil {
665 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700666 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800667 }
668}
669
Colin Crossd11fcda2017-10-23 17:59:01 -0700670func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
671 aModule, _ := module.(Module)
672 if aModule == nil {
673 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
674 return nil
675 }
676
677 if !aModule.Enabled() {
678 if a.AConfig().AllowMissingDependencies() {
679 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
680 } else {
681 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
682 }
683 return nil
684 }
685
686 return aModule
687}
688
689func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
690 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
691 if aModule := a.validateAndroidModule(module); aModule != nil {
692 visit(aModule)
693 }
694 })
695}
696
697func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
698 a.ModuleContext.VisitDirectDepsIf(
699 // pred
700 func(module blueprint.Module) bool {
701 if aModule := a.validateAndroidModule(module); aModule != nil {
702 return pred(aModule)
703 } else {
704 return false
705 }
706 },
707 // visit
708 func(module blueprint.Module) {
709 visit(module.(Module))
710 })
711}
712
713func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
714 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
715 if aModule := a.validateAndroidModule(module); aModule != nil {
716 visit(aModule)
717 }
718 })
719}
720
721func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
722 a.ModuleContext.VisitDepsDepthFirstIf(
723 // pred
724 func(module blueprint.Module) bool {
725 if aModule := a.validateAndroidModule(module); aModule != nil {
726 return pred(aModule)
727 } else {
728 return false
729 }
730 },
731 // visit
732 func(module blueprint.Module) {
733 visit(module.(Module))
734 })
735}
736
737func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
738 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
739 childAndroidModule := a.validateAndroidModule(child)
740 parentAndroidModule := a.validateAndroidModule(parent)
741 if childAndroidModule != nil && parentAndroidModule != nil {
742 return visit(childAndroidModule, parentAndroidModule)
743 } else {
744 return false
745 }
746 })
747}
748
Colin Crossa1ad8d12016-06-01 17:09:44 -0700749func (a *androidBaseContextImpl) Target() Target {
750 return a.target
751}
752
Colin Cross8b74d172016-09-13 09:59:14 -0700753func (a *androidBaseContextImpl) TargetPrimary() bool {
754 return a.targetPrimary
755}
756
Colin Crossf6566ed2015-03-24 11:13:38 -0700757func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700758 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800759}
760
Colin Crossa1ad8d12016-06-01 17:09:44 -0700761func (a *androidBaseContextImpl) Os() OsType {
762 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800763}
764
Colin Crossf6566ed2015-03-24 11:13:38 -0700765func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700766 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700767}
768
769func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700770 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700771}
772
Colin Cross0af4b842015-04-30 16:36:18 -0700773func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700774 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700775}
776
Colin Cross3edeee12017-04-04 12:59:48 -0700777func (a *androidBaseContextImpl) Windows() bool {
778 return a.target.Os == Windows
779}
780
Colin Crossf6566ed2015-03-24 11:13:38 -0700781func (a *androidBaseContextImpl) Debug() bool {
782 return a.debug
783}
784
Colin Cross1e7d3702016-08-24 15:25:47 -0700785func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700786 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
787 return true
788 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700789 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
790}
791
Colin Cross1332b002015-04-07 17:11:30 -0700792func (a *androidBaseContextImpl) AConfig() Config {
793 return a.config
794}
795
Colin Cross9272ade2016-08-17 15:24:12 -0700796func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
797 return DeviceConfig{a.config.deviceConfig}
798}
799
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700800func (a *androidBaseContextImpl) InstallOnVendorPartition() bool {
Dan Willemsenaa118f92017-04-06 12:49:58 -0700801 return a.vendor
Dan Willemsen782a2d12015-12-21 14:55:28 -0800802}
803
Colin Cross8d8f8e22016-08-03 11:57:50 -0700804func (a *androidModuleContext) InstallInData() bool {
805 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800806}
807
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700808func (a *androidModuleContext) InstallInSanitizerDir() bool {
809 return a.module.InstallInSanitizerDir()
810}
811
Colin Cross893d8162017-04-26 17:34:03 -0700812func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
813 if a.module.base().commonProperties.SkipInstall {
814 return true
815 }
816
817 if a.Device() {
818 if a.AConfig().SkipDeviceInstall() {
819 return true
820 }
821
822 if a.AConfig().SkipMegaDeviceInstall(fullInstallPath.String()) {
823 return true
824 }
825 }
826
827 return false
828}
829
Colin Cross5c517922017-08-31 12:29:17 -0700830func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700831 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -0700832 return a.installFile(installPath, name, srcPath, Cp, deps)
833}
834
835func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
836 deps ...Path) OutputPath {
837 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
838}
839
840func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
841 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700842
Dan Willemsen782a2d12015-12-21 14:55:28 -0800843 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700844 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800845
Colin Cross893d8162017-04-26 17:34:03 -0700846 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700847
Dan Willemsen322acaf2016-01-12 23:07:05 -0800848 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700849
Colin Cross89562dc2016-10-03 17:47:19 -0700850 var implicitDeps, orderOnlyDeps Paths
851
852 if a.Host() {
853 // Installed host modules might be used during the build, depend directly on their
854 // dependencies so their timestamp is updated whenever their dependency is updated
855 implicitDeps = deps
856 } else {
857 orderOnlyDeps = deps
858 }
859
Colin Crossae887032017-10-23 17:16:14 -0700860 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -0700861 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -0700862 Description: "install " + fullInstallPath.Base(),
863 Output: fullInstallPath,
864 Input: srcPath,
865 Implicits: implicitDeps,
866 OrderOnly: orderOnlyDeps,
867 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800868 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800869
Dan Willemsen322acaf2016-01-12 23:07:05 -0800870 a.installFiles = append(a.installFiles, fullInstallPath)
871 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700872 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700873 return fullInstallPath
874}
875
Colin Cross3854a602016-01-11 12:49:11 -0800876func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
877 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700878 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800879
Colin Cross893d8162017-04-26 17:34:03 -0700880 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700881
Colin Crossae887032017-10-23 17:16:14 -0700882 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700883 Rule: Symlink,
884 Description: "install symlink " + fullInstallPath.Base(),
885 Output: fullInstallPath,
886 OrderOnly: Paths{srcPath},
887 Default: !a.AConfig().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -0800888 Args: map[string]string{
889 "fromPath": srcPath.String(),
890 },
891 })
Colin Cross3854a602016-01-11 12:49:11 -0800892
Colin Cross12fc4972016-01-11 12:49:11 -0800893 a.installFiles = append(a.installFiles, fullInstallPath)
894 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
895 }
Colin Cross3854a602016-01-11 12:49:11 -0800896 return fullInstallPath
897}
898
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700899func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800900 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
901}
902
Colin Cross3f40fa42015-01-30 17:27:36 -0800903type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700904 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800905}
906
907func isFileInstaller(m blueprint.Module) bool {
908 _, ok := m.(fileInstaller)
909 return ok
910}
911
912func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700913 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800914 return ok
915}
Colin Crossfce53272015-04-08 11:21:40 -0700916
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700917func findStringInSlice(str string, slice []string) int {
918 for i, s := range slice {
919 if s == str {
920 return i
Colin Crossfce53272015-04-08 11:21:40 -0700921 }
922 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700923 return -1
924}
925
Colin Cross068e0fe2016-12-13 15:23:47 -0800926func SrcIsModule(s string) string {
927 if len(s) > 1 && s[0] == ':' {
928 return s[1:]
929 }
930 return ""
931}
932
933type sourceDependencyTag struct {
934 blueprint.BaseDependencyTag
935}
936
937var SourceDepTag sourceDependencyTag
938
939// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
940// modules listed in srcFiles using ":module" syntax
941func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
942 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -0700943 set := make(map[string]bool)
944
Colin Cross068e0fe2016-12-13 15:23:47 -0800945 for _, s := range srcFiles {
946 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -0700947 if _, found := set[m]; found {
948 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
949 } else {
950 set[m] = true
951 deps = append(deps, m)
952 }
Colin Cross068e0fe2016-12-13 15:23:47 -0800953 }
954 }
955
956 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
957}
958
959type SourceFileProducer interface {
960 Srcs() Paths
961}
962
963// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800964// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700965func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800966 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
967}
968
969func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700970 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800971
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700972 for i, e := range excludes {
973 j := findStringInSlice(e, srcFiles)
974 if j != -1 {
975 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
976 }
977
978 excludes[i] = filepath.Join(prefix, e)
979 }
980
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800981 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700982 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800983 if m := SrcIsModule(s); m != "" {
984 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -0700985 if module == nil {
986 // Error will have been handled by ExtractSourcesDeps
987 continue
988 }
Colin Cross068e0fe2016-12-13 15:23:47 -0800989 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800990 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800991 } else {
992 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
993 }
994 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800995 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
Colin Cross05a39cb2017-10-09 13:35:19 -0700996 for i, s := range globbedSrcFiles {
997 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800998 }
Colin Cross05a39cb2017-10-09 13:35:19 -0700999 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001000 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001001 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1002 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -07001003 }
1004 }
1005
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001006 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001007}
1008
Nan Zhang6d34b302017-02-04 17:47:46 -08001009func (ctx *androidModuleContext) RequiredModuleNames() []string {
1010 return ctx.module.base().commonProperties.Required
1011}
1012
Colin Cross7f19f372016-11-01 11:10:25 -07001013func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1014 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001015 if err != nil {
1016 ctx.ModuleErrorf("glob: %s", err.Error())
1017 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001018 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -07001019}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001020
Colin Cross463a90e2015-06-17 14:20:06 -07001021func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001022 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001023}
1024
Colin Cross1f8c52b2015-06-16 16:38:17 -07001025func BuildTargetSingleton() blueprint.Singleton {
1026 return &buildTargetSingleton{}
1027}
1028
Colin Cross87d8b562017-04-25 10:01:55 -07001029func parentDir(dir string) string {
1030 dir, _ = filepath.Split(dir)
1031 return filepath.Clean(dir)
1032}
1033
Colin Cross1f8c52b2015-06-16 16:38:17 -07001034type buildTargetSingleton struct{}
1035
1036func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
1037 checkbuildDeps := []string{}
1038
Colin Cross87d8b562017-04-25 10:01:55 -07001039 mmTarget := func(dir string) string {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001040 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -07001041 }
1042
1043 modulesInDir := make(map[string][]string)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001044
1045 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -07001046 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001047 blueprintDir := a.base().blueprintDir
1048 installTarget := a.base().installTarget
1049 checkbuildTarget := a.base().checkbuildTarget
1050
1051 if checkbuildTarget != "" {
1052 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
Colin Cross87d8b562017-04-25 10:01:55 -07001053 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001054 }
1055
1056 if installTarget != "" {
Colin Cross87d8b562017-04-25 10:01:55 -07001057 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001058 }
1059 }
1060 })
1061
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001062 suffix := ""
1063 if ctx.Config().(Config).EmbeddedInMake() {
1064 suffix = "-soong"
1065 }
1066
Colin Cross1f8c52b2015-06-16 16:38:17 -07001067 // Create a top-level checkbuild target that depends on all modules
1068 ctx.Build(pctx, blueprint.BuildParams{
1069 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001070 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -07001071 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -07001072 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001073 })
1074
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001075 // Make will generate the MODULES-IN-* targets
1076 if ctx.Config().(Config).EmbeddedInMake() {
1077 return
1078 }
1079
Colin Cross87d8b562017-04-25 10:01:55 -07001080 // Ensure ancestor directories are in modulesInDir
1081 dirs := sortedKeys(modulesInDir)
1082 for _, dir := range dirs {
1083 dir := parentDir(dir)
1084 for dir != "." && dir != "/" {
1085 if _, exists := modulesInDir[dir]; exists {
1086 break
1087 }
1088 modulesInDir[dir] = nil
1089 dir = parentDir(dir)
1090 }
1091 }
1092
1093 // Make directories build their direct subdirectories
1094 dirs = sortedKeys(modulesInDir)
1095 for _, dir := range dirs {
1096 p := parentDir(dir)
1097 if p != "." && p != "/" {
1098 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1099 }
1100 }
1101
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001102 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1103 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1104 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001105 for _, dir := range dirs {
1106 ctx.Build(pctx, blueprint.BuildParams{
1107 Rule: blueprint.Phony,
Colin Cross87d8b562017-04-25 10:01:55 -07001108 Outputs: []string{mmTarget(dir)},
1109 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001110 // HACK: checkbuild should be an optional build, but force it
1111 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -08001112 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001113 })
1114 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001115
1116 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1117 osDeps := map[OsType]Paths{}
1118 ctx.VisitAllModules(func(module blueprint.Module) {
1119 if a, ok := module.(Module); ok {
1120 if a.Enabled() {
1121 os := a.Target().Os
1122 osDeps[os] = append(osDeps[os], a.base().checkbuildFiles...)
1123 }
1124 }
1125 })
1126
1127 osClass := make(map[string][]string)
1128 for os, deps := range osDeps {
1129 var className string
1130
1131 switch os.Class {
1132 case Host:
1133 className = "host"
1134 case HostCross:
1135 className = "host-cross"
1136 case Device:
1137 className = "target"
1138 default:
1139 continue
1140 }
1141
1142 name := className + "-" + os.Name
1143 osClass[className] = append(osClass[className], name)
1144
1145 ctx.Build(pctx, blueprint.BuildParams{
1146 Rule: blueprint.Phony,
1147 Outputs: []string{name},
1148 Implicits: deps.Strings(),
1149 Optional: true,
1150 })
1151 }
1152
1153 // Wrap those into host|host-cross|target phony rules
1154 osClasses := sortedKeys(osClass)
1155 for _, class := range osClasses {
1156 ctx.Build(pctx, blueprint.BuildParams{
1157 Rule: blueprint.Phony,
1158 Outputs: []string{class},
1159 Implicits: osClass[class],
1160 Optional: true,
1161 })
1162 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001163}
Colin Crossd779da42015-12-17 18:00:23 -08001164
1165type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001166 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001167 ctx interface {
1168 ModuleName(blueprint.Module) string
1169 ModuleSubDir(blueprint.Module) string
1170 }
1171}
1172
1173func (s AndroidModulesByName) Len() int { return len(s.slice) }
1174func (s AndroidModulesByName) Less(i, j int) bool {
1175 mi, mj := s.slice[i], s.slice[j]
1176 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1177
1178 if ni != nj {
1179 return ni < nj
1180 } else {
1181 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1182 }
1183}
1184func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }