blob: 2b6f8ba581772691b5d5a215b277ce87ddd4325a [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
22 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070023 "github.com/google/blueprint/pathtools"
Colin Cross3f40fa42015-01-30 17:27:36 -080024)
25
26var (
27 DeviceSharedLibrary = "shared_library"
28 DeviceStaticLibrary = "static_library"
29 DeviceExecutable = "executable"
30 HostSharedLibrary = "host_shared_library"
31 HostStaticLibrary = "host_static_library"
32 HostExecutable = "host_executable"
33)
34
Dan Willemsen34cc69e2015-09-23 15:26:20 -070035type ModuleBuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070036 Rule blueprint.Rule
37 Output WritablePath
38 Outputs WritablePaths
39 ImplicitOutput WritablePath
40 ImplicitOutputs WritablePaths
41 Input Path
42 Inputs Paths
43 Implicit Path
44 Implicits Paths
45 OrderOnly Paths
46 Default bool
47 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070048}
49
Colin Crossf6566ed2015-03-24 11:13:38 -070050type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070051 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070052 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070053 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070054 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070055 Host() bool
56 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070057 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070058 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070059 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070060 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070061 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070062}
63
Colin Cross635c3b02016-05-18 15:37:25 -070064type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070065 blueprint.BaseModuleContext
66 androidBaseContext
67}
68
Colin Cross635c3b02016-05-18 15:37:25 -070069type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080070 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070071 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080072
Dan Willemsen34cc69e2015-09-23 15:26:20 -070073 // Similar to Build, but takes Paths instead of []string,
74 // and performs more verification.
75 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070076
Dan Willemsen34cc69e2015-09-23 15:26:20 -070077 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070078 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070079
Colin Crossa2344662016-03-24 13:14:12 -070080 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
81 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080082 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070083 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080084
85 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070086
87 Proprietary() bool
88 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080089}
90
Colin Cross635c3b02016-05-18 15:37:25 -070091type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080092 blueprint.Module
93
Colin Cross635c3b02016-05-18 15:37:25 -070094 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -070095 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080096
Colin Cross635c3b02016-05-18 15:37:25 -070097 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080098 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070099 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800100 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800101}
102
Colin Crossfc754582016-05-17 16:34:16 -0700103type nameProperties struct {
104 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700105 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700106}
107
108type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700109 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800110
Dan Willemsen0effe062015-11-30 16:06:01 -0800111 // emit build rules for this module
112 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800113
Colin Cross7d5136f2015-05-11 13:39:40 -0700114 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800115 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
116 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
117 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700118 Compile_multilib string `android:"arch_variant"`
119
120 Target struct {
121 Host struct {
122 Compile_multilib string
123 }
124 Android struct {
125 Compile_multilib string
126 }
127 }
128
129 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800130
Dan Willemsen782a2d12015-12-21 14:55:28 -0800131 // whether this is a proprietary vendor module, and should be installed into /vendor
132 Proprietary bool
133
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700134 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
135 // file
136 Logtags []string
137
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700138 // init.rc files to be installed if this module is installed
139 Init_rc []string
140
Chris Wolfe998306e2016-08-15 14:47:23 -0400141 // names of other modules to install if this module is installed
142 Required []string
143
Colin Crossa1ad8d12016-06-01 17:09:44 -0700144 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700145 CompileTarget Target `blueprint:"mutated"`
146 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800147
148 // Set by InitAndroidModule
149 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700150 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700151
152 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800153}
154
155type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700156 Host_supported *bool
157 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800158}
159
Colin Crossc472d572015-03-17 15:06:21 -0700160type Multilib string
161
162const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700163 MultilibBoth Multilib = "both"
164 MultilibFirst Multilib = "first"
165 MultilibCommon Multilib = "common"
166 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700167)
168
Colin Crossa1ad8d12016-06-01 17:09:44 -0700169type HostOrDeviceSupported int
170
171const (
172 _ HostOrDeviceSupported = iota
173 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700174 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700175 DeviceSupported
176 HostAndDeviceSupported
177 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700178 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700179)
180
Colin Cross635c3b02016-05-18 15:37:25 -0700181func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800182 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
183
184 base := m.base()
185 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700186
Colin Crossfc754582016-05-17 16:34:16 -0700187 propertyStructs = append(propertyStructs,
188 &base.nameProperties,
189 &base.commonProperties,
190 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700191
192 return m, propertyStructs
193}
194
Colin Cross635c3b02016-05-18 15:37:25 -0700195func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700196 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
197
198 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
199
200 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800201 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700202 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700203 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800204
Dan Willemsen218f6562015-07-08 18:13:11 -0700205 switch hod {
206 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800207 // Default to module to device supported, host not supported, can override in module
208 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700209 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700210 fallthrough
211 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800212 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
213 }
214
Colin Crosscfad1192015-11-02 16:43:11 -0800215 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800216}
217
218// A AndroidModuleBase object contains the properties that are common to all Android
219// modules. It should be included as an anonymous field in every module
220// struct definition. InitAndroidModule should then be called from the module's
221// factory function, and the return values from InitAndroidModule should be
222// returned from the factory function.
223//
224// The AndroidModuleBase type is responsible for implementing the
225// GenerateBuildActions method to support the blueprint.Module interface. This
226// method will then call the module's GenerateAndroidBuildActions method once
227// for each build variant that is to be built. GenerateAndroidBuildActions is
228// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
229// AndroidModuleContext exposes extra functionality specific to the Android build
230// system including details about the particular build variant that is to be
231// generated.
232//
233// For example:
234//
235// import (
236// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700237// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800238// )
239//
240// type myModule struct {
241// common.AndroidModuleBase
242// properties struct {
243// MyProperty string
244// }
245// }
246//
247// func NewMyModule() (blueprint.Module, []interface{}) {
248// m := &myModule{}
249// return common.InitAndroidModule(m, &m.properties)
250// }
251//
252// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
253// // Get the CPU architecture for the current build variant.
254// variantArch := ctx.Arch()
255//
256// // ...
257// }
Colin Cross635c3b02016-05-18 15:37:25 -0700258type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800259 // Putting the curiously recurring thing pointing to the thing that contains
260 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700261 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800262
Colin Crossfc754582016-05-17 16:34:16 -0700263 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800264 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700265 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800266 hostAndDeviceProperties hostAndDeviceProperties
267 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700268 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700269 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800270
271 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700272 installFiles Paths
273 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700274
275 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
276 // Only set on the final variant of each module
277 installTarget string
278 checkbuildTarget string
279 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700280
Colin Cross178a5092016-09-13 13:42:32 -0700281 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800282}
283
Colin Crossce75d2c2016-10-06 16:12:58 -0700284// Name returns the name of the module. It may be overridden by individual module types, for
285// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700286func (a *ModuleBase) Name() string {
287 return a.nameProperties.Name
288}
289
Colin Crossce75d2c2016-10-06 16:12:58 -0700290// BaseModuleName returns the name of the module as specified in the blueprints file.
291func (a *ModuleBase) BaseModuleName() string {
292 return a.nameProperties.Name
293}
294
Colin Cross635c3b02016-05-18 15:37:25 -0700295func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800296 return a
297}
298
Colin Cross8b74d172016-09-13 09:59:14 -0700299func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700300 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700301 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700302}
303
Colin Crossa1ad8d12016-06-01 17:09:44 -0700304func (a *ModuleBase) Target() Target {
305 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800306}
307
Colin Cross8b74d172016-09-13 09:59:14 -0700308func (a *ModuleBase) TargetPrimary() bool {
309 return a.commonProperties.CompilePrimary
310}
311
Colin Crossa1ad8d12016-06-01 17:09:44 -0700312func (a *ModuleBase) Os() OsType {
313 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800314}
315
Colin Cross635c3b02016-05-18 15:37:25 -0700316func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700317 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800318}
319
Colin Cross635c3b02016-05-18 15:37:25 -0700320func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700321 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800322}
323
Dan Willemsen0b24c742016-10-04 15:13:37 -0700324func (a *ModuleBase) ArchSpecific() bool {
325 return a.commonProperties.ArchSpecific
326}
327
Colin Crossa1ad8d12016-06-01 17:09:44 -0700328func (a *ModuleBase) OsClassSupported() []OsClass {
329 switch a.commonProperties.HostOrDeviceSupported {
330 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700331 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700332 case HostSupportedNoCross:
333 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700334 case DeviceSupported:
335 return []OsClass{Device}
336 case HostAndDeviceSupported:
337 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700338 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700339 supported = append(supported, Host, HostCross)
340 }
Colin Crossa4190c12016-07-12 13:11:25 -0700341 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700342 supported = append(supported, Device)
343 }
344 return supported
345 default:
346 return nil
347 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800348}
349
Colin Cross635c3b02016-05-18 15:37:25 -0700350func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800351 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
352 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700353 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800354}
355
Colin Cross635c3b02016-05-18 15:37:25 -0700356func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800357 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800358 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800359 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800360 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800361}
362
Colin Crossce75d2c2016-10-06 16:12:58 -0700363func (a *ModuleBase) SkipInstall() {
364 a.commonProperties.SkipInstall = true
365}
366
Colin Cross635c3b02016-05-18 15:37:25 -0700367func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700368 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800369
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700370 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800371 ctx.VisitDepsDepthFirstIf(isFileInstaller,
372 func(m blueprint.Module) {
373 fileInstaller := m.(fileInstaller)
374 files := fileInstaller.filesToInstall()
375 result = append(result, files...)
376 })
377
378 return result
379}
380
Colin Cross635c3b02016-05-18 15:37:25 -0700381func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 return a.installFiles
383}
384
Colin Cross635c3b02016-05-18 15:37:25 -0700385func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800386 return p.noAddressSanitizer
387}
388
Colin Cross635c3b02016-05-18 15:37:25 -0700389func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800390 return false
391}
392
Colin Cross635c3b02016-05-18 15:37:25 -0700393func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700394 allInstalledFiles := Paths{}
395 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800396 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700397 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700398 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
399 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800400 })
401
Colin Cross9454bfa2015-03-17 13:24:18 -0700402 deps := []string{}
403
Colin Cross3f40fa42015-01-30 17:27:36 -0800404 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700405 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800406 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700407 Rule: blueprint.Phony,
408 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700409 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800410 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700411 })
412 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700413 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700414 }
415
416 if len(allCheckbuildFiles) > 0 {
417 name := ctx.ModuleName() + "-checkbuild"
418 ctx.Build(pctx, blueprint.BuildParams{
419 Rule: blueprint.Phony,
420 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700421 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700422 Optional: true,
423 })
424 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700425 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700426 }
427
428 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800429 suffix := ""
430 if ctx.Config().(Config).EmbeddedInMake() {
431 suffix = "-soong"
432 }
433
Colin Cross9454bfa2015-03-17 13:24:18 -0700434 ctx.Build(pctx, blueprint.BuildParams{
435 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800436 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700437 Implicits: deps,
438 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800439 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700440
441 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800442 }
443}
444
Colin Cross635c3b02016-05-18 15:37:25 -0700445func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700446 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700447 target: a.commonProperties.CompileTarget,
448 targetPrimary: a.commonProperties.CompilePrimary,
449 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800450 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800451}
452
Colin Cross635c3b02016-05-18 15:37:25 -0700453func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800454 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700455 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700456 ModuleContext: ctx,
457 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
458 installDeps: a.computeInstallDeps(ctx),
459 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800460 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800461 }
462
Colin Cross9b1d13d2016-09-19 15:18:11 -0700463 if a.Enabled() {
464 a.module.GenerateAndroidBuildActions(androidCtx)
465 if ctx.Failed() {
466 return
467 }
468
469 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
470 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800471 }
472
Colin Cross9b1d13d2016-09-19 15:18:11 -0700473 if a == ctx.FinalModule().(Module).base() {
474 a.generateModuleTarget(ctx)
475 if ctx.Failed() {
476 return
477 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800478 }
479}
480
Colin Crossf6566ed2015-03-24 11:13:38 -0700481type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700482 target Target
483 targetPrimary bool
484 debug bool
485 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700486}
487
Colin Cross3f40fa42015-01-30 17:27:36 -0800488type androidModuleContext struct {
489 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700490 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700491 installDeps Paths
492 installFiles Paths
493 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800494 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700495 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800496}
497
498func (a *androidModuleContext) ninjaError(outputs []string, err error) {
499 a.ModuleContext.Build(pctx, blueprint.BuildParams{
500 Rule: ErrorRule,
501 Outputs: outputs,
502 Optional: true,
503 Args: map[string]string{
504 "error": err.Error(),
505 },
506 })
507 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800508}
509
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800510func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700511 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800512 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
513 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
514 return
515 }
516
Colin Cross3f40fa42015-01-30 17:27:36 -0800517 params.Optional = true
518 a.ModuleContext.Build(pctx, params)
519}
520
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700521func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
522 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700523 Rule: params.Rule,
524 Outputs: params.Outputs.Strings(),
525 ImplicitOutputs: params.ImplicitOutputs.Strings(),
526 Inputs: params.Inputs.Strings(),
527 Implicits: params.Implicits.Strings(),
528 OrderOnly: params.OrderOnly.Strings(),
529 Args: params.Args,
530 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700531 }
532
533 if params.Output != nil {
534 bparams.Outputs = append(bparams.Outputs, params.Output.String())
535 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700536 if params.ImplicitOutput != nil {
537 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
538 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700539 if params.Input != nil {
540 bparams.Inputs = append(bparams.Inputs, params.Input.String())
541 }
542 if params.Implicit != nil {
543 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
544 }
545
Colin Cross6ff51382015-12-17 16:39:19 -0800546 if a.missingDeps != nil {
547 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
548 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
549 return
550 }
551
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700552 a.ModuleContext.Build(pctx, bparams)
553}
554
Colin Cross6ff51382015-12-17 16:39:19 -0800555func (a *androidModuleContext) GetMissingDependencies() []string {
556 return a.missingDeps
557}
558
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800559func (a *androidModuleContext) AddMissingDependencies(deps []string) {
560 if deps != nil {
561 a.missingDeps = append(a.missingDeps, deps...)
562 }
563}
564
Colin Crossa1ad8d12016-06-01 17:09:44 -0700565func (a *androidBaseContextImpl) Target() Target {
566 return a.target
567}
568
Colin Cross8b74d172016-09-13 09:59:14 -0700569func (a *androidBaseContextImpl) TargetPrimary() bool {
570 return a.targetPrimary
571}
572
Colin Crossf6566ed2015-03-24 11:13:38 -0700573func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700574 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800575}
576
Colin Crossa1ad8d12016-06-01 17:09:44 -0700577func (a *androidBaseContextImpl) Os() OsType {
578 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800579}
580
Colin Crossf6566ed2015-03-24 11:13:38 -0700581func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700582 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700583}
584
585func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700586 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700587}
588
Colin Cross0af4b842015-04-30 16:36:18 -0700589func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700590 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700591}
592
Colin Crossf6566ed2015-03-24 11:13:38 -0700593func (a *androidBaseContextImpl) Debug() bool {
594 return a.debug
595}
596
Colin Cross1e7d3702016-08-24 15:25:47 -0700597func (a *androidBaseContextImpl) PrimaryArch() bool {
598 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
599}
600
Colin Cross1332b002015-04-07 17:11:30 -0700601func (a *androidBaseContextImpl) AConfig() Config {
602 return a.config
603}
604
Colin Cross9272ade2016-08-17 15:24:12 -0700605func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
606 return DeviceConfig{a.config.deviceConfig}
607}
608
Colin Cross8d8f8e22016-08-03 11:57:50 -0700609func (a *androidModuleContext) Proprietary() bool {
610 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800611}
612
Colin Cross8d8f8e22016-08-03 11:57:50 -0700613func (a *androidModuleContext) InstallInData() bool {
614 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800615}
616
617func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700618 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700619
Dan Willemsen782a2d12015-12-21 14:55:28 -0800620 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700621 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800622
Colin Crossce75d2c2016-10-06 16:12:58 -0700623 if !a.module.base().commonProperties.SkipInstall &&
624 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
625
Dan Willemsen322acaf2016-01-12 23:07:05 -0800626 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700627
Colin Cross89562dc2016-10-03 17:47:19 -0700628 var implicitDeps, orderOnlyDeps Paths
629
630 if a.Host() {
631 // Installed host modules might be used during the build, depend directly on their
632 // dependencies so their timestamp is updated whenever their dependency is updated
633 implicitDeps = deps
634 } else {
635 orderOnlyDeps = deps
636 }
637
Dan Willemsen322acaf2016-01-12 23:07:05 -0800638 a.ModuleBuild(pctx, ModuleBuildParams{
639 Rule: Cp,
640 Output: fullInstallPath,
641 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700642 Implicits: implicitDeps,
643 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800644 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800645 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800646
Dan Willemsen322acaf2016-01-12 23:07:05 -0800647 a.installFiles = append(a.installFiles, fullInstallPath)
648 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700649 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700650 return fullInstallPath
651}
652
Colin Crossa2344662016-03-24 13:14:12 -0700653func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700654 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800655}
656
Colin Cross3854a602016-01-11 12:49:11 -0800657func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
658 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700659 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800660
Colin Crossce75d2c2016-10-06 16:12:58 -0700661 if !a.module.base().commonProperties.SkipInstall &&
662 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
663
Colin Cross12fc4972016-01-11 12:49:11 -0800664 a.ModuleBuild(pctx, ModuleBuildParams{
665 Rule: Symlink,
666 Output: fullInstallPath,
667 OrderOnly: Paths{srcPath},
668 Default: !a.AConfig().EmbeddedInMake(),
669 Args: map[string]string{
670 "fromPath": srcPath.String(),
671 },
672 })
Colin Cross3854a602016-01-11 12:49:11 -0800673
Colin Cross12fc4972016-01-11 12:49:11 -0800674 a.installFiles = append(a.installFiles, fullInstallPath)
675 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
676 }
Colin Cross3854a602016-01-11 12:49:11 -0800677 return fullInstallPath
678}
679
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700680func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800681 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
682}
683
Colin Cross3f40fa42015-01-30 17:27:36 -0800684type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700685 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800686}
687
688func isFileInstaller(m blueprint.Module) bool {
689 _, ok := m.(fileInstaller)
690 return ok
691}
692
693func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700694 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800695 return ok
696}
Colin Crossfce53272015-04-08 11:21:40 -0700697
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700698func findStringInSlice(str string, slice []string) int {
699 for i, s := range slice {
700 if s == str {
701 return i
Colin Crossfce53272015-04-08 11:21:40 -0700702 }
703 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700704 return -1
705}
706
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700707func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
708 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700709 for i, e := range excludes {
710 j := findStringInSlice(e, srcFiles)
711 if j != -1 {
712 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
713 }
714
715 excludes[i] = filepath.Join(prefix, e)
716 }
717
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700718 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700719 for _, s := range srcFiles {
Colin Cross7f19f372016-11-01 11:10:25 -0700720 if pathtools.IsGlob(s) {
721 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700722 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700723 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700724 }
725 }
726
727 return globbedSrcFiles
728}
729
Colin Cross7f19f372016-11-01 11:10:25 -0700730func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
731 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700732 if err != nil {
733 ctx.ModuleErrorf("glob: %s", err.Error())
734 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700735 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700736}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700737
Colin Cross463a90e2015-06-17 14:20:06 -0700738func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700739 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700740}
741
Colin Cross1f8c52b2015-06-16 16:38:17 -0700742func BuildTargetSingleton() blueprint.Singleton {
743 return &buildTargetSingleton{}
744}
745
746type buildTargetSingleton struct{}
747
748func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
749 checkbuildDeps := []string{}
750
751 dirModules := make(map[string][]string)
752
753 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700754 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700755 blueprintDir := a.base().blueprintDir
756 installTarget := a.base().installTarget
757 checkbuildTarget := a.base().checkbuildTarget
758
759 if checkbuildTarget != "" {
760 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
761 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
762 }
763
764 if installTarget != "" {
765 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
766 }
767 }
768 })
769
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800770 suffix := ""
771 if ctx.Config().(Config).EmbeddedInMake() {
772 suffix = "-soong"
773 }
774
Colin Cross1f8c52b2015-06-16 16:38:17 -0700775 // Create a top-level checkbuild target that depends on all modules
776 ctx.Build(pctx, blueprint.BuildParams{
777 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800778 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700779 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700780 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700781 })
782
783 // Create a mm/<directory> target that depends on all modules in a directory
784 dirs := sortedKeys(dirModules)
785 for _, dir := range dirs {
786 ctx.Build(pctx, blueprint.BuildParams{
787 Rule: blueprint.Phony,
788 Outputs: []string{filepath.Join("mm", dir)},
789 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800790 // HACK: checkbuild should be an optional build, but force it
791 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800792 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700793 })
794 }
795}
Colin Crossd779da42015-12-17 18:00:23 -0800796
797type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700798 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800799 ctx interface {
800 ModuleName(blueprint.Module) string
801 ModuleSubDir(blueprint.Module) string
802 }
803}
804
805func (s AndroidModulesByName) Len() int { return len(s.slice) }
806func (s AndroidModulesByName) Less(i, j int) bool {
807 mi, mj := s.slice[i], s.slice[j]
808 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
809
810 if ni != nj {
811 return ni < nj
812 } else {
813 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
814 }
815}
816func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }