blob: bf9dfaac94c4ebf55c41b5a50b6b02e32ee472ca [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
28var (
29 DeviceSharedLibrary = "shared_library"
30 DeviceStaticLibrary = "static_library"
31 DeviceExecutable = "executable"
32 HostSharedLibrary = "host_shared_library"
33 HostStaticLibrary = "host_static_library"
34 HostExecutable = "host_executable"
35)
36
Dan Willemsen34cc69e2015-09-23 15:26:20 -070037type ModuleBuildParams struct {
38 Rule blueprint.Rule
39 Output WritablePath
40 Outputs WritablePaths
41 Input Path
42 Inputs Paths
43 Implicit Path
44 Implicits Paths
45 OrderOnly Paths
46 Default bool
47 Args map[string]string
48}
49
Colin Crossf6566ed2015-03-24 11:13:38 -070050type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070051 Target() Target
Colin Crossf6566ed2015-03-24 11:13:38 -070052 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070053 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070054 Host() bool
55 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070056 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070057 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070058 AConfig() Config
Colin Crossf6566ed2015-03-24 11:13:38 -070059}
60
Colin Cross635c3b02016-05-18 15:37:25 -070061type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070062 blueprint.BaseModuleContext
63 androidBaseContext
64}
65
Colin Cross635c3b02016-05-18 15:37:25 -070066type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080067 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070068 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080069
Dan Willemsen34cc69e2015-09-23 15:26:20 -070070 // Similar to Build, but takes Paths instead of []string,
71 // and performs more verification.
72 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070073
Dan Willemsen34cc69e2015-09-23 15:26:20 -070074 ExpandSources(srcFiles, excludes []string) Paths
75 Glob(outDir, globPattern string, excludes []string) Paths
76
Colin Crossa2344662016-03-24 13:14:12 -070077 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
78 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080079 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070080 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080081
82 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070083
84 Proprietary() bool
85 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080086}
87
Colin Cross635c3b02016-05-18 15:37:25 -070088type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080089 blueprint.Module
90
Colin Cross635c3b02016-05-18 15:37:25 -070091 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080092
Colin Cross635c3b02016-05-18 15:37:25 -070093 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080094 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070095 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -080096 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080097}
98
Colin Cross3f40fa42015-01-30 17:27:36 -080099type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700100 Name string
101 Deps []string
102 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800103
Dan Willemsen0effe062015-11-30 16:06:01 -0800104 // emit build rules for this module
105 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800106
Colin Cross7d5136f2015-05-11 13:39:40 -0700107 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800108 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
109 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
110 // platform
111 Compile_multilib string
112
Dan Willemsen782a2d12015-12-21 14:55:28 -0800113 // whether this is a proprietary vendor module, and should be installed into /vendor
114 Proprietary bool
115
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700116 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
117 // file
118 Logtags []string
119
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700120 // init.rc files to be installed if this module is installed
121 Init_rc []string
122
Chris Wolfe998306e2016-08-15 14:47:23 -0400123 // names of other modules to install if this module is installed
124 Required []string
125
Colin Crossa1ad8d12016-06-01 17:09:44 -0700126 // Set by TargetMutator
127 CompileTarget Target `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800128
129 // Set by InitAndroidModule
130 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
131}
132
133type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700134 Host_supported *bool
135 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800136}
137
Colin Crossc472d572015-03-17 15:06:21 -0700138type Multilib string
139
140const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700141 MultilibBoth Multilib = "both"
142 MultilibFirst Multilib = "first"
143 MultilibCommon Multilib = "common"
144 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700145)
146
Colin Crossa1ad8d12016-06-01 17:09:44 -0700147type HostOrDeviceSupported int
148
149const (
150 _ HostOrDeviceSupported = iota
151 HostSupported
152 DeviceSupported
153 HostAndDeviceSupported
154 HostAndDeviceDefault
155)
156
Colin Cross635c3b02016-05-18 15:37:25 -0700157func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800158 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
159
160 base := m.base()
161 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700162
Colin Cross7f64b6d2015-07-09 13:57:48 -0700163 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700164
165 return m, propertyStructs
166}
167
Colin Cross635c3b02016-05-18 15:37:25 -0700168func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700169 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
170
171 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
172
173 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800174 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800175 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800176
Dan Willemsen218f6562015-07-08 18:13:11 -0700177 switch hod {
178 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800179 // Default to module to device supported, host not supported, can override in module
180 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700181 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700182 fallthrough
183 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800184 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
185 }
186
Colin Crosscfad1192015-11-02 16:43:11 -0800187 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800188}
189
190// A AndroidModuleBase object contains the properties that are common to all Android
191// modules. It should be included as an anonymous field in every module
192// struct definition. InitAndroidModule should then be called from the module's
193// factory function, and the return values from InitAndroidModule should be
194// returned from the factory function.
195//
196// The AndroidModuleBase type is responsible for implementing the
197// GenerateBuildActions method to support the blueprint.Module interface. This
198// method will then call the module's GenerateAndroidBuildActions method once
199// for each build variant that is to be built. GenerateAndroidBuildActions is
200// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
201// AndroidModuleContext exposes extra functionality specific to the Android build
202// system including details about the particular build variant that is to be
203// generated.
204//
205// For example:
206//
207// import (
208// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700209// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800210// )
211//
212// type myModule struct {
213// common.AndroidModuleBase
214// properties struct {
215// MyProperty string
216// }
217// }
218//
219// func NewMyModule() (blueprint.Module, []interface{}) {
220// m := &myModule{}
221// return common.InitAndroidModule(m, &m.properties)
222// }
223//
224// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
225// // Get the CPU architecture for the current build variant.
226// variantArch := ctx.Arch()
227//
228// // ...
229// }
Colin Cross635c3b02016-05-18 15:37:25 -0700230type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800231 // Putting the curiously recurring thing pointing to the thing that contains
232 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700233 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800234
235 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700236 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800237 hostAndDeviceProperties hostAndDeviceProperties
238 generalProperties []interface{}
239 archProperties []*archProperties
240
241 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700242 installFiles Paths
243 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700244
245 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
246 // Only set on the final variant of each module
247 installTarget string
248 checkbuildTarget string
249 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800250}
251
Colin Cross635c3b02016-05-18 15:37:25 -0700252func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800253 return a
254}
255
Colin Crossa1ad8d12016-06-01 17:09:44 -0700256func (a *ModuleBase) SetTarget(target Target) {
257 a.commonProperties.CompileTarget = target
Colin Crossd3ba0392015-05-07 14:11:29 -0700258}
259
Colin Crossa1ad8d12016-06-01 17:09:44 -0700260func (a *ModuleBase) Target() Target {
261 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800262}
263
Colin Crossa1ad8d12016-06-01 17:09:44 -0700264func (a *ModuleBase) Os() OsType {
265 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800266}
267
Colin Cross635c3b02016-05-18 15:37:25 -0700268func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700269 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800270}
271
Colin Cross635c3b02016-05-18 15:37:25 -0700272func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700273 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800274}
275
Colin Crossa1ad8d12016-06-01 17:09:44 -0700276func (a *ModuleBase) OsClassSupported() []OsClass {
277 switch a.commonProperties.HostOrDeviceSupported {
278 case HostSupported:
279 // TODO(ccross): explicitly mark host cross support
280 return []OsClass{Host, HostCross}
281 case DeviceSupported:
282 return []OsClass{Device}
283 case HostAndDeviceSupported:
284 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700285 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700286 supported = append(supported, Host, HostCross)
287 }
Colin Crossa4190c12016-07-12 13:11:25 -0700288 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700289 supported = append(supported, Device)
290 }
291 return supported
292 default:
293 return nil
294 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800295}
296
Colin Cross635c3b02016-05-18 15:37:25 -0700297func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800298 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
299 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700300 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800301}
302
Colin Cross635c3b02016-05-18 15:37:25 -0700303func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800304 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700305 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800306 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800307 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800308}
309
Colin Cross635c3b02016-05-18 15:37:25 -0700310func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700311 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800312
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700313 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800314 ctx.VisitDepsDepthFirstIf(isFileInstaller,
315 func(m blueprint.Module) {
316 fileInstaller := m.(fileInstaller)
317 files := fileInstaller.filesToInstall()
318 result = append(result, files...)
319 })
320
321 return result
322}
323
Colin Cross635c3b02016-05-18 15:37:25 -0700324func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800325 return a.installFiles
326}
327
Colin Cross635c3b02016-05-18 15:37:25 -0700328func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800329 return p.noAddressSanitizer
330}
331
Colin Cross635c3b02016-05-18 15:37:25 -0700332func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800333 return false
334}
335
Colin Cross635c3b02016-05-18 15:37:25 -0700336func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
337 if a != ctx.FinalModule().(Module).base() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800338 return
339 }
340
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700341 allInstalledFiles := Paths{}
342 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800343 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700344 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700345 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
346 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800347 })
348
Colin Cross9454bfa2015-03-17 13:24:18 -0700349 deps := []string{}
350
Colin Cross3f40fa42015-01-30 17:27:36 -0800351 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700352 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800353 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700354 Rule: blueprint.Phony,
355 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700356 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800357 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700358 })
359 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700360 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700361 }
362
363 if len(allCheckbuildFiles) > 0 {
364 name := ctx.ModuleName() + "-checkbuild"
365 ctx.Build(pctx, blueprint.BuildParams{
366 Rule: blueprint.Phony,
367 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700368 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700369 Optional: true,
370 })
371 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700372 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700373 }
374
375 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800376 suffix := ""
377 if ctx.Config().(Config).EmbeddedInMake() {
378 suffix = "-soong"
379 }
380
Colin Cross9454bfa2015-03-17 13:24:18 -0700381 ctx.Build(pctx, blueprint.BuildParams{
382 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800383 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700384 Implicits: deps,
385 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800386 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700387
388 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800389 }
390}
391
Colin Cross635c3b02016-05-18 15:37:25 -0700392func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700393 return androidBaseContextImpl{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700394 target: a.commonProperties.CompileTarget,
395 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800396 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800397}
398
Colin Cross635c3b02016-05-18 15:37:25 -0700399func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800400 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700401 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700402 ModuleContext: ctx,
403 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
404 installDeps: a.computeInstallDeps(ctx),
405 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800406 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800407 }
408
Dan Willemsen0effe062015-11-30 16:06:01 -0800409 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800410 return
411 }
412
413 a.module.GenerateAndroidBuildActions(androidCtx)
414 if ctx.Failed() {
415 return
416 }
417
Colin Crossc9404352015-03-26 16:10:12 -0700418 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
419 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
420
Colin Cross3f40fa42015-01-30 17:27:36 -0800421 a.generateModuleTarget(ctx)
422 if ctx.Failed() {
423 return
424 }
425}
426
Colin Crossf6566ed2015-03-24 11:13:38 -0700427type androidBaseContextImpl struct {
Colin Cross8d8f8e22016-08-03 11:57:50 -0700428 target Target
429 debug bool
430 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700431}
432
Colin Cross3f40fa42015-01-30 17:27:36 -0800433type androidModuleContext struct {
434 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700435 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700436 installDeps Paths
437 installFiles Paths
438 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800439 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700440 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800441}
442
443func (a *androidModuleContext) ninjaError(outputs []string, err error) {
444 a.ModuleContext.Build(pctx, blueprint.BuildParams{
445 Rule: ErrorRule,
446 Outputs: outputs,
447 Optional: true,
448 Args: map[string]string{
449 "error": err.Error(),
450 },
451 })
452 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800453}
454
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800455func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700456 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800457 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
458 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
459 return
460 }
461
Colin Cross3f40fa42015-01-30 17:27:36 -0800462 params.Optional = true
463 a.ModuleContext.Build(pctx, params)
464}
465
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700466func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
467 bparams := blueprint.BuildParams{
468 Rule: params.Rule,
469 Outputs: params.Outputs.Strings(),
470 Inputs: params.Inputs.Strings(),
471 Implicits: params.Implicits.Strings(),
472 OrderOnly: params.OrderOnly.Strings(),
473 Args: params.Args,
474 Optional: !params.Default,
475 }
476
477 if params.Output != nil {
478 bparams.Outputs = append(bparams.Outputs, params.Output.String())
479 }
480 if params.Input != nil {
481 bparams.Inputs = append(bparams.Inputs, params.Input.String())
482 }
483 if params.Implicit != nil {
484 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
485 }
486
Colin Cross6ff51382015-12-17 16:39:19 -0800487 if a.missingDeps != nil {
488 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
489 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
490 return
491 }
492
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700493 a.ModuleContext.Build(pctx, bparams)
494}
495
Colin Cross6ff51382015-12-17 16:39:19 -0800496func (a *androidModuleContext) GetMissingDependencies() []string {
497 return a.missingDeps
498}
499
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800500func (a *androidModuleContext) AddMissingDependencies(deps []string) {
501 if deps != nil {
502 a.missingDeps = append(a.missingDeps, deps...)
503 }
504}
505
Colin Crossa1ad8d12016-06-01 17:09:44 -0700506func (a *androidBaseContextImpl) Target() Target {
507 return a.target
508}
509
Colin Crossf6566ed2015-03-24 11:13:38 -0700510func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700511 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800512}
513
Colin Crossa1ad8d12016-06-01 17:09:44 -0700514func (a *androidBaseContextImpl) Os() OsType {
515 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800516}
517
Colin Crossf6566ed2015-03-24 11:13:38 -0700518func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700519 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700520}
521
522func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700523 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700524}
525
Colin Cross0af4b842015-04-30 16:36:18 -0700526func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700527 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700528}
529
Colin Crossf6566ed2015-03-24 11:13:38 -0700530func (a *androidBaseContextImpl) Debug() bool {
531 return a.debug
532}
533
Colin Cross1332b002015-04-07 17:11:30 -0700534func (a *androidBaseContextImpl) AConfig() Config {
535 return a.config
536}
537
Colin Cross8d8f8e22016-08-03 11:57:50 -0700538func (a *androidModuleContext) Proprietary() bool {
539 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800540}
541
Colin Cross8d8f8e22016-08-03 11:57:50 -0700542func (a *androidModuleContext) InstallInData() bool {
543 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800544}
545
546func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700547 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700548
Dan Willemsen782a2d12015-12-21 14:55:28 -0800549 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800550
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800551 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800552 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700553
Dan Willemsen322acaf2016-01-12 23:07:05 -0800554 a.ModuleBuild(pctx, ModuleBuildParams{
555 Rule: Cp,
556 Output: fullInstallPath,
557 Input: srcPath,
558 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800559 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800560 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800561
Dan Willemsen322acaf2016-01-12 23:07:05 -0800562 a.installFiles = append(a.installFiles, fullInstallPath)
563 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700564 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700565 return fullInstallPath
566}
567
Colin Crossa2344662016-03-24 13:14:12 -0700568func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700569 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800570}
571
Colin Cross3854a602016-01-11 12:49:11 -0800572func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
573 fullInstallPath := installPath.Join(a, name)
574
Colin Cross12fc4972016-01-11 12:49:11 -0800575 if a.Host() || !a.AConfig().SkipDeviceInstall() {
576 a.ModuleBuild(pctx, ModuleBuildParams{
577 Rule: Symlink,
578 Output: fullInstallPath,
579 OrderOnly: Paths{srcPath},
580 Default: !a.AConfig().EmbeddedInMake(),
581 Args: map[string]string{
582 "fromPath": srcPath.String(),
583 },
584 })
Colin Cross3854a602016-01-11 12:49:11 -0800585
Colin Cross12fc4972016-01-11 12:49:11 -0800586 a.installFiles = append(a.installFiles, fullInstallPath)
587 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
588 }
Colin Cross3854a602016-01-11 12:49:11 -0800589 return fullInstallPath
590}
591
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700592func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800593 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
594}
595
Colin Cross3f40fa42015-01-30 17:27:36 -0800596type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700597 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800598}
599
600func isFileInstaller(m blueprint.Module) bool {
601 _, ok := m.(fileInstaller)
602 return ok
603}
604
605func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700606 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800607 return ok
608}
Colin Crossfce53272015-04-08 11:21:40 -0700609
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700610func findStringInSlice(str string, slice []string) int {
611 for i, s := range slice {
612 if s == str {
613 return i
Colin Crossfce53272015-04-08 11:21:40 -0700614 }
615 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700616 return -1
617}
618
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700619func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
620 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700621 for i, e := range excludes {
622 j := findStringInSlice(e, srcFiles)
623 if j != -1 {
624 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
625 }
626
627 excludes[i] = filepath.Join(prefix, e)
628 }
629
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700630 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700631 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700632 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700633 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700634 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700635 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700636 }
637 }
638
639 return globbedSrcFiles
640}
641
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700642func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
643 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700644 if err != nil {
645 ctx.ModuleErrorf("glob: %s", err.Error())
646 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700647 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700648}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700649
Colin Cross463a90e2015-06-17 14:20:06 -0700650func init() {
651 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
652}
653
Colin Cross1f8c52b2015-06-16 16:38:17 -0700654func BuildTargetSingleton() blueprint.Singleton {
655 return &buildTargetSingleton{}
656}
657
658type buildTargetSingleton struct{}
659
660func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
661 checkbuildDeps := []string{}
662
663 dirModules := make(map[string][]string)
664
665 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700666 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700667 blueprintDir := a.base().blueprintDir
668 installTarget := a.base().installTarget
669 checkbuildTarget := a.base().checkbuildTarget
670
671 if checkbuildTarget != "" {
672 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
673 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
674 }
675
676 if installTarget != "" {
677 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
678 }
679 }
680 })
681
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800682 suffix := ""
683 if ctx.Config().(Config).EmbeddedInMake() {
684 suffix = "-soong"
685 }
686
Colin Cross1f8c52b2015-06-16 16:38:17 -0700687 // Create a top-level checkbuild target that depends on all modules
688 ctx.Build(pctx, blueprint.BuildParams{
689 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800690 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700691 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700692 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700693 })
694
695 // Create a mm/<directory> target that depends on all modules in a directory
696 dirs := sortedKeys(dirModules)
697 for _, dir := range dirs {
698 ctx.Build(pctx, blueprint.BuildParams{
699 Rule: blueprint.Phony,
700 Outputs: []string{filepath.Join("mm", dir)},
701 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800702 // HACK: checkbuild should be an optional build, but force it
703 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800704 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700705 })
706 }
707}
Colin Crossd779da42015-12-17 18:00:23 -0800708
709type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700710 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800711 ctx interface {
712 ModuleName(blueprint.Module) string
713 ModuleSubDir(blueprint.Module) string
714 }
715}
716
717func (s AndroidModulesByName) Len() int { return len(s.slice) }
718func (s AndroidModulesByName) Less(i, j int) bool {
719 mi, mj := s.slice[i], s.slice[j]
720 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
721
722 if ni != nj {
723 return ni < nj
724 } else {
725 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
726 }
727}
728func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }