blob: 5894ee7e419a4ac1e3331b808f27303b89331e3e [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 {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070037 Rule blueprint.Rule
38 Output WritablePath
39 Outputs WritablePaths
40 ImplicitOutput WritablePath
41 ImplicitOutputs WritablePaths
42 Input Path
43 Inputs Paths
44 Implicit Path
45 Implicits Paths
46 OrderOnly Paths
47 Default bool
48 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070049}
50
Colin Crossf6566ed2015-03-24 11:13:38 -070051type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070052 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070053 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070054 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070055 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070056 Host() bool
57 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070058 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070059 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070060 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070061 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070062 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070063}
64
Colin Cross635c3b02016-05-18 15:37:25 -070065type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070066 blueprint.BaseModuleContext
67 androidBaseContext
68}
69
Colin Cross635c3b02016-05-18 15:37:25 -070070type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080071 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070072 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080073
Dan Willemsen34cc69e2015-09-23 15:26:20 -070074 // Similar to Build, but takes Paths instead of []string,
75 // and performs more verification.
76 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070077
Dan Willemsen34cc69e2015-09-23 15:26:20 -070078 ExpandSources(srcFiles, excludes []string) Paths
79 Glob(outDir, globPattern string, excludes []string) Paths
80
Colin Crossa2344662016-03-24 13:14:12 -070081 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
82 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080083 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070084 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080085
86 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070087
88 Proprietary() bool
89 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080090}
91
Colin Cross635c3b02016-05-18 15:37:25 -070092type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080093 blueprint.Module
94
Colin Cross635c3b02016-05-18 15:37:25 -070095 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -070096 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080097
Colin Cross635c3b02016-05-18 15:37:25 -070098 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080099 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700100 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800101 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800102}
103
Colin Crossfc754582016-05-17 16:34:16 -0700104type nameProperties struct {
105 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700106 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700107}
108
109type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700110 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800111
Dan Willemsen0effe062015-11-30 16:06:01 -0800112 // emit build rules for this module
113 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800114
Colin Cross7d5136f2015-05-11 13:39:40 -0700115 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800116 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
117 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
118 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700119 Compile_multilib string `android:"arch_variant"`
120
121 Target struct {
122 Host struct {
123 Compile_multilib string
124 }
125 Android struct {
126 Compile_multilib string
127 }
128 }
129
130 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800131
Dan Willemsen782a2d12015-12-21 14:55:28 -0800132 // whether this is a proprietary vendor module, and should be installed into /vendor
133 Proprietary bool
134
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700135 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
136 // file
137 Logtags []string
138
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700139 // init.rc files to be installed if this module is installed
140 Init_rc []string
141
Chris Wolfe998306e2016-08-15 14:47:23 -0400142 // names of other modules to install if this module is installed
143 Required []string
144
Colin Crossa1ad8d12016-06-01 17:09:44 -0700145 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700146 CompileTarget Target `blueprint:"mutated"`
147 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800148
149 // Set by InitAndroidModule
150 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700151 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700152
153 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800154}
155
156type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700157 Host_supported *bool
158 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800159}
160
Colin Crossc472d572015-03-17 15:06:21 -0700161type Multilib string
162
163const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700164 MultilibBoth Multilib = "both"
165 MultilibFirst Multilib = "first"
166 MultilibCommon Multilib = "common"
167 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700168)
169
Colin Crossa1ad8d12016-06-01 17:09:44 -0700170type HostOrDeviceSupported int
171
172const (
173 _ HostOrDeviceSupported = iota
174 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700175 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700176 DeviceSupported
177 HostAndDeviceSupported
178 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700179 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700180)
181
Colin Cross635c3b02016-05-18 15:37:25 -0700182func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800183 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
184
185 base := m.base()
186 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700187
Colin Crossfc754582016-05-17 16:34:16 -0700188 propertyStructs = append(propertyStructs,
189 &base.nameProperties,
190 &base.commonProperties,
191 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700192
193 return m, propertyStructs
194}
195
Colin Cross635c3b02016-05-18 15:37:25 -0700196func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700197 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
198
199 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
200
201 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800202 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700203 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700204 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800205
Dan Willemsen218f6562015-07-08 18:13:11 -0700206 switch hod {
207 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800208 // Default to module to device supported, host not supported, can override in module
209 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700210 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700211 fallthrough
212 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800213 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
214 }
215
Colin Crosscfad1192015-11-02 16:43:11 -0800216 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800217}
218
219// A AndroidModuleBase object contains the properties that are common to all Android
220// modules. It should be included as an anonymous field in every module
221// struct definition. InitAndroidModule should then be called from the module's
222// factory function, and the return values from InitAndroidModule should be
223// returned from the factory function.
224//
225// The AndroidModuleBase type is responsible for implementing the
226// GenerateBuildActions method to support the blueprint.Module interface. This
227// method will then call the module's GenerateAndroidBuildActions method once
228// for each build variant that is to be built. GenerateAndroidBuildActions is
229// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
230// AndroidModuleContext exposes extra functionality specific to the Android build
231// system including details about the particular build variant that is to be
232// generated.
233//
234// For example:
235//
236// import (
237// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700238// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800239// )
240//
241// type myModule struct {
242// common.AndroidModuleBase
243// properties struct {
244// MyProperty string
245// }
246// }
247//
248// func NewMyModule() (blueprint.Module, []interface{}) {
249// m := &myModule{}
250// return common.InitAndroidModule(m, &m.properties)
251// }
252//
253// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
254// // Get the CPU architecture for the current build variant.
255// variantArch := ctx.Arch()
256//
257// // ...
258// }
Colin Cross635c3b02016-05-18 15:37:25 -0700259type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800260 // Putting the curiously recurring thing pointing to the thing that contains
261 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700262 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800263
Colin Crossfc754582016-05-17 16:34:16 -0700264 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800265 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700266 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800267 hostAndDeviceProperties hostAndDeviceProperties
268 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700269 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700270 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800271
272 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700273 installFiles Paths
274 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700275
276 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
277 // Only set on the final variant of each module
278 installTarget string
279 checkbuildTarget string
280 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700281
Colin Cross178a5092016-09-13 13:42:32 -0700282 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800283}
284
Colin Crossce75d2c2016-10-06 16:12:58 -0700285// Name returns the name of the module. It may be overridden by individual module types, for
286// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700287func (a *ModuleBase) Name() string {
288 return a.nameProperties.Name
289}
290
Colin Crossce75d2c2016-10-06 16:12:58 -0700291// BaseModuleName returns the name of the module as specified in the blueprints file.
292func (a *ModuleBase) BaseModuleName() string {
293 return a.nameProperties.Name
294}
295
Colin Cross635c3b02016-05-18 15:37:25 -0700296func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800297 return a
298}
299
Colin Cross8b74d172016-09-13 09:59:14 -0700300func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700301 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700302 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700303}
304
Colin Crossa1ad8d12016-06-01 17:09:44 -0700305func (a *ModuleBase) Target() Target {
306 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800307}
308
Colin Cross8b74d172016-09-13 09:59:14 -0700309func (a *ModuleBase) TargetPrimary() bool {
310 return a.commonProperties.CompilePrimary
311}
312
Colin Crossa1ad8d12016-06-01 17:09:44 -0700313func (a *ModuleBase) Os() OsType {
314 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800315}
316
Colin Cross635c3b02016-05-18 15:37:25 -0700317func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700318 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800319}
320
Colin Cross635c3b02016-05-18 15:37:25 -0700321func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700322 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800323}
324
Dan Willemsen0b24c742016-10-04 15:13:37 -0700325func (a *ModuleBase) ArchSpecific() bool {
326 return a.commonProperties.ArchSpecific
327}
328
Colin Crossa1ad8d12016-06-01 17:09:44 -0700329func (a *ModuleBase) OsClassSupported() []OsClass {
330 switch a.commonProperties.HostOrDeviceSupported {
331 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700332 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700333 case HostSupportedNoCross:
334 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700335 case DeviceSupported:
336 return []OsClass{Device}
337 case HostAndDeviceSupported:
338 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700339 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700340 supported = append(supported, Host, HostCross)
341 }
Colin Crossa4190c12016-07-12 13:11:25 -0700342 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700343 supported = append(supported, Device)
344 }
345 return supported
346 default:
347 return nil
348 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800349}
350
Colin Cross635c3b02016-05-18 15:37:25 -0700351func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800352 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
353 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700354 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800355}
356
Colin Cross635c3b02016-05-18 15:37:25 -0700357func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800358 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700359 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800360 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800361 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800362}
363
Colin Crossce75d2c2016-10-06 16:12:58 -0700364func (a *ModuleBase) SkipInstall() {
365 a.commonProperties.SkipInstall = true
366}
367
Colin Cross635c3b02016-05-18 15:37:25 -0700368func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700369 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800370
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700371 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800372 ctx.VisitDepsDepthFirstIf(isFileInstaller,
373 func(m blueprint.Module) {
374 fileInstaller := m.(fileInstaller)
375 files := fileInstaller.filesToInstall()
376 result = append(result, files...)
377 })
378
379 return result
380}
381
Colin Cross635c3b02016-05-18 15:37:25 -0700382func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800383 return a.installFiles
384}
385
Colin Cross635c3b02016-05-18 15:37:25 -0700386func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800387 return p.noAddressSanitizer
388}
389
Colin Cross635c3b02016-05-18 15:37:25 -0700390func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800391 return false
392}
393
Colin Cross635c3b02016-05-18 15:37:25 -0700394func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700395 allInstalledFiles := Paths{}
396 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800397 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700398 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700399 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
400 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800401 })
402
Colin Cross9454bfa2015-03-17 13:24:18 -0700403 deps := []string{}
404
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700406 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800407 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700408 Rule: blueprint.Phony,
409 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700410 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800411 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700412 })
413 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700414 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700415 }
416
417 if len(allCheckbuildFiles) > 0 {
418 name := ctx.ModuleName() + "-checkbuild"
419 ctx.Build(pctx, blueprint.BuildParams{
420 Rule: blueprint.Phony,
421 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700422 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700423 Optional: true,
424 })
425 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700426 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700427 }
428
429 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800430 suffix := ""
431 if ctx.Config().(Config).EmbeddedInMake() {
432 suffix = "-soong"
433 }
434
Colin Cross9454bfa2015-03-17 13:24:18 -0700435 ctx.Build(pctx, blueprint.BuildParams{
436 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800437 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700438 Implicits: deps,
439 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800440 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700441
442 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800443 }
444}
445
Colin Cross635c3b02016-05-18 15:37:25 -0700446func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700447 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700448 target: a.commonProperties.CompileTarget,
449 targetPrimary: a.commonProperties.CompilePrimary,
450 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800451 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800452}
453
Colin Cross635c3b02016-05-18 15:37:25 -0700454func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800455 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700456 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700457 ModuleContext: ctx,
458 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
459 installDeps: a.computeInstallDeps(ctx),
460 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800461 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800462 }
463
Colin Cross9b1d13d2016-09-19 15:18:11 -0700464 if a.Enabled() {
465 a.module.GenerateAndroidBuildActions(androidCtx)
466 if ctx.Failed() {
467 return
468 }
469
470 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
471 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800472 }
473
Colin Cross9b1d13d2016-09-19 15:18:11 -0700474 if a == ctx.FinalModule().(Module).base() {
475 a.generateModuleTarget(ctx)
476 if ctx.Failed() {
477 return
478 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800479 }
480}
481
Colin Crossf6566ed2015-03-24 11:13:38 -0700482type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700483 target Target
484 targetPrimary bool
485 debug bool
486 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700487}
488
Colin Cross3f40fa42015-01-30 17:27:36 -0800489type androidModuleContext struct {
490 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700491 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700492 installDeps Paths
493 installFiles Paths
494 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800495 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700496 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800497}
498
499func (a *androidModuleContext) ninjaError(outputs []string, err error) {
500 a.ModuleContext.Build(pctx, blueprint.BuildParams{
501 Rule: ErrorRule,
502 Outputs: outputs,
503 Optional: true,
504 Args: map[string]string{
505 "error": err.Error(),
506 },
507 })
508 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800509}
510
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800511func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700512 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800513 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
514 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
515 return
516 }
517
Colin Cross3f40fa42015-01-30 17:27:36 -0800518 params.Optional = true
519 a.ModuleContext.Build(pctx, params)
520}
521
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700522func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
523 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700524 Rule: params.Rule,
525 Outputs: params.Outputs.Strings(),
526 ImplicitOutputs: params.ImplicitOutputs.Strings(),
527 Inputs: params.Inputs.Strings(),
528 Implicits: params.Implicits.Strings(),
529 OrderOnly: params.OrderOnly.Strings(),
530 Args: params.Args,
531 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700532 }
533
534 if params.Output != nil {
535 bparams.Outputs = append(bparams.Outputs, params.Output.String())
536 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700537 if params.ImplicitOutput != nil {
538 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
539 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700540 if params.Input != nil {
541 bparams.Inputs = append(bparams.Inputs, params.Input.String())
542 }
543 if params.Implicit != nil {
544 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
545 }
546
Colin Cross6ff51382015-12-17 16:39:19 -0800547 if a.missingDeps != nil {
548 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
549 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
550 return
551 }
552
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700553 a.ModuleContext.Build(pctx, bparams)
554}
555
Colin Cross6ff51382015-12-17 16:39:19 -0800556func (a *androidModuleContext) GetMissingDependencies() []string {
557 return a.missingDeps
558}
559
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800560func (a *androidModuleContext) AddMissingDependencies(deps []string) {
561 if deps != nil {
562 a.missingDeps = append(a.missingDeps, deps...)
563 }
564}
565
Colin Crossa1ad8d12016-06-01 17:09:44 -0700566func (a *androidBaseContextImpl) Target() Target {
567 return a.target
568}
569
Colin Cross8b74d172016-09-13 09:59:14 -0700570func (a *androidBaseContextImpl) TargetPrimary() bool {
571 return a.targetPrimary
572}
573
Colin Crossf6566ed2015-03-24 11:13:38 -0700574func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700575 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800576}
577
Colin Crossa1ad8d12016-06-01 17:09:44 -0700578func (a *androidBaseContextImpl) Os() OsType {
579 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800580}
581
Colin Crossf6566ed2015-03-24 11:13:38 -0700582func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700583 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700584}
585
586func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700587 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700588}
589
Colin Cross0af4b842015-04-30 16:36:18 -0700590func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700591 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700592}
593
Colin Crossf6566ed2015-03-24 11:13:38 -0700594func (a *androidBaseContextImpl) Debug() bool {
595 return a.debug
596}
597
Colin Cross1e7d3702016-08-24 15:25:47 -0700598func (a *androidBaseContextImpl) PrimaryArch() bool {
599 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
600}
601
Colin Cross1332b002015-04-07 17:11:30 -0700602func (a *androidBaseContextImpl) AConfig() Config {
603 return a.config
604}
605
Colin Cross9272ade2016-08-17 15:24:12 -0700606func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
607 return DeviceConfig{a.config.deviceConfig}
608}
609
Colin Cross8d8f8e22016-08-03 11:57:50 -0700610func (a *androidModuleContext) Proprietary() bool {
611 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800612}
613
Colin Cross8d8f8e22016-08-03 11:57:50 -0700614func (a *androidModuleContext) InstallInData() bool {
615 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800616}
617
618func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700619 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700620
Dan Willemsen782a2d12015-12-21 14:55:28 -0800621 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700622 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800623
Colin Crossce75d2c2016-10-06 16:12:58 -0700624 if !a.module.base().commonProperties.SkipInstall &&
625 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
626
Dan Willemsen322acaf2016-01-12 23:07:05 -0800627 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700628
Colin Cross89562dc2016-10-03 17:47:19 -0700629 var implicitDeps, orderOnlyDeps Paths
630
631 if a.Host() {
632 // Installed host modules might be used during the build, depend directly on their
633 // dependencies so their timestamp is updated whenever their dependency is updated
634 implicitDeps = deps
635 } else {
636 orderOnlyDeps = deps
637 }
638
Dan Willemsen322acaf2016-01-12 23:07:05 -0800639 a.ModuleBuild(pctx, ModuleBuildParams{
640 Rule: Cp,
641 Output: fullInstallPath,
642 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700643 Implicits: implicitDeps,
644 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800645 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800646 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800647
Dan Willemsen322acaf2016-01-12 23:07:05 -0800648 a.installFiles = append(a.installFiles, fullInstallPath)
649 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700650 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700651 return fullInstallPath
652}
653
Colin Crossa2344662016-03-24 13:14:12 -0700654func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700655 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800656}
657
Colin Cross3854a602016-01-11 12:49:11 -0800658func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
659 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700660 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800661
Colin Crossce75d2c2016-10-06 16:12:58 -0700662 if !a.module.base().commonProperties.SkipInstall &&
663 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
664
Colin Cross12fc4972016-01-11 12:49:11 -0800665 a.ModuleBuild(pctx, ModuleBuildParams{
666 Rule: Symlink,
667 Output: fullInstallPath,
668 OrderOnly: Paths{srcPath},
669 Default: !a.AConfig().EmbeddedInMake(),
670 Args: map[string]string{
671 "fromPath": srcPath.String(),
672 },
673 })
Colin Cross3854a602016-01-11 12:49:11 -0800674
Colin Cross12fc4972016-01-11 12:49:11 -0800675 a.installFiles = append(a.installFiles, fullInstallPath)
676 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
677 }
Colin Cross3854a602016-01-11 12:49:11 -0800678 return fullInstallPath
679}
680
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700681func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800682 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
683}
684
Colin Cross3f40fa42015-01-30 17:27:36 -0800685type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700686 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800687}
688
689func isFileInstaller(m blueprint.Module) bool {
690 _, ok := m.(fileInstaller)
691 return ok
692}
693
694func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700695 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800696 return ok
697}
Colin Crossfce53272015-04-08 11:21:40 -0700698
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700699func findStringInSlice(str string, slice []string) int {
700 for i, s := range slice {
701 if s == str {
702 return i
Colin Crossfce53272015-04-08 11:21:40 -0700703 }
704 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700705 return -1
706}
707
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700708func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
709 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700710 for i, e := range excludes {
711 j := findStringInSlice(e, srcFiles)
712 if j != -1 {
713 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
714 }
715
716 excludes[i] = filepath.Join(prefix, e)
717 }
718
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700719 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700720 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700721 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700722 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700723 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700724 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700725 }
726 }
727
728 return globbedSrcFiles
729}
730
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700731func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
732 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700733 if err != nil {
734 ctx.ModuleErrorf("glob: %s", err.Error())
735 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700736 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700737}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700738
Colin Cross463a90e2015-06-17 14:20:06 -0700739func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700740 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700741}
742
Colin Cross1f8c52b2015-06-16 16:38:17 -0700743func BuildTargetSingleton() blueprint.Singleton {
744 return &buildTargetSingleton{}
745}
746
747type buildTargetSingleton struct{}
748
749func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
750 checkbuildDeps := []string{}
751
752 dirModules := make(map[string][]string)
753
754 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700755 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700756 blueprintDir := a.base().blueprintDir
757 installTarget := a.base().installTarget
758 checkbuildTarget := a.base().checkbuildTarget
759
760 if checkbuildTarget != "" {
761 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
762 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
763 }
764
765 if installTarget != "" {
766 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
767 }
768 }
769 })
770
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800771 suffix := ""
772 if ctx.Config().(Config).EmbeddedInMake() {
773 suffix = "-soong"
774 }
775
Colin Cross1f8c52b2015-06-16 16:38:17 -0700776 // Create a top-level checkbuild target that depends on all modules
777 ctx.Build(pctx, blueprint.BuildParams{
778 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800779 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700780 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700781 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700782 })
783
784 // Create a mm/<directory> target that depends on all modules in a directory
785 dirs := sortedKeys(dirModules)
786 for _, dir := range dirs {
787 ctx.Build(pctx, blueprint.BuildParams{
788 Rule: blueprint.Phony,
789 Outputs: []string{filepath.Join("mm", dir)},
790 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800791 // HACK: checkbuild should be an optional build, but force it
792 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800793 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700794 })
795 }
796}
Colin Crossd779da42015-12-17 18:00:23 -0800797
798type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700799 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800800 ctx interface {
801 ModuleName(blueprint.Module) string
802 ModuleSubDir(blueprint.Module) string
803 }
804}
805
806func (s AndroidModulesByName) Len() int { return len(s.slice) }
807func (s AndroidModulesByName) Less(i, j int) bool {
808 mi, mj := s.slice[i], s.slice[j]
809 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
810
811 if ni != nj {
812 return ni < nj
813 } else {
814 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
815 }
816}
817func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }