blob: bacf66634b066db93ce07eed347aca804e543b80 [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 Cross5aac3622017-08-31 15:07:09 -0700165 // relative path to a file to include in the list of notices for the device
166 Notice *string
167
Colin Crossa1ad8d12016-06-01 17:09:44 -0700168 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700169 CompileTarget Target `blueprint:"mutated"`
170 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800171
172 // Set by InitAndroidModule
173 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700174 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700175
176 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800177}
178
179type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700180 Host_supported *bool
181 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800182}
183
Colin Crossc472d572015-03-17 15:06:21 -0700184type Multilib string
185
186const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700187 MultilibBoth Multilib = "both"
188 MultilibFirst Multilib = "first"
189 MultilibCommon Multilib = "common"
190 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700191)
192
Colin Crossa1ad8d12016-06-01 17:09:44 -0700193type HostOrDeviceSupported int
194
195const (
196 _ HostOrDeviceSupported = iota
197 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700198 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700199 DeviceSupported
200 HostAndDeviceSupported
201 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700202 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700203)
204
Colin Cross36242852017-06-23 15:06:31 -0700205func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800206 base := m.base()
207 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700208
Colin Cross36242852017-06-23 15:06:31 -0700209 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700210 &base.nameProperties,
211 &base.commonProperties,
212 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700213}
214
Colin Cross36242852017-06-23 15:06:31 -0700215func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
216 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700217
218 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800219 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700220 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700221 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800222
Dan Willemsen218f6562015-07-08 18:13:11 -0700223 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700224 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700225 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800226 }
227
Colin Cross36242852017-06-23 15:06:31 -0700228 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800229}
230
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800231// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800232// modules. It should be included as an anonymous field in every module
233// struct definition. InitAndroidModule should then be called from the module's
234// factory function, and the return values from InitAndroidModule should be
235// returned from the factory function.
236//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800237// The ModuleBase type is responsible for implementing the GenerateBuildActions
238// method to support the blueprint.Module interface. This method will then call
239// the module's GenerateAndroidBuildActions method once for each build variant
240// that is to be built. GenerateAndroidBuildActions is passed a
241// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800242// AndroidModuleContext exposes extra functionality specific to the Android build
243// system including details about the particular build variant that is to be
244// generated.
245//
246// For example:
247//
248// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800249// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800250// )
251//
252// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800253// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800254// properties struct {
255// MyProperty string
256// }
257// }
258//
Colin Cross36242852017-06-23 15:06:31 -0700259// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800260// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700261// m.AddProperties(&m.properties)
262// android.InitAndroidModule(m)
263// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800264// }
265//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800266// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800267// // Get the CPU architecture for the current build variant.
268// variantArch := ctx.Arch()
269//
270// // ...
271// }
Colin Cross635c3b02016-05-18 15:37:25 -0700272type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800273 // Putting the curiously recurring thing pointing to the thing that contains
274 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700275 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700276 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800277
Colin Crossfc754582016-05-17 16:34:16 -0700278 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800279 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700280 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800281 hostAndDeviceProperties hostAndDeviceProperties
282 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700283 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700284 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800285
286 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700287 installFiles Paths
288 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700289
290 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
291 // Only set on the final variant of each module
292 installTarget string
293 checkbuildTarget string
294 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700295
Colin Cross178a5092016-09-13 13:42:32 -0700296 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700297
298 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700299
300 // For tests
301 buildParams []ModuleBuildParams
Colin Cross36242852017-06-23 15:06:31 -0700302}
303
304func (a *ModuleBase) AddProperties(props ...interface{}) {
305 a.registerProps = append(a.registerProps, props...)
306}
307
308func (a *ModuleBase) GetProperties() []interface{} {
309 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800310}
311
Colin Crosscec81712017-07-13 14:43:27 -0700312func (a *ModuleBase) BuildParamsForTests() []ModuleBuildParams {
313 return a.buildParams
314}
315
Colin Crossce75d2c2016-10-06 16:12:58 -0700316// Name returns the name of the module. It may be overridden by individual module types, for
317// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700318func (a *ModuleBase) Name() string {
319 return a.nameProperties.Name
320}
321
Colin Crossce75d2c2016-10-06 16:12:58 -0700322// BaseModuleName returns the name of the module as specified in the blueprints file.
323func (a *ModuleBase) BaseModuleName() string {
324 return a.nameProperties.Name
325}
326
Colin Cross635c3b02016-05-18 15:37:25 -0700327func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800328 return a
329}
330
Colin Cross8b74d172016-09-13 09:59:14 -0700331func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700332 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700333 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700334}
335
Colin Crossa1ad8d12016-06-01 17:09:44 -0700336func (a *ModuleBase) Target() Target {
337 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800338}
339
Colin Cross8b74d172016-09-13 09:59:14 -0700340func (a *ModuleBase) TargetPrimary() bool {
341 return a.commonProperties.CompilePrimary
342}
343
Colin Crossa1ad8d12016-06-01 17:09:44 -0700344func (a *ModuleBase) Os() OsType {
345 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800346}
347
Colin Cross635c3b02016-05-18 15:37:25 -0700348func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700349 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800350}
351
Colin Cross635c3b02016-05-18 15:37:25 -0700352func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700353 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800354}
355
Dan Willemsen0b24c742016-10-04 15:13:37 -0700356func (a *ModuleBase) ArchSpecific() bool {
357 return a.commonProperties.ArchSpecific
358}
359
Colin Crossa1ad8d12016-06-01 17:09:44 -0700360func (a *ModuleBase) OsClassSupported() []OsClass {
361 switch a.commonProperties.HostOrDeviceSupported {
362 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700363 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700364 case HostSupportedNoCross:
365 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700366 case DeviceSupported:
367 return []OsClass{Device}
368 case HostAndDeviceSupported:
369 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700370 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700371 supported = append(supported, Host, HostCross)
372 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700373 if a.hostAndDeviceProperties.Device_supported == nil ||
374 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700375 supported = append(supported, Device)
376 }
377 return supported
378 default:
379 return nil
380 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800381}
382
Colin Cross635c3b02016-05-18 15:37:25 -0700383func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800384 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
385 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700386 (a.hostAndDeviceProperties.Device_supported == nil ||
387 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800388}
389
Colin Cross635c3b02016-05-18 15:37:25 -0700390func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800391 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800392 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800393 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800394 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800395}
396
Colin Crossce75d2c2016-10-06 16:12:58 -0700397func (a *ModuleBase) SkipInstall() {
398 a.commonProperties.SkipInstall = true
399}
400
Colin Cross635c3b02016-05-18 15:37:25 -0700401func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700402 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800403
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700404 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 ctx.VisitDepsDepthFirstIf(isFileInstaller,
406 func(m blueprint.Module) {
407 fileInstaller := m.(fileInstaller)
408 files := fileInstaller.filesToInstall()
409 result = append(result, files...)
410 })
411
412 return result
413}
414
Colin Cross635c3b02016-05-18 15:37:25 -0700415func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800416 return a.installFiles
417}
418
Colin Cross635c3b02016-05-18 15:37:25 -0700419func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800420 return p.noAddressSanitizer
421}
422
Colin Cross635c3b02016-05-18 15:37:25 -0700423func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800424 return false
425}
426
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700427func (p *ModuleBase) InstallInSanitizerDir() bool {
428 return false
429}
430
Colin Cross635c3b02016-05-18 15:37:25 -0700431func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700432 allInstalledFiles := Paths{}
433 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800434 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700435 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700436 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
437 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 })
439
Colin Cross9454bfa2015-03-17 13:24:18 -0700440 deps := []string{}
441
Colin Cross3f40fa42015-01-30 17:27:36 -0800442 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700443 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800444 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700445 Rule: blueprint.Phony,
446 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700447 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800448 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700449 })
450 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700451 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700452 }
453
454 if len(allCheckbuildFiles) > 0 {
455 name := ctx.ModuleName() + "-checkbuild"
456 ctx.Build(pctx, blueprint.BuildParams{
457 Rule: blueprint.Phony,
458 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700459 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700460 Optional: true,
461 })
462 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700463 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700464 }
465
466 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800467 suffix := ""
468 if ctx.Config().(Config).EmbeddedInMake() {
469 suffix = "-soong"
470 }
471
Colin Cross9454bfa2015-03-17 13:24:18 -0700472 ctx.Build(pctx, blueprint.BuildParams{
473 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800474 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700475 Implicits: deps,
476 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700478
479 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800480 }
481}
482
Colin Cross635c3b02016-05-18 15:37:25 -0700483func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700484 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700485 target: a.commonProperties.CompileTarget,
486 targetPrimary: a.commonProperties.CompilePrimary,
Dan Willemsenaa118f92017-04-06 12:49:58 -0700487 vendor: a.commonProperties.Proprietary || a.commonProperties.Vendor,
Colin Cross8b74d172016-09-13 09:59:14 -0700488 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800489 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800490}
491
Colin Cross635c3b02016-05-18 15:37:25 -0700492func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800493 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700494 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700495 ModuleContext: ctx,
496 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
497 installDeps: a.computeInstallDeps(ctx),
498 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800499 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800500 }
501
Colin Cross67a5c132017-05-09 13:45:28 -0700502 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
503 var suffix []string
504 if androidCtx.Os().Class != Device && androidCtx.Os().Class != Generic {
505 suffix = append(suffix, androidCtx.Os().String())
506 }
507 if !androidCtx.PrimaryArch() {
508 suffix = append(suffix, androidCtx.Arch().ArchType.String())
509 }
510
511 ctx.Variable(pctx, "moduleDesc", desc)
512
513 s := ""
514 if len(suffix) > 0 {
515 s = " [" + strings.Join(suffix, " ") + "]"
516 }
517 ctx.Variable(pctx, "moduleDescSuffix", s)
518
Colin Cross9b1d13d2016-09-19 15:18:11 -0700519 if a.Enabled() {
520 a.module.GenerateAndroidBuildActions(androidCtx)
521 if ctx.Failed() {
522 return
523 }
524
525 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
526 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800527 }
528
Colin Cross9b1d13d2016-09-19 15:18:11 -0700529 if a == ctx.FinalModule().(Module).base() {
530 a.generateModuleTarget(ctx)
531 if ctx.Failed() {
532 return
533 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800534 }
Colin Crosscec81712017-07-13 14:43:27 -0700535
536 a.buildParams = androidCtx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800537}
538
Colin Crossf6566ed2015-03-24 11:13:38 -0700539type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700540 target Target
541 targetPrimary bool
542 debug bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700543 vendor bool
Colin Cross8b74d172016-09-13 09:59:14 -0700544 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700545}
546
Colin Cross3f40fa42015-01-30 17:27:36 -0800547type androidModuleContext struct {
548 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700549 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700550 installDeps Paths
551 installFiles Paths
552 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800553 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700554 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700555
556 // For tests
557 buildParams []ModuleBuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800558}
559
Colin Cross67a5c132017-05-09 13:45:28 -0700560func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross6ff51382015-12-17 16:39:19 -0800561 a.ModuleContext.Build(pctx, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700562 Rule: ErrorRule,
563 Description: desc,
564 Outputs: outputs,
565 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800566 Args: map[string]string{
567 "error": err.Error(),
568 },
569 })
570 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800571}
572
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800573func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700574 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700575 a.ninjaError(params.Description, params.Outputs,
576 fmt.Errorf("module %s missing dependencies: %s\n",
577 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800578 return
579 }
580
Colin Cross3f40fa42015-01-30 17:27:36 -0800581 params.Optional = true
582 a.ModuleContext.Build(pctx, params)
583}
584
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700585func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
Colin Crosscec81712017-07-13 14:43:27 -0700586 if a.config.captureBuild {
587 a.buildParams = append(a.buildParams, params)
588 }
589
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700590 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700591 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800592 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700593 Outputs: params.Outputs.Strings(),
594 ImplicitOutputs: params.ImplicitOutputs.Strings(),
595 Inputs: params.Inputs.Strings(),
596 Implicits: params.Implicits.Strings(),
597 OrderOnly: params.OrderOnly.Strings(),
598 Args: params.Args,
599 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700600 }
601
Colin Cross67a5c132017-05-09 13:45:28 -0700602 if params.Description != "" {
603 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
604 }
605
Colin Cross33bfb0a2016-11-21 17:23:08 -0800606 if params.Depfile != nil {
607 bparams.Depfile = params.Depfile.String()
608 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700609 if params.Output != nil {
610 bparams.Outputs = append(bparams.Outputs, params.Output.String())
611 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700612 if params.ImplicitOutput != nil {
613 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
614 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700615 if params.Input != nil {
616 bparams.Inputs = append(bparams.Inputs, params.Input.String())
617 }
618 if params.Implicit != nil {
619 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
620 }
621
Colin Cross6ff51382015-12-17 16:39:19 -0800622 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700623 a.ninjaError(bparams.Description, bparams.Outputs,
624 fmt.Errorf("module %s missing dependencies: %s\n",
625 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800626 return
627 }
628
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700629 a.ModuleContext.Build(pctx, bparams)
630}
631
Colin Cross6ff51382015-12-17 16:39:19 -0800632func (a *androidModuleContext) GetMissingDependencies() []string {
633 return a.missingDeps
634}
635
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800636func (a *androidModuleContext) AddMissingDependencies(deps []string) {
637 if deps != nil {
638 a.missingDeps = append(a.missingDeps, deps...)
639 }
640}
641
Colin Crossa1ad8d12016-06-01 17:09:44 -0700642func (a *androidBaseContextImpl) Target() Target {
643 return a.target
644}
645
Colin Cross8b74d172016-09-13 09:59:14 -0700646func (a *androidBaseContextImpl) TargetPrimary() bool {
647 return a.targetPrimary
648}
649
Colin Crossf6566ed2015-03-24 11:13:38 -0700650func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700651 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800652}
653
Colin Crossa1ad8d12016-06-01 17:09:44 -0700654func (a *androidBaseContextImpl) Os() OsType {
655 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800656}
657
Colin Crossf6566ed2015-03-24 11:13:38 -0700658func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700659 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700660}
661
662func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700663 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700664}
665
Colin Cross0af4b842015-04-30 16:36:18 -0700666func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700667 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700668}
669
Colin Cross3edeee12017-04-04 12:59:48 -0700670func (a *androidBaseContextImpl) Windows() bool {
671 return a.target.Os == Windows
672}
673
Colin Crossf6566ed2015-03-24 11:13:38 -0700674func (a *androidBaseContextImpl) Debug() bool {
675 return a.debug
676}
677
Colin Cross1e7d3702016-08-24 15:25:47 -0700678func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700679 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
680 return true
681 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700682 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
683}
684
Colin Cross1332b002015-04-07 17:11:30 -0700685func (a *androidBaseContextImpl) AConfig() Config {
686 return a.config
687}
688
Colin Cross9272ade2016-08-17 15:24:12 -0700689func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
690 return DeviceConfig{a.config.deviceConfig}
691}
692
Dan Willemsenaa118f92017-04-06 12:49:58 -0700693func (a *androidBaseContextImpl) Vendor() bool {
694 return a.vendor
Dan Willemsen782a2d12015-12-21 14:55:28 -0800695}
696
Colin Cross8d8f8e22016-08-03 11:57:50 -0700697func (a *androidModuleContext) InstallInData() bool {
698 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800699}
700
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700701func (a *androidModuleContext) InstallInSanitizerDir() bool {
702 return a.module.InstallInSanitizerDir()
703}
704
Colin Cross893d8162017-04-26 17:34:03 -0700705func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
706 if a.module.base().commonProperties.SkipInstall {
707 return true
708 }
709
710 if a.Device() {
711 if a.AConfig().SkipDeviceInstall() {
712 return true
713 }
714
715 if a.AConfig().SkipMegaDeviceInstall(fullInstallPath.String()) {
716 return true
717 }
718 }
719
720 return false
721}
722
Colin Cross5c517922017-08-31 12:29:17 -0700723func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700724 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -0700725 return a.installFile(installPath, name, srcPath, Cp, deps)
726}
727
728func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
729 deps ...Path) OutputPath {
730 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
731}
732
733func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
734 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700735
Dan Willemsen782a2d12015-12-21 14:55:28 -0800736 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700737 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800738
Colin Cross893d8162017-04-26 17:34:03 -0700739 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700740
Dan Willemsen322acaf2016-01-12 23:07:05 -0800741 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700742
Colin Cross89562dc2016-10-03 17:47:19 -0700743 var implicitDeps, orderOnlyDeps Paths
744
745 if a.Host() {
746 // Installed host modules might be used during the build, depend directly on their
747 // dependencies so their timestamp is updated whenever their dependency is updated
748 implicitDeps = deps
749 } else {
750 orderOnlyDeps = deps
751 }
752
Dan Willemsen322acaf2016-01-12 23:07:05 -0800753 a.ModuleBuild(pctx, ModuleBuildParams{
Colin Cross5c517922017-08-31 12:29:17 -0700754 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -0700755 Description: "install " + fullInstallPath.Base(),
756 Output: fullInstallPath,
757 Input: srcPath,
758 Implicits: implicitDeps,
759 OrderOnly: orderOnlyDeps,
760 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800761 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800762
Dan Willemsen322acaf2016-01-12 23:07:05 -0800763 a.installFiles = append(a.installFiles, fullInstallPath)
764 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700765 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700766 return fullInstallPath
767}
768
Colin Cross3854a602016-01-11 12:49:11 -0800769func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
770 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700771 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800772
Colin Cross893d8162017-04-26 17:34:03 -0700773 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700774
Colin Cross12fc4972016-01-11 12:49:11 -0800775 a.ModuleBuild(pctx, ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700776 Rule: Symlink,
777 Description: "install symlink " + fullInstallPath.Base(),
778 Output: fullInstallPath,
779 OrderOnly: Paths{srcPath},
780 Default: !a.AConfig().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -0800781 Args: map[string]string{
782 "fromPath": srcPath.String(),
783 },
784 })
Colin Cross3854a602016-01-11 12:49:11 -0800785
Colin Cross12fc4972016-01-11 12:49:11 -0800786 a.installFiles = append(a.installFiles, fullInstallPath)
787 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
788 }
Colin Cross3854a602016-01-11 12:49:11 -0800789 return fullInstallPath
790}
791
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700792func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800793 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
794}
795
Colin Cross3f40fa42015-01-30 17:27:36 -0800796type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700797 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800798}
799
800func isFileInstaller(m blueprint.Module) bool {
801 _, ok := m.(fileInstaller)
802 return ok
803}
804
805func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700806 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800807 return ok
808}
Colin Crossfce53272015-04-08 11:21:40 -0700809
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700810func findStringInSlice(str string, slice []string) int {
811 for i, s := range slice {
812 if s == str {
813 return i
Colin Crossfce53272015-04-08 11:21:40 -0700814 }
815 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700816 return -1
817}
818
Colin Cross068e0fe2016-12-13 15:23:47 -0800819func SrcIsModule(s string) string {
820 if len(s) > 1 && s[0] == ':' {
821 return s[1:]
822 }
823 return ""
824}
825
826type sourceDependencyTag struct {
827 blueprint.BaseDependencyTag
828}
829
830var SourceDepTag sourceDependencyTag
831
832// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
833// modules listed in srcFiles using ":module" syntax
834func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
835 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -0700836 set := make(map[string]bool)
837
Colin Cross068e0fe2016-12-13 15:23:47 -0800838 for _, s := range srcFiles {
839 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -0700840 if _, found := set[m]; found {
841 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
842 } else {
843 set[m] = true
844 deps = append(deps, m)
845 }
Colin Cross068e0fe2016-12-13 15:23:47 -0800846 }
847 }
848
849 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
850}
851
852type SourceFileProducer interface {
853 Srcs() Paths
854}
855
856// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800857// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700858func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800859 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
860}
861
862func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700863 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800864
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700865 for i, e := range excludes {
866 j := findStringInSlice(e, srcFiles)
867 if j != -1 {
868 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
869 }
870
871 excludes[i] = filepath.Join(prefix, e)
872 }
873
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800874 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700875 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800876 if m := SrcIsModule(s); m != "" {
877 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
878 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800879 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800880 } else {
881 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
882 }
883 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800884 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
885 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
886 for i, s := range expandedSrcFiles {
887 expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
888 }
Colin Cross8f101b42015-06-17 15:09:06 -0700889 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800890 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
891 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700892 }
893 }
894
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800895 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700896}
897
Nan Zhang6d34b302017-02-04 17:47:46 -0800898func (ctx *androidModuleContext) RequiredModuleNames() []string {
899 return ctx.module.base().commonProperties.Required
900}
901
Colin Cross7f19f372016-11-01 11:10:25 -0700902func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
903 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700904 if err != nil {
905 ctx.ModuleErrorf("glob: %s", err.Error())
906 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700907 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700908}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700909
Colin Cross463a90e2015-06-17 14:20:06 -0700910func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700911 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700912}
913
Colin Cross1f8c52b2015-06-16 16:38:17 -0700914func BuildTargetSingleton() blueprint.Singleton {
915 return &buildTargetSingleton{}
916}
917
Colin Cross87d8b562017-04-25 10:01:55 -0700918func parentDir(dir string) string {
919 dir, _ = filepath.Split(dir)
920 return filepath.Clean(dir)
921}
922
Colin Cross1f8c52b2015-06-16 16:38:17 -0700923type buildTargetSingleton struct{}
924
925func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
926 checkbuildDeps := []string{}
927
Colin Cross87d8b562017-04-25 10:01:55 -0700928 mmTarget := func(dir string) string {
929 return filepath.Join("mm", dir)
930 }
931
932 modulesInDir := make(map[string][]string)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700933
934 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700935 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700936 blueprintDir := a.base().blueprintDir
937 installTarget := a.base().installTarget
938 checkbuildTarget := a.base().checkbuildTarget
939
940 if checkbuildTarget != "" {
941 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
Colin Cross87d8b562017-04-25 10:01:55 -0700942 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700943 }
944
945 if installTarget != "" {
Colin Cross87d8b562017-04-25 10:01:55 -0700946 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700947 }
948 }
949 })
950
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800951 suffix := ""
952 if ctx.Config().(Config).EmbeddedInMake() {
953 suffix = "-soong"
954 }
955
Colin Cross1f8c52b2015-06-16 16:38:17 -0700956 // Create a top-level checkbuild target that depends on all modules
957 ctx.Build(pctx, blueprint.BuildParams{
958 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800959 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700960 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700961 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700962 })
963
Colin Cross87d8b562017-04-25 10:01:55 -0700964 // Ensure ancestor directories are in modulesInDir
965 dirs := sortedKeys(modulesInDir)
966 for _, dir := range dirs {
967 dir := parentDir(dir)
968 for dir != "." && dir != "/" {
969 if _, exists := modulesInDir[dir]; exists {
970 break
971 }
972 modulesInDir[dir] = nil
973 dir = parentDir(dir)
974 }
975 }
976
977 // Make directories build their direct subdirectories
978 dirs = sortedKeys(modulesInDir)
979 for _, dir := range dirs {
980 p := parentDir(dir)
981 if p != "." && p != "/" {
982 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
983 }
984 }
985
986 // Create a mm/<directory> target that depends on all modules in a directory, and depends
987 // on the mm/* targets of all of its subdirectories that contain Android.bp files.
Colin Cross1f8c52b2015-06-16 16:38:17 -0700988 for _, dir := range dirs {
989 ctx.Build(pctx, blueprint.BuildParams{
990 Rule: blueprint.Phony,
Colin Cross87d8b562017-04-25 10:01:55 -0700991 Outputs: []string{mmTarget(dir)},
992 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800993 // HACK: checkbuild should be an optional build, but force it
994 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800995 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700996 })
997 }
998}
Colin Crossd779da42015-12-17 18:00:23 -0800999
1000type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001001 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001002 ctx interface {
1003 ModuleName(blueprint.Module) string
1004 ModuleSubDir(blueprint.Module) string
1005 }
1006}
1007
1008func (s AndroidModulesByName) Len() int { return len(s.slice) }
1009func (s AndroidModulesByName) Less(i, j int) bool {
1010 mi, mj := s.slice[i], s.slice[j]
1011 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1012
1013 if ni != nj {
1014 return ni < nj
1015 } else {
1016 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1017 }
1018}
1019func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }