blob: d6eee44686fdfeba2c98db983c0ebe54b0cb91a4 [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
Colin Cross8f101b42015-06-17 15:09:06 -070022 "android/soong/glob"
23
Colin Crossf6566ed2015-03-24 11:13:38 -070024 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080025)
26
Colin Crossa120ec12016-08-19 16:07:38 -070027func init() {
Colin Cross178a5092016-09-13 13:42:32 -070028 RegisterTopDownMutator("load_hooks", loadHookMutator).Parallel()
Colin Crossa120ec12016-08-19 16:07:38 -070029 RegisterBottomUpMutator("defaults_deps", defaultsDepsMutator).Parallel()
30 RegisterTopDownMutator("defaults", defaultsMutator).Parallel()
31
32 RegisterBottomUpMutator("arch", ArchMutator).Parallel()
Colin Cross178a5092016-09-13 13:42:32 -070033 RegisterTopDownMutator("arch_hooks", archHookMutator).Parallel()
Colin Crossa120ec12016-08-19 16:07:38 -070034}
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 Cross8b74d172016-09-13 09:59:14 -070060 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070061 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070062 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070063 Host() bool
64 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070065 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070066 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070067 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070068 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070069 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070070}
71
Colin Cross635c3b02016-05-18 15:37:25 -070072type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070073 blueprint.BaseModuleContext
74 androidBaseContext
75}
76
Colin Cross635c3b02016-05-18 15:37:25 -070077type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080078 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070079 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080080
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081 // Similar to Build, but takes Paths instead of []string,
82 // and performs more verification.
83 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070084
Dan Willemsen34cc69e2015-09-23 15:26:20 -070085 ExpandSources(srcFiles, excludes []string) Paths
86 Glob(outDir, globPattern string, excludes []string) Paths
87
Colin Crossa2344662016-03-24 13:14:12 -070088 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
89 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080090 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070091 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080092
93 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070094
95 Proprietary() bool
96 InstallInData() bool
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 Cross3f40fa42015-01-30 17:27:36 -0800103
Colin Cross635c3b02016-05-18 15:37:25 -0700104 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800105 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700106 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800107 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800108}
109
Colin Cross3f40fa42015-01-30 17:27:36 -0800110type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700111 Name string
112 Deps []string
113 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800114
Dan Willemsen0effe062015-11-30 16:06:01 -0800115 // emit build rules for this module
116 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800117
Colin Cross7d5136f2015-05-11 13:39:40 -0700118 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800119 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
120 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
121 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700122 Compile_multilib string `android:"arch_variant"`
123
124 Target struct {
125 Host struct {
126 Compile_multilib string
127 }
128 Android struct {
129 Compile_multilib string
130 }
131 }
132
133 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800134
Dan Willemsen782a2d12015-12-21 14:55:28 -0800135 // whether this is a proprietary vendor module, and should be installed into /vendor
136 Proprietary bool
137
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700138 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
139 // file
140 Logtags []string
141
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700142 // init.rc files to be installed if this module is installed
143 Init_rc []string
144
Chris Wolfe998306e2016-08-15 14:47:23 -0400145 // names of other modules to install if this module is installed
146 Required []string
147
Colin Crossa1ad8d12016-06-01 17:09:44 -0700148 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700149 CompileTarget Target `blueprint:"mutated"`
150 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800151
152 // Set by InitAndroidModule
153 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700154 ArchSpecific 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
176 DeviceSupported
177 HostAndDeviceSupported
178 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700179 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700180)
181
Colin Cross635c3b02016-05-18 15:37:25 -0700182func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800183 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
184
185 base := m.base()
186 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700187
Colin Cross7f64b6d2015-07-09 13:57:48 -0700188 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700189
190 return m, propertyStructs
191}
192
Colin Cross635c3b02016-05-18 15:37:25 -0700193func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700194 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
195
196 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
197
198 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800199 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700200 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700201 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800202
Dan Willemsen218f6562015-07-08 18:13:11 -0700203 switch hod {
204 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800205 // Default to module to device supported, host not supported, can override in module
206 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700207 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700208 fallthrough
209 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800210 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
211 }
212
Colin Crosscfad1192015-11-02 16:43:11 -0800213 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800214}
215
216// 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{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700265 archProperties []interface{}
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
Colin Cross178a5092016-09-13 13:42:32 -0700278 hooks hooks
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 Cross8b74d172016-09-13 09:59:14 -0700285func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700286 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700287 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700288}
289
Colin Crossa1ad8d12016-06-01 17:09:44 -0700290func (a *ModuleBase) Target() Target {
291 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800292}
293
Colin Cross8b74d172016-09-13 09:59:14 -0700294func (a *ModuleBase) TargetPrimary() bool {
295 return a.commonProperties.CompilePrimary
296}
297
Colin Crossa1ad8d12016-06-01 17:09:44 -0700298func (a *ModuleBase) Os() OsType {
299 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800300}
301
Colin Cross635c3b02016-05-18 15:37:25 -0700302func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700303 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800304}
305
Colin Cross635c3b02016-05-18 15:37:25 -0700306func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700307 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800308}
309
Dan Willemsen0b24c742016-10-04 15:13:37 -0700310func (a *ModuleBase) ArchSpecific() bool {
311 return a.commonProperties.ArchSpecific
312}
313
Colin Crossa1ad8d12016-06-01 17:09:44 -0700314func (a *ModuleBase) OsClassSupported() []OsClass {
315 switch a.commonProperties.HostOrDeviceSupported {
316 case HostSupported:
317 // TODO(ccross): explicitly mark host cross support
318 return []OsClass{Host, HostCross}
319 case DeviceSupported:
320 return []OsClass{Device}
321 case HostAndDeviceSupported:
322 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700323 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700324 supported = append(supported, Host, HostCross)
325 }
Colin Crossa4190c12016-07-12 13:11:25 -0700326 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700327 supported = append(supported, Device)
328 }
329 return supported
330 default:
331 return nil
332 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800333}
334
Colin Cross635c3b02016-05-18 15:37:25 -0700335func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800336 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
337 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700338 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800339}
340
Colin Cross635c3b02016-05-18 15:37:25 -0700341func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800342 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700343 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800344 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800345 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800346}
347
Colin Cross635c3b02016-05-18 15:37:25 -0700348func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700349 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800350
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700351 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800352 ctx.VisitDepsDepthFirstIf(isFileInstaller,
353 func(m blueprint.Module) {
354 fileInstaller := m.(fileInstaller)
355 files := fileInstaller.filesToInstall()
356 result = append(result, files...)
357 })
358
359 return result
360}
361
Colin Cross635c3b02016-05-18 15:37:25 -0700362func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800363 return a.installFiles
364}
365
Colin Cross635c3b02016-05-18 15:37:25 -0700366func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800367 return p.noAddressSanitizer
368}
369
Colin Cross635c3b02016-05-18 15:37:25 -0700370func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800371 return false
372}
373
Colin Cross635c3b02016-05-18 15:37:25 -0700374func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700375 allInstalledFiles := Paths{}
376 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800377 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700378 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700379 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
380 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800381 })
382
Colin Cross9454bfa2015-03-17 13:24:18 -0700383 deps := []string{}
384
Colin Cross3f40fa42015-01-30 17:27:36 -0800385 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700386 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800387 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700388 Rule: blueprint.Phony,
389 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700390 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800391 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700392 })
393 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700394 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700395 }
396
397 if len(allCheckbuildFiles) > 0 {
398 name := ctx.ModuleName() + "-checkbuild"
399 ctx.Build(pctx, blueprint.BuildParams{
400 Rule: blueprint.Phony,
401 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700402 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700403 Optional: true,
404 })
405 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700406 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700407 }
408
409 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800410 suffix := ""
411 if ctx.Config().(Config).EmbeddedInMake() {
412 suffix = "-soong"
413 }
414
Colin Cross9454bfa2015-03-17 13:24:18 -0700415 ctx.Build(pctx, blueprint.BuildParams{
416 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800417 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700418 Implicits: deps,
419 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800420 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700421
422 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800423 }
424}
425
Colin Cross635c3b02016-05-18 15:37:25 -0700426func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700427 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700428 target: a.commonProperties.CompileTarget,
429 targetPrimary: a.commonProperties.CompilePrimary,
430 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800431 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800432}
433
Colin Cross635c3b02016-05-18 15:37:25 -0700434func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800435 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700436 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700437 ModuleContext: ctx,
438 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
439 installDeps: a.computeInstallDeps(ctx),
440 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800441 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800442 }
443
Colin Cross9b1d13d2016-09-19 15:18:11 -0700444 if a.Enabled() {
445 a.module.GenerateAndroidBuildActions(androidCtx)
446 if ctx.Failed() {
447 return
448 }
449
450 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
451 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800452 }
453
Colin Cross9b1d13d2016-09-19 15:18:11 -0700454 if a == ctx.FinalModule().(Module).base() {
455 a.generateModuleTarget(ctx)
456 if ctx.Failed() {
457 return
458 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800459 }
460}
461
Colin Crossf6566ed2015-03-24 11:13:38 -0700462type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700463 target Target
464 targetPrimary bool
465 debug bool
466 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700467}
468
Colin Cross3f40fa42015-01-30 17:27:36 -0800469type androidModuleContext struct {
470 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700471 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700472 installDeps Paths
473 installFiles Paths
474 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800475 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700476 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800477}
478
479func (a *androidModuleContext) ninjaError(outputs []string, err error) {
480 a.ModuleContext.Build(pctx, blueprint.BuildParams{
481 Rule: ErrorRule,
482 Outputs: outputs,
483 Optional: true,
484 Args: map[string]string{
485 "error": err.Error(),
486 },
487 })
488 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800489}
490
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800491func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700492 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800493 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
494 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
495 return
496 }
497
Colin Cross3f40fa42015-01-30 17:27:36 -0800498 params.Optional = true
499 a.ModuleContext.Build(pctx, params)
500}
501
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700502func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
503 bparams := blueprint.BuildParams{
504 Rule: params.Rule,
505 Outputs: params.Outputs.Strings(),
506 Inputs: params.Inputs.Strings(),
507 Implicits: params.Implicits.Strings(),
508 OrderOnly: params.OrderOnly.Strings(),
509 Args: params.Args,
510 Optional: !params.Default,
511 }
512
513 if params.Output != nil {
514 bparams.Outputs = append(bparams.Outputs, params.Output.String())
515 }
516 if params.Input != nil {
517 bparams.Inputs = append(bparams.Inputs, params.Input.String())
518 }
519 if params.Implicit != nil {
520 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
521 }
522
Colin Cross6ff51382015-12-17 16:39:19 -0800523 if a.missingDeps != nil {
524 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
525 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
526 return
527 }
528
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700529 a.ModuleContext.Build(pctx, bparams)
530}
531
Colin Cross6ff51382015-12-17 16:39:19 -0800532func (a *androidModuleContext) GetMissingDependencies() []string {
533 return a.missingDeps
534}
535
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800536func (a *androidModuleContext) AddMissingDependencies(deps []string) {
537 if deps != nil {
538 a.missingDeps = append(a.missingDeps, deps...)
539 }
540}
541
Colin Crossa1ad8d12016-06-01 17:09:44 -0700542func (a *androidBaseContextImpl) Target() Target {
543 return a.target
544}
545
Colin Cross8b74d172016-09-13 09:59:14 -0700546func (a *androidBaseContextImpl) TargetPrimary() bool {
547 return a.targetPrimary
548}
549
Colin Crossf6566ed2015-03-24 11:13:38 -0700550func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700551 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800552}
553
Colin Crossa1ad8d12016-06-01 17:09:44 -0700554func (a *androidBaseContextImpl) Os() OsType {
555 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800556}
557
Colin Crossf6566ed2015-03-24 11:13:38 -0700558func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700559 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700560}
561
562func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700563 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700564}
565
Colin Cross0af4b842015-04-30 16:36:18 -0700566func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700567 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700568}
569
Colin Crossf6566ed2015-03-24 11:13:38 -0700570func (a *androidBaseContextImpl) Debug() bool {
571 return a.debug
572}
573
Colin Cross1e7d3702016-08-24 15:25:47 -0700574func (a *androidBaseContextImpl) PrimaryArch() bool {
575 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
576}
577
Colin Cross1332b002015-04-07 17:11:30 -0700578func (a *androidBaseContextImpl) AConfig() Config {
579 return a.config
580}
581
Colin Cross9272ade2016-08-17 15:24:12 -0700582func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
583 return DeviceConfig{a.config.deviceConfig}
584}
585
Colin Cross8d8f8e22016-08-03 11:57:50 -0700586func (a *androidModuleContext) Proprietary() bool {
587 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800588}
589
Colin Cross8d8f8e22016-08-03 11:57:50 -0700590func (a *androidModuleContext) InstallInData() bool {
591 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800592}
593
594func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700595 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700596
Dan Willemsen782a2d12015-12-21 14:55:28 -0800597 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700598 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800599
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800600 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800601 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700602
Colin Cross89562dc2016-10-03 17:47:19 -0700603 var implicitDeps, orderOnlyDeps Paths
604
605 if a.Host() {
606 // Installed host modules might be used during the build, depend directly on their
607 // dependencies so their timestamp is updated whenever their dependency is updated
608 implicitDeps = deps
609 } else {
610 orderOnlyDeps = deps
611 }
612
Dan Willemsen322acaf2016-01-12 23:07:05 -0800613 a.ModuleBuild(pctx, ModuleBuildParams{
614 Rule: Cp,
615 Output: fullInstallPath,
616 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700617 Implicits: implicitDeps,
618 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800619 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800620 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800621
Dan Willemsen322acaf2016-01-12 23:07:05 -0800622 a.installFiles = append(a.installFiles, fullInstallPath)
623 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700624 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700625 return fullInstallPath
626}
627
Colin Crossa2344662016-03-24 13:14:12 -0700628func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700629 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800630}
631
Colin Cross3854a602016-01-11 12:49:11 -0800632func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
633 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700634 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800635
Colin Cross12fc4972016-01-11 12:49:11 -0800636 if a.Host() || !a.AConfig().SkipDeviceInstall() {
637 a.ModuleBuild(pctx, ModuleBuildParams{
638 Rule: Symlink,
639 Output: fullInstallPath,
640 OrderOnly: Paths{srcPath},
641 Default: !a.AConfig().EmbeddedInMake(),
642 Args: map[string]string{
643 "fromPath": srcPath.String(),
644 },
645 })
Colin Cross3854a602016-01-11 12:49:11 -0800646
Colin Cross12fc4972016-01-11 12:49:11 -0800647 a.installFiles = append(a.installFiles, fullInstallPath)
648 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
649 }
Colin Cross3854a602016-01-11 12:49:11 -0800650 return fullInstallPath
651}
652
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700653func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800654 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
655}
656
Colin Cross3f40fa42015-01-30 17:27:36 -0800657type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700658 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800659}
660
661func isFileInstaller(m blueprint.Module) bool {
662 _, ok := m.(fileInstaller)
663 return ok
664}
665
666func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700667 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800668 return ok
669}
Colin Crossfce53272015-04-08 11:21:40 -0700670
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700671func findStringInSlice(str string, slice []string) int {
672 for i, s := range slice {
673 if s == str {
674 return i
Colin Crossfce53272015-04-08 11:21:40 -0700675 }
676 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700677 return -1
678}
679
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700680func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
681 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700682 for i, e := range excludes {
683 j := findStringInSlice(e, srcFiles)
684 if j != -1 {
685 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
686 }
687
688 excludes[i] = filepath.Join(prefix, e)
689 }
690
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700691 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700692 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700693 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700694 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700695 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700696 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700697 }
698 }
699
700 return globbedSrcFiles
701}
702
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700703func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
704 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700705 if err != nil {
706 ctx.ModuleErrorf("glob: %s", err.Error())
707 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700708 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700709}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700710
Colin Cross463a90e2015-06-17 14:20:06 -0700711func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700712 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700713}
714
Colin Cross1f8c52b2015-06-16 16:38:17 -0700715func BuildTargetSingleton() blueprint.Singleton {
716 return &buildTargetSingleton{}
717}
718
719type buildTargetSingleton struct{}
720
721func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
722 checkbuildDeps := []string{}
723
724 dirModules := make(map[string][]string)
725
726 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700727 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700728 blueprintDir := a.base().blueprintDir
729 installTarget := a.base().installTarget
730 checkbuildTarget := a.base().checkbuildTarget
731
732 if checkbuildTarget != "" {
733 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
734 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
735 }
736
737 if installTarget != "" {
738 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
739 }
740 }
741 })
742
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800743 suffix := ""
744 if ctx.Config().(Config).EmbeddedInMake() {
745 suffix = "-soong"
746 }
747
Colin Cross1f8c52b2015-06-16 16:38:17 -0700748 // Create a top-level checkbuild target that depends on all modules
749 ctx.Build(pctx, blueprint.BuildParams{
750 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800751 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700752 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700753 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700754 })
755
756 // Create a mm/<directory> target that depends on all modules in a directory
757 dirs := sortedKeys(dirModules)
758 for _, dir := range dirs {
759 ctx.Build(pctx, blueprint.BuildParams{
760 Rule: blueprint.Phony,
761 Outputs: []string{filepath.Join("mm", dir)},
762 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800763 // HACK: checkbuild should be an optional build, but force it
764 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800765 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700766 })
767 }
768}
Colin Crossd779da42015-12-17 18:00:23 -0800769
770type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700771 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800772 ctx interface {
773 ModuleName(blueprint.Module) string
774 ModuleSubDir(blueprint.Module) string
775 }
776}
777
778func (s AndroidModulesByName) Len() int { return len(s.slice) }
779func (s AndroidModulesByName) Less(i, j int) bool {
780 mi, mj := s.slice[i], s.slice[j]
781 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
782
783 if ni != nj {
784 return ni < nj
785 } else {
786 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
787 }
788}
789func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }