blob: 9afc8a7c37512d3bfaee195958367a98498c63b7 [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
Dan Willemsen34cc69e2015-09-23 15:26:20 -070035type ModuleBuildParams 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 Crossf6566ed2015-03-24 11:13:38 -070053type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070054 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070055 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070056 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070057 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070058 Host() bool
59 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070060 Darwin() bool
Colin Cross3edeee12017-04-04 12:59:48 -070061 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070062 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070063 PrimaryArch() bool
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070064 InstallOnVendorPartition() bool
Colin Cross1332b002015-04-07 17:11:30 -070065 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070066 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070067}
68
Colin Cross635c3b02016-05-18 15:37:25 -070069type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070070 blueprint.BaseModuleContext
71 androidBaseContext
72}
73
Colin Cross635c3b02016-05-18 15:37:25 -070074type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080075 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070076 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080077
Dan Willemsen34cc69e2015-09-23 15:26:20 -070078 // Similar to Build, but takes Paths instead of []string,
79 // and performs more verification.
80 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070081
Dan Willemsen34cc69e2015-09-23 15:26:20 -070082 ExpandSources(srcFiles, excludes []string) Paths
Colin Crossfaeb7aa2017-02-01 14:12:44 -080083 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070084 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070085
Colin Cross5c517922017-08-31 12:29:17 -070086 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
87 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080088 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070089 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080090
91 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070092
Colin Cross8d8f8e22016-08-03 11:57:50 -070093 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070094 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -080095
96 RequiredModuleNames() []string
Colin Cross3f40fa42015-01-30 17:27:36 -080097}
98
Colin Cross635c3b02016-05-18 15:37:25 -070099type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800100 blueprint.Module
101
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700102 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
103 // but GenerateAndroidBuildActions also has access to Android-specific information.
104 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700105 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700106
Colin Cross1e676be2016-10-12 14:38:15 -0700107 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800108
Colin Cross635c3b02016-05-18 15:37:25 -0700109 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800110 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700111 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800112 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700113 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800114 SkipInstall()
Colin Cross36242852017-06-23 15:06:31 -0700115
116 AddProperties(props ...interface{})
117 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700118
119 BuildParamsForTests() []ModuleBuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800120}
121
Colin Crossfc754582016-05-17 16:34:16 -0700122type nameProperties struct {
123 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700124 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700125}
126
127type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700128 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800129
Dan Willemsen0effe062015-11-30 16:06:01 -0800130 // emit build rules for this module
131 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800132
Colin Cross7d5136f2015-05-11 13:39:40 -0700133 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800134 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
135 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
136 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700137 Compile_multilib string `android:"arch_variant"`
138
139 Target struct {
140 Host struct {
141 Compile_multilib string
142 }
143 Android struct {
144 Compile_multilib string
145 }
146 }
147
148 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800149
Dan Willemsen782a2d12015-12-21 14:55:28 -0800150 // whether this is a proprietary vendor module, and should be installed into /vendor
151 Proprietary bool
152
Colin Cross55708f32017-03-20 13:23:34 -0700153 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700154 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700155
Dan Willemsenaa118f92017-04-06 12:49:58 -0700156 // whether this module is device specific and should be installed into /vendor
157 Vendor bool
158
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700159 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
160 // file
161 Logtags []string
162
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700163 // init.rc files to be installed if this module is installed
164 Init_rc []string
165
Chris Wolfe998306e2016-08-15 14:47:23 -0400166 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700167 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400168
Colin Cross5aac3622017-08-31 15:07:09 -0700169 // relative path to a file to include in the list of notices for the device
170 Notice *string
171
Colin Crossa1ad8d12016-06-01 17:09:44 -0700172 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700173 CompileTarget Target `blueprint:"mutated"`
174 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800175
176 // Set by InitAndroidModule
177 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700178 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700179
180 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800181}
182
183type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700184 Host_supported *bool
185 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800186}
187
Colin Crossc472d572015-03-17 15:06:21 -0700188type Multilib string
189
190const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700191 MultilibBoth Multilib = "both"
192 MultilibFirst Multilib = "first"
193 MultilibCommon Multilib = "common"
194 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700195)
196
Colin Crossa1ad8d12016-06-01 17:09:44 -0700197type HostOrDeviceSupported int
198
199const (
200 _ HostOrDeviceSupported = iota
201 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700202 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700203 DeviceSupported
204 HostAndDeviceSupported
205 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700206 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700207)
208
Colin Cross36242852017-06-23 15:06:31 -0700209func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800210 base := m.base()
211 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700212
Colin Cross36242852017-06-23 15:06:31 -0700213 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700214 &base.nameProperties,
215 &base.commonProperties,
216 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700217}
218
Colin Cross36242852017-06-23 15:06:31 -0700219func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
220 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700221
222 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800223 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700224 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700225 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800226
Dan Willemsen218f6562015-07-08 18:13:11 -0700227 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700228 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700229 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800230 }
231
Colin Cross36242852017-06-23 15:06:31 -0700232 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800233}
234
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800235// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800236// modules. It should be included as an anonymous field in every module
237// struct definition. InitAndroidModule should then be called from the module's
238// factory function, and the return values from InitAndroidModule should be
239// returned from the factory function.
240//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800241// The ModuleBase type is responsible for implementing the GenerateBuildActions
242// method to support the blueprint.Module interface. This method will then call
243// the module's GenerateAndroidBuildActions method once for each build variant
244// that is to be built. GenerateAndroidBuildActions is passed a
245// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800246// AndroidModuleContext exposes extra functionality specific to the Android build
247// system including details about the particular build variant that is to be
248// generated.
249//
250// For example:
251//
252// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800253// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800254// )
255//
256// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800257// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800258// properties struct {
259// MyProperty string
260// }
261// }
262//
Colin Cross36242852017-06-23 15:06:31 -0700263// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800264// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700265// m.AddProperties(&m.properties)
266// android.InitAndroidModule(m)
267// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800268// }
269//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800270// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800271// // Get the CPU architecture for the current build variant.
272// variantArch := ctx.Arch()
273//
274// // ...
275// }
Colin Cross635c3b02016-05-18 15:37:25 -0700276type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800277 // Putting the curiously recurring thing pointing to the thing that contains
278 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700279 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700280 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800281
Colin Crossfc754582016-05-17 16:34:16 -0700282 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800283 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700284 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800285 hostAndDeviceProperties hostAndDeviceProperties
286 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700287 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700288 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800289
290 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700291 installFiles Paths
292 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700293
294 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
295 // Only set on the final variant of each module
296 installTarget string
297 checkbuildTarget string
298 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700299
Colin Cross178a5092016-09-13 13:42:32 -0700300 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700301
302 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700303
304 // For tests
305 buildParams []ModuleBuildParams
Colin Cross36242852017-06-23 15:06:31 -0700306}
307
308func (a *ModuleBase) AddProperties(props ...interface{}) {
309 a.registerProps = append(a.registerProps, props...)
310}
311
312func (a *ModuleBase) GetProperties() []interface{} {
313 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800314}
315
Colin Crosscec81712017-07-13 14:43:27 -0700316func (a *ModuleBase) BuildParamsForTests() []ModuleBuildParams {
317 return a.buildParams
318}
319
Colin Crossce75d2c2016-10-06 16:12:58 -0700320// Name returns the name of the module. It may be overridden by individual module types, for
321// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700322func (a *ModuleBase) Name() string {
323 return a.nameProperties.Name
324}
325
Colin Crossce75d2c2016-10-06 16:12:58 -0700326// BaseModuleName returns the name of the module as specified in the blueprints file.
327func (a *ModuleBase) BaseModuleName() string {
328 return a.nameProperties.Name
329}
330
Colin Cross635c3b02016-05-18 15:37:25 -0700331func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800332 return a
333}
334
Colin Cross8b74d172016-09-13 09:59:14 -0700335func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700336 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700337 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700338}
339
Colin Crossa1ad8d12016-06-01 17:09:44 -0700340func (a *ModuleBase) Target() Target {
341 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800342}
343
Colin Cross8b74d172016-09-13 09:59:14 -0700344func (a *ModuleBase) TargetPrimary() bool {
345 return a.commonProperties.CompilePrimary
346}
347
Colin Crossa1ad8d12016-06-01 17:09:44 -0700348func (a *ModuleBase) Os() OsType {
349 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800350}
351
Colin Cross635c3b02016-05-18 15:37:25 -0700352func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700353 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800354}
355
Colin Cross635c3b02016-05-18 15:37:25 -0700356func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700357 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800358}
359
Dan Willemsen0b24c742016-10-04 15:13:37 -0700360func (a *ModuleBase) ArchSpecific() bool {
361 return a.commonProperties.ArchSpecific
362}
363
Colin Crossa1ad8d12016-06-01 17:09:44 -0700364func (a *ModuleBase) OsClassSupported() []OsClass {
365 switch a.commonProperties.HostOrDeviceSupported {
366 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700367 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700368 case HostSupportedNoCross:
369 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700370 case DeviceSupported:
371 return []OsClass{Device}
372 case HostAndDeviceSupported:
373 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700374 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700375 supported = append(supported, Host, HostCross)
376 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700377 if a.hostAndDeviceProperties.Device_supported == nil ||
378 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700379 supported = append(supported, Device)
380 }
381 return supported
382 default:
383 return nil
384 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800385}
386
Colin Cross635c3b02016-05-18 15:37:25 -0700387func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800388 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
389 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700390 (a.hostAndDeviceProperties.Device_supported == nil ||
391 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800392}
393
Colin Cross635c3b02016-05-18 15:37:25 -0700394func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800395 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800396 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800397 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800398 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800399}
400
Colin Crossce75d2c2016-10-06 16:12:58 -0700401func (a *ModuleBase) SkipInstall() {
402 a.commonProperties.SkipInstall = true
403}
404
Colin Cross635c3b02016-05-18 15:37:25 -0700405func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700406 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800407
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700408 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800409 ctx.VisitDepsDepthFirstIf(isFileInstaller,
410 func(m blueprint.Module) {
411 fileInstaller := m.(fileInstaller)
412 files := fileInstaller.filesToInstall()
413 result = append(result, files...)
414 })
415
416 return result
417}
418
Colin Cross635c3b02016-05-18 15:37:25 -0700419func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800420 return a.installFiles
421}
422
Colin Cross635c3b02016-05-18 15:37:25 -0700423func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800424 return p.noAddressSanitizer
425}
426
Colin Cross635c3b02016-05-18 15:37:25 -0700427func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800428 return false
429}
430
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700431func (p *ModuleBase) InstallInSanitizerDir() bool {
432 return false
433}
434
Colin Cross635c3b02016-05-18 15:37:25 -0700435func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700436 allInstalledFiles := Paths{}
437 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700439 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700440 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
441 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800442 })
443
Colin Cross9454bfa2015-03-17 13:24:18 -0700444 deps := []string{}
445
Colin Cross3f40fa42015-01-30 17:27:36 -0800446 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700447 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800448 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700449 Rule: blueprint.Phony,
450 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700451 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800452 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700453 })
454 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700455 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700456 }
457
458 if len(allCheckbuildFiles) > 0 {
459 name := ctx.ModuleName() + "-checkbuild"
460 ctx.Build(pctx, blueprint.BuildParams{
461 Rule: blueprint.Phony,
462 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700463 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700464 Optional: true,
465 })
466 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700467 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700468 }
469
470 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800471 suffix := ""
472 if ctx.Config().(Config).EmbeddedInMake() {
473 suffix = "-soong"
474 }
475
Colin Cross9454bfa2015-03-17 13:24:18 -0700476 ctx.Build(pctx, blueprint.BuildParams{
477 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800478 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700479 Implicits: deps,
480 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800481 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700482
483 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800484 }
485}
486
Colin Cross635c3b02016-05-18 15:37:25 -0700487func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700488 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700489 target: a.commonProperties.CompileTarget,
490 targetPrimary: a.commonProperties.CompilePrimary,
Dan Willemsenaa118f92017-04-06 12:49:58 -0700491 vendor: a.commonProperties.Proprietary || a.commonProperties.Vendor,
Colin Cross8b74d172016-09-13 09:59:14 -0700492 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800493 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800494}
495
Colin Cross635c3b02016-05-18 15:37:25 -0700496func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800497 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700498 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700499 ModuleContext: ctx,
500 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
501 installDeps: a.computeInstallDeps(ctx),
502 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800503 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800504 }
505
Colin Cross67a5c132017-05-09 13:45:28 -0700506 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
507 var suffix []string
508 if androidCtx.Os().Class != Device && androidCtx.Os().Class != Generic {
509 suffix = append(suffix, androidCtx.Os().String())
510 }
511 if !androidCtx.PrimaryArch() {
512 suffix = append(suffix, androidCtx.Arch().ArchType.String())
513 }
514
515 ctx.Variable(pctx, "moduleDesc", desc)
516
517 s := ""
518 if len(suffix) > 0 {
519 s = " [" + strings.Join(suffix, " ") + "]"
520 }
521 ctx.Variable(pctx, "moduleDescSuffix", s)
522
Colin Cross9b1d13d2016-09-19 15:18:11 -0700523 if a.Enabled() {
524 a.module.GenerateAndroidBuildActions(androidCtx)
525 if ctx.Failed() {
526 return
527 }
528
529 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
530 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800531 }
532
Colin Cross9b1d13d2016-09-19 15:18:11 -0700533 if a == ctx.FinalModule().(Module).base() {
534 a.generateModuleTarget(ctx)
535 if ctx.Failed() {
536 return
537 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800538 }
Colin Crosscec81712017-07-13 14:43:27 -0700539
540 a.buildParams = androidCtx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800541}
542
Colin Crossf6566ed2015-03-24 11:13:38 -0700543type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700544 target Target
545 targetPrimary bool
546 debug bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700547 vendor bool
Colin Cross8b74d172016-09-13 09:59:14 -0700548 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700549}
550
Colin Cross3f40fa42015-01-30 17:27:36 -0800551type androidModuleContext struct {
552 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700553 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700554 installDeps Paths
555 installFiles Paths
556 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800557 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700558 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700559
560 // For tests
561 buildParams []ModuleBuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800562}
563
Colin Cross67a5c132017-05-09 13:45:28 -0700564func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross6ff51382015-12-17 16:39:19 -0800565 a.ModuleContext.Build(pctx, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700566 Rule: ErrorRule,
567 Description: desc,
568 Outputs: outputs,
569 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800570 Args: map[string]string{
571 "error": err.Error(),
572 },
573 })
574 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800575}
576
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800577func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700578 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700579 a.ninjaError(params.Description, params.Outputs,
580 fmt.Errorf("module %s missing dependencies: %s\n",
581 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800582 return
583 }
584
Colin Cross3f40fa42015-01-30 17:27:36 -0800585 params.Optional = true
586 a.ModuleContext.Build(pctx, params)
587}
588
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700589func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
Colin Crosscec81712017-07-13 14:43:27 -0700590 if a.config.captureBuild {
591 a.buildParams = append(a.buildParams, params)
592 }
593
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700594 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700595 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800596 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700597 Outputs: params.Outputs.Strings(),
598 ImplicitOutputs: params.ImplicitOutputs.Strings(),
599 Inputs: params.Inputs.Strings(),
600 Implicits: params.Implicits.Strings(),
601 OrderOnly: params.OrderOnly.Strings(),
602 Args: params.Args,
603 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700604 }
605
Colin Cross67a5c132017-05-09 13:45:28 -0700606 if params.Description != "" {
607 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
608 }
609
Colin Cross33bfb0a2016-11-21 17:23:08 -0800610 if params.Depfile != nil {
611 bparams.Depfile = params.Depfile.String()
612 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700613 if params.Output != nil {
614 bparams.Outputs = append(bparams.Outputs, params.Output.String())
615 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700616 if params.ImplicitOutput != nil {
617 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
618 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700619 if params.Input != nil {
620 bparams.Inputs = append(bparams.Inputs, params.Input.String())
621 }
622 if params.Implicit != nil {
623 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
624 }
625
Colin Cross6ff51382015-12-17 16:39:19 -0800626 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700627 a.ninjaError(bparams.Description, bparams.Outputs,
628 fmt.Errorf("module %s missing dependencies: %s\n",
629 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800630 return
631 }
632
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700633 a.ModuleContext.Build(pctx, bparams)
634}
635
Colin Cross6ff51382015-12-17 16:39:19 -0800636func (a *androidModuleContext) GetMissingDependencies() []string {
637 return a.missingDeps
638}
639
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800640func (a *androidModuleContext) AddMissingDependencies(deps []string) {
641 if deps != nil {
642 a.missingDeps = append(a.missingDeps, deps...)
643 }
644}
645
Colin Crossa1ad8d12016-06-01 17:09:44 -0700646func (a *androidBaseContextImpl) Target() Target {
647 return a.target
648}
649
Colin Cross8b74d172016-09-13 09:59:14 -0700650func (a *androidBaseContextImpl) TargetPrimary() bool {
651 return a.targetPrimary
652}
653
Colin Crossf6566ed2015-03-24 11:13:38 -0700654func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700655 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800656}
657
Colin Crossa1ad8d12016-06-01 17:09:44 -0700658func (a *androidBaseContextImpl) Os() OsType {
659 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800660}
661
Colin Crossf6566ed2015-03-24 11:13:38 -0700662func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700663 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700664}
665
666func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700667 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700668}
669
Colin Cross0af4b842015-04-30 16:36:18 -0700670func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700671 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700672}
673
Colin Cross3edeee12017-04-04 12:59:48 -0700674func (a *androidBaseContextImpl) Windows() bool {
675 return a.target.Os == Windows
676}
677
Colin Crossf6566ed2015-03-24 11:13:38 -0700678func (a *androidBaseContextImpl) Debug() bool {
679 return a.debug
680}
681
Colin Cross1e7d3702016-08-24 15:25:47 -0700682func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700683 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
684 return true
685 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700686 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
687}
688
Colin Cross1332b002015-04-07 17:11:30 -0700689func (a *androidBaseContextImpl) AConfig() Config {
690 return a.config
691}
692
Colin Cross9272ade2016-08-17 15:24:12 -0700693func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
694 return DeviceConfig{a.config.deviceConfig}
695}
696
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700697func (a *androidBaseContextImpl) InstallOnVendorPartition() bool {
Dan Willemsenaa118f92017-04-06 12:49:58 -0700698 return a.vendor
Dan Willemsen782a2d12015-12-21 14:55:28 -0800699}
700
Colin Cross8d8f8e22016-08-03 11:57:50 -0700701func (a *androidModuleContext) InstallInData() bool {
702 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800703}
704
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700705func (a *androidModuleContext) InstallInSanitizerDir() bool {
706 return a.module.InstallInSanitizerDir()
707}
708
Colin Cross893d8162017-04-26 17:34:03 -0700709func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
710 if a.module.base().commonProperties.SkipInstall {
711 return true
712 }
713
714 if a.Device() {
715 if a.AConfig().SkipDeviceInstall() {
716 return true
717 }
718
719 if a.AConfig().SkipMegaDeviceInstall(fullInstallPath.String()) {
720 return true
721 }
722 }
723
724 return false
725}
726
Colin Cross5c517922017-08-31 12:29:17 -0700727func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700728 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -0700729 return a.installFile(installPath, name, srcPath, Cp, deps)
730}
731
732func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
733 deps ...Path) OutputPath {
734 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
735}
736
737func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
738 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700739
Dan Willemsen782a2d12015-12-21 14:55:28 -0800740 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700741 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800742
Colin Cross893d8162017-04-26 17:34:03 -0700743 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700744
Dan Willemsen322acaf2016-01-12 23:07:05 -0800745 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700746
Colin Cross89562dc2016-10-03 17:47:19 -0700747 var implicitDeps, orderOnlyDeps Paths
748
749 if a.Host() {
750 // Installed host modules might be used during the build, depend directly on their
751 // dependencies so their timestamp is updated whenever their dependency is updated
752 implicitDeps = deps
753 } else {
754 orderOnlyDeps = deps
755 }
756
Dan Willemsen322acaf2016-01-12 23:07:05 -0800757 a.ModuleBuild(pctx, ModuleBuildParams{
Colin Cross5c517922017-08-31 12:29:17 -0700758 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -0700759 Description: "install " + fullInstallPath.Base(),
760 Output: fullInstallPath,
761 Input: srcPath,
762 Implicits: implicitDeps,
763 OrderOnly: orderOnlyDeps,
764 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800765 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800766
Dan Willemsen322acaf2016-01-12 23:07:05 -0800767 a.installFiles = append(a.installFiles, fullInstallPath)
768 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700769 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700770 return fullInstallPath
771}
772
Colin Cross3854a602016-01-11 12:49:11 -0800773func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
774 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700775 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800776
Colin Cross893d8162017-04-26 17:34:03 -0700777 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700778
Colin Cross12fc4972016-01-11 12:49:11 -0800779 a.ModuleBuild(pctx, ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700780 Rule: Symlink,
781 Description: "install symlink " + fullInstallPath.Base(),
782 Output: fullInstallPath,
783 OrderOnly: Paths{srcPath},
784 Default: !a.AConfig().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -0800785 Args: map[string]string{
786 "fromPath": srcPath.String(),
787 },
788 })
Colin Cross3854a602016-01-11 12:49:11 -0800789
Colin Cross12fc4972016-01-11 12:49:11 -0800790 a.installFiles = append(a.installFiles, fullInstallPath)
791 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
792 }
Colin Cross3854a602016-01-11 12:49:11 -0800793 return fullInstallPath
794}
795
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700796func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800797 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
798}
799
Colin Cross3f40fa42015-01-30 17:27:36 -0800800type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700801 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800802}
803
804func isFileInstaller(m blueprint.Module) bool {
805 _, ok := m.(fileInstaller)
806 return ok
807}
808
809func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700810 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800811 return ok
812}
Colin Crossfce53272015-04-08 11:21:40 -0700813
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700814func findStringInSlice(str string, slice []string) int {
815 for i, s := range slice {
816 if s == str {
817 return i
Colin Crossfce53272015-04-08 11:21:40 -0700818 }
819 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700820 return -1
821}
822
Colin Cross068e0fe2016-12-13 15:23:47 -0800823func SrcIsModule(s string) string {
824 if len(s) > 1 && s[0] == ':' {
825 return s[1:]
826 }
827 return ""
828}
829
830type sourceDependencyTag struct {
831 blueprint.BaseDependencyTag
832}
833
834var SourceDepTag sourceDependencyTag
835
836// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
837// modules listed in srcFiles using ":module" syntax
838func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
839 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -0700840 set := make(map[string]bool)
841
Colin Cross068e0fe2016-12-13 15:23:47 -0800842 for _, s := range srcFiles {
843 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -0700844 if _, found := set[m]; found {
845 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
846 } else {
847 set[m] = true
848 deps = append(deps, m)
849 }
Colin Cross068e0fe2016-12-13 15:23:47 -0800850 }
851 }
852
853 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
854}
855
856type SourceFileProducer interface {
857 Srcs() Paths
858}
859
860// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800861// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700862func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800863 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
864}
865
866func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700867 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800868
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700869 for i, e := range excludes {
870 j := findStringInSlice(e, srcFiles)
871 if j != -1 {
872 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
873 }
874
875 excludes[i] = filepath.Join(prefix, e)
876 }
877
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800878 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700879 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800880 if m := SrcIsModule(s); m != "" {
881 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
882 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800883 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800884 } else {
885 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
886 }
887 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800888 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
Colin Cross05a39cb2017-10-09 13:35:19 -0700889 for i, s := range globbedSrcFiles {
890 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800891 }
Colin Cross05a39cb2017-10-09 13:35:19 -0700892 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -0700893 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800894 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
895 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700896 }
897 }
898
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800899 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700900}
901
Nan Zhang6d34b302017-02-04 17:47:46 -0800902func (ctx *androidModuleContext) RequiredModuleNames() []string {
903 return ctx.module.base().commonProperties.Required
904}
905
Colin Cross7f19f372016-11-01 11:10:25 -0700906func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
907 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700908 if err != nil {
909 ctx.ModuleErrorf("glob: %s", err.Error())
910 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700911 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700912}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700913
Colin Cross463a90e2015-06-17 14:20:06 -0700914func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700915 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700916}
917
Colin Cross1f8c52b2015-06-16 16:38:17 -0700918func BuildTargetSingleton() blueprint.Singleton {
919 return &buildTargetSingleton{}
920}
921
Colin Cross87d8b562017-04-25 10:01:55 -0700922func parentDir(dir string) string {
923 dir, _ = filepath.Split(dir)
924 return filepath.Clean(dir)
925}
926
Colin Cross1f8c52b2015-06-16 16:38:17 -0700927type buildTargetSingleton struct{}
928
929func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
930 checkbuildDeps := []string{}
931
Colin Cross87d8b562017-04-25 10:01:55 -0700932 mmTarget := func(dir string) string {
Dan Willemsend2e95fb2017-09-20 14:30:50 -0700933 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -0700934 }
935
936 modulesInDir := make(map[string][]string)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700937
938 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700939 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700940 blueprintDir := a.base().blueprintDir
941 installTarget := a.base().installTarget
942 checkbuildTarget := a.base().checkbuildTarget
943
944 if checkbuildTarget != "" {
945 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
Colin Cross87d8b562017-04-25 10:01:55 -0700946 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700947 }
948
949 if installTarget != "" {
Colin Cross87d8b562017-04-25 10:01:55 -0700950 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700951 }
952 }
953 })
954
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800955 suffix := ""
956 if ctx.Config().(Config).EmbeddedInMake() {
957 suffix = "-soong"
958 }
959
Colin Cross1f8c52b2015-06-16 16:38:17 -0700960 // Create a top-level checkbuild target that depends on all modules
961 ctx.Build(pctx, blueprint.BuildParams{
962 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800963 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700964 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700965 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700966 })
967
Dan Willemsend2e95fb2017-09-20 14:30:50 -0700968 // Make will generate the MODULES-IN-* targets
969 if ctx.Config().(Config).EmbeddedInMake() {
970 return
971 }
972
Colin Cross87d8b562017-04-25 10:01:55 -0700973 // Ensure ancestor directories are in modulesInDir
974 dirs := sortedKeys(modulesInDir)
975 for _, dir := range dirs {
976 dir := parentDir(dir)
977 for dir != "." && dir != "/" {
978 if _, exists := modulesInDir[dir]; exists {
979 break
980 }
981 modulesInDir[dir] = nil
982 dir = parentDir(dir)
983 }
984 }
985
986 // Make directories build their direct subdirectories
987 dirs = sortedKeys(modulesInDir)
988 for _, dir := range dirs {
989 p := parentDir(dir)
990 if p != "." && p != "/" {
991 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
992 }
993 }
994
Dan Willemsend2e95fb2017-09-20 14:30:50 -0700995 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
996 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
997 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -0700998 for _, dir := range dirs {
999 ctx.Build(pctx, blueprint.BuildParams{
1000 Rule: blueprint.Phony,
Colin Cross87d8b562017-04-25 10:01:55 -07001001 Outputs: []string{mmTarget(dir)},
1002 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001003 // HACK: checkbuild should be an optional build, but force it
1004 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -08001005 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001006 })
1007 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001008
1009 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1010 osDeps := map[OsType]Paths{}
1011 ctx.VisitAllModules(func(module blueprint.Module) {
1012 if a, ok := module.(Module); ok {
1013 if a.Enabled() {
1014 os := a.Target().Os
1015 osDeps[os] = append(osDeps[os], a.base().checkbuildFiles...)
1016 }
1017 }
1018 })
1019
1020 osClass := make(map[string][]string)
1021 for os, deps := range osDeps {
1022 var className string
1023
1024 switch os.Class {
1025 case Host:
1026 className = "host"
1027 case HostCross:
1028 className = "host-cross"
1029 case Device:
1030 className = "target"
1031 default:
1032 continue
1033 }
1034
1035 name := className + "-" + os.Name
1036 osClass[className] = append(osClass[className], name)
1037
1038 ctx.Build(pctx, blueprint.BuildParams{
1039 Rule: blueprint.Phony,
1040 Outputs: []string{name},
1041 Implicits: deps.Strings(),
1042 Optional: true,
1043 })
1044 }
1045
1046 // Wrap those into host|host-cross|target phony rules
1047 osClasses := sortedKeys(osClass)
1048 for _, class := range osClasses {
1049 ctx.Build(pctx, blueprint.BuildParams{
1050 Rule: blueprint.Phony,
1051 Outputs: []string{class},
1052 Implicits: osClass[class],
1053 Optional: true,
1054 })
1055 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001056}
Colin Crossd779da42015-12-17 18:00:23 -08001057
1058type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001059 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001060 ctx interface {
1061 ModuleName(blueprint.Module) string
1062 ModuleSubDir(blueprint.Module) string
1063 }
1064}
1065
1066func (s AndroidModulesByName) Len() int { return len(s.slice) }
1067func (s AndroidModulesByName) Less(i, j int) bool {
1068 mi, mj := s.slice[i], s.slice[j]
1069 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1070
1071 if ni != nj {
1072 return ni < nj
1073 } else {
1074 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1075 }
1076}
1077func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }