blob: 18555234a16aa646fc3a7b0cd9784e228bc9761d [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 {
51 Arch() Arch
Colin Crossd3ba0392015-05-07 14:11:29 -070052 HostOrDevice() HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -080053 HostType() HostType
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
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080082
83 AddMissingDependencies(deps []string)
Colin Cross3f40fa42015-01-30 17:27:36 -080084}
85
Colin Cross635c3b02016-05-18 15:37:25 -070086type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080087 blueprint.Module
88
Colin Cross635c3b02016-05-18 15:37:25 -070089 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080090
Colin Cross635c3b02016-05-18 15:37:25 -070091 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080092 Enabled() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080093 HostOrDevice() HostOrDevice
Dan Willemsen782a2d12015-12-21 14:55:28 -080094 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080095}
96
Colin Cross3f40fa42015-01-30 17:27:36 -080097type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070098 Name string
99 Deps []string
100 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800101
Dan Willemsen0effe062015-11-30 16:06:01 -0800102 // emit build rules for this module
103 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800104
Colin Cross7d5136f2015-05-11 13:39:40 -0700105 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800106 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
107 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
108 // platform
109 Compile_multilib string
110
Dan Willemsen782a2d12015-12-21 14:55:28 -0800111 // whether this is a proprietary vendor module, and should be installed into /vendor
112 Proprietary bool
113
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700114 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
115 // file
116 Logtags []string
117
Colin Crossd3ba0392015-05-07 14:11:29 -0700118 // Set by HostOrDeviceMutator
119 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
120
Dan Willemsen490fd492015-11-24 17:53:15 -0800121 // Set by HostTypeMutator
122 CompileHostType HostType `blueprint:"mutated"`
123
Colin Cross3f40fa42015-01-30 17:27:36 -0800124 // Set by ArchMutator
125 CompileArch Arch `blueprint:"mutated"`
126
127 // Set by InitAndroidModule
128 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
129}
130
131type hostAndDeviceProperties struct {
132 Host_supported bool
133 Device_supported bool
134}
135
Colin Crossc472d572015-03-17 15:06:21 -0700136type Multilib string
137
138const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700139 MultilibBoth Multilib = "both"
140 MultilibFirst Multilib = "first"
141 MultilibCommon Multilib = "common"
142 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700143)
144
Colin Cross635c3b02016-05-18 15:37:25 -0700145func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800146 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
147
148 base := m.base()
149 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700150
Colin Cross7f64b6d2015-07-09 13:57:48 -0700151 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700152
153 return m, propertyStructs
154}
155
Colin Cross635c3b02016-05-18 15:37:25 -0700156func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700157 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
158
159 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
160
161 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800162 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800163 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800164
Dan Willemsen218f6562015-07-08 18:13:11 -0700165 switch hod {
166 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800167 // Default to module to device supported, host not supported, can override in module
168 // properties
169 base.hostAndDeviceProperties.Device_supported = true
Dan Willemsen218f6562015-07-08 18:13:11 -0700170 fallthrough
171 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800172 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
173 }
174
Colin Crosscfad1192015-11-02 16:43:11 -0800175 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800176}
177
178// A AndroidModuleBase object contains the properties that are common to all Android
179// modules. It should be included as an anonymous field in every module
180// struct definition. InitAndroidModule should then be called from the module's
181// factory function, and the return values from InitAndroidModule should be
182// returned from the factory function.
183//
184// The AndroidModuleBase type is responsible for implementing the
185// GenerateBuildActions method to support the blueprint.Module interface. This
186// method will then call the module's GenerateAndroidBuildActions method once
187// for each build variant that is to be built. GenerateAndroidBuildActions is
188// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
189// AndroidModuleContext exposes extra functionality specific to the Android build
190// system including details about the particular build variant that is to be
191// generated.
192//
193// For example:
194//
195// import (
196// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700197// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800198// )
199//
200// type myModule struct {
201// common.AndroidModuleBase
202// properties struct {
203// MyProperty string
204// }
205// }
206//
207// func NewMyModule() (blueprint.Module, []interface{}) {
208// m := &myModule{}
209// return common.InitAndroidModule(m, &m.properties)
210// }
211//
212// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
213// // Get the CPU architecture for the current build variant.
214// variantArch := ctx.Arch()
215//
216// // ...
217// }
Colin Cross635c3b02016-05-18 15:37:25 -0700218type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800219 // Putting the curiously recurring thing pointing to the thing that contains
220 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700221 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800222
223 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700224 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800225 hostAndDeviceProperties hostAndDeviceProperties
226 generalProperties []interface{}
227 archProperties []*archProperties
228
229 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700230 installFiles Paths
231 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700232
233 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
234 // Only set on the final variant of each module
235 installTarget string
236 checkbuildTarget string
237 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800238}
239
Colin Cross635c3b02016-05-18 15:37:25 -0700240func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800241 return a
242}
243
Colin Cross635c3b02016-05-18 15:37:25 -0700244func (a *ModuleBase) SetHostOrDevice(hod HostOrDevice) {
Colin Crossd3ba0392015-05-07 14:11:29 -0700245 a.commonProperties.CompileHostOrDevice = hod
246}
247
Colin Cross635c3b02016-05-18 15:37:25 -0700248func (a *ModuleBase) SetHostType(ht HostType) {
Dan Willemsen490fd492015-11-24 17:53:15 -0800249 a.commonProperties.CompileHostType = ht
250}
251
Colin Cross635c3b02016-05-18 15:37:25 -0700252func (a *ModuleBase) SetArch(arch Arch) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800253 a.commonProperties.CompileArch = arch
254}
255
Colin Cross635c3b02016-05-18 15:37:25 -0700256func (a *ModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700257 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800258}
259
Colin Cross635c3b02016-05-18 15:37:25 -0700260func (a *ModuleBase) HostType() HostType {
Dan Willemsen490fd492015-11-24 17:53:15 -0800261 return a.commonProperties.CompileHostType
262}
263
Colin Cross635c3b02016-05-18 15:37:25 -0700264func (a *ModuleBase) Host() bool {
Dan Willemsen97750522016-02-09 17:43:51 -0800265 return a.HostOrDevice().Host()
266}
267
Colin Cross635c3b02016-05-18 15:37:25 -0700268func (a *ModuleBase) Arch() Arch {
Dan Willemsen97750522016-02-09 17:43:51 -0800269 return a.commonProperties.CompileArch
270}
271
Colin Cross635c3b02016-05-18 15:37:25 -0700272func (a *ModuleBase) HostSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800273 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
274 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
275 a.hostAndDeviceProperties.Host_supported
276}
277
Colin Cross635c3b02016-05-18 15:37:25 -0700278func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800279 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
280 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
281 a.hostAndDeviceProperties.Device_supported
282}
283
Colin Cross635c3b02016-05-18 15:37:25 -0700284func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800285 if a.commonProperties.Enabled == nil {
286 if a.HostSupported() && a.HostOrDevice().Host() && a.HostType() == Windows {
287 return false
288 } else {
289 return true
290 }
Dan Willemsen490fd492015-11-24 17:53:15 -0800291 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800292 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800293}
294
Colin Cross635c3b02016-05-18 15:37:25 -0700295func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700296 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800297
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700298 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800299 ctx.VisitDepsDepthFirstIf(isFileInstaller,
300 func(m blueprint.Module) {
301 fileInstaller := m.(fileInstaller)
302 files := fileInstaller.filesToInstall()
303 result = append(result, files...)
304 })
305
306 return result
307}
308
Colin Cross635c3b02016-05-18 15:37:25 -0700309func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800310 return a.installFiles
311}
312
Colin Cross635c3b02016-05-18 15:37:25 -0700313func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800314 return p.noAddressSanitizer
315}
316
Colin Cross635c3b02016-05-18 15:37:25 -0700317func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800318 return false
319}
320
Colin Cross635c3b02016-05-18 15:37:25 -0700321func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
322 if a != ctx.FinalModule().(Module).base() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800323 return
324 }
325
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700326 allInstalledFiles := Paths{}
327 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800328 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700329 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700330 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
331 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800332 })
333
Colin Cross9454bfa2015-03-17 13:24:18 -0700334 deps := []string{}
335
Colin Cross3f40fa42015-01-30 17:27:36 -0800336 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700337 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800338 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700339 Rule: blueprint.Phony,
340 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700341 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800342 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700343 })
344 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700345 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700346 }
347
348 if len(allCheckbuildFiles) > 0 {
349 name := ctx.ModuleName() + "-checkbuild"
350 ctx.Build(pctx, blueprint.BuildParams{
351 Rule: blueprint.Phony,
352 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700353 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700354 Optional: true,
355 })
356 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700357 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700358 }
359
360 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800361 suffix := ""
362 if ctx.Config().(Config).EmbeddedInMake() {
363 suffix = "-soong"
364 }
365
Colin Cross9454bfa2015-03-17 13:24:18 -0700366 ctx.Build(pctx, blueprint.BuildParams{
367 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800368 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700369 Implicits: deps,
370 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800371 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700372
373 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800374 }
375}
376
Colin Cross635c3b02016-05-18 15:37:25 -0700377func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700378 return androidBaseContextImpl{
Dan Willemsen782a2d12015-12-21 14:55:28 -0800379 arch: a.commonProperties.CompileArch,
380 hod: a.commonProperties.CompileHostOrDevice,
381 ht: a.commonProperties.CompileHostType,
382 proprietary: a.commonProperties.Proprietary,
383 config: ctx.Config().(Config),
384 installInData: a.module.InstallInData(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800385 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800386}
387
Colin Cross635c3b02016-05-18 15:37:25 -0700388func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800389 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700390 ModuleContext: ctx,
391 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
392 installDeps: a.computeInstallDeps(ctx),
393 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800394 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800395 }
396
Dan Willemsen0effe062015-11-30 16:06:01 -0800397 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800398 return
399 }
400
401 a.module.GenerateAndroidBuildActions(androidCtx)
402 if ctx.Failed() {
403 return
404 }
405
Colin Crossc9404352015-03-26 16:10:12 -0700406 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
407 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
408
Colin Cross3f40fa42015-01-30 17:27:36 -0800409 a.generateModuleTarget(ctx)
410 if ctx.Failed() {
411 return
412 }
413}
414
Colin Crossf6566ed2015-03-24 11:13:38 -0700415type androidBaseContextImpl struct {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800416 arch Arch
417 hod HostOrDevice
418 ht HostType
419 debug bool
420 config Config
421 proprietary bool
422 installInData bool
Colin Crossf6566ed2015-03-24 11:13:38 -0700423}
424
Colin Cross3f40fa42015-01-30 17:27:36 -0800425type androidModuleContext struct {
426 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700427 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700428 installDeps Paths
429 installFiles Paths
430 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800431 missingDeps []string
432}
433
434func (a *androidModuleContext) ninjaError(outputs []string, err error) {
435 a.ModuleContext.Build(pctx, blueprint.BuildParams{
436 Rule: ErrorRule,
437 Outputs: outputs,
438 Optional: true,
439 Args: map[string]string{
440 "error": err.Error(),
441 },
442 })
443 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800444}
445
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800446func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700447 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800448 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
449 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
450 return
451 }
452
Colin Cross3f40fa42015-01-30 17:27:36 -0800453 params.Optional = true
454 a.ModuleContext.Build(pctx, params)
455}
456
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700457func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
458 bparams := blueprint.BuildParams{
459 Rule: params.Rule,
460 Outputs: params.Outputs.Strings(),
461 Inputs: params.Inputs.Strings(),
462 Implicits: params.Implicits.Strings(),
463 OrderOnly: params.OrderOnly.Strings(),
464 Args: params.Args,
465 Optional: !params.Default,
466 }
467
468 if params.Output != nil {
469 bparams.Outputs = append(bparams.Outputs, params.Output.String())
470 }
471 if params.Input != nil {
472 bparams.Inputs = append(bparams.Inputs, params.Input.String())
473 }
474 if params.Implicit != nil {
475 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
476 }
477
Colin Cross6ff51382015-12-17 16:39:19 -0800478 if a.missingDeps != nil {
479 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
480 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
481 return
482 }
483
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700484 a.ModuleContext.Build(pctx, bparams)
485}
486
Colin Cross6ff51382015-12-17 16:39:19 -0800487func (a *androidModuleContext) GetMissingDependencies() []string {
488 return a.missingDeps
489}
490
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800491func (a *androidModuleContext) AddMissingDependencies(deps []string) {
492 if deps != nil {
493 a.missingDeps = append(a.missingDeps, deps...)
494 }
495}
496
Colin Crossf6566ed2015-03-24 11:13:38 -0700497func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800498 return a.arch
499}
500
Colin Crossd3ba0392015-05-07 14:11:29 -0700501func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
502 return a.hod
503}
504
Dan Willemsen490fd492015-11-24 17:53:15 -0800505func (a *androidBaseContextImpl) HostType() HostType {
506 return a.ht
507}
508
Colin Crossf6566ed2015-03-24 11:13:38 -0700509func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700510 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700511}
512
513func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700514 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700515}
516
Colin Cross0af4b842015-04-30 16:36:18 -0700517func (a *androidBaseContextImpl) Darwin() bool {
Dan Willemsen490fd492015-11-24 17:53:15 -0800518 return a.hod.Host() && a.ht == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700519}
520
Colin Crossf6566ed2015-03-24 11:13:38 -0700521func (a *androidBaseContextImpl) Debug() bool {
522 return a.debug
523}
524
Colin Cross1332b002015-04-07 17:11:30 -0700525func (a *androidBaseContextImpl) AConfig() Config {
526 return a.config
527}
528
Dan Willemsen782a2d12015-12-21 14:55:28 -0800529func (a *androidBaseContextImpl) Proprietary() bool {
530 return a.proprietary
531}
532
533func (a *androidBaseContextImpl) InstallInData() bool {
534 return a.installInData
535}
536
537func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700538 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700539
Dan Willemsen782a2d12015-12-21 14:55:28 -0800540 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800541
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800542 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800543 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700544
Dan Willemsen322acaf2016-01-12 23:07:05 -0800545 a.ModuleBuild(pctx, ModuleBuildParams{
546 Rule: Cp,
547 Output: fullInstallPath,
548 Input: srcPath,
549 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800550 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800551 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800552
Dan Willemsen322acaf2016-01-12 23:07:05 -0800553 a.installFiles = append(a.installFiles, fullInstallPath)
554 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700555 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700556 return fullInstallPath
557}
558
Colin Crossa2344662016-03-24 13:14:12 -0700559func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700560 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800561}
562
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700563func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800564 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
565}
566
Colin Cross3f40fa42015-01-30 17:27:36 -0800567type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700568 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800569}
570
571func isFileInstaller(m blueprint.Module) bool {
572 _, ok := m.(fileInstaller)
573 return ok
574}
575
576func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700577 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800578 return ok
579}
Colin Crossfce53272015-04-08 11:21:40 -0700580
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700581func findStringInSlice(str string, slice []string) int {
582 for i, s := range slice {
583 if s == str {
584 return i
Colin Crossfce53272015-04-08 11:21:40 -0700585 }
586 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700587 return -1
588}
589
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700590func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
591 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700592 for i, e := range excludes {
593 j := findStringInSlice(e, srcFiles)
594 if j != -1 {
595 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
596 }
597
598 excludes[i] = filepath.Join(prefix, e)
599 }
600
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700601 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700602 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700603 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700604 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700605 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700606 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700607 }
608 }
609
610 return globbedSrcFiles
611}
612
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700613func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
614 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700615 if err != nil {
616 ctx.ModuleErrorf("glob: %s", err.Error())
617 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700618 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700619}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700620
Colin Cross463a90e2015-06-17 14:20:06 -0700621func init() {
622 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
623}
624
Colin Cross1f8c52b2015-06-16 16:38:17 -0700625func BuildTargetSingleton() blueprint.Singleton {
626 return &buildTargetSingleton{}
627}
628
629type buildTargetSingleton struct{}
630
631func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
632 checkbuildDeps := []string{}
633
634 dirModules := make(map[string][]string)
635
636 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700637 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700638 blueprintDir := a.base().blueprintDir
639 installTarget := a.base().installTarget
640 checkbuildTarget := a.base().checkbuildTarget
641
642 if checkbuildTarget != "" {
643 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
644 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
645 }
646
647 if installTarget != "" {
648 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
649 }
650 }
651 })
652
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800653 suffix := ""
654 if ctx.Config().(Config).EmbeddedInMake() {
655 suffix = "-soong"
656 }
657
Colin Cross1f8c52b2015-06-16 16:38:17 -0700658 // Create a top-level checkbuild target that depends on all modules
659 ctx.Build(pctx, blueprint.BuildParams{
660 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800661 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700662 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700663 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700664 })
665
666 // Create a mm/<directory> target that depends on all modules in a directory
667 dirs := sortedKeys(dirModules)
668 for _, dir := range dirs {
669 ctx.Build(pctx, blueprint.BuildParams{
670 Rule: blueprint.Phony,
671 Outputs: []string{filepath.Join("mm", dir)},
672 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800673 // HACK: checkbuild should be an optional build, but force it
674 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800675 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700676 })
677 }
678}
Colin Crossd779da42015-12-17 18:00:23 -0800679
680type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700681 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800682 ctx interface {
683 ModuleName(blueprint.Module) string
684 ModuleSubDir(blueprint.Module) string
685 }
686}
687
688func (s AndroidModulesByName) Len() int { return len(s.slice) }
689func (s AndroidModulesByName) Less(i, j int) bool {
690 mi, mj := s.slice[i], s.slice[j]
691 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
692
693 if ni != nj {
694 return ni < nj
695 } else {
696 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
697 }
698}
699func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }