blob: 110f04c73595e298f6bfdea69e44267c3a64886f [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
Dan Willemsen9f3c5742016-11-03 14:28:31 -070039 Output WritablePath
40 Outputs WritablePaths
41 ImplicitOutput WritablePath
42 ImplicitOutputs WritablePaths
43 Input Path
44 Inputs Paths
45 Implicit Path
46 Implicits Paths
47 OrderOnly Paths
48 Default bool
49 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070050}
51
Colin Crossf6566ed2015-03-24 11:13:38 -070052type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070053 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070054 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070055 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070056 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070057 Host() bool
58 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070059 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070061 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070062 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070063 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070064}
65
Colin Cross635c3b02016-05-18 15:37:25 -070066type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070067 blueprint.BaseModuleContext
68 androidBaseContext
69}
70
Colin Cross635c3b02016-05-18 15:37:25 -070071type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080072 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070073 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080074
Dan Willemsen34cc69e2015-09-23 15:26:20 -070075 // Similar to Build, but takes Paths instead of []string,
76 // and performs more verification.
77 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070078
Dan Willemsen34cc69e2015-09-23 15:26:20 -070079 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070080 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081
Colin Crossa2344662016-03-24 13:14:12 -070082 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
83 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080084 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070085 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080086
87 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070088
89 Proprietary() bool
90 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080091}
92
Colin Cross635c3b02016-05-18 15:37:25 -070093type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080094 blueprint.Module
95
Colin Cross635c3b02016-05-18 15:37:25 -070096 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -070097 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080098
Colin Cross635c3b02016-05-18 15:37:25 -070099 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800100 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700101 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800102 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800103}
104
Colin Crossfc754582016-05-17 16:34:16 -0700105type nameProperties struct {
106 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700107 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700108}
109
110type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700111 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800112
Dan Willemsen0effe062015-11-30 16:06:01 -0800113 // emit build rules for this module
114 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800115
Colin Cross7d5136f2015-05-11 13:39:40 -0700116 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800117 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
118 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
119 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700120 Compile_multilib string `android:"arch_variant"`
121
122 Target struct {
123 Host struct {
124 Compile_multilib string
125 }
126 Android struct {
127 Compile_multilib string
128 }
129 }
130
131 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800132
Dan Willemsen782a2d12015-12-21 14:55:28 -0800133 // whether this is a proprietary vendor module, and should be installed into /vendor
134 Proprietary bool
135
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700136 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
137 // file
138 Logtags []string
139
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700140 // init.rc files to be installed if this module is installed
141 Init_rc []string
142
Chris Wolfe998306e2016-08-15 14:47:23 -0400143 // names of other modules to install if this module is installed
144 Required []string
145
Colin Crossa1ad8d12016-06-01 17:09:44 -0700146 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700147 CompileTarget Target `blueprint:"mutated"`
148 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800149
150 // Set by InitAndroidModule
151 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700152 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700153
154 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800155}
156
157type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700158 Host_supported *bool
159 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800160}
161
Colin Crossc472d572015-03-17 15:06:21 -0700162type Multilib string
163
164const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700165 MultilibBoth Multilib = "both"
166 MultilibFirst Multilib = "first"
167 MultilibCommon Multilib = "common"
168 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700169)
170
Colin Crossa1ad8d12016-06-01 17:09:44 -0700171type HostOrDeviceSupported int
172
173const (
174 _ HostOrDeviceSupported = iota
175 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700176 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700177 DeviceSupported
178 HostAndDeviceSupported
179 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700180 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700181)
182
Colin Cross635c3b02016-05-18 15:37:25 -0700183func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800184 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
185
186 base := m.base()
187 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700188
Colin Crossfc754582016-05-17 16:34:16 -0700189 propertyStructs = append(propertyStructs,
190 &base.nameProperties,
191 &base.commonProperties,
192 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700193
194 return m, propertyStructs
195}
196
Colin Cross635c3b02016-05-18 15:37:25 -0700197func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700198 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
199
200 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
201
202 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800203 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700204 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700205 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800206
Dan Willemsen218f6562015-07-08 18:13:11 -0700207 switch hod {
208 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800209 // Default to module to device supported, host not supported, can override in module
210 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700211 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700212 fallthrough
213 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800214 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
215 }
216
Colin Crosscfad1192015-11-02 16:43:11 -0800217 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800218}
219
220// A AndroidModuleBase object contains the properties that are common to all Android
221// modules. It should be included as an anonymous field in every module
222// struct definition. InitAndroidModule should then be called from the module's
223// factory function, and the return values from InitAndroidModule should be
224// returned from the factory function.
225//
226// The AndroidModuleBase type is responsible for implementing the
227// GenerateBuildActions method to support the blueprint.Module interface. This
228// method will then call the module's GenerateAndroidBuildActions method once
229// for each build variant that is to be built. GenerateAndroidBuildActions is
230// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
231// AndroidModuleContext exposes extra functionality specific to the Android build
232// system including details about the particular build variant that is to be
233// generated.
234//
235// For example:
236//
237// import (
238// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700239// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800240// )
241//
242// type myModule struct {
243// common.AndroidModuleBase
244// properties struct {
245// MyProperty string
246// }
247// }
248//
249// func NewMyModule() (blueprint.Module, []interface{}) {
250// m := &myModule{}
251// return common.InitAndroidModule(m, &m.properties)
252// }
253//
254// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
255// // Get the CPU architecture for the current build variant.
256// variantArch := ctx.Arch()
257//
258// // ...
259// }
Colin Cross635c3b02016-05-18 15:37:25 -0700260type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800261 // Putting the curiously recurring thing pointing to the thing that contains
262 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700263 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800264
Colin Crossfc754582016-05-17 16:34:16 -0700265 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800266 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700267 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800268 hostAndDeviceProperties hostAndDeviceProperties
269 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700270 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700271 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800272
273 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700274 installFiles Paths
275 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700276
277 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
278 // Only set on the final variant of each module
279 installTarget string
280 checkbuildTarget string
281 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700282
Colin Cross178a5092016-09-13 13:42:32 -0700283 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800284}
285
Colin Crossce75d2c2016-10-06 16:12:58 -0700286// Name returns the name of the module. It may be overridden by individual module types, for
287// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700288func (a *ModuleBase) Name() string {
289 return a.nameProperties.Name
290}
291
Colin Crossce75d2c2016-10-06 16:12:58 -0700292// BaseModuleName returns the name of the module as specified in the blueprints file.
293func (a *ModuleBase) BaseModuleName() string {
294 return a.nameProperties.Name
295}
296
Colin Cross635c3b02016-05-18 15:37:25 -0700297func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800298 return a
299}
300
Colin Cross8b74d172016-09-13 09:59:14 -0700301func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700302 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700303 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700304}
305
Colin Crossa1ad8d12016-06-01 17:09:44 -0700306func (a *ModuleBase) Target() Target {
307 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800308}
309
Colin Cross8b74d172016-09-13 09:59:14 -0700310func (a *ModuleBase) TargetPrimary() bool {
311 return a.commonProperties.CompilePrimary
312}
313
Colin Crossa1ad8d12016-06-01 17:09:44 -0700314func (a *ModuleBase) Os() OsType {
315 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800316}
317
Colin Cross635c3b02016-05-18 15:37:25 -0700318func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700319 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800320}
321
Colin Cross635c3b02016-05-18 15:37:25 -0700322func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700323 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800324}
325
Dan Willemsen0b24c742016-10-04 15:13:37 -0700326func (a *ModuleBase) ArchSpecific() bool {
327 return a.commonProperties.ArchSpecific
328}
329
Colin Crossa1ad8d12016-06-01 17:09:44 -0700330func (a *ModuleBase) OsClassSupported() []OsClass {
331 switch a.commonProperties.HostOrDeviceSupported {
332 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700333 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700334 case HostSupportedNoCross:
335 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700336 case DeviceSupported:
337 return []OsClass{Device}
338 case HostAndDeviceSupported:
339 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700340 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700341 supported = append(supported, Host, HostCross)
342 }
Colin Crossa4190c12016-07-12 13:11:25 -0700343 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700344 supported = append(supported, Device)
345 }
346 return supported
347 default:
348 return nil
349 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800350}
351
Colin Cross635c3b02016-05-18 15:37:25 -0700352func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800353 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
354 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700355 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800356}
357
Colin Cross635c3b02016-05-18 15:37:25 -0700358func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800359 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800360 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800361 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800362 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800363}
364
Colin Crossce75d2c2016-10-06 16:12:58 -0700365func (a *ModuleBase) SkipInstall() {
366 a.commonProperties.SkipInstall = true
367}
368
Colin Cross635c3b02016-05-18 15:37:25 -0700369func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700370 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800371
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700372 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800373 ctx.VisitDepsDepthFirstIf(isFileInstaller,
374 func(m blueprint.Module) {
375 fileInstaller := m.(fileInstaller)
376 files := fileInstaller.filesToInstall()
377 result = append(result, files...)
378 })
379
380 return result
381}
382
Colin Cross635c3b02016-05-18 15:37:25 -0700383func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800384 return a.installFiles
385}
386
Colin Cross635c3b02016-05-18 15:37:25 -0700387func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800388 return p.noAddressSanitizer
389}
390
Colin Cross635c3b02016-05-18 15:37:25 -0700391func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800392 return false
393}
394
Colin Cross635c3b02016-05-18 15:37:25 -0700395func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700396 allInstalledFiles := Paths{}
397 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800398 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700399 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700400 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
401 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800402 })
403
Colin Cross9454bfa2015-03-17 13:24:18 -0700404 deps := []string{}
405
Colin Cross3f40fa42015-01-30 17:27:36 -0800406 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700407 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800408 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700409 Rule: blueprint.Phony,
410 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700411 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800412 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700413 })
414 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700415 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700416 }
417
418 if len(allCheckbuildFiles) > 0 {
419 name := ctx.ModuleName() + "-checkbuild"
420 ctx.Build(pctx, blueprint.BuildParams{
421 Rule: blueprint.Phony,
422 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700423 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700424 Optional: true,
425 })
426 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700427 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700428 }
429
430 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800431 suffix := ""
432 if ctx.Config().(Config).EmbeddedInMake() {
433 suffix = "-soong"
434 }
435
Colin Cross9454bfa2015-03-17 13:24:18 -0700436 ctx.Build(pctx, blueprint.BuildParams{
437 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800438 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700439 Implicits: deps,
440 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800441 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700442
443 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800444 }
445}
446
Colin Cross635c3b02016-05-18 15:37:25 -0700447func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700448 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700449 target: a.commonProperties.CompileTarget,
450 targetPrimary: a.commonProperties.CompilePrimary,
451 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800452 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800453}
454
Colin Cross635c3b02016-05-18 15:37:25 -0700455func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800456 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700457 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700458 ModuleContext: ctx,
459 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
460 installDeps: a.computeInstallDeps(ctx),
461 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800462 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800463 }
464
Colin Cross9b1d13d2016-09-19 15:18:11 -0700465 if a.Enabled() {
466 a.module.GenerateAndroidBuildActions(androidCtx)
467 if ctx.Failed() {
468 return
469 }
470
471 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
472 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800473 }
474
Colin Cross9b1d13d2016-09-19 15:18:11 -0700475 if a == ctx.FinalModule().(Module).base() {
476 a.generateModuleTarget(ctx)
477 if ctx.Failed() {
478 return
479 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800480 }
481}
482
Colin Crossf6566ed2015-03-24 11:13:38 -0700483type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700484 target Target
485 targetPrimary bool
486 debug bool
487 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700488}
489
Colin Cross3f40fa42015-01-30 17:27:36 -0800490type androidModuleContext struct {
491 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700492 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700493 installDeps Paths
494 installFiles Paths
495 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800496 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700497 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800498}
499
500func (a *androidModuleContext) ninjaError(outputs []string, err error) {
501 a.ModuleContext.Build(pctx, blueprint.BuildParams{
502 Rule: ErrorRule,
503 Outputs: outputs,
504 Optional: true,
505 Args: map[string]string{
506 "error": err.Error(),
507 },
508 })
509 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800510}
511
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800512func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700513 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800514 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
515 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
516 return
517 }
518
Colin Cross3f40fa42015-01-30 17:27:36 -0800519 params.Optional = true
520 a.ModuleContext.Build(pctx, params)
521}
522
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700523func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
524 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700525 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800526 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700527 Outputs: params.Outputs.Strings(),
528 ImplicitOutputs: params.ImplicitOutputs.Strings(),
529 Inputs: params.Inputs.Strings(),
530 Implicits: params.Implicits.Strings(),
531 OrderOnly: params.OrderOnly.Strings(),
532 Args: params.Args,
533 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700534 }
535
Colin Cross33bfb0a2016-11-21 17:23:08 -0800536 if params.Depfile != nil {
537 bparams.Depfile = params.Depfile.String()
538 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700539 if params.Output != nil {
540 bparams.Outputs = append(bparams.Outputs, params.Output.String())
541 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700542 if params.ImplicitOutput != nil {
543 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
544 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700545 if params.Input != nil {
546 bparams.Inputs = append(bparams.Inputs, params.Input.String())
547 }
548 if params.Implicit != nil {
549 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
550 }
551
Colin Cross6ff51382015-12-17 16:39:19 -0800552 if a.missingDeps != nil {
553 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
554 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
555 return
556 }
557
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700558 a.ModuleContext.Build(pctx, bparams)
559}
560
Colin Cross6ff51382015-12-17 16:39:19 -0800561func (a *androidModuleContext) GetMissingDependencies() []string {
562 return a.missingDeps
563}
564
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800565func (a *androidModuleContext) AddMissingDependencies(deps []string) {
566 if deps != nil {
567 a.missingDeps = append(a.missingDeps, deps...)
568 }
569}
570
Colin Crossa1ad8d12016-06-01 17:09:44 -0700571func (a *androidBaseContextImpl) Target() Target {
572 return a.target
573}
574
Colin Cross8b74d172016-09-13 09:59:14 -0700575func (a *androidBaseContextImpl) TargetPrimary() bool {
576 return a.targetPrimary
577}
578
Colin Crossf6566ed2015-03-24 11:13:38 -0700579func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700580 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800581}
582
Colin Crossa1ad8d12016-06-01 17:09:44 -0700583func (a *androidBaseContextImpl) Os() OsType {
584 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800585}
586
Colin Crossf6566ed2015-03-24 11:13:38 -0700587func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700588 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700589}
590
591func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700592 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700593}
594
Colin Cross0af4b842015-04-30 16:36:18 -0700595func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700596 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700597}
598
Colin Crossf6566ed2015-03-24 11:13:38 -0700599func (a *androidBaseContextImpl) Debug() bool {
600 return a.debug
601}
602
Colin Cross1e7d3702016-08-24 15:25:47 -0700603func (a *androidBaseContextImpl) PrimaryArch() bool {
604 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
605}
606
Colin Cross1332b002015-04-07 17:11:30 -0700607func (a *androidBaseContextImpl) AConfig() Config {
608 return a.config
609}
610
Colin Cross9272ade2016-08-17 15:24:12 -0700611func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
612 return DeviceConfig{a.config.deviceConfig}
613}
614
Colin Cross8d8f8e22016-08-03 11:57:50 -0700615func (a *androidModuleContext) Proprietary() bool {
616 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800617}
618
Colin Cross8d8f8e22016-08-03 11:57:50 -0700619func (a *androidModuleContext) InstallInData() bool {
620 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800621}
622
623func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700624 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700625
Dan Willemsen782a2d12015-12-21 14:55:28 -0800626 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700627 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800628
Colin Crossce75d2c2016-10-06 16:12:58 -0700629 if !a.module.base().commonProperties.SkipInstall &&
630 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
631
Dan Willemsen322acaf2016-01-12 23:07:05 -0800632 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700633
Colin Cross89562dc2016-10-03 17:47:19 -0700634 var implicitDeps, orderOnlyDeps Paths
635
636 if a.Host() {
637 // Installed host modules might be used during the build, depend directly on their
638 // dependencies so their timestamp is updated whenever their dependency is updated
639 implicitDeps = deps
640 } else {
641 orderOnlyDeps = deps
642 }
643
Dan Willemsen322acaf2016-01-12 23:07:05 -0800644 a.ModuleBuild(pctx, ModuleBuildParams{
645 Rule: Cp,
646 Output: fullInstallPath,
647 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700648 Implicits: implicitDeps,
649 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800650 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800651 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800652
Dan Willemsen322acaf2016-01-12 23:07:05 -0800653 a.installFiles = append(a.installFiles, fullInstallPath)
654 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700655 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700656 return fullInstallPath
657}
658
Colin Crossa2344662016-03-24 13:14:12 -0700659func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700660 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800661}
662
Colin Cross3854a602016-01-11 12:49:11 -0800663func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
664 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700665 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800666
Colin Crossce75d2c2016-10-06 16:12:58 -0700667 if !a.module.base().commonProperties.SkipInstall &&
668 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
669
Colin Cross12fc4972016-01-11 12:49:11 -0800670 a.ModuleBuild(pctx, ModuleBuildParams{
671 Rule: Symlink,
672 Output: fullInstallPath,
673 OrderOnly: Paths{srcPath},
674 Default: !a.AConfig().EmbeddedInMake(),
675 Args: map[string]string{
676 "fromPath": srcPath.String(),
677 },
678 })
Colin Cross3854a602016-01-11 12:49:11 -0800679
Colin Cross12fc4972016-01-11 12:49:11 -0800680 a.installFiles = append(a.installFiles, fullInstallPath)
681 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
682 }
Colin Cross3854a602016-01-11 12:49:11 -0800683 return fullInstallPath
684}
685
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700686func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800687 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
688}
689
Colin Cross3f40fa42015-01-30 17:27:36 -0800690type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700691 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800692}
693
694func isFileInstaller(m blueprint.Module) bool {
695 _, ok := m.(fileInstaller)
696 return ok
697}
698
699func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700700 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800701 return ok
702}
Colin Crossfce53272015-04-08 11:21:40 -0700703
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700704func findStringInSlice(str string, slice []string) int {
705 for i, s := range slice {
706 if s == str {
707 return i
Colin Crossfce53272015-04-08 11:21:40 -0700708 }
709 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700710 return -1
711}
712
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700713func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
714 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700715 for i, e := range excludes {
716 j := findStringInSlice(e, srcFiles)
717 if j != -1 {
718 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
719 }
720
721 excludes[i] = filepath.Join(prefix, e)
722 }
723
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700724 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700725 for _, s := range srcFiles {
Colin Cross7f19f372016-11-01 11:10:25 -0700726 if pathtools.IsGlob(s) {
727 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700728 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700729 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700730 }
731 }
732
733 return globbedSrcFiles
734}
735
Colin Cross7f19f372016-11-01 11:10:25 -0700736func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
737 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700738 if err != nil {
739 ctx.ModuleErrorf("glob: %s", err.Error())
740 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700741 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700742}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700743
Colin Cross463a90e2015-06-17 14:20:06 -0700744func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700745 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700746}
747
Colin Cross1f8c52b2015-06-16 16:38:17 -0700748func BuildTargetSingleton() blueprint.Singleton {
749 return &buildTargetSingleton{}
750}
751
752type buildTargetSingleton struct{}
753
754func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
755 checkbuildDeps := []string{}
756
757 dirModules := make(map[string][]string)
758
759 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700760 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700761 blueprintDir := a.base().blueprintDir
762 installTarget := a.base().installTarget
763 checkbuildTarget := a.base().checkbuildTarget
764
765 if checkbuildTarget != "" {
766 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
767 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
768 }
769
770 if installTarget != "" {
771 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
772 }
773 }
774 })
775
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800776 suffix := ""
777 if ctx.Config().(Config).EmbeddedInMake() {
778 suffix = "-soong"
779 }
780
Colin Cross1f8c52b2015-06-16 16:38:17 -0700781 // Create a top-level checkbuild target that depends on all modules
782 ctx.Build(pctx, blueprint.BuildParams{
783 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800784 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700785 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700786 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700787 })
788
789 // Create a mm/<directory> target that depends on all modules in a directory
790 dirs := sortedKeys(dirModules)
791 for _, dir := range dirs {
792 ctx.Build(pctx, blueprint.BuildParams{
793 Rule: blueprint.Phony,
794 Outputs: []string{filepath.Join("mm", dir)},
795 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800796 // HACK: checkbuild should be an optional build, but force it
797 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800798 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700799 })
800 }
801}
Colin Crossd779da42015-12-17 18:00:23 -0800802
803type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700804 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800805 ctx interface {
806 ModuleName(blueprint.Module) string
807 ModuleSubDir(blueprint.Module) string
808 }
809}
810
811func (s AndroidModulesByName) Len() int { return len(s.slice) }
812func (s AndroidModulesByName) Less(i, j int) bool {
813 mi, mj := s.slice[i], s.slice[j]
814 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
815
816 if ni != nj {
817 return ni < nj
818 } else {
819 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
820 }
821}
822func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }