blob: fb2e70305368066fbd28e204ec6da5fdba384c2a [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
Dan Willemsenaa118f92017-04-06 12:49:58 -070064 Vendor() 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
Colin Cross635c3b02016-05-18 15:37:25 -0700102 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -0700103 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800104
Colin Cross635c3b02016-05-18 15:37:25 -0700105 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800106 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700107 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800108 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700109 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800110 SkipInstall()
Colin Cross36242852017-06-23 15:06:31 -0700111
112 AddProperties(props ...interface{})
113 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700114
115 BuildParamsForTests() []ModuleBuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800116}
117
Colin Crossfc754582016-05-17 16:34:16 -0700118type nameProperties struct {
119 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700120 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700121}
122
123type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700124 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800125
Dan Willemsen0effe062015-11-30 16:06:01 -0800126 // emit build rules for this module
127 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800128
Colin Cross7d5136f2015-05-11 13:39:40 -0700129 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800130 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
131 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
132 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700133 Compile_multilib string `android:"arch_variant"`
134
135 Target struct {
136 Host struct {
137 Compile_multilib string
138 }
139 Android struct {
140 Compile_multilib string
141 }
142 }
143
144 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800145
Dan Willemsen782a2d12015-12-21 14:55:28 -0800146 // whether this is a proprietary vendor module, and should be installed into /vendor
147 Proprietary bool
148
Colin Cross55708f32017-03-20 13:23:34 -0700149 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700150 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700151
Dan Willemsenaa118f92017-04-06 12:49:58 -0700152 // whether this module is device specific and should be installed into /vendor
153 Vendor bool
154
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700155 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
156 // file
157 Logtags []string
158
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700159 // init.rc files to be installed if this module is installed
160 Init_rc []string
161
Chris Wolfe998306e2016-08-15 14:47:23 -0400162 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700163 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400164
Colin Crossa1ad8d12016-06-01 17:09:44 -0700165 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700166 CompileTarget Target `blueprint:"mutated"`
167 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800168
169 // Set by InitAndroidModule
170 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700171 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700172
173 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800174}
175
176type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700177 Host_supported *bool
178 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800179}
180
Colin Crossc472d572015-03-17 15:06:21 -0700181type Multilib string
182
183const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700184 MultilibBoth Multilib = "both"
185 MultilibFirst Multilib = "first"
186 MultilibCommon Multilib = "common"
187 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700188)
189
Colin Crossa1ad8d12016-06-01 17:09:44 -0700190type HostOrDeviceSupported int
191
192const (
193 _ HostOrDeviceSupported = iota
194 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700195 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700196 DeviceSupported
197 HostAndDeviceSupported
198 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700199 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700200)
201
Colin Cross36242852017-06-23 15:06:31 -0700202func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800203 base := m.base()
204 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700205
Colin Cross36242852017-06-23 15:06:31 -0700206 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700207 &base.nameProperties,
208 &base.commonProperties,
209 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700210}
211
Colin Cross36242852017-06-23 15:06:31 -0700212func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
213 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700214
215 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800216 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700217 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700218 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800219
Dan Willemsen218f6562015-07-08 18:13:11 -0700220 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700221 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700222 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800223 }
224
Colin Cross36242852017-06-23 15:06:31 -0700225 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800226}
227
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800228// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800229// modules. It should be included as an anonymous field in every module
230// struct definition. InitAndroidModule should then be called from the module's
231// factory function, and the return values from InitAndroidModule should be
232// returned from the factory function.
233//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800234// The ModuleBase type is responsible for implementing the GenerateBuildActions
235// method to support the blueprint.Module interface. This method will then call
236// the module's GenerateAndroidBuildActions method once for each build variant
237// that is to be built. GenerateAndroidBuildActions is passed a
238// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800239// AndroidModuleContext exposes extra functionality specific to the Android build
240// system including details about the particular build variant that is to be
241// generated.
242//
243// For example:
244//
245// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800246// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800247// )
248//
249// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800250// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800251// properties struct {
252// MyProperty string
253// }
254// }
255//
Colin Cross36242852017-06-23 15:06:31 -0700256// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800257// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700258// m.AddProperties(&m.properties)
259// android.InitAndroidModule(m)
260// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800261// }
262//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800263// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800264// // Get the CPU architecture for the current build variant.
265// variantArch := ctx.Arch()
266//
267// // ...
268// }
Colin Cross635c3b02016-05-18 15:37:25 -0700269type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800270 // Putting the curiously recurring thing pointing to the thing that contains
271 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700272 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700273 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800274
Colin Crossfc754582016-05-17 16:34:16 -0700275 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800276 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700277 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800278 hostAndDeviceProperties hostAndDeviceProperties
279 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700280 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700281 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800282
283 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700284 installFiles Paths
285 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700286
287 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
288 // Only set on the final variant of each module
289 installTarget string
290 checkbuildTarget string
291 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700292
Colin Cross178a5092016-09-13 13:42:32 -0700293 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700294
295 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700296
297 // For tests
298 buildParams []ModuleBuildParams
Colin Cross36242852017-06-23 15:06:31 -0700299}
300
301func (a *ModuleBase) AddProperties(props ...interface{}) {
302 a.registerProps = append(a.registerProps, props...)
303}
304
305func (a *ModuleBase) GetProperties() []interface{} {
306 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800307}
308
Colin Crosscec81712017-07-13 14:43:27 -0700309func (a *ModuleBase) BuildParamsForTests() []ModuleBuildParams {
310 return a.buildParams
311}
312
Colin Crossce75d2c2016-10-06 16:12:58 -0700313// Name returns the name of the module. It may be overridden by individual module types, for
314// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700315func (a *ModuleBase) Name() string {
316 return a.nameProperties.Name
317}
318
Colin Crossce75d2c2016-10-06 16:12:58 -0700319// BaseModuleName returns the name of the module as specified in the blueprints file.
320func (a *ModuleBase) BaseModuleName() string {
321 return a.nameProperties.Name
322}
323
Colin Cross635c3b02016-05-18 15:37:25 -0700324func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800325 return a
326}
327
Colin Cross8b74d172016-09-13 09:59:14 -0700328func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700329 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700330 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700331}
332
Colin Crossa1ad8d12016-06-01 17:09:44 -0700333func (a *ModuleBase) Target() Target {
334 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800335}
336
Colin Cross8b74d172016-09-13 09:59:14 -0700337func (a *ModuleBase) TargetPrimary() bool {
338 return a.commonProperties.CompilePrimary
339}
340
Colin Crossa1ad8d12016-06-01 17:09:44 -0700341func (a *ModuleBase) Os() OsType {
342 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800343}
344
Colin Cross635c3b02016-05-18 15:37:25 -0700345func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700346 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800347}
348
Colin Cross635c3b02016-05-18 15:37:25 -0700349func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700350 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800351}
352
Dan Willemsen0b24c742016-10-04 15:13:37 -0700353func (a *ModuleBase) ArchSpecific() bool {
354 return a.commonProperties.ArchSpecific
355}
356
Colin Crossa1ad8d12016-06-01 17:09:44 -0700357func (a *ModuleBase) OsClassSupported() []OsClass {
358 switch a.commonProperties.HostOrDeviceSupported {
359 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700360 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700361 case HostSupportedNoCross:
362 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700363 case DeviceSupported:
364 return []OsClass{Device}
365 case HostAndDeviceSupported:
366 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700367 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700368 supported = append(supported, Host, HostCross)
369 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700370 if a.hostAndDeviceProperties.Device_supported == nil ||
371 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700372 supported = append(supported, Device)
373 }
374 return supported
375 default:
376 return nil
377 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800378}
379
Colin Cross635c3b02016-05-18 15:37:25 -0700380func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800381 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
382 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700383 (a.hostAndDeviceProperties.Device_supported == nil ||
384 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800385}
386
Colin Cross635c3b02016-05-18 15:37:25 -0700387func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800388 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800389 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800390 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800391 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800392}
393
Colin Crossce75d2c2016-10-06 16:12:58 -0700394func (a *ModuleBase) SkipInstall() {
395 a.commonProperties.SkipInstall = true
396}
397
Colin Cross635c3b02016-05-18 15:37:25 -0700398func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700399 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800400
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700401 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800402 ctx.VisitDepsDepthFirstIf(isFileInstaller,
403 func(m blueprint.Module) {
404 fileInstaller := m.(fileInstaller)
405 files := fileInstaller.filesToInstall()
406 result = append(result, files...)
407 })
408
409 return result
410}
411
Colin Cross635c3b02016-05-18 15:37:25 -0700412func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800413 return a.installFiles
414}
415
Colin Cross635c3b02016-05-18 15:37:25 -0700416func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800417 return p.noAddressSanitizer
418}
419
Colin Cross635c3b02016-05-18 15:37:25 -0700420func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800421 return false
422}
423
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700424func (p *ModuleBase) InstallInSanitizerDir() bool {
425 return false
426}
427
Colin Cross635c3b02016-05-18 15:37:25 -0700428func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700429 allInstalledFiles := Paths{}
430 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800431 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700432 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700433 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
434 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800435 })
436
Colin Cross9454bfa2015-03-17 13:24:18 -0700437 deps := []string{}
438
Colin Cross3f40fa42015-01-30 17:27:36 -0800439 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700440 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800441 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700442 Rule: blueprint.Phony,
443 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700444 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800445 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700446 })
447 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700448 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700449 }
450
451 if len(allCheckbuildFiles) > 0 {
452 name := ctx.ModuleName() + "-checkbuild"
453 ctx.Build(pctx, blueprint.BuildParams{
454 Rule: blueprint.Phony,
455 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700456 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700457 Optional: true,
458 })
459 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700460 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700461 }
462
463 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800464 suffix := ""
465 if ctx.Config().(Config).EmbeddedInMake() {
466 suffix = "-soong"
467 }
468
Colin Cross9454bfa2015-03-17 13:24:18 -0700469 ctx.Build(pctx, blueprint.BuildParams{
470 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800471 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700472 Implicits: deps,
473 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800474 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700475
476 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 }
478}
479
Colin Cross635c3b02016-05-18 15:37:25 -0700480func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700481 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700482 target: a.commonProperties.CompileTarget,
483 targetPrimary: a.commonProperties.CompilePrimary,
Dan Willemsenaa118f92017-04-06 12:49:58 -0700484 vendor: a.commonProperties.Proprietary || a.commonProperties.Vendor,
Colin Cross8b74d172016-09-13 09:59:14 -0700485 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800486 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800487}
488
Colin Cross635c3b02016-05-18 15:37:25 -0700489func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800490 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700491 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700492 ModuleContext: ctx,
493 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
494 installDeps: a.computeInstallDeps(ctx),
495 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800496 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800497 }
498
Colin Cross67a5c132017-05-09 13:45:28 -0700499 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
500 var suffix []string
501 if androidCtx.Os().Class != Device && androidCtx.Os().Class != Generic {
502 suffix = append(suffix, androidCtx.Os().String())
503 }
504 if !androidCtx.PrimaryArch() {
505 suffix = append(suffix, androidCtx.Arch().ArchType.String())
506 }
507
508 ctx.Variable(pctx, "moduleDesc", desc)
509
510 s := ""
511 if len(suffix) > 0 {
512 s = " [" + strings.Join(suffix, " ") + "]"
513 }
514 ctx.Variable(pctx, "moduleDescSuffix", s)
515
Colin Cross9b1d13d2016-09-19 15:18:11 -0700516 if a.Enabled() {
517 a.module.GenerateAndroidBuildActions(androidCtx)
518 if ctx.Failed() {
519 return
520 }
521
522 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
523 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800524 }
525
Colin Cross9b1d13d2016-09-19 15:18:11 -0700526 if a == ctx.FinalModule().(Module).base() {
527 a.generateModuleTarget(ctx)
528 if ctx.Failed() {
529 return
530 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800531 }
Colin Crosscec81712017-07-13 14:43:27 -0700532
533 a.buildParams = androidCtx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800534}
535
Colin Crossf6566ed2015-03-24 11:13:38 -0700536type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700537 target Target
538 targetPrimary bool
539 debug bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700540 vendor bool
Colin Cross8b74d172016-09-13 09:59:14 -0700541 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700542}
543
Colin Cross3f40fa42015-01-30 17:27:36 -0800544type androidModuleContext struct {
545 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700546 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700547 installDeps Paths
548 installFiles Paths
549 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800550 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700551 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700552
553 // For tests
554 buildParams []ModuleBuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800555}
556
Colin Cross67a5c132017-05-09 13:45:28 -0700557func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross6ff51382015-12-17 16:39:19 -0800558 a.ModuleContext.Build(pctx, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700559 Rule: ErrorRule,
560 Description: desc,
561 Outputs: outputs,
562 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800563 Args: map[string]string{
564 "error": err.Error(),
565 },
566 })
567 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800568}
569
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800570func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700571 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700572 a.ninjaError(params.Description, params.Outputs,
573 fmt.Errorf("module %s missing dependencies: %s\n",
574 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800575 return
576 }
577
Colin Cross3f40fa42015-01-30 17:27:36 -0800578 params.Optional = true
579 a.ModuleContext.Build(pctx, params)
580}
581
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700582func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
Colin Crosscec81712017-07-13 14:43:27 -0700583 if a.config.captureBuild {
584 a.buildParams = append(a.buildParams, params)
585 }
586
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700587 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700588 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800589 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700590 Outputs: params.Outputs.Strings(),
591 ImplicitOutputs: params.ImplicitOutputs.Strings(),
592 Inputs: params.Inputs.Strings(),
593 Implicits: params.Implicits.Strings(),
594 OrderOnly: params.OrderOnly.Strings(),
595 Args: params.Args,
596 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700597 }
598
Colin Cross67a5c132017-05-09 13:45:28 -0700599 if params.Description != "" {
600 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
601 }
602
Colin Cross33bfb0a2016-11-21 17:23:08 -0800603 if params.Depfile != nil {
604 bparams.Depfile = params.Depfile.String()
605 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700606 if params.Output != nil {
607 bparams.Outputs = append(bparams.Outputs, params.Output.String())
608 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700609 if params.ImplicitOutput != nil {
610 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
611 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700612 if params.Input != nil {
613 bparams.Inputs = append(bparams.Inputs, params.Input.String())
614 }
615 if params.Implicit != nil {
616 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
617 }
618
Colin Cross6ff51382015-12-17 16:39:19 -0800619 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700620 a.ninjaError(bparams.Description, bparams.Outputs,
621 fmt.Errorf("module %s missing dependencies: %s\n",
622 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800623 return
624 }
625
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700626 a.ModuleContext.Build(pctx, bparams)
627}
628
Colin Cross6ff51382015-12-17 16:39:19 -0800629func (a *androidModuleContext) GetMissingDependencies() []string {
630 return a.missingDeps
631}
632
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800633func (a *androidModuleContext) AddMissingDependencies(deps []string) {
634 if deps != nil {
635 a.missingDeps = append(a.missingDeps, deps...)
636 }
637}
638
Colin Crossa1ad8d12016-06-01 17:09:44 -0700639func (a *androidBaseContextImpl) Target() Target {
640 return a.target
641}
642
Colin Cross8b74d172016-09-13 09:59:14 -0700643func (a *androidBaseContextImpl) TargetPrimary() bool {
644 return a.targetPrimary
645}
646
Colin Crossf6566ed2015-03-24 11:13:38 -0700647func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700648 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800649}
650
Colin Crossa1ad8d12016-06-01 17:09:44 -0700651func (a *androidBaseContextImpl) Os() OsType {
652 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800653}
654
Colin Crossf6566ed2015-03-24 11:13:38 -0700655func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700656 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700657}
658
659func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700660 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700661}
662
Colin Cross0af4b842015-04-30 16:36:18 -0700663func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700664 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700665}
666
Colin Cross3edeee12017-04-04 12:59:48 -0700667func (a *androidBaseContextImpl) Windows() bool {
668 return a.target.Os == Windows
669}
670
Colin Crossf6566ed2015-03-24 11:13:38 -0700671func (a *androidBaseContextImpl) Debug() bool {
672 return a.debug
673}
674
Colin Cross1e7d3702016-08-24 15:25:47 -0700675func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700676 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
677 return true
678 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700679 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
680}
681
Colin Cross1332b002015-04-07 17:11:30 -0700682func (a *androidBaseContextImpl) AConfig() Config {
683 return a.config
684}
685
Colin Cross9272ade2016-08-17 15:24:12 -0700686func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
687 return DeviceConfig{a.config.deviceConfig}
688}
689
Dan Willemsenaa118f92017-04-06 12:49:58 -0700690func (a *androidBaseContextImpl) Vendor() bool {
691 return a.vendor
Dan Willemsen782a2d12015-12-21 14:55:28 -0800692}
693
Colin Cross8d8f8e22016-08-03 11:57:50 -0700694func (a *androidModuleContext) InstallInData() bool {
695 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800696}
697
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700698func (a *androidModuleContext) InstallInSanitizerDir() bool {
699 return a.module.InstallInSanitizerDir()
700}
701
Colin Cross893d8162017-04-26 17:34:03 -0700702func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
703 if a.module.base().commonProperties.SkipInstall {
704 return true
705 }
706
707 if a.Device() {
708 if a.AConfig().SkipDeviceInstall() {
709 return true
710 }
711
712 if a.AConfig().SkipMegaDeviceInstall(fullInstallPath.String()) {
713 return true
714 }
715 }
716
717 return false
718}
719
Colin Cross5c517922017-08-31 12:29:17 -0700720func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700721 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -0700722 return a.installFile(installPath, name, srcPath, Cp, deps)
723}
724
725func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
726 deps ...Path) OutputPath {
727 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
728}
729
730func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
731 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700732
Dan Willemsen782a2d12015-12-21 14:55:28 -0800733 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700734 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800735
Colin Cross893d8162017-04-26 17:34:03 -0700736 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700737
Dan Willemsen322acaf2016-01-12 23:07:05 -0800738 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700739
Colin Cross89562dc2016-10-03 17:47:19 -0700740 var implicitDeps, orderOnlyDeps Paths
741
742 if a.Host() {
743 // Installed host modules might be used during the build, depend directly on their
744 // dependencies so their timestamp is updated whenever their dependency is updated
745 implicitDeps = deps
746 } else {
747 orderOnlyDeps = deps
748 }
749
Dan Willemsen322acaf2016-01-12 23:07:05 -0800750 a.ModuleBuild(pctx, ModuleBuildParams{
Colin Cross5c517922017-08-31 12:29:17 -0700751 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -0700752 Description: "install " + fullInstallPath.Base(),
753 Output: fullInstallPath,
754 Input: srcPath,
755 Implicits: implicitDeps,
756 OrderOnly: orderOnlyDeps,
757 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800758 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800759
Dan Willemsen322acaf2016-01-12 23:07:05 -0800760 a.installFiles = append(a.installFiles, fullInstallPath)
761 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700762 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700763 return fullInstallPath
764}
765
Colin Cross3854a602016-01-11 12:49:11 -0800766func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
767 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700768 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800769
Colin Cross893d8162017-04-26 17:34:03 -0700770 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700771
Colin Cross12fc4972016-01-11 12:49:11 -0800772 a.ModuleBuild(pctx, ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700773 Rule: Symlink,
774 Description: "install symlink " + fullInstallPath.Base(),
775 Output: fullInstallPath,
776 OrderOnly: Paths{srcPath},
777 Default: !a.AConfig().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -0800778 Args: map[string]string{
779 "fromPath": srcPath.String(),
780 },
781 })
Colin Cross3854a602016-01-11 12:49:11 -0800782
Colin Cross12fc4972016-01-11 12:49:11 -0800783 a.installFiles = append(a.installFiles, fullInstallPath)
784 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
785 }
Colin Cross3854a602016-01-11 12:49:11 -0800786 return fullInstallPath
787}
788
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700789func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800790 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
791}
792
Colin Cross3f40fa42015-01-30 17:27:36 -0800793type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700794 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800795}
796
797func isFileInstaller(m blueprint.Module) bool {
798 _, ok := m.(fileInstaller)
799 return ok
800}
801
802func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700803 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800804 return ok
805}
Colin Crossfce53272015-04-08 11:21:40 -0700806
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700807func findStringInSlice(str string, slice []string) int {
808 for i, s := range slice {
809 if s == str {
810 return i
Colin Crossfce53272015-04-08 11:21:40 -0700811 }
812 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700813 return -1
814}
815
Colin Cross068e0fe2016-12-13 15:23:47 -0800816func SrcIsModule(s string) string {
817 if len(s) > 1 && s[0] == ':' {
818 return s[1:]
819 }
820 return ""
821}
822
823type sourceDependencyTag struct {
824 blueprint.BaseDependencyTag
825}
826
827var SourceDepTag sourceDependencyTag
828
829// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
830// modules listed in srcFiles using ":module" syntax
831func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
832 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -0700833 set := make(map[string]bool)
834
Colin Cross068e0fe2016-12-13 15:23:47 -0800835 for _, s := range srcFiles {
836 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -0700837 if _, found := set[m]; found {
838 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
839 } else {
840 set[m] = true
841 deps = append(deps, m)
842 }
Colin Cross068e0fe2016-12-13 15:23:47 -0800843 }
844 }
845
846 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
847}
848
849type SourceFileProducer interface {
850 Srcs() Paths
851}
852
853// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800854// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700855func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800856 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
857}
858
859func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700860 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800861
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700862 for i, e := range excludes {
863 j := findStringInSlice(e, srcFiles)
864 if j != -1 {
865 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
866 }
867
868 excludes[i] = filepath.Join(prefix, e)
869 }
870
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800871 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700872 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800873 if m := SrcIsModule(s); m != "" {
874 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
875 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800876 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800877 } else {
878 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
879 }
880 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800881 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
882 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
883 for i, s := range expandedSrcFiles {
884 expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
885 }
Colin Cross8f101b42015-06-17 15:09:06 -0700886 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800887 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
888 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700889 }
890 }
891
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800892 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700893}
894
Nan Zhang6d34b302017-02-04 17:47:46 -0800895func (ctx *androidModuleContext) RequiredModuleNames() []string {
896 return ctx.module.base().commonProperties.Required
897}
898
Colin Cross7f19f372016-11-01 11:10:25 -0700899func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
900 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700901 if err != nil {
902 ctx.ModuleErrorf("glob: %s", err.Error())
903 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700904 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700905}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700906
Colin Cross463a90e2015-06-17 14:20:06 -0700907func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700908 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700909}
910
Colin Cross1f8c52b2015-06-16 16:38:17 -0700911func BuildTargetSingleton() blueprint.Singleton {
912 return &buildTargetSingleton{}
913}
914
Colin Cross87d8b562017-04-25 10:01:55 -0700915func parentDir(dir string) string {
916 dir, _ = filepath.Split(dir)
917 return filepath.Clean(dir)
918}
919
Colin Cross1f8c52b2015-06-16 16:38:17 -0700920type buildTargetSingleton struct{}
921
922func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
923 checkbuildDeps := []string{}
924
Colin Cross87d8b562017-04-25 10:01:55 -0700925 mmTarget := func(dir string) string {
926 return filepath.Join("mm", dir)
927 }
928
929 modulesInDir := make(map[string][]string)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700930
931 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700932 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700933 blueprintDir := a.base().blueprintDir
934 installTarget := a.base().installTarget
935 checkbuildTarget := a.base().checkbuildTarget
936
937 if checkbuildTarget != "" {
938 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
Colin Cross87d8b562017-04-25 10:01:55 -0700939 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700940 }
941
942 if installTarget != "" {
Colin Cross87d8b562017-04-25 10:01:55 -0700943 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700944 }
945 }
946 })
947
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800948 suffix := ""
949 if ctx.Config().(Config).EmbeddedInMake() {
950 suffix = "-soong"
951 }
952
Colin Cross1f8c52b2015-06-16 16:38:17 -0700953 // Create a top-level checkbuild target that depends on all modules
954 ctx.Build(pctx, blueprint.BuildParams{
955 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800956 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700957 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700958 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700959 })
960
Colin Cross87d8b562017-04-25 10:01:55 -0700961 // Ensure ancestor directories are in modulesInDir
962 dirs := sortedKeys(modulesInDir)
963 for _, dir := range dirs {
964 dir := parentDir(dir)
965 for dir != "." && dir != "/" {
966 if _, exists := modulesInDir[dir]; exists {
967 break
968 }
969 modulesInDir[dir] = nil
970 dir = parentDir(dir)
971 }
972 }
973
974 // Make directories build their direct subdirectories
975 dirs = sortedKeys(modulesInDir)
976 for _, dir := range dirs {
977 p := parentDir(dir)
978 if p != "." && p != "/" {
979 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
980 }
981 }
982
983 // Create a mm/<directory> target that depends on all modules in a directory, and depends
984 // on the mm/* targets of all of its subdirectories that contain Android.bp files.
Colin Cross1f8c52b2015-06-16 16:38:17 -0700985 for _, dir := range dirs {
986 ctx.Build(pctx, blueprint.BuildParams{
987 Rule: blueprint.Phony,
Colin Cross87d8b562017-04-25 10:01:55 -0700988 Outputs: []string{mmTarget(dir)},
989 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800990 // HACK: checkbuild should be an optional build, but force it
991 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800992 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700993 })
994 }
995}
Colin Crossd779da42015-12-17 18:00:23 -0800996
997type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700998 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800999 ctx interface {
1000 ModuleName(blueprint.Module) string
1001 ModuleSubDir(blueprint.Module) string
1002 }
1003}
1004
1005func (s AndroidModulesByName) Len() int { return len(s.slice) }
1006func (s AndroidModulesByName) Less(i, j int) bool {
1007 mi, mj := s.slice[i], s.slice[j]
1008 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1009
1010 if ni != nj {
1011 return ni < nj
1012 } else {
1013 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1014 }
1015}
1016func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }