blob: 00219aec6d99314e2daa89cc14f24fc2011d51d5 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross6ff51382015-12-17 16:39:19 -080018 "fmt"
Colin Cross3f40fa42015-01-30 17:27:36 -080019 "path/filepath"
Colin Cross6ff51382015-12-17 16:39:19 -080020 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070021
Dan Willemsen0effe062015-11-30 16:06:01 -080022 "android/soong"
Colin Cross8f101b42015-06-17 15:09:06 -070023 "android/soong/glob"
24
Colin Crossf6566ed2015-03-24 11:13:38 -070025 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080026)
27
Colin Crossa120ec12016-08-19 16:07:38 -070028func init() {
Colin Cross178a5092016-09-13 13:42:32 -070029 RegisterTopDownMutator("load_hooks", loadHookMutator).Parallel()
Colin Crossa120ec12016-08-19 16:07:38 -070030 RegisterBottomUpMutator("defaults_deps", defaultsDepsMutator).Parallel()
31 RegisterTopDownMutator("defaults", defaultsMutator).Parallel()
32
33 RegisterBottomUpMutator("arch", ArchMutator).Parallel()
Colin Cross178a5092016-09-13 13:42:32 -070034 RegisterTopDownMutator("arch_hooks", archHookMutator).Parallel()
Colin Crossa120ec12016-08-19 16:07:38 -070035}
36
Colin Cross3f40fa42015-01-30 17:27:36 -080037var (
38 DeviceSharedLibrary = "shared_library"
39 DeviceStaticLibrary = "static_library"
40 DeviceExecutable = "executable"
41 HostSharedLibrary = "host_shared_library"
42 HostStaticLibrary = "host_static_library"
43 HostExecutable = "host_executable"
44)
45
Dan Willemsen34cc69e2015-09-23 15:26:20 -070046type ModuleBuildParams struct {
47 Rule blueprint.Rule
48 Output WritablePath
49 Outputs WritablePaths
50 Input Path
51 Inputs Paths
52 Implicit Path
53 Implicits Paths
54 OrderOnly Paths
55 Default bool
56 Args map[string]string
57}
58
Colin Crossf6566ed2015-03-24 11:13:38 -070059type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070060 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070061 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070062 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070063 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070064 Host() bool
65 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070066 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070067 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070068 PrimaryArch() bool
Colin Cross1332b002015-04-07 17:11:30 -070069 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070070 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070071}
72
Colin Cross635c3b02016-05-18 15:37:25 -070073type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070074 blueprint.BaseModuleContext
75 androidBaseContext
76}
77
Colin Cross635c3b02016-05-18 15:37:25 -070078type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080079 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070080 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080081
Dan Willemsen34cc69e2015-09-23 15:26:20 -070082 // Similar to Build, but takes Paths instead of []string,
83 // and performs more verification.
84 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070085
Dan Willemsen34cc69e2015-09-23 15:26:20 -070086 ExpandSources(srcFiles, excludes []string) Paths
87 Glob(outDir, globPattern string, excludes []string) Paths
88
Colin Crossa2344662016-03-24 13:14:12 -070089 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
90 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080091 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070092 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080093
94 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070095
96 Proprietary() bool
97 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080098}
99
Colin Cross635c3b02016-05-18 15:37:25 -0700100type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800101 blueprint.Module
102
Colin Cross635c3b02016-05-18 15:37:25 -0700103 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800104
Colin Cross635c3b02016-05-18 15:37:25 -0700105 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800106 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700107 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800108 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800109}
110
Colin Cross3f40fa42015-01-30 17:27:36 -0800111type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700112 Name string
113 Deps []string
114 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800115
Dan Willemsen0effe062015-11-30 16:06:01 -0800116 // emit build rules for this module
117 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800118
Colin Cross7d5136f2015-05-11 13:39:40 -0700119 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800120 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
121 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
122 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700123 Compile_multilib string `android:"arch_variant"`
124
125 Target struct {
126 Host struct {
127 Compile_multilib string
128 }
129 Android struct {
130 Compile_multilib string
131 }
132 }
133
134 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800135
Dan Willemsen782a2d12015-12-21 14:55:28 -0800136 // whether this is a proprietary vendor module, and should be installed into /vendor
137 Proprietary bool
138
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700139 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
140 // file
141 Logtags []string
142
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700143 // init.rc files to be installed if this module is installed
144 Init_rc []string
145
Chris Wolfe998306e2016-08-15 14:47:23 -0400146 // names of other modules to install if this module is installed
147 Required []string
148
Colin Crossa1ad8d12016-06-01 17:09:44 -0700149 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700150 CompileTarget Target `blueprint:"mutated"`
151 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800152
153 // Set by InitAndroidModule
154 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700155 ArchSpecific bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800156}
157
158type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700159 Host_supported *bool
160 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800161}
162
Colin Crossc472d572015-03-17 15:06:21 -0700163type Multilib string
164
165const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700166 MultilibBoth Multilib = "both"
167 MultilibFirst Multilib = "first"
168 MultilibCommon Multilib = "common"
169 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700170)
171
Colin Crossa1ad8d12016-06-01 17:09:44 -0700172type HostOrDeviceSupported int
173
174const (
175 _ HostOrDeviceSupported = iota
176 HostSupported
177 DeviceSupported
178 HostAndDeviceSupported
179 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700180 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700181)
182
Colin Cross635c3b02016-05-18 15:37:25 -0700183func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800184 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
185
186 base := m.base()
187 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700188
Colin Cross7f64b6d2015-07-09 13:57:48 -0700189 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700190
191 return m, propertyStructs
192}
193
Colin Cross635c3b02016-05-18 15:37:25 -0700194func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700195 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
196
197 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
198
199 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800200 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700201 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700202 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800203
Dan Willemsen218f6562015-07-08 18:13:11 -0700204 switch hod {
205 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800206 // Default to module to device supported, host not supported, can override in module
207 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700208 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700209 fallthrough
210 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800211 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
212 }
213
Colin Crosscfad1192015-11-02 16:43:11 -0800214 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800215}
216
217// A AndroidModuleBase object contains the properties that are common to all Android
218// modules. It should be included as an anonymous field in every module
219// struct definition. InitAndroidModule should then be called from the module's
220// factory function, and the return values from InitAndroidModule should be
221// returned from the factory function.
222//
223// The AndroidModuleBase type is responsible for implementing the
224// GenerateBuildActions method to support the blueprint.Module interface. This
225// method will then call the module's GenerateAndroidBuildActions method once
226// for each build variant that is to be built. GenerateAndroidBuildActions is
227// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
228// AndroidModuleContext exposes extra functionality specific to the Android build
229// system including details about the particular build variant that is to be
230// generated.
231//
232// For example:
233//
234// import (
235// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700236// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800237// )
238//
239// type myModule struct {
240// common.AndroidModuleBase
241// properties struct {
242// MyProperty string
243// }
244// }
245//
246// func NewMyModule() (blueprint.Module, []interface{}) {
247// m := &myModule{}
248// return common.InitAndroidModule(m, &m.properties)
249// }
250//
251// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
252// // Get the CPU architecture for the current build variant.
253// variantArch := ctx.Arch()
254//
255// // ...
256// }
Colin Cross635c3b02016-05-18 15:37:25 -0700257type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800258 // Putting the curiously recurring thing pointing to the thing that contains
259 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700260 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800261
262 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 Cross635c3b02016-05-18 15:37:25 -0700282func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800283 return a
284}
285
Colin Cross8b74d172016-09-13 09:59:14 -0700286func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700287 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700288 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700289}
290
Colin Crossa1ad8d12016-06-01 17:09:44 -0700291func (a *ModuleBase) Target() Target {
292 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800293}
294
Colin Cross8b74d172016-09-13 09:59:14 -0700295func (a *ModuleBase) TargetPrimary() bool {
296 return a.commonProperties.CompilePrimary
297}
298
Colin Crossa1ad8d12016-06-01 17:09:44 -0700299func (a *ModuleBase) Os() OsType {
300 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800301}
302
Colin Cross635c3b02016-05-18 15:37:25 -0700303func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700304 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800305}
306
Colin Cross635c3b02016-05-18 15:37:25 -0700307func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700308 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800309}
310
Dan Willemsen0b24c742016-10-04 15:13:37 -0700311func (a *ModuleBase) ArchSpecific() bool {
312 return a.commonProperties.ArchSpecific
313}
314
Colin Crossa1ad8d12016-06-01 17:09:44 -0700315func (a *ModuleBase) OsClassSupported() []OsClass {
316 switch a.commonProperties.HostOrDeviceSupported {
317 case HostSupported:
318 // TODO(ccross): explicitly mark host cross support
319 return []OsClass{Host, HostCross}
320 case DeviceSupported:
321 return []OsClass{Device}
322 case HostAndDeviceSupported:
323 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700324 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700325 supported = append(supported, Host, HostCross)
326 }
Colin Crossa4190c12016-07-12 13:11:25 -0700327 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700328 supported = append(supported, Device)
329 }
330 return supported
331 default:
332 return nil
333 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800334}
335
Colin Cross635c3b02016-05-18 15:37:25 -0700336func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800337 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
338 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700339 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800340}
341
Colin Cross635c3b02016-05-18 15:37:25 -0700342func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800343 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700344 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800345 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800346 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800347}
348
Colin Cross635c3b02016-05-18 15:37:25 -0700349func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700350 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800351
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700352 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800353 ctx.VisitDepsDepthFirstIf(isFileInstaller,
354 func(m blueprint.Module) {
355 fileInstaller := m.(fileInstaller)
356 files := fileInstaller.filesToInstall()
357 result = append(result, files...)
358 })
359
360 return result
361}
362
Colin Cross635c3b02016-05-18 15:37:25 -0700363func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800364 return a.installFiles
365}
366
Colin Cross635c3b02016-05-18 15:37:25 -0700367func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800368 return p.noAddressSanitizer
369}
370
Colin Cross635c3b02016-05-18 15:37:25 -0700371func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800372 return false
373}
374
Colin Cross635c3b02016-05-18 15:37:25 -0700375func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700376 allInstalledFiles := Paths{}
377 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800378 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700379 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700380 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
381 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 })
383
Colin Cross9454bfa2015-03-17 13:24:18 -0700384 deps := []string{}
385
Colin Cross3f40fa42015-01-30 17:27:36 -0800386 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700387 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800388 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700389 Rule: blueprint.Phony,
390 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700391 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800392 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700393 })
394 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700395 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700396 }
397
398 if len(allCheckbuildFiles) > 0 {
399 name := ctx.ModuleName() + "-checkbuild"
400 ctx.Build(pctx, blueprint.BuildParams{
401 Rule: blueprint.Phony,
402 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700403 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700404 Optional: true,
405 })
406 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700407 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700408 }
409
410 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800411 suffix := ""
412 if ctx.Config().(Config).EmbeddedInMake() {
413 suffix = "-soong"
414 }
415
Colin Cross9454bfa2015-03-17 13:24:18 -0700416 ctx.Build(pctx, blueprint.BuildParams{
417 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800418 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700419 Implicits: deps,
420 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800421 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700422
423 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800424 }
425}
426
Colin Cross635c3b02016-05-18 15:37:25 -0700427func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700428 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700429 target: a.commonProperties.CompileTarget,
430 targetPrimary: a.commonProperties.CompilePrimary,
431 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800432 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800433}
434
Colin Cross635c3b02016-05-18 15:37:25 -0700435func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800436 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700437 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700438 ModuleContext: ctx,
439 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
440 installDeps: a.computeInstallDeps(ctx),
441 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800442 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800443 }
444
Colin Cross9b1d13d2016-09-19 15:18:11 -0700445 if a.Enabled() {
446 a.module.GenerateAndroidBuildActions(androidCtx)
447 if ctx.Failed() {
448 return
449 }
450
451 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
452 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800453 }
454
Colin Cross9b1d13d2016-09-19 15:18:11 -0700455 if a == ctx.FinalModule().(Module).base() {
456 a.generateModuleTarget(ctx)
457 if ctx.Failed() {
458 return
459 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800460 }
461}
462
Colin Crossf6566ed2015-03-24 11:13:38 -0700463type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700464 target Target
465 targetPrimary bool
466 debug bool
467 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700468}
469
Colin Cross3f40fa42015-01-30 17:27:36 -0800470type androidModuleContext struct {
471 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700472 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700473 installDeps Paths
474 installFiles Paths
475 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800476 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700477 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800478}
479
480func (a *androidModuleContext) ninjaError(outputs []string, err error) {
481 a.ModuleContext.Build(pctx, blueprint.BuildParams{
482 Rule: ErrorRule,
483 Outputs: outputs,
484 Optional: true,
485 Args: map[string]string{
486 "error": err.Error(),
487 },
488 })
489 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800490}
491
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800492func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700493 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800494 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
495 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
496 return
497 }
498
Colin Cross3f40fa42015-01-30 17:27:36 -0800499 params.Optional = true
500 a.ModuleContext.Build(pctx, params)
501}
502
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700503func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
504 bparams := blueprint.BuildParams{
505 Rule: params.Rule,
506 Outputs: params.Outputs.Strings(),
507 Inputs: params.Inputs.Strings(),
508 Implicits: params.Implicits.Strings(),
509 OrderOnly: params.OrderOnly.Strings(),
510 Args: params.Args,
511 Optional: !params.Default,
512 }
513
514 if params.Output != nil {
515 bparams.Outputs = append(bparams.Outputs, params.Output.String())
516 }
517 if params.Input != nil {
518 bparams.Inputs = append(bparams.Inputs, params.Input.String())
519 }
520 if params.Implicit != nil {
521 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
522 }
523
Colin Cross6ff51382015-12-17 16:39:19 -0800524 if a.missingDeps != nil {
525 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
526 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
527 return
528 }
529
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700530 a.ModuleContext.Build(pctx, bparams)
531}
532
Colin Cross6ff51382015-12-17 16:39:19 -0800533func (a *androidModuleContext) GetMissingDependencies() []string {
534 return a.missingDeps
535}
536
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800537func (a *androidModuleContext) AddMissingDependencies(deps []string) {
538 if deps != nil {
539 a.missingDeps = append(a.missingDeps, deps...)
540 }
541}
542
Colin Crossa1ad8d12016-06-01 17:09:44 -0700543func (a *androidBaseContextImpl) Target() Target {
544 return a.target
545}
546
Colin Cross8b74d172016-09-13 09:59:14 -0700547func (a *androidBaseContextImpl) TargetPrimary() bool {
548 return a.targetPrimary
549}
550
Colin Crossf6566ed2015-03-24 11:13:38 -0700551func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700552 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800553}
554
Colin Crossa1ad8d12016-06-01 17:09:44 -0700555func (a *androidBaseContextImpl) Os() OsType {
556 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800557}
558
Colin Crossf6566ed2015-03-24 11:13:38 -0700559func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700560 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700561}
562
563func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700564 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700565}
566
Colin Cross0af4b842015-04-30 16:36:18 -0700567func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700568 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700569}
570
Colin Crossf6566ed2015-03-24 11:13:38 -0700571func (a *androidBaseContextImpl) Debug() bool {
572 return a.debug
573}
574
Colin Cross1e7d3702016-08-24 15:25:47 -0700575func (a *androidBaseContextImpl) PrimaryArch() bool {
576 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
577}
578
Colin Cross1332b002015-04-07 17:11:30 -0700579func (a *androidBaseContextImpl) AConfig() Config {
580 return a.config
581}
582
Colin Cross9272ade2016-08-17 15:24:12 -0700583func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
584 return DeviceConfig{a.config.deviceConfig}
585}
586
Colin Cross8d8f8e22016-08-03 11:57:50 -0700587func (a *androidModuleContext) Proprietary() bool {
588 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800589}
590
Colin Cross8d8f8e22016-08-03 11:57:50 -0700591func (a *androidModuleContext) InstallInData() bool {
592 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800593}
594
595func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700596 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700597
Dan Willemsen782a2d12015-12-21 14:55:28 -0800598 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700599 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800600
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800601 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800602 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700603
Colin Cross89562dc2016-10-03 17:47:19 -0700604 var implicitDeps, orderOnlyDeps Paths
605
606 if a.Host() {
607 // Installed host modules might be used during the build, depend directly on their
608 // dependencies so their timestamp is updated whenever their dependency is updated
609 implicitDeps = deps
610 } else {
611 orderOnlyDeps = deps
612 }
613
Dan Willemsen322acaf2016-01-12 23:07:05 -0800614 a.ModuleBuild(pctx, ModuleBuildParams{
615 Rule: Cp,
616 Output: fullInstallPath,
617 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700618 Implicits: implicitDeps,
619 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800620 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800621 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800622
Dan Willemsen322acaf2016-01-12 23:07:05 -0800623 a.installFiles = append(a.installFiles, fullInstallPath)
624 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700625 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700626 return fullInstallPath
627}
628
Colin Crossa2344662016-03-24 13:14:12 -0700629func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700630 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800631}
632
Colin Cross3854a602016-01-11 12:49:11 -0800633func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
634 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700635 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800636
Colin Cross12fc4972016-01-11 12:49:11 -0800637 if a.Host() || !a.AConfig().SkipDeviceInstall() {
638 a.ModuleBuild(pctx, ModuleBuildParams{
639 Rule: Symlink,
640 Output: fullInstallPath,
641 OrderOnly: Paths{srcPath},
642 Default: !a.AConfig().EmbeddedInMake(),
643 Args: map[string]string{
644 "fromPath": srcPath.String(),
645 },
646 })
Colin Cross3854a602016-01-11 12:49:11 -0800647
Colin Cross12fc4972016-01-11 12:49:11 -0800648 a.installFiles = append(a.installFiles, fullInstallPath)
649 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
650 }
Colin Cross3854a602016-01-11 12:49:11 -0800651 return fullInstallPath
652}
653
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700654func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800655 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
656}
657
Colin Cross3f40fa42015-01-30 17:27:36 -0800658type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700659 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800660}
661
662func isFileInstaller(m blueprint.Module) bool {
663 _, ok := m.(fileInstaller)
664 return ok
665}
666
667func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700668 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800669 return ok
670}
Colin Crossfce53272015-04-08 11:21:40 -0700671
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700672func findStringInSlice(str string, slice []string) int {
673 for i, s := range slice {
674 if s == str {
675 return i
Colin Crossfce53272015-04-08 11:21:40 -0700676 }
677 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700678 return -1
679}
680
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700681func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
682 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700683 for i, e := range excludes {
684 j := findStringInSlice(e, srcFiles)
685 if j != -1 {
686 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
687 }
688
689 excludes[i] = filepath.Join(prefix, e)
690 }
691
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700692 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700693 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700694 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700695 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700696 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700697 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700698 }
699 }
700
701 return globbedSrcFiles
702}
703
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700704func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
705 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700706 if err != nil {
707 ctx.ModuleErrorf("glob: %s", err.Error())
708 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700709 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700710}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700711
Colin Cross463a90e2015-06-17 14:20:06 -0700712func init() {
713 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
714}
715
Colin Cross1f8c52b2015-06-16 16:38:17 -0700716func BuildTargetSingleton() blueprint.Singleton {
717 return &buildTargetSingleton{}
718}
719
720type buildTargetSingleton struct{}
721
722func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
723 checkbuildDeps := []string{}
724
725 dirModules := make(map[string][]string)
726
727 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700728 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700729 blueprintDir := a.base().blueprintDir
730 installTarget := a.base().installTarget
731 checkbuildTarget := a.base().checkbuildTarget
732
733 if checkbuildTarget != "" {
734 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
735 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
736 }
737
738 if installTarget != "" {
739 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
740 }
741 }
742 })
743
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800744 suffix := ""
745 if ctx.Config().(Config).EmbeddedInMake() {
746 suffix = "-soong"
747 }
748
Colin Cross1f8c52b2015-06-16 16:38:17 -0700749 // Create a top-level checkbuild target that depends on all modules
750 ctx.Build(pctx, blueprint.BuildParams{
751 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800752 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700753 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700754 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700755 })
756
757 // Create a mm/<directory> target that depends on all modules in a directory
758 dirs := sortedKeys(dirModules)
759 for _, dir := range dirs {
760 ctx.Build(pctx, blueprint.BuildParams{
761 Rule: blueprint.Phony,
762 Outputs: []string{filepath.Join("mm", dir)},
763 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800764 // HACK: checkbuild should be an optional build, but force it
765 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800766 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700767 })
768 }
769}
Colin Crossd779da42015-12-17 18:00:23 -0800770
771type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700772 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800773 ctx interface {
774 ModuleName(blueprint.Module) string
775 ModuleSubDir(blueprint.Module) string
776 }
777}
778
779func (s AndroidModulesByName) Len() int { return len(s.slice) }
780func (s AndroidModulesByName) Less(i, j int) bool {
781 mi, mj := s.slice[i], s.slice[j]
782 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
783
784 if ni != nj {
785 return ni < nj
786 } else {
787 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
788 }
789}
790func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }