blob: aaaa2fbf2bfe978db2961691cb5151e458b4de19 [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
Dan Willemsen0effe062015-11-30 16:06:01 -080022 "android/soong"
Colin Cross8f101b42015-06-17 15:09:06 -070023 "android/soong/glob"
24
Colin Crossf6566ed2015-03-24 11:13:38 -070025 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080026)
27
Colin Crossa120ec12016-08-19 16:07:38 -070028func init() {
29 RegisterTopDownMutator("customizer", customizerMutator).Parallel()
30 RegisterBottomUpMutator("defaults_deps", defaultsDepsMutator).Parallel()
31 RegisterTopDownMutator("defaults", defaultsMutator).Parallel()
32
33 RegisterBottomUpMutator("arch", ArchMutator).Parallel()
34}
35
Colin Cross3f40fa42015-01-30 17:27:36 -080036var (
37 DeviceSharedLibrary = "shared_library"
38 DeviceStaticLibrary = "static_library"
39 DeviceExecutable = "executable"
40 HostSharedLibrary = "host_shared_library"
41 HostStaticLibrary = "host_static_library"
42 HostExecutable = "host_executable"
43)
44
Dan Willemsen34cc69e2015-09-23 15:26:20 -070045type ModuleBuildParams struct {
46 Rule blueprint.Rule
47 Output WritablePath
48 Outputs WritablePaths
49 Input Path
50 Inputs Paths
51 Implicit Path
52 Implicits Paths
53 OrderOnly Paths
54 Default bool
55 Args map[string]string
56}
57
Colin Crossf6566ed2015-03-24 11:13:38 -070058type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070059 Target() Target
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070061 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070062 Host() bool
63 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070064 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070065 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070066 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070067 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070068 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070069}
70
Colin Cross635c3b02016-05-18 15:37:25 -070071type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070072 blueprint.BaseModuleContext
73 androidBaseContext
74}
75
Colin Cross635c3b02016-05-18 15:37:25 -070076type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080077 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070078 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080079
Dan Willemsen34cc69e2015-09-23 15:26:20 -070080 // Similar to Build, but takes Paths instead of []string,
81 // and performs more verification.
82 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070083
Dan Willemsen34cc69e2015-09-23 15:26:20 -070084 ExpandSources(srcFiles, excludes []string) Paths
85 Glob(outDir, globPattern string, excludes []string) Paths
86
Colin Crossa2344662016-03-24 13:14:12 -070087 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
88 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080089 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070090 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080091
92 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070093
94 Proprietary() bool
95 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080096}
97
Colin Cross635c3b02016-05-18 15:37:25 -070098type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080099 blueprint.Module
100
Colin Cross635c3b02016-05-18 15:37:25 -0700101 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800102
Colin Cross635c3b02016-05-18 15:37:25 -0700103 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800104 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700105 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800106 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800107}
108
Colin Cross3f40fa42015-01-30 17:27:36 -0800109type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700110 Name string
111 Deps []string
112 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800113
Dan Willemsen0effe062015-11-30 16:06:01 -0800114 // emit build rules for this module
115 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800116
Colin Cross7d5136f2015-05-11 13:39:40 -0700117 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800118 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
119 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
120 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700121 Compile_multilib string `android:"arch_variant"`
122
123 Target struct {
124 Host struct {
125 Compile_multilib string
126 }
127 Android struct {
128 Compile_multilib string
129 }
130 }
131
132 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800133
Dan Willemsen782a2d12015-12-21 14:55:28 -0800134 // whether this is a proprietary vendor module, and should be installed into /vendor
135 Proprietary bool
136
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700137 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
138 // file
139 Logtags []string
140
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700141 // init.rc files to be installed if this module is installed
142 Init_rc []string
143
Chris Wolfe998306e2016-08-15 14:47:23 -0400144 // names of other modules to install if this module is installed
145 Required []string
146
Colin Crossa1ad8d12016-06-01 17:09:44 -0700147 // Set by TargetMutator
148 CompileTarget Target `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800149
150 // Set by InitAndroidModule
151 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
152}
153
154type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700155 Host_supported *bool
156 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800157}
158
Colin Crossc472d572015-03-17 15:06:21 -0700159type Multilib string
160
161const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700162 MultilibBoth Multilib = "both"
163 MultilibFirst Multilib = "first"
164 MultilibCommon Multilib = "common"
165 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700166)
167
Colin Crossa1ad8d12016-06-01 17:09:44 -0700168type HostOrDeviceSupported int
169
170const (
171 _ HostOrDeviceSupported = iota
172 HostSupported
173 DeviceSupported
174 HostAndDeviceSupported
175 HostAndDeviceDefault
176)
177
Colin Cross635c3b02016-05-18 15:37:25 -0700178func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800179 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
180
181 base := m.base()
182 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700183
Colin Cross7f64b6d2015-07-09 13:57:48 -0700184 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700185
186 return m, propertyStructs
187}
188
Colin Cross635c3b02016-05-18 15:37:25 -0700189func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700190 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
191
192 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
193
194 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800195 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700196 base.commonProperties.Default_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800197
Dan Willemsen218f6562015-07-08 18:13:11 -0700198 switch hod {
199 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800200 // Default to module to device supported, host not supported, can override in module
201 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700202 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700203 fallthrough
204 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800205 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
206 }
207
Colin Crosscfad1192015-11-02 16:43:11 -0800208 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800209}
210
Colin Crossa120ec12016-08-19 16:07:38 -0700211func AddCustomizer(m blueprint.Module, c PropertyCustomizer) {
212 base := m.(Module).base()
213 base.customizers = append(base.customizers, c)
214}
215
Colin Cross3f40fa42015-01-30 17:27:36 -0800216// A AndroidModuleBase object contains the properties that are common to all Android
217// modules. It should be included as an anonymous field in every module
218// struct definition. InitAndroidModule should then be called from the module's
219// factory function, and the return values from InitAndroidModule should be
220// returned from the factory function.
221//
222// The AndroidModuleBase type is responsible for implementing the
223// GenerateBuildActions method to support the blueprint.Module interface. This
224// method will then call the module's GenerateAndroidBuildActions method once
225// for each build variant that is to be built. GenerateAndroidBuildActions is
226// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
227// AndroidModuleContext exposes extra functionality specific to the Android build
228// system including details about the particular build variant that is to be
229// generated.
230//
231// For example:
232//
233// import (
234// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700235// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800236// )
237//
238// type myModule struct {
239// common.AndroidModuleBase
240// properties struct {
241// MyProperty string
242// }
243// }
244//
245// func NewMyModule() (blueprint.Module, []interface{}) {
246// m := &myModule{}
247// return common.InitAndroidModule(m, &m.properties)
248// }
249//
250// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
251// // Get the CPU architecture for the current build variant.
252// variantArch := ctx.Arch()
253//
254// // ...
255// }
Colin Cross635c3b02016-05-18 15:37:25 -0700256type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800257 // Putting the curiously recurring thing pointing to the thing that contains
258 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700259 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800260
261 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700262 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800263 hostAndDeviceProperties hostAndDeviceProperties
264 generalProperties []interface{}
265 archProperties []*archProperties
Colin Crossa120ec12016-08-19 16:07:38 -0700266 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800267
268 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700269 installFiles Paths
270 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700271
272 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
273 // Only set on the final variant of each module
274 installTarget string
275 checkbuildTarget string
276 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700277
278 customizers []PropertyCustomizer
Colin Cross3f40fa42015-01-30 17:27:36 -0800279}
280
Colin Cross635c3b02016-05-18 15:37:25 -0700281func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800282 return a
283}
284
Colin Crossa1ad8d12016-06-01 17:09:44 -0700285func (a *ModuleBase) SetTarget(target Target) {
286 a.commonProperties.CompileTarget = target
Colin Crossd3ba0392015-05-07 14:11:29 -0700287}
288
Colin Crossa1ad8d12016-06-01 17:09:44 -0700289func (a *ModuleBase) Target() Target {
290 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800291}
292
Colin Crossa1ad8d12016-06-01 17:09:44 -0700293func (a *ModuleBase) Os() OsType {
294 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800295}
296
Colin Cross635c3b02016-05-18 15:37:25 -0700297func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700298 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800299}
300
Colin Cross635c3b02016-05-18 15:37:25 -0700301func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700302 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800303}
304
Colin Crossa1ad8d12016-06-01 17:09:44 -0700305func (a *ModuleBase) OsClassSupported() []OsClass {
306 switch a.commonProperties.HostOrDeviceSupported {
307 case HostSupported:
308 // TODO(ccross): explicitly mark host cross support
309 return []OsClass{Host, HostCross}
310 case DeviceSupported:
311 return []OsClass{Device}
312 case HostAndDeviceSupported:
313 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700314 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700315 supported = append(supported, Host, HostCross)
316 }
Colin Crossa4190c12016-07-12 13:11:25 -0700317 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700318 supported = append(supported, Device)
319 }
320 return supported
321 default:
322 return nil
323 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800324}
325
Colin Cross635c3b02016-05-18 15:37:25 -0700326func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800327 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
328 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700329 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800330}
331
Colin Cross635c3b02016-05-18 15:37:25 -0700332func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800333 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700334 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800335 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800336 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800337}
338
Colin Cross635c3b02016-05-18 15:37:25 -0700339func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700340 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800341
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700342 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800343 ctx.VisitDepsDepthFirstIf(isFileInstaller,
344 func(m blueprint.Module) {
345 fileInstaller := m.(fileInstaller)
346 files := fileInstaller.filesToInstall()
347 result = append(result, files...)
348 })
349
350 return result
351}
352
Colin Cross635c3b02016-05-18 15:37:25 -0700353func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800354 return a.installFiles
355}
356
Colin Cross635c3b02016-05-18 15:37:25 -0700357func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800358 return p.noAddressSanitizer
359}
360
Colin Cross635c3b02016-05-18 15:37:25 -0700361func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800362 return false
363}
364
Colin Cross635c3b02016-05-18 15:37:25 -0700365func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
366 if a != ctx.FinalModule().(Module).base() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800367 return
368 }
369
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700370 allInstalledFiles := Paths{}
371 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800372 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700373 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700374 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
375 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800376 })
377
Colin Cross9454bfa2015-03-17 13:24:18 -0700378 deps := []string{}
379
Colin Cross3f40fa42015-01-30 17:27:36 -0800380 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700381 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700383 Rule: blueprint.Phony,
384 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700385 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800386 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700387 })
388 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700389 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700390 }
391
392 if len(allCheckbuildFiles) > 0 {
393 name := ctx.ModuleName() + "-checkbuild"
394 ctx.Build(pctx, blueprint.BuildParams{
395 Rule: blueprint.Phony,
396 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700397 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700398 Optional: true,
399 })
400 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700401 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700402 }
403
404 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800405 suffix := ""
406 if ctx.Config().(Config).EmbeddedInMake() {
407 suffix = "-soong"
408 }
409
Colin Cross9454bfa2015-03-17 13:24:18 -0700410 ctx.Build(pctx, blueprint.BuildParams{
411 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800412 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700413 Implicits: deps,
414 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800415 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700416
417 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800418 }
419}
420
Colin Cross635c3b02016-05-18 15:37:25 -0700421func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700422 return androidBaseContextImpl{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700423 target: a.commonProperties.CompileTarget,
424 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800425 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800426}
427
Colin Cross635c3b02016-05-18 15:37:25 -0700428func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800429 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700430 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700431 ModuleContext: ctx,
432 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
433 installDeps: a.computeInstallDeps(ctx),
434 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800435 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800436 }
437
Dan Willemsen0effe062015-11-30 16:06:01 -0800438 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800439 return
440 }
441
442 a.module.GenerateAndroidBuildActions(androidCtx)
443 if ctx.Failed() {
444 return
445 }
446
Colin Crossc9404352015-03-26 16:10:12 -0700447 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
448 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
449
Colin Cross3f40fa42015-01-30 17:27:36 -0800450 a.generateModuleTarget(ctx)
451 if ctx.Failed() {
452 return
453 }
454}
455
Colin Crossf6566ed2015-03-24 11:13:38 -0700456type androidBaseContextImpl struct {
Colin Cross8d8f8e22016-08-03 11:57:50 -0700457 target Target
458 debug bool
459 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700460}
461
Colin Cross3f40fa42015-01-30 17:27:36 -0800462type androidModuleContext struct {
463 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700464 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700465 installDeps Paths
466 installFiles Paths
467 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800468 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700469 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800470}
471
472func (a *androidModuleContext) ninjaError(outputs []string, err error) {
473 a.ModuleContext.Build(pctx, blueprint.BuildParams{
474 Rule: ErrorRule,
475 Outputs: outputs,
476 Optional: true,
477 Args: map[string]string{
478 "error": err.Error(),
479 },
480 })
481 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800482}
483
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800484func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700485 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800486 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
487 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
488 return
489 }
490
Colin Cross3f40fa42015-01-30 17:27:36 -0800491 params.Optional = true
492 a.ModuleContext.Build(pctx, params)
493}
494
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700495func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
496 bparams := blueprint.BuildParams{
497 Rule: params.Rule,
498 Outputs: params.Outputs.Strings(),
499 Inputs: params.Inputs.Strings(),
500 Implicits: params.Implicits.Strings(),
501 OrderOnly: params.OrderOnly.Strings(),
502 Args: params.Args,
503 Optional: !params.Default,
504 }
505
506 if params.Output != nil {
507 bparams.Outputs = append(bparams.Outputs, params.Output.String())
508 }
509 if params.Input != nil {
510 bparams.Inputs = append(bparams.Inputs, params.Input.String())
511 }
512 if params.Implicit != nil {
513 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
514 }
515
Colin Cross6ff51382015-12-17 16:39:19 -0800516 if a.missingDeps != nil {
517 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
518 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
519 return
520 }
521
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700522 a.ModuleContext.Build(pctx, bparams)
523}
524
Colin Cross6ff51382015-12-17 16:39:19 -0800525func (a *androidModuleContext) GetMissingDependencies() []string {
526 return a.missingDeps
527}
528
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800529func (a *androidModuleContext) AddMissingDependencies(deps []string) {
530 if deps != nil {
531 a.missingDeps = append(a.missingDeps, deps...)
532 }
533}
534
Colin Crossa1ad8d12016-06-01 17:09:44 -0700535func (a *androidBaseContextImpl) Target() Target {
536 return a.target
537}
538
Colin Crossf6566ed2015-03-24 11:13:38 -0700539func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700540 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800541}
542
Colin Crossa1ad8d12016-06-01 17:09:44 -0700543func (a *androidBaseContextImpl) Os() OsType {
544 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800545}
546
Colin Crossf6566ed2015-03-24 11:13:38 -0700547func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700548 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700549}
550
551func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700552 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700553}
554
Colin Cross0af4b842015-04-30 16:36:18 -0700555func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700556 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700557}
558
Colin Crossf6566ed2015-03-24 11:13:38 -0700559func (a *androidBaseContextImpl) Debug() bool {
560 return a.debug
561}
562
Colin Cross1e7d3702016-08-24 15:25:47 -0700563func (a *androidBaseContextImpl) PrimaryArch() bool {
564 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
565}
566
Colin Cross1332b002015-04-07 17:11:30 -0700567func (a *androidBaseContextImpl) AConfig() Config {
568 return a.config
569}
570
Colin Cross9272ade2016-08-17 15:24:12 -0700571func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
572 return DeviceConfig{a.config.deviceConfig}
573}
574
Colin Cross8d8f8e22016-08-03 11:57:50 -0700575func (a *androidModuleContext) Proprietary() bool {
576 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800577}
578
Colin Cross8d8f8e22016-08-03 11:57:50 -0700579func (a *androidModuleContext) InstallInData() bool {
580 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800581}
582
583func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700584 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700585
Dan Willemsen782a2d12015-12-21 14:55:28 -0800586 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800587
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800588 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800589 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700590
Dan Willemsen322acaf2016-01-12 23:07:05 -0800591 a.ModuleBuild(pctx, ModuleBuildParams{
592 Rule: Cp,
593 Output: fullInstallPath,
594 Input: srcPath,
595 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800596 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800597 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800598
Dan Willemsen322acaf2016-01-12 23:07:05 -0800599 a.installFiles = append(a.installFiles, fullInstallPath)
600 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700601 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700602 return fullInstallPath
603}
604
Colin Crossa2344662016-03-24 13:14:12 -0700605func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700606 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800607}
608
Colin Cross3854a602016-01-11 12:49:11 -0800609func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
610 fullInstallPath := installPath.Join(a, name)
611
Colin Cross12fc4972016-01-11 12:49:11 -0800612 if a.Host() || !a.AConfig().SkipDeviceInstall() {
613 a.ModuleBuild(pctx, ModuleBuildParams{
614 Rule: Symlink,
615 Output: fullInstallPath,
616 OrderOnly: Paths{srcPath},
617 Default: !a.AConfig().EmbeddedInMake(),
618 Args: map[string]string{
619 "fromPath": srcPath.String(),
620 },
621 })
Colin Cross3854a602016-01-11 12:49:11 -0800622
Colin Cross12fc4972016-01-11 12:49:11 -0800623 a.installFiles = append(a.installFiles, fullInstallPath)
624 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
625 }
Colin Cross3854a602016-01-11 12:49:11 -0800626 return fullInstallPath
627}
628
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700629func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800630 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
631}
632
Colin Cross3f40fa42015-01-30 17:27:36 -0800633type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700634 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800635}
636
637func isFileInstaller(m blueprint.Module) bool {
638 _, ok := m.(fileInstaller)
639 return ok
640}
641
642func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700643 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800644 return ok
645}
Colin Crossfce53272015-04-08 11:21:40 -0700646
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700647func findStringInSlice(str string, slice []string) int {
648 for i, s := range slice {
649 if s == str {
650 return i
Colin Crossfce53272015-04-08 11:21:40 -0700651 }
652 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700653 return -1
654}
655
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700656func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
657 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700658 for i, e := range excludes {
659 j := findStringInSlice(e, srcFiles)
660 if j != -1 {
661 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
662 }
663
664 excludes[i] = filepath.Join(prefix, e)
665 }
666
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700667 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700668 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700669 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700670 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700671 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700672 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700673 }
674 }
675
676 return globbedSrcFiles
677}
678
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700679func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
680 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700681 if err != nil {
682 ctx.ModuleErrorf("glob: %s", err.Error())
683 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700684 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700685}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700686
Colin Cross463a90e2015-06-17 14:20:06 -0700687func init() {
688 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
689}
690
Colin Cross1f8c52b2015-06-16 16:38:17 -0700691func BuildTargetSingleton() blueprint.Singleton {
692 return &buildTargetSingleton{}
693}
694
695type buildTargetSingleton struct{}
696
697func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
698 checkbuildDeps := []string{}
699
700 dirModules := make(map[string][]string)
701
702 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700703 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700704 blueprintDir := a.base().blueprintDir
705 installTarget := a.base().installTarget
706 checkbuildTarget := a.base().checkbuildTarget
707
708 if checkbuildTarget != "" {
709 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
710 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
711 }
712
713 if installTarget != "" {
714 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
715 }
716 }
717 })
718
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800719 suffix := ""
720 if ctx.Config().(Config).EmbeddedInMake() {
721 suffix = "-soong"
722 }
723
Colin Cross1f8c52b2015-06-16 16:38:17 -0700724 // Create a top-level checkbuild target that depends on all modules
725 ctx.Build(pctx, blueprint.BuildParams{
726 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800727 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700728 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700729 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700730 })
731
732 // Create a mm/<directory> target that depends on all modules in a directory
733 dirs := sortedKeys(dirModules)
734 for _, dir := range dirs {
735 ctx.Build(pctx, blueprint.BuildParams{
736 Rule: blueprint.Phony,
737 Outputs: []string{filepath.Join("mm", dir)},
738 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800739 // HACK: checkbuild should be an optional build, but force it
740 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800741 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700742 })
743 }
744}
Colin Crossd779da42015-12-17 18:00:23 -0800745
746type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700747 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800748 ctx interface {
749 ModuleName(blueprint.Module) string
750 ModuleSubDir(blueprint.Module) string
751 }
752}
753
754func (s AndroidModulesByName) Len() int { return len(s.slice) }
755func (s AndroidModulesByName) Less(i, j int) bool {
756 mi, mj := s.slice[i], s.slice[j]
757 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
758
759 if ni != nj {
760 return ni < nj
761 } else {
762 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
763 }
764}
765func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }