blob: 572b16230a687996bb9dad720a80b8611b3f56fb [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
173 DeviceSupported
174 HostAndDeviceSupported
175 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700176 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700177)
178
Colin Cross635c3b02016-05-18 15:37:25 -0700179func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800180 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
181
182 base := m.base()
183 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700184
Colin Crossfc754582016-05-17 16:34:16 -0700185 propertyStructs = append(propertyStructs,
186 &base.nameProperties,
187 &base.commonProperties,
188 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700189
190 return m, propertyStructs
191}
192
Colin Cross635c3b02016-05-18 15:37:25 -0700193func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700194 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
195
196 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
197
198 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800199 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700200 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700201 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800202
Dan Willemsen218f6562015-07-08 18:13:11 -0700203 switch hod {
204 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800205 // Default to module to device supported, host not supported, can override in module
206 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700207 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700208 fallthrough
209 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800210 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
211 }
212
Colin Crosscfad1192015-11-02 16:43:11 -0800213 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800214}
215
216// A AndroidModuleBase object contains the properties that are common to all Android
217// modules. It should be included as an anonymous field in every module
218// struct definition. InitAndroidModule should then be called from the module's
219// factory function, and the return values from InitAndroidModule should be
220// returned from the factory function.
221//
222// The AndroidModuleBase type is responsible for implementing the
223// GenerateBuildActions method to support the blueprint.Module interface. This
224// method will then call the module's GenerateAndroidBuildActions method once
225// for each build variant that is to be built. GenerateAndroidBuildActions is
226// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
227// AndroidModuleContext exposes extra functionality specific to the Android build
228// system including details about the particular build variant that is to be
229// generated.
230//
231// For example:
232//
233// import (
234// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700235// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800236// )
237//
238// type myModule struct {
239// common.AndroidModuleBase
240// properties struct {
241// MyProperty string
242// }
243// }
244//
245// func NewMyModule() (blueprint.Module, []interface{}) {
246// m := &myModule{}
247// return common.InitAndroidModule(m, &m.properties)
248// }
249//
250// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
251// // Get the CPU architecture for the current build variant.
252// variantArch := ctx.Arch()
253//
254// // ...
255// }
Colin Cross635c3b02016-05-18 15:37:25 -0700256type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800257 // Putting the curiously recurring thing pointing to the thing that contains
258 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700259 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800260
Colin Crossfc754582016-05-17 16:34:16 -0700261 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800262 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700263 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800264 hostAndDeviceProperties hostAndDeviceProperties
265 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700266 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700267 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800268
269 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700270 installFiles Paths
271 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700272
273 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
274 // Only set on the final variant of each module
275 installTarget string
276 checkbuildTarget string
277 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700278
Colin Cross178a5092016-09-13 13:42:32 -0700279 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800280}
281
Colin Crossce75d2c2016-10-06 16:12:58 -0700282// Name returns the name of the module. It may be overridden by individual module types, for
283// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700284func (a *ModuleBase) Name() string {
285 return a.nameProperties.Name
286}
287
Colin Crossce75d2c2016-10-06 16:12:58 -0700288// BaseModuleName returns the name of the module as specified in the blueprints file.
289func (a *ModuleBase) BaseModuleName() string {
290 return a.nameProperties.Name
291}
292
Colin Cross635c3b02016-05-18 15:37:25 -0700293func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800294 return a
295}
296
Colin Cross8b74d172016-09-13 09:59:14 -0700297func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700298 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700299 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700300}
301
Colin Crossa1ad8d12016-06-01 17:09:44 -0700302func (a *ModuleBase) Target() Target {
303 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800304}
305
Colin Cross8b74d172016-09-13 09:59:14 -0700306func (a *ModuleBase) TargetPrimary() bool {
307 return a.commonProperties.CompilePrimary
308}
309
Colin Crossa1ad8d12016-06-01 17:09:44 -0700310func (a *ModuleBase) Os() OsType {
311 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800312}
313
Colin Cross635c3b02016-05-18 15:37:25 -0700314func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700315 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800316}
317
Colin Cross635c3b02016-05-18 15:37:25 -0700318func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700319 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800320}
321
Dan Willemsen0b24c742016-10-04 15:13:37 -0700322func (a *ModuleBase) ArchSpecific() bool {
323 return a.commonProperties.ArchSpecific
324}
325
Colin Crossa1ad8d12016-06-01 17:09:44 -0700326func (a *ModuleBase) OsClassSupported() []OsClass {
327 switch a.commonProperties.HostOrDeviceSupported {
328 case HostSupported:
329 // TODO(ccross): explicitly mark host cross support
330 return []OsClass{Host, HostCross}
331 case DeviceSupported:
332 return []OsClass{Device}
333 case HostAndDeviceSupported:
334 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700335 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700336 supported = append(supported, Host, HostCross)
337 }
Colin Crossa4190c12016-07-12 13:11:25 -0700338 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700339 supported = append(supported, Device)
340 }
341 return supported
342 default:
343 return nil
344 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800345}
346
Colin Cross635c3b02016-05-18 15:37:25 -0700347func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800348 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
349 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700350 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800351}
352
Colin Cross635c3b02016-05-18 15:37:25 -0700353func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800354 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700355 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800356 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800357 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800358}
359
Colin Crossce75d2c2016-10-06 16:12:58 -0700360func (a *ModuleBase) SkipInstall() {
361 a.commonProperties.SkipInstall = true
362}
363
Colin Cross635c3b02016-05-18 15:37:25 -0700364func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700365 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800366
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700367 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800368 ctx.VisitDepsDepthFirstIf(isFileInstaller,
369 func(m blueprint.Module) {
370 fileInstaller := m.(fileInstaller)
371 files := fileInstaller.filesToInstall()
372 result = append(result, files...)
373 })
374
375 return result
376}
377
Colin Cross635c3b02016-05-18 15:37:25 -0700378func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800379 return a.installFiles
380}
381
Colin Cross635c3b02016-05-18 15:37:25 -0700382func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800383 return p.noAddressSanitizer
384}
385
Colin Cross635c3b02016-05-18 15:37:25 -0700386func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800387 return false
388}
389
Colin Cross635c3b02016-05-18 15:37:25 -0700390func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700391 allInstalledFiles := Paths{}
392 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800393 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700394 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700395 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
396 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800397 })
398
Colin Cross9454bfa2015-03-17 13:24:18 -0700399 deps := []string{}
400
Colin Cross3f40fa42015-01-30 17:27:36 -0800401 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700402 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800403 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700404 Rule: blueprint.Phony,
405 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700406 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800407 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700408 })
409 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700410 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700411 }
412
413 if len(allCheckbuildFiles) > 0 {
414 name := ctx.ModuleName() + "-checkbuild"
415 ctx.Build(pctx, blueprint.BuildParams{
416 Rule: blueprint.Phony,
417 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700418 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700419 Optional: true,
420 })
421 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700422 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700423 }
424
425 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800426 suffix := ""
427 if ctx.Config().(Config).EmbeddedInMake() {
428 suffix = "-soong"
429 }
430
Colin Cross9454bfa2015-03-17 13:24:18 -0700431 ctx.Build(pctx, blueprint.BuildParams{
432 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800433 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700434 Implicits: deps,
435 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800436 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700437
438 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800439 }
440}
441
Colin Cross635c3b02016-05-18 15:37:25 -0700442func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700443 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700444 target: a.commonProperties.CompileTarget,
445 targetPrimary: a.commonProperties.CompilePrimary,
446 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800447 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800448}
449
Colin Cross635c3b02016-05-18 15:37:25 -0700450func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800451 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700452 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700453 ModuleContext: ctx,
454 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
455 installDeps: a.computeInstallDeps(ctx),
456 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800457 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800458 }
459
Colin Cross9b1d13d2016-09-19 15:18:11 -0700460 if a.Enabled() {
461 a.module.GenerateAndroidBuildActions(androidCtx)
462 if ctx.Failed() {
463 return
464 }
465
466 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
467 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800468 }
469
Colin Cross9b1d13d2016-09-19 15:18:11 -0700470 if a == ctx.FinalModule().(Module).base() {
471 a.generateModuleTarget(ctx)
472 if ctx.Failed() {
473 return
474 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800475 }
476}
477
Colin Crossf6566ed2015-03-24 11:13:38 -0700478type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700479 target Target
480 targetPrimary bool
481 debug bool
482 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700483}
484
Colin Cross3f40fa42015-01-30 17:27:36 -0800485type androidModuleContext struct {
486 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700487 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700488 installDeps Paths
489 installFiles Paths
490 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800491 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700492 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800493}
494
495func (a *androidModuleContext) ninjaError(outputs []string, err error) {
496 a.ModuleContext.Build(pctx, blueprint.BuildParams{
497 Rule: ErrorRule,
498 Outputs: outputs,
499 Optional: true,
500 Args: map[string]string{
501 "error": err.Error(),
502 },
503 })
504 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800505}
506
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800507func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700508 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800509 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
510 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
511 return
512 }
513
Colin Cross3f40fa42015-01-30 17:27:36 -0800514 params.Optional = true
515 a.ModuleContext.Build(pctx, params)
516}
517
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700518func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
519 bparams := blueprint.BuildParams{
520 Rule: params.Rule,
521 Outputs: params.Outputs.Strings(),
522 Inputs: params.Inputs.Strings(),
523 Implicits: params.Implicits.Strings(),
524 OrderOnly: params.OrderOnly.Strings(),
525 Args: params.Args,
526 Optional: !params.Default,
527 }
528
529 if params.Output != nil {
530 bparams.Outputs = append(bparams.Outputs, params.Output.String())
531 }
532 if params.Input != nil {
533 bparams.Inputs = append(bparams.Inputs, params.Input.String())
534 }
535 if params.Implicit != nil {
536 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
537 }
538
Colin Cross6ff51382015-12-17 16:39:19 -0800539 if a.missingDeps != nil {
540 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
541 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
542 return
543 }
544
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700545 a.ModuleContext.Build(pctx, bparams)
546}
547
Colin Cross6ff51382015-12-17 16:39:19 -0800548func (a *androidModuleContext) GetMissingDependencies() []string {
549 return a.missingDeps
550}
551
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800552func (a *androidModuleContext) AddMissingDependencies(deps []string) {
553 if deps != nil {
554 a.missingDeps = append(a.missingDeps, deps...)
555 }
556}
557
Colin Crossa1ad8d12016-06-01 17:09:44 -0700558func (a *androidBaseContextImpl) Target() Target {
559 return a.target
560}
561
Colin Cross8b74d172016-09-13 09:59:14 -0700562func (a *androidBaseContextImpl) TargetPrimary() bool {
563 return a.targetPrimary
564}
565
Colin Crossf6566ed2015-03-24 11:13:38 -0700566func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700567 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800568}
569
Colin Crossa1ad8d12016-06-01 17:09:44 -0700570func (a *androidBaseContextImpl) Os() OsType {
571 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800572}
573
Colin Crossf6566ed2015-03-24 11:13:38 -0700574func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700575 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700576}
577
578func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700579 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700580}
581
Colin Cross0af4b842015-04-30 16:36:18 -0700582func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700583 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700584}
585
Colin Crossf6566ed2015-03-24 11:13:38 -0700586func (a *androidBaseContextImpl) Debug() bool {
587 return a.debug
588}
589
Colin Cross1e7d3702016-08-24 15:25:47 -0700590func (a *androidBaseContextImpl) PrimaryArch() bool {
591 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
592}
593
Colin Cross1332b002015-04-07 17:11:30 -0700594func (a *androidBaseContextImpl) AConfig() Config {
595 return a.config
596}
597
Colin Cross9272ade2016-08-17 15:24:12 -0700598func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
599 return DeviceConfig{a.config.deviceConfig}
600}
601
Colin Cross8d8f8e22016-08-03 11:57:50 -0700602func (a *androidModuleContext) Proprietary() bool {
603 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800604}
605
Colin Cross8d8f8e22016-08-03 11:57:50 -0700606func (a *androidModuleContext) InstallInData() bool {
607 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800608}
609
610func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700611 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700612
Dan Willemsen782a2d12015-12-21 14:55:28 -0800613 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700614 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800615
Colin Crossce75d2c2016-10-06 16:12:58 -0700616 if !a.module.base().commonProperties.SkipInstall &&
617 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
618
Dan Willemsen322acaf2016-01-12 23:07:05 -0800619 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700620
Colin Cross89562dc2016-10-03 17:47:19 -0700621 var implicitDeps, orderOnlyDeps Paths
622
623 if a.Host() {
624 // Installed host modules might be used during the build, depend directly on their
625 // dependencies so their timestamp is updated whenever their dependency is updated
626 implicitDeps = deps
627 } else {
628 orderOnlyDeps = deps
629 }
630
Dan Willemsen322acaf2016-01-12 23:07:05 -0800631 a.ModuleBuild(pctx, ModuleBuildParams{
632 Rule: Cp,
633 Output: fullInstallPath,
634 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700635 Implicits: implicitDeps,
636 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800637 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800638 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800639
Dan Willemsen322acaf2016-01-12 23:07:05 -0800640 a.installFiles = append(a.installFiles, fullInstallPath)
641 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700642 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700643 return fullInstallPath
644}
645
Colin Crossa2344662016-03-24 13:14:12 -0700646func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700647 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800648}
649
Colin Cross3854a602016-01-11 12:49:11 -0800650func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
651 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700652 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800653
Colin Crossce75d2c2016-10-06 16:12:58 -0700654 if !a.module.base().commonProperties.SkipInstall &&
655 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
656
Colin Cross12fc4972016-01-11 12:49:11 -0800657 a.ModuleBuild(pctx, ModuleBuildParams{
658 Rule: Symlink,
659 Output: fullInstallPath,
660 OrderOnly: Paths{srcPath},
661 Default: !a.AConfig().EmbeddedInMake(),
662 Args: map[string]string{
663 "fromPath": srcPath.String(),
664 },
665 })
Colin Cross3854a602016-01-11 12:49:11 -0800666
Colin Cross12fc4972016-01-11 12:49:11 -0800667 a.installFiles = append(a.installFiles, fullInstallPath)
668 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
669 }
Colin Cross3854a602016-01-11 12:49:11 -0800670 return fullInstallPath
671}
672
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700673func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800674 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
675}
676
Colin Cross3f40fa42015-01-30 17:27:36 -0800677type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700678 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800679}
680
681func isFileInstaller(m blueprint.Module) bool {
682 _, ok := m.(fileInstaller)
683 return ok
684}
685
686func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700687 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800688 return ok
689}
Colin Crossfce53272015-04-08 11:21:40 -0700690
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700691func findStringInSlice(str string, slice []string) int {
692 for i, s := range slice {
693 if s == str {
694 return i
Colin Crossfce53272015-04-08 11:21:40 -0700695 }
696 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700697 return -1
698}
699
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700700func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
701 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700702 for i, e := range excludes {
703 j := findStringInSlice(e, srcFiles)
704 if j != -1 {
705 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
706 }
707
708 excludes[i] = filepath.Join(prefix, e)
709 }
710
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700711 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700712 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700713 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700714 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700715 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700716 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700717 }
718 }
719
720 return globbedSrcFiles
721}
722
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700723func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
724 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700725 if err != nil {
726 ctx.ModuleErrorf("glob: %s", err.Error())
727 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700728 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700729}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700730
Colin Cross463a90e2015-06-17 14:20:06 -0700731func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700732 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700733}
734
Colin Cross1f8c52b2015-06-16 16:38:17 -0700735func BuildTargetSingleton() blueprint.Singleton {
736 return &buildTargetSingleton{}
737}
738
739type buildTargetSingleton struct{}
740
741func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
742 checkbuildDeps := []string{}
743
744 dirModules := make(map[string][]string)
745
746 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700747 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700748 blueprintDir := a.base().blueprintDir
749 installTarget := a.base().installTarget
750 checkbuildTarget := a.base().checkbuildTarget
751
752 if checkbuildTarget != "" {
753 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
754 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
755 }
756
757 if installTarget != "" {
758 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
759 }
760 }
761 })
762
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800763 suffix := ""
764 if ctx.Config().(Config).EmbeddedInMake() {
765 suffix = "-soong"
766 }
767
Colin Cross1f8c52b2015-06-16 16:38:17 -0700768 // Create a top-level checkbuild target that depends on all modules
769 ctx.Build(pctx, blueprint.BuildParams{
770 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800771 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700772 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700773 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700774 })
775
776 // Create a mm/<directory> target that depends on all modules in a directory
777 dirs := sortedKeys(dirModules)
778 for _, dir := range dirs {
779 ctx.Build(pctx, blueprint.BuildParams{
780 Rule: blueprint.Phony,
781 Outputs: []string{filepath.Join("mm", dir)},
782 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800783 // HACK: checkbuild should be an optional build, but force it
784 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800785 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700786 })
787 }
788}
Colin Crossd779da42015-12-17 18:00:23 -0800789
790type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700791 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800792 ctx interface {
793 ModuleName(blueprint.Module) string
794 ModuleSubDir(blueprint.Module) string
795 }
796}
797
798func (s AndroidModulesByName) Len() int { return len(s.slice) }
799func (s AndroidModulesByName) Less(i, j int) bool {
800 mi, mj := s.slice[i], s.slice[j]
801 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
802
803 if ni != nj {
804 return ni < nj
805 } else {
806 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
807 }
808}
809func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }