blob: 216aefe9df041815b8bbec23663f1566c2a7e87f [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
Dan Willemsen782a2d12015-12-21 14:55:28 -080059 Proprietary() bool
60 InstallInData() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070061}
62
Colin Cross635c3b02016-05-18 15:37:25 -070063type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070064 blueprint.BaseModuleContext
65 androidBaseContext
66}
67
Colin Cross635c3b02016-05-18 15:37:25 -070068type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080069 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070070 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080071
Dan Willemsen34cc69e2015-09-23 15:26:20 -070072 // Similar to Build, but takes Paths instead of []string,
73 // and performs more verification.
74 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070075
Dan Willemsen34cc69e2015-09-23 15:26:20 -070076 ExpandSources(srcFiles, excludes []string) Paths
77 Glob(outDir, globPattern string, excludes []string) Paths
78
Colin Crossa2344662016-03-24 13:14:12 -070079 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
80 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080081 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070082 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080083
84 AddMissingDependencies(deps []string)
Colin Cross3f40fa42015-01-30 17:27:36 -080085}
86
Colin Cross635c3b02016-05-18 15:37:25 -070087type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080088 blueprint.Module
89
Colin Cross635c3b02016-05-18 15:37:25 -070090 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080091
Colin Cross635c3b02016-05-18 15:37:25 -070092 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080093 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070094 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -080095 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080096}
97
Colin Cross3f40fa42015-01-30 17:27:36 -080098type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070099 Name string
100 Deps []string
101 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800102
Dan Willemsen0effe062015-11-30 16:06:01 -0800103 // emit build rules for this module
104 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800105
Colin Cross7d5136f2015-05-11 13:39:40 -0700106 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800107 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
108 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
109 // platform
110 Compile_multilib string
111
Dan Willemsen782a2d12015-12-21 14:55:28 -0800112 // whether this is a proprietary vendor module, and should be installed into /vendor
113 Proprietary bool
114
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700115 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
116 // file
117 Logtags []string
118
Colin Crossa1ad8d12016-06-01 17:09:44 -0700119 // Set by TargetMutator
120 CompileTarget Target `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800121
122 // Set by InitAndroidModule
123 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
124}
125
126type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700127 Host_supported *bool
128 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800129}
130
Colin Crossc472d572015-03-17 15:06:21 -0700131type Multilib string
132
133const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700134 MultilibBoth Multilib = "both"
135 MultilibFirst Multilib = "first"
136 MultilibCommon Multilib = "common"
137 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700138)
139
Colin Crossa1ad8d12016-06-01 17:09:44 -0700140type HostOrDeviceSupported int
141
142const (
143 _ HostOrDeviceSupported = iota
144 HostSupported
145 DeviceSupported
146 HostAndDeviceSupported
147 HostAndDeviceDefault
148)
149
Colin Cross635c3b02016-05-18 15:37:25 -0700150func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800151 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
152
153 base := m.base()
154 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700155
Colin Cross7f64b6d2015-07-09 13:57:48 -0700156 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700157
158 return m, propertyStructs
159}
160
Colin Cross635c3b02016-05-18 15:37:25 -0700161func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700162 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
163
164 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
165
166 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800167 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800168 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800169
Dan Willemsen218f6562015-07-08 18:13:11 -0700170 switch hod {
171 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800172 // Default to module to device supported, host not supported, can override in module
173 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700174 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700175 fallthrough
176 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800177 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
178 }
179
Colin Crosscfad1192015-11-02 16:43:11 -0800180 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800181}
182
183// A AndroidModuleBase object contains the properties that are common to all Android
184// modules. It should be included as an anonymous field in every module
185// struct definition. InitAndroidModule should then be called from the module's
186// factory function, and the return values from InitAndroidModule should be
187// returned from the factory function.
188//
189// The AndroidModuleBase type is responsible for implementing the
190// GenerateBuildActions method to support the blueprint.Module interface. This
191// method will then call the module's GenerateAndroidBuildActions method once
192// for each build variant that is to be built. GenerateAndroidBuildActions is
193// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
194// AndroidModuleContext exposes extra functionality specific to the Android build
195// system including details about the particular build variant that is to be
196// generated.
197//
198// For example:
199//
200// import (
201// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700202// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800203// )
204//
205// type myModule struct {
206// common.AndroidModuleBase
207// properties struct {
208// MyProperty string
209// }
210// }
211//
212// func NewMyModule() (blueprint.Module, []interface{}) {
213// m := &myModule{}
214// return common.InitAndroidModule(m, &m.properties)
215// }
216//
217// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
218// // Get the CPU architecture for the current build variant.
219// variantArch := ctx.Arch()
220//
221// // ...
222// }
Colin Cross635c3b02016-05-18 15:37:25 -0700223type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800224 // Putting the curiously recurring thing pointing to the thing that contains
225 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700226 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800227
228 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700229 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800230 hostAndDeviceProperties hostAndDeviceProperties
231 generalProperties []interface{}
232 archProperties []*archProperties
233
234 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700235 installFiles Paths
236 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700237
238 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
239 // Only set on the final variant of each module
240 installTarget string
241 checkbuildTarget string
242 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800243}
244
Colin Cross635c3b02016-05-18 15:37:25 -0700245func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800246 return a
247}
248
Colin Crossa1ad8d12016-06-01 17:09:44 -0700249func (a *ModuleBase) SetTarget(target Target) {
250 a.commonProperties.CompileTarget = target
Colin Crossd3ba0392015-05-07 14:11:29 -0700251}
252
Colin Crossa1ad8d12016-06-01 17:09:44 -0700253func (a *ModuleBase) Target() Target {
254 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800255}
256
Colin Crossa1ad8d12016-06-01 17:09:44 -0700257func (a *ModuleBase) Os() OsType {
258 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800259}
260
Colin Cross635c3b02016-05-18 15:37:25 -0700261func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700262 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800263}
264
Colin Cross635c3b02016-05-18 15:37:25 -0700265func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700266 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800267}
268
Colin Crossa1ad8d12016-06-01 17:09:44 -0700269func (a *ModuleBase) OsClassSupported() []OsClass {
270 switch a.commonProperties.HostOrDeviceSupported {
271 case HostSupported:
272 // TODO(ccross): explicitly mark host cross support
273 return []OsClass{Host, HostCross}
274 case DeviceSupported:
275 return []OsClass{Device}
276 case HostAndDeviceSupported:
277 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700278 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700279 supported = append(supported, Host, HostCross)
280 }
Colin Crossa4190c12016-07-12 13:11:25 -0700281 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700282 supported = append(supported, Device)
283 }
284 return supported
285 default:
286 return nil
287 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800288}
289
Colin Cross635c3b02016-05-18 15:37:25 -0700290func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800291 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
292 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700293 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800294}
295
Colin Cross635c3b02016-05-18 15:37:25 -0700296func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800297 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700298 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800299 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800300 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800301}
302
Colin Cross635c3b02016-05-18 15:37:25 -0700303func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700304 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800305
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700306 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800307 ctx.VisitDepsDepthFirstIf(isFileInstaller,
308 func(m blueprint.Module) {
309 fileInstaller := m.(fileInstaller)
310 files := fileInstaller.filesToInstall()
311 result = append(result, files...)
312 })
313
314 return result
315}
316
Colin Cross635c3b02016-05-18 15:37:25 -0700317func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800318 return a.installFiles
319}
320
Colin Cross635c3b02016-05-18 15:37:25 -0700321func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800322 return p.noAddressSanitizer
323}
324
Colin Cross635c3b02016-05-18 15:37:25 -0700325func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800326 return false
327}
328
Colin Cross635c3b02016-05-18 15:37:25 -0700329func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
330 if a != ctx.FinalModule().(Module).base() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800331 return
332 }
333
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700334 allInstalledFiles := Paths{}
335 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800336 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700337 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700338 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
339 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800340 })
341
Colin Cross9454bfa2015-03-17 13:24:18 -0700342 deps := []string{}
343
Colin Cross3f40fa42015-01-30 17:27:36 -0800344 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700345 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800346 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700347 Rule: blueprint.Phony,
348 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700349 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800350 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700351 })
352 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700353 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700354 }
355
356 if len(allCheckbuildFiles) > 0 {
357 name := ctx.ModuleName() + "-checkbuild"
358 ctx.Build(pctx, blueprint.BuildParams{
359 Rule: blueprint.Phony,
360 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700361 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700362 Optional: true,
363 })
364 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700365 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700366 }
367
368 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800369 suffix := ""
370 if ctx.Config().(Config).EmbeddedInMake() {
371 suffix = "-soong"
372 }
373
Colin Cross9454bfa2015-03-17 13:24:18 -0700374 ctx.Build(pctx, blueprint.BuildParams{
375 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800376 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700377 Implicits: deps,
378 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800379 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700380
381 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 }
383}
384
Colin Cross635c3b02016-05-18 15:37:25 -0700385func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700386 return androidBaseContextImpl{
Colin Crossa1ad8d12016-06-01 17:09:44 -0700387 target: a.commonProperties.CompileTarget,
Dan Willemsen782a2d12015-12-21 14:55:28 -0800388 proprietary: a.commonProperties.Proprietary,
389 config: ctx.Config().(Config),
390 installInData: a.module.InstallInData(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800391 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800392}
393
Colin Cross635c3b02016-05-18 15:37:25 -0700394func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800395 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700396 ModuleContext: ctx,
397 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
398 installDeps: a.computeInstallDeps(ctx),
399 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800400 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800401 }
402
Dan Willemsen0effe062015-11-30 16:06:01 -0800403 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800404 return
405 }
406
407 a.module.GenerateAndroidBuildActions(androidCtx)
408 if ctx.Failed() {
409 return
410 }
411
Colin Crossc9404352015-03-26 16:10:12 -0700412 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
413 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
414
Colin Cross3f40fa42015-01-30 17:27:36 -0800415 a.generateModuleTarget(ctx)
416 if ctx.Failed() {
417 return
418 }
419}
420
Colin Crossf6566ed2015-03-24 11:13:38 -0700421type androidBaseContextImpl struct {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700422 target Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800423 debug bool
424 config Config
425 proprietary bool
426 installInData bool
Colin Crossf6566ed2015-03-24 11:13:38 -0700427}
428
Colin Cross3f40fa42015-01-30 17:27:36 -0800429type androidModuleContext struct {
430 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700431 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700432 installDeps Paths
433 installFiles Paths
434 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800435 missingDeps []string
436}
437
438func (a *androidModuleContext) ninjaError(outputs []string, err error) {
439 a.ModuleContext.Build(pctx, blueprint.BuildParams{
440 Rule: ErrorRule,
441 Outputs: outputs,
442 Optional: true,
443 Args: map[string]string{
444 "error": err.Error(),
445 },
446 })
447 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800448}
449
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800450func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700451 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800452 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
453 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
454 return
455 }
456
Colin Cross3f40fa42015-01-30 17:27:36 -0800457 params.Optional = true
458 a.ModuleContext.Build(pctx, params)
459}
460
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700461func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
462 bparams := blueprint.BuildParams{
463 Rule: params.Rule,
464 Outputs: params.Outputs.Strings(),
465 Inputs: params.Inputs.Strings(),
466 Implicits: params.Implicits.Strings(),
467 OrderOnly: params.OrderOnly.Strings(),
468 Args: params.Args,
469 Optional: !params.Default,
470 }
471
472 if params.Output != nil {
473 bparams.Outputs = append(bparams.Outputs, params.Output.String())
474 }
475 if params.Input != nil {
476 bparams.Inputs = append(bparams.Inputs, params.Input.String())
477 }
478 if params.Implicit != nil {
479 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
480 }
481
Colin Cross6ff51382015-12-17 16:39:19 -0800482 if a.missingDeps != nil {
483 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
484 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
485 return
486 }
487
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700488 a.ModuleContext.Build(pctx, bparams)
489}
490
Colin Cross6ff51382015-12-17 16:39:19 -0800491func (a *androidModuleContext) GetMissingDependencies() []string {
492 return a.missingDeps
493}
494
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800495func (a *androidModuleContext) AddMissingDependencies(deps []string) {
496 if deps != nil {
497 a.missingDeps = append(a.missingDeps, deps...)
498 }
499}
500
Colin Crossa1ad8d12016-06-01 17:09:44 -0700501func (a *androidBaseContextImpl) Target() Target {
502 return a.target
503}
504
Colin Crossf6566ed2015-03-24 11:13:38 -0700505func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700506 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800507}
508
Colin Crossa1ad8d12016-06-01 17:09:44 -0700509func (a *androidBaseContextImpl) Os() OsType {
510 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800511}
512
Colin Crossf6566ed2015-03-24 11:13:38 -0700513func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700514 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700515}
516
517func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700518 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700519}
520
Colin Cross0af4b842015-04-30 16:36:18 -0700521func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700522 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700523}
524
Colin Crossf6566ed2015-03-24 11:13:38 -0700525func (a *androidBaseContextImpl) Debug() bool {
526 return a.debug
527}
528
Colin Cross1332b002015-04-07 17:11:30 -0700529func (a *androidBaseContextImpl) AConfig() Config {
530 return a.config
531}
532
Dan Willemsen782a2d12015-12-21 14:55:28 -0800533func (a *androidBaseContextImpl) Proprietary() bool {
534 return a.proprietary
535}
536
537func (a *androidBaseContextImpl) InstallInData() bool {
538 return a.installInData
539}
540
541func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700542 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700543
Dan Willemsen782a2d12015-12-21 14:55:28 -0800544 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800545
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800546 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800547 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700548
Dan Willemsen322acaf2016-01-12 23:07:05 -0800549 a.ModuleBuild(pctx, ModuleBuildParams{
550 Rule: Cp,
551 Output: fullInstallPath,
552 Input: srcPath,
553 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800554 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800555 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800556
Dan Willemsen322acaf2016-01-12 23:07:05 -0800557 a.installFiles = append(a.installFiles, fullInstallPath)
558 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700559 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700560 return fullInstallPath
561}
562
Colin Crossa2344662016-03-24 13:14:12 -0700563func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700564 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800565}
566
Colin Cross3854a602016-01-11 12:49:11 -0800567func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
568 fullInstallPath := installPath.Join(a, name)
569
Colin Cross12fc4972016-01-11 12:49:11 -0800570 if a.Host() || !a.AConfig().SkipDeviceInstall() {
571 a.ModuleBuild(pctx, ModuleBuildParams{
572 Rule: Symlink,
573 Output: fullInstallPath,
574 OrderOnly: Paths{srcPath},
575 Default: !a.AConfig().EmbeddedInMake(),
576 Args: map[string]string{
577 "fromPath": srcPath.String(),
578 },
579 })
Colin Cross3854a602016-01-11 12:49:11 -0800580
Colin Cross12fc4972016-01-11 12:49:11 -0800581 a.installFiles = append(a.installFiles, fullInstallPath)
582 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
583 }
Colin Cross3854a602016-01-11 12:49:11 -0800584 return fullInstallPath
585}
586
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700587func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800588 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
589}
590
Colin Cross3f40fa42015-01-30 17:27:36 -0800591type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700592 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800593}
594
595func isFileInstaller(m blueprint.Module) bool {
596 _, ok := m.(fileInstaller)
597 return ok
598}
599
600func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700601 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800602 return ok
603}
Colin Crossfce53272015-04-08 11:21:40 -0700604
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700605func findStringInSlice(str string, slice []string) int {
606 for i, s := range slice {
607 if s == str {
608 return i
Colin Crossfce53272015-04-08 11:21:40 -0700609 }
610 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700611 return -1
612}
613
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700614func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
615 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700616 for i, e := range excludes {
617 j := findStringInSlice(e, srcFiles)
618 if j != -1 {
619 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
620 }
621
622 excludes[i] = filepath.Join(prefix, e)
623 }
624
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700625 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700626 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700627 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700628 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700629 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700630 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700631 }
632 }
633
634 return globbedSrcFiles
635}
636
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700637func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
638 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700639 if err != nil {
640 ctx.ModuleErrorf("glob: %s", err.Error())
641 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700642 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700643}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700644
Colin Cross463a90e2015-06-17 14:20:06 -0700645func init() {
646 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
647}
648
Colin Cross1f8c52b2015-06-16 16:38:17 -0700649func BuildTargetSingleton() blueprint.Singleton {
650 return &buildTargetSingleton{}
651}
652
653type buildTargetSingleton struct{}
654
655func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
656 checkbuildDeps := []string{}
657
658 dirModules := make(map[string][]string)
659
660 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700661 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700662 blueprintDir := a.base().blueprintDir
663 installTarget := a.base().installTarget
664 checkbuildTarget := a.base().checkbuildTarget
665
666 if checkbuildTarget != "" {
667 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
668 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
669 }
670
671 if installTarget != "" {
672 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
673 }
674 }
675 })
676
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800677 suffix := ""
678 if ctx.Config().(Config).EmbeddedInMake() {
679 suffix = "-soong"
680 }
681
Colin Cross1f8c52b2015-06-16 16:38:17 -0700682 // Create a top-level checkbuild target that depends on all modules
683 ctx.Build(pctx, blueprint.BuildParams{
684 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800685 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700686 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700687 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700688 })
689
690 // Create a mm/<directory> target that depends on all modules in a directory
691 dirs := sortedKeys(dirModules)
692 for _, dir := range dirs {
693 ctx.Build(pctx, blueprint.BuildParams{
694 Rule: blueprint.Phony,
695 Outputs: []string{filepath.Join("mm", dir)},
696 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800697 // HACK: checkbuild should be an optional build, but force it
698 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800699 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700700 })
701 }
702}
Colin Crossd779da42015-12-17 18:00:23 -0800703
704type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700705 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800706 ctx interface {
707 ModuleName(blueprint.Module) string
708 ModuleSubDir(blueprint.Module) string
709 }
710}
711
712func (s AndroidModulesByName) Len() int { return len(s.slice) }
713func (s AndroidModulesByName) Less(i, j int) bool {
714 mi, mj := s.slice[i], s.slice[j]
715 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
716
717 if ni != nj {
718 return ni < nj
719 } else {
720 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
721 }
722}
723func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }