blob: 230d95cab97224f290d93c631f7160057154a3b8 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross6ff51382015-12-17 16:39:19 -080018 "fmt"
Colin Cross3f40fa42015-01-30 17:27:36 -080019 "path/filepath"
Colin Cross6ff51382015-12-17 16:39:19 -080020 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070021
Colin Cross8f101b42015-06-17 15:09:06 -070022 "android/soong/glob"
23
Colin Crossf6566ed2015-03-24 11:13:38 -070024 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080025)
26
27var (
28 DeviceSharedLibrary = "shared_library"
29 DeviceStaticLibrary = "static_library"
30 DeviceExecutable = "executable"
31 HostSharedLibrary = "host_shared_library"
32 HostStaticLibrary = "host_static_library"
33 HostExecutable = "host_executable"
34)
35
Dan Willemsen34cc69e2015-09-23 15:26:20 -070036type ModuleBuildParams struct {
37 Rule blueprint.Rule
38 Output WritablePath
39 Outputs WritablePaths
40 Input Path
41 Inputs Paths
42 Implicit Path
43 Implicits Paths
44 OrderOnly Paths
45 Default bool
46 Args map[string]string
47}
48
Colin Crossf6566ed2015-03-24 11:13:38 -070049type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070050 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070051 TargetPrimary() bool
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 Cross1e7d3702016-08-24 15:25:47 -070058 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070059 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070060 DeviceConfig() DeviceConfig
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 Cross8d8f8e22016-08-03 11:57:50 -070085
86 Proprietary() bool
87 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080088}
89
Colin Cross635c3b02016-05-18 15:37:25 -070090type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080091 blueprint.Module
92
Colin Cross635c3b02016-05-18 15:37:25 -070093 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -070094 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080095
Colin Cross635c3b02016-05-18 15:37:25 -070096 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080097 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070098 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -080099 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800100}
101
Colin Crossfc754582016-05-17 16:34:16 -0700102type nameProperties struct {
103 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700104 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700105}
106
107type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700108 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800109
Dan Willemsen0effe062015-11-30 16:06:01 -0800110 // emit build rules for this module
111 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800112
Colin Cross7d5136f2015-05-11 13:39:40 -0700113 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800114 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
115 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
116 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700117 Compile_multilib string `android:"arch_variant"`
118
119 Target struct {
120 Host struct {
121 Compile_multilib string
122 }
123 Android struct {
124 Compile_multilib string
125 }
126 }
127
128 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800129
Dan Willemsen782a2d12015-12-21 14:55:28 -0800130 // whether this is a proprietary vendor module, and should be installed into /vendor
131 Proprietary bool
132
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700133 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
134 // file
135 Logtags []string
136
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700137 // init.rc files to be installed if this module is installed
138 Init_rc []string
139
Chris Wolfe998306e2016-08-15 14:47:23 -0400140 // names of other modules to install if this module is installed
141 Required []string
142
Colin Crossa1ad8d12016-06-01 17:09:44 -0700143 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700144 CompileTarget Target `blueprint:"mutated"`
145 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800146
147 // Set by InitAndroidModule
148 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700149 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700150
151 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800152}
153
154type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700155 Host_supported *bool
156 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800157}
158
Colin Crossc472d572015-03-17 15:06:21 -0700159type Multilib string
160
161const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700162 MultilibBoth Multilib = "both"
163 MultilibFirst Multilib = "first"
164 MultilibCommon Multilib = "common"
165 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700166)
167
Colin Crossa1ad8d12016-06-01 17:09:44 -0700168type HostOrDeviceSupported int
169
170const (
171 _ HostOrDeviceSupported = iota
172 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700173 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700174 DeviceSupported
175 HostAndDeviceSupported
176 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700177 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700178)
179
Colin Cross635c3b02016-05-18 15:37:25 -0700180func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800181 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
182
183 base := m.base()
184 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700185
Colin Crossfc754582016-05-17 16:34:16 -0700186 propertyStructs = append(propertyStructs,
187 &base.nameProperties,
188 &base.commonProperties,
189 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700190
191 return m, propertyStructs
192}
193
Colin Cross635c3b02016-05-18 15:37:25 -0700194func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700195 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
196
197 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
198
199 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800200 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700201 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700202 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800203
Dan Willemsen218f6562015-07-08 18:13:11 -0700204 switch hod {
205 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800206 // Default to module to device supported, host not supported, can override in module
207 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700208 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700209 fallthrough
210 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800211 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
212 }
213
Colin Crosscfad1192015-11-02 16:43:11 -0800214 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800215}
216
217// A AndroidModuleBase object contains the properties that are common to all Android
218// modules. It should be included as an anonymous field in every module
219// struct definition. InitAndroidModule should then be called from the module's
220// factory function, and the return values from InitAndroidModule should be
221// returned from the factory function.
222//
223// The AndroidModuleBase type is responsible for implementing the
224// GenerateBuildActions method to support the blueprint.Module interface. This
225// method will then call the module's GenerateAndroidBuildActions method once
226// for each build variant that is to be built. GenerateAndroidBuildActions is
227// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
228// AndroidModuleContext exposes extra functionality specific to the Android build
229// system including details about the particular build variant that is to be
230// generated.
231//
232// For example:
233//
234// import (
235// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700236// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800237// )
238//
239// type myModule struct {
240// common.AndroidModuleBase
241// properties struct {
242// MyProperty string
243// }
244// }
245//
246// func NewMyModule() (blueprint.Module, []interface{}) {
247// m := &myModule{}
248// return common.InitAndroidModule(m, &m.properties)
249// }
250//
251// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
252// // Get the CPU architecture for the current build variant.
253// variantArch := ctx.Arch()
254//
255// // ...
256// }
Colin Cross635c3b02016-05-18 15:37:25 -0700257type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800258 // Putting the curiously recurring thing pointing to the thing that contains
259 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700260 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800261
Colin Crossfc754582016-05-17 16:34:16 -0700262 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800263 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700264 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800265 hostAndDeviceProperties hostAndDeviceProperties
266 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700267 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700268 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800269
270 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700271 installFiles Paths
272 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700273
274 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
275 // Only set on the final variant of each module
276 installTarget string
277 checkbuildTarget string
278 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700279
Colin Cross178a5092016-09-13 13:42:32 -0700280 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800281}
282
Colin Crossce75d2c2016-10-06 16:12:58 -0700283// Name returns the name of the module. It may be overridden by individual module types, for
284// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700285func (a *ModuleBase) Name() string {
286 return a.nameProperties.Name
287}
288
Colin Crossce75d2c2016-10-06 16:12:58 -0700289// BaseModuleName returns the name of the module as specified in the blueprints file.
290func (a *ModuleBase) BaseModuleName() string {
291 return a.nameProperties.Name
292}
293
Colin Cross635c3b02016-05-18 15:37:25 -0700294func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800295 return a
296}
297
Colin Cross8b74d172016-09-13 09:59:14 -0700298func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700299 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700300 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700301}
302
Colin Crossa1ad8d12016-06-01 17:09:44 -0700303func (a *ModuleBase) Target() Target {
304 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800305}
306
Colin Cross8b74d172016-09-13 09:59:14 -0700307func (a *ModuleBase) TargetPrimary() bool {
308 return a.commonProperties.CompilePrimary
309}
310
Colin Crossa1ad8d12016-06-01 17:09:44 -0700311func (a *ModuleBase) Os() OsType {
312 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800313}
314
Colin Cross635c3b02016-05-18 15:37:25 -0700315func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700316 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800317}
318
Colin Cross635c3b02016-05-18 15:37:25 -0700319func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700320 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800321}
322
Dan Willemsen0b24c742016-10-04 15:13:37 -0700323func (a *ModuleBase) ArchSpecific() bool {
324 return a.commonProperties.ArchSpecific
325}
326
Colin Crossa1ad8d12016-06-01 17:09:44 -0700327func (a *ModuleBase) OsClassSupported() []OsClass {
328 switch a.commonProperties.HostOrDeviceSupported {
329 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700330 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700331 case HostSupportedNoCross:
332 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700333 case DeviceSupported:
334 return []OsClass{Device}
335 case HostAndDeviceSupported:
336 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700337 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700338 supported = append(supported, Host, HostCross)
339 }
Colin Crossa4190c12016-07-12 13:11:25 -0700340 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700341 supported = append(supported, Device)
342 }
343 return supported
344 default:
345 return nil
346 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800347}
348
Colin Cross635c3b02016-05-18 15:37:25 -0700349func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800350 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
351 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700352 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800353}
354
Colin Cross635c3b02016-05-18 15:37:25 -0700355func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800356 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700357 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800358 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800359 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800360}
361
Colin Crossce75d2c2016-10-06 16:12:58 -0700362func (a *ModuleBase) SkipInstall() {
363 a.commonProperties.SkipInstall = true
364}
365
Colin Cross635c3b02016-05-18 15:37:25 -0700366func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700367 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800368
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700369 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800370 ctx.VisitDepsDepthFirstIf(isFileInstaller,
371 func(m blueprint.Module) {
372 fileInstaller := m.(fileInstaller)
373 files := fileInstaller.filesToInstall()
374 result = append(result, files...)
375 })
376
377 return result
378}
379
Colin Cross635c3b02016-05-18 15:37:25 -0700380func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800381 return a.installFiles
382}
383
Colin Cross635c3b02016-05-18 15:37:25 -0700384func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800385 return p.noAddressSanitizer
386}
387
Colin Cross635c3b02016-05-18 15:37:25 -0700388func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800389 return false
390}
391
Colin Cross635c3b02016-05-18 15:37:25 -0700392func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700393 allInstalledFiles := Paths{}
394 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800395 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700396 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700397 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
398 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800399 })
400
Colin Cross9454bfa2015-03-17 13:24:18 -0700401 deps := []string{}
402
Colin Cross3f40fa42015-01-30 17:27:36 -0800403 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700404 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700406 Rule: blueprint.Phony,
407 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700408 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800409 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700410 })
411 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700412 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700413 }
414
415 if len(allCheckbuildFiles) > 0 {
416 name := ctx.ModuleName() + "-checkbuild"
417 ctx.Build(pctx, blueprint.BuildParams{
418 Rule: blueprint.Phony,
419 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700420 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700421 Optional: true,
422 })
423 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700424 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700425 }
426
427 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800428 suffix := ""
429 if ctx.Config().(Config).EmbeddedInMake() {
430 suffix = "-soong"
431 }
432
Colin Cross9454bfa2015-03-17 13:24:18 -0700433 ctx.Build(pctx, blueprint.BuildParams{
434 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800435 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700436 Implicits: deps,
437 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700439
440 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800441 }
442}
443
Colin Cross635c3b02016-05-18 15:37:25 -0700444func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700445 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700446 target: a.commonProperties.CompileTarget,
447 targetPrimary: a.commonProperties.CompilePrimary,
448 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800449 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800450}
451
Colin Cross635c3b02016-05-18 15:37:25 -0700452func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800453 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700454 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700455 ModuleContext: ctx,
456 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
457 installDeps: a.computeInstallDeps(ctx),
458 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800459 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800460 }
461
Colin Cross9b1d13d2016-09-19 15:18:11 -0700462 if a.Enabled() {
463 a.module.GenerateAndroidBuildActions(androidCtx)
464 if ctx.Failed() {
465 return
466 }
467
468 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
469 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800470 }
471
Colin Cross9b1d13d2016-09-19 15:18:11 -0700472 if a == ctx.FinalModule().(Module).base() {
473 a.generateModuleTarget(ctx)
474 if ctx.Failed() {
475 return
476 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 }
478}
479
Colin Crossf6566ed2015-03-24 11:13:38 -0700480type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700481 target Target
482 targetPrimary bool
483 debug bool
484 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700485}
486
Colin Cross3f40fa42015-01-30 17:27:36 -0800487type androidModuleContext struct {
488 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700489 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700490 installDeps Paths
491 installFiles Paths
492 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800493 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700494 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800495}
496
497func (a *androidModuleContext) ninjaError(outputs []string, err error) {
498 a.ModuleContext.Build(pctx, blueprint.BuildParams{
499 Rule: ErrorRule,
500 Outputs: outputs,
501 Optional: true,
502 Args: map[string]string{
503 "error": err.Error(),
504 },
505 })
506 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800507}
508
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800509func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700510 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800511 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
512 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
513 return
514 }
515
Colin Cross3f40fa42015-01-30 17:27:36 -0800516 params.Optional = true
517 a.ModuleContext.Build(pctx, params)
518}
519
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700520func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
521 bparams := blueprint.BuildParams{
522 Rule: params.Rule,
523 Outputs: params.Outputs.Strings(),
524 Inputs: params.Inputs.Strings(),
525 Implicits: params.Implicits.Strings(),
526 OrderOnly: params.OrderOnly.Strings(),
527 Args: params.Args,
528 Optional: !params.Default,
529 }
530
531 if params.Output != nil {
532 bparams.Outputs = append(bparams.Outputs, params.Output.String())
533 }
534 if params.Input != nil {
535 bparams.Inputs = append(bparams.Inputs, params.Input.String())
536 }
537 if params.Implicit != nil {
538 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
539 }
540
Colin Cross6ff51382015-12-17 16:39:19 -0800541 if a.missingDeps != nil {
542 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
543 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
544 return
545 }
546
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700547 a.ModuleContext.Build(pctx, bparams)
548}
549
Colin Cross6ff51382015-12-17 16:39:19 -0800550func (a *androidModuleContext) GetMissingDependencies() []string {
551 return a.missingDeps
552}
553
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800554func (a *androidModuleContext) AddMissingDependencies(deps []string) {
555 if deps != nil {
556 a.missingDeps = append(a.missingDeps, deps...)
557 }
558}
559
Colin Crossa1ad8d12016-06-01 17:09:44 -0700560func (a *androidBaseContextImpl) Target() Target {
561 return a.target
562}
563
Colin Cross8b74d172016-09-13 09:59:14 -0700564func (a *androidBaseContextImpl) TargetPrimary() bool {
565 return a.targetPrimary
566}
567
Colin Crossf6566ed2015-03-24 11:13:38 -0700568func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700569 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800570}
571
Colin Crossa1ad8d12016-06-01 17:09:44 -0700572func (a *androidBaseContextImpl) Os() OsType {
573 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800574}
575
Colin Crossf6566ed2015-03-24 11:13:38 -0700576func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700577 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700578}
579
580func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700581 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700582}
583
Colin Cross0af4b842015-04-30 16:36:18 -0700584func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700585 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700586}
587
Colin Crossf6566ed2015-03-24 11:13:38 -0700588func (a *androidBaseContextImpl) Debug() bool {
589 return a.debug
590}
591
Colin Cross1e7d3702016-08-24 15:25:47 -0700592func (a *androidBaseContextImpl) PrimaryArch() bool {
593 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
594}
595
Colin Cross1332b002015-04-07 17:11:30 -0700596func (a *androidBaseContextImpl) AConfig() Config {
597 return a.config
598}
599
Colin Cross9272ade2016-08-17 15:24:12 -0700600func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
601 return DeviceConfig{a.config.deviceConfig}
602}
603
Colin Cross8d8f8e22016-08-03 11:57:50 -0700604func (a *androidModuleContext) Proprietary() bool {
605 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800606}
607
Colin Cross8d8f8e22016-08-03 11:57:50 -0700608func (a *androidModuleContext) InstallInData() bool {
609 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800610}
611
612func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700613 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700614
Dan Willemsen782a2d12015-12-21 14:55:28 -0800615 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700616 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800617
Colin Crossce75d2c2016-10-06 16:12:58 -0700618 if !a.module.base().commonProperties.SkipInstall &&
619 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
620
Dan Willemsen322acaf2016-01-12 23:07:05 -0800621 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700622
Colin Cross89562dc2016-10-03 17:47:19 -0700623 var implicitDeps, orderOnlyDeps Paths
624
625 if a.Host() {
626 // Installed host modules might be used during the build, depend directly on their
627 // dependencies so their timestamp is updated whenever their dependency is updated
628 implicitDeps = deps
629 } else {
630 orderOnlyDeps = deps
631 }
632
Dan Willemsen322acaf2016-01-12 23:07:05 -0800633 a.ModuleBuild(pctx, ModuleBuildParams{
634 Rule: Cp,
635 Output: fullInstallPath,
636 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700637 Implicits: implicitDeps,
638 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800639 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800640 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800641
Dan Willemsen322acaf2016-01-12 23:07:05 -0800642 a.installFiles = append(a.installFiles, fullInstallPath)
643 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700644 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700645 return fullInstallPath
646}
647
Colin Crossa2344662016-03-24 13:14:12 -0700648func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700649 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800650}
651
Colin Cross3854a602016-01-11 12:49:11 -0800652func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
653 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700654 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800655
Colin Crossce75d2c2016-10-06 16:12:58 -0700656 if !a.module.base().commonProperties.SkipInstall &&
657 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
658
Colin Cross12fc4972016-01-11 12:49:11 -0800659 a.ModuleBuild(pctx, ModuleBuildParams{
660 Rule: Symlink,
661 Output: fullInstallPath,
662 OrderOnly: Paths{srcPath},
663 Default: !a.AConfig().EmbeddedInMake(),
664 Args: map[string]string{
665 "fromPath": srcPath.String(),
666 },
667 })
Colin Cross3854a602016-01-11 12:49:11 -0800668
Colin Cross12fc4972016-01-11 12:49:11 -0800669 a.installFiles = append(a.installFiles, fullInstallPath)
670 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
671 }
Colin Cross3854a602016-01-11 12:49:11 -0800672 return fullInstallPath
673}
674
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700675func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800676 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
677}
678
Colin Cross3f40fa42015-01-30 17:27:36 -0800679type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700680 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800681}
682
683func isFileInstaller(m blueprint.Module) bool {
684 _, ok := m.(fileInstaller)
685 return ok
686}
687
688func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700689 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800690 return ok
691}
Colin Crossfce53272015-04-08 11:21:40 -0700692
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700693func findStringInSlice(str string, slice []string) int {
694 for i, s := range slice {
695 if s == str {
696 return i
Colin Crossfce53272015-04-08 11:21:40 -0700697 }
698 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700699 return -1
700}
701
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700702func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
703 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700704 for i, e := range excludes {
705 j := findStringInSlice(e, srcFiles)
706 if j != -1 {
707 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
708 }
709
710 excludes[i] = filepath.Join(prefix, e)
711 }
712
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700713 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700714 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700715 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700716 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700717 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700718 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700719 }
720 }
721
722 return globbedSrcFiles
723}
724
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700725func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
726 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700727 if err != nil {
728 ctx.ModuleErrorf("glob: %s", err.Error())
729 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700730 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700731}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700732
Colin Cross463a90e2015-06-17 14:20:06 -0700733func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700734 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700735}
736
Colin Cross1f8c52b2015-06-16 16:38:17 -0700737func BuildTargetSingleton() blueprint.Singleton {
738 return &buildTargetSingleton{}
739}
740
741type buildTargetSingleton struct{}
742
743func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
744 checkbuildDeps := []string{}
745
746 dirModules := make(map[string][]string)
747
748 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700749 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700750 blueprintDir := a.base().blueprintDir
751 installTarget := a.base().installTarget
752 checkbuildTarget := a.base().checkbuildTarget
753
754 if checkbuildTarget != "" {
755 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
756 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
757 }
758
759 if installTarget != "" {
760 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
761 }
762 }
763 })
764
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800765 suffix := ""
766 if ctx.Config().(Config).EmbeddedInMake() {
767 suffix = "-soong"
768 }
769
Colin Cross1f8c52b2015-06-16 16:38:17 -0700770 // Create a top-level checkbuild target that depends on all modules
771 ctx.Build(pctx, blueprint.BuildParams{
772 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800773 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700774 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700775 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700776 })
777
778 // Create a mm/<directory> target that depends on all modules in a directory
779 dirs := sortedKeys(dirModules)
780 for _, dir := range dirs {
781 ctx.Build(pctx, blueprint.BuildParams{
782 Rule: blueprint.Phony,
783 Outputs: []string{filepath.Join("mm", dir)},
784 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800785 // HACK: checkbuild should be an optional build, but force it
786 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800787 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700788 })
789 }
790}
Colin Crossd779da42015-12-17 18:00:23 -0800791
792type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700793 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800794 ctx interface {
795 ModuleName(blueprint.Module) string
796 ModuleSubDir(blueprint.Module) string
797 }
798}
799
800func (s AndroidModulesByName) Len() int { return len(s.slice) }
801func (s AndroidModulesByName) Less(i, j int) bool {
802 mi, mj := s.slice[i], s.slice[j]
803 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
804
805 if ni != nj {
806 return ni < nj
807 } else {
808 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
809 }
810}
811func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }