blob: 26e8e63ab4c2ab23c6eb861d00e7abb2b109f2d0 [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"
Alex Lightfb4353d2019-01-17 13:57:45 -080019 "path"
Colin Cross3f40fa42015-01-30 17:27:36 -080020 "path/filepath"
Colin Cross0875c522017-11-28 17:34:01 -080021 "sort"
Colin Cross6ff51382015-12-17 16:39:19 -080022 "strings"
Colin Crossaabf6792017-11-29 00:27:14 -080023 "text/scanner"
Colin Crossf6566ed2015-03-24 11:13:38 -070024
25 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070026 "github.com/google/blueprint/pathtools"
Colin Crossfe4bc362018-09-12 10:02:13 -070027 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080028)
29
30var (
31 DeviceSharedLibrary = "shared_library"
32 DeviceStaticLibrary = "static_library"
33 DeviceExecutable = "executable"
34 HostSharedLibrary = "host_shared_library"
35 HostStaticLibrary = "host_static_library"
36 HostExecutable = "host_executable"
37)
38
Colin Crossae887032017-10-23 17:16:14 -070039type BuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070040 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080041 Deps blueprint.Deps
42 Depfile WritablePath
Colin Cross67a5c132017-05-09 13:45:28 -070043 Description string
Dan Willemsen9f3c5742016-11-03 14:28:31 -070044 Output WritablePath
45 Outputs WritablePaths
46 ImplicitOutput WritablePath
47 ImplicitOutputs WritablePaths
48 Input Path
49 Inputs Paths
50 Implicit Path
51 Implicits Paths
52 OrderOnly Paths
53 Default bool
54 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070055}
56
Colin Crossae887032017-10-23 17:16:14 -070057type ModuleBuildParams BuildParams
58
Colin Cross0ea8ba82019-06-06 14:33:29 -070059// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
Colin Cross7e0a2cb2019-06-06 16:13:11 -070060// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
61// instead of a blueprint.Module, plus some extra methods that return Android-specific information
Colin Cross0ea8ba82019-06-06 14:33:29 -070062// about the current module.
63type BaseModuleContext interface {
Colin Cross7e0a2cb2019-06-06 16:13:11 -070064 Module() Module
Colin Cross0ea8ba82019-06-06 14:33:29 -070065 ModuleName() string
66 ModuleDir() string
67 ModuleType() string
68 Config() Config
69
Colin Cross7e0a2cb2019-06-06 16:13:11 -070070 OtherModuleName(m blueprint.Module) string
71 OtherModuleDir(m blueprint.Module) string
72 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
73 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
74 OtherModuleExists(name string) bool
75
76 GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
77 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
78 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
79
80 VisitDirectDepsBlueprint(visit func(blueprint.Module))
81 VisitDirectDeps(visit func(Module))
82 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
83 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
84 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
85 VisitDepsDepthFirst(visit func(Module))
86 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
87 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
88 WalkDeps(visit func(Module, Module) bool)
89 WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
90 // GetWalkPath is supposed to be called in visit function passed in WalkDeps()
91 // and returns a top-down dependency path from a start module to current child module.
92 GetWalkPath() []Module
93
Colin Cross0ea8ba82019-06-06 14:33:29 -070094 ContainsProperty(name string) bool
95 Errorf(pos scanner.Position, fmt string, args ...interface{})
96 ModuleErrorf(fmt string, args ...interface{})
97 PropertyErrorf(property, fmt string, args ...interface{})
98 Failed() bool
99
100 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
101 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
102 // builder whenever a file matching the pattern as added or removed, without rerunning if a
103 // file that does not match the pattern is added to a searched directory.
104 GlobWithDeps(pattern string, excludes []string) ([]string, error)
105
Colin Cross7e0a2cb2019-06-06 16:13:11 -0700106 Glob(globPattern string, excludes []string) Paths
107 GlobFiles(globPattern string, excludes []string) Paths
108
Colin Cross0ea8ba82019-06-06 14:33:29 -0700109 Fs() pathtools.FileSystem
110 AddNinjaFileDeps(deps ...string)
111
Colin Crossa1ad8d12016-06-01 17:09:44 -0700112 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -0700113 TargetPrimary() bool
Colin Crossee0bc3b2018-10-02 22:01:37 -0700114 MultiTargets() []Target
Colin Crossf6566ed2015-03-24 11:13:38 -0700115 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -0700116 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -0700117 Host() bool
118 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -0700119 Darwin() bool
Doug Horn21b94272019-01-16 12:06:11 -0800120 Fuchsia() bool
Colin Cross3edeee12017-04-04 12:59:48 -0700121 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -0700122 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -0700123 PrimaryArch() bool
Jiyong Park2db76922017-11-08 16:03:48 +0900124 Platform() bool
125 DeviceSpecific() bool
126 SocSpecific() bool
127 ProductSpecific() bool
Dario Frenifd05a742018-05-29 13:28:54 +0100128 ProductServicesSpecific() bool
Colin Cross1332b002015-04-07 17:11:30 -0700129 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -0700130 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -0700131}
132
Colin Cross0ea8ba82019-06-06 14:33:29 -0700133// Deprecated: use BaseModuleContext instead
Colin Cross635c3b02016-05-18 15:37:25 -0700134type BaseContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -0800135 BaseModuleContext
Colin Crossaabf6792017-11-29 00:27:14 -0800136}
137
Colin Cross635c3b02016-05-18 15:37:25 -0700138type ModuleContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -0800139 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800140
Colin Crossae887032017-10-23 17:16:14 -0700141 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800142 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700143
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700144 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross366938f2017-12-11 16:29:02 -0800145 ExpandSource(srcFile, prop string) Path
Colin Cross2383f3b2018-02-06 14:40:13 -0800146 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700147
Colin Cross5c517922017-08-31 12:29:17 -0700148 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
149 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800150 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Jiyong Parkf1194352019-02-25 11:05:47 +0900151 InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700152 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800153
154 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700155
Colin Cross8d8f8e22016-08-03 11:57:50 -0700156 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700157 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900158 InstallInRecovery() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800159
160 RequiredModuleNames() []string
Sasha Smundakb6d23052019-04-01 18:37:36 -0700161 HostRequiredModuleNames() []string
162 TargetRequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700163
Colin Cross3f68a132017-10-23 17:10:29 -0700164 ModuleSubDir() string
165
Colin Cross0875c522017-11-28 17:34:01 -0800166 Variable(pctx PackageContext, name, value string)
167 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700168 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
169 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800170 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700171
Colin Cross0875c522017-11-28 17:34:01 -0800172 PrimaryModule() Module
173 FinalModule() Module
174 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700175
176 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800177 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800178}
179
Colin Cross635c3b02016-05-18 15:37:25 -0700180type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800181 blueprint.Module
182
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700183 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
184 // but GenerateAndroidBuildActions also has access to Android-specific information.
185 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700186 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700187
Colin Cross1e676be2016-10-12 14:38:15 -0700188 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800189
Colin Cross635c3b02016-05-18 15:37:25 -0700190 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800191 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700192 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800193 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700194 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900195 InstallInRecovery() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800196 SkipInstall()
Jiyong Park374510b2018-03-19 18:23:01 +0900197 ExportedToMake() bool
Jiyong Park52818fc2019-03-18 12:01:38 +0900198 NoticeFile() OptionalPath
Colin Cross36242852017-06-23 15:06:31 -0700199
200 AddProperties(props ...interface{})
201 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700202
Colin Crossae887032017-10-23 17:16:14 -0700203 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800204 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800205 VariablesForTests() map[string]string
Colin Cross3f40fa42015-01-30 17:27:36 -0800206}
207
Colin Crossfc754582016-05-17 16:34:16 -0700208type nameProperties struct {
209 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800210 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700211}
212
213type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800214 // emit build rules for this module
215 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800216
Paul Duffin2e61fa62019-03-28 14:10:57 +0000217 // Controls the visibility of this module to other modules. Allowable values are one or more of
218 // these formats:
219 //
220 // ["//visibility:public"]: Anyone can use this module.
221 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
222 // this module.
223 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
224 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
225 // this module. Note that sub-packages do not have access to the rule; for example,
226 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
227 // is a special module and must be used verbatim. It represents all of the modules in the
228 // package.
229 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
230 // or other or in one of their sub-packages have access to this module. For example,
231 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
232 // to depend on this rule (but not //independent:evil)
233 // ["//project"]: This is shorthand for ["//project:__pkg__"]
234 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
235 // //project is the module's package. e.g. using [":__subpackages__"] in
236 // packages/apps/Settings/Android.bp is equivalent to
237 // //packages/apps/Settings:__subpackages__.
238 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
239 // for now. It is an error if it is used in a module.
240 // See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
241 // more details.
242 Visibility []string
243
Colin Cross7d5136f2015-05-11 13:39:40 -0700244 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800245 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
246 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
247 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700248 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700249
250 Target struct {
251 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700252 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700253 }
254 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700255 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700256 }
257 }
258
Colin Crossee0bc3b2018-10-02 22:01:37 -0700259 UseTargetVariants bool `blueprint:"mutated"`
260 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800261
Dan Willemsen782a2d12015-12-21 14:55:28 -0800262 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700263 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800264
Colin Cross55708f32017-03-20 13:23:34 -0700265 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700266 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700267
Jiyong Park2db76922017-11-08 16:03:48 +0900268 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
269 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
270 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700271 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700272
Jiyong Park2db76922017-11-08 16:03:48 +0900273 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
274 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
275 Soc_specific *bool
276
277 // whether this module is specific to a device, not only for SoC, but also for off-chip
278 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
279 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
280 // This implies `soc_specific:true`.
281 Device_specific *bool
282
283 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900284 // network operator, etc). When set to true, it is installed into /product (or
285 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900286 Product_specific *bool
287
Dario Frenifd05a742018-05-29 13:28:54 +0100288 // whether this module provides services owned by the OS provider to the core platform. When set
Dario Freni95cf7672018-08-17 00:57:57 +0100289 // to true, it is installed into /product_services (or /system/product_services if
290 // product_services partition does not exist).
291 Product_services_specific *bool
Dario Frenifd05a742018-05-29 13:28:54 +0100292
Jiyong Parkf9332f12018-02-01 00:54:12 +0900293 // Whether this module is installed to recovery partition
294 Recovery *bool
295
dimitry1f33e402019-03-26 12:39:31 +0100296 // Whether this module is built for non-native architecures (also known as native bridge binary)
297 Native_bridge_supported *bool `android:"arch_variant"`
298
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700299 // init.rc files to be installed if this module is installed
Colin Cross27b922f2019-03-04 22:35:41 -0800300 Init_rc []string `android:"path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700301
Steven Moreland57a23d22018-04-04 15:42:19 -0700302 // VINTF manifest fragments to be installed if this module is installed
Colin Cross27b922f2019-03-04 22:35:41 -0800303 Vintf_fragments []string `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700304
Chris Wolfe998306e2016-08-15 14:47:23 -0400305 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700306 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400307
Sasha Smundakb6d23052019-04-01 18:37:36 -0700308 // names of other modules to install on host if this module is installed
309 Host_required []string `android:"arch_variant"`
310
311 // names of other modules to install on target if this module is installed
312 Target_required []string `android:"arch_variant"`
313
Colin Cross5aac3622017-08-31 15:07:09 -0700314 // relative path to a file to include in the list of notices for the device
Colin Cross27b922f2019-03-04 22:35:41 -0800315 Notice *string `android:"path"`
Colin Cross5aac3622017-08-31 15:07:09 -0700316
Dan Willemsen569edc52018-11-19 09:33:29 -0800317 Dist struct {
318 // copy the output of this module to the $DIST_DIR when `dist` is specified on the
319 // command line and any of these targets are also on the command line, or otherwise
320 // built
321 Targets []string `android:"arch_variant"`
322
323 // The name of the output artifact. This defaults to the basename of the output of
324 // the module.
325 Dest *string `android:"arch_variant"`
326
327 // The directory within the dist directory to store the artifact. Defaults to the
328 // top level directory ("").
329 Dir *string `android:"arch_variant"`
330
331 // A suffix to add to the artifact file name (before any extension).
332 Suffix *string `android:"arch_variant"`
333 } `android:"arch_variant"`
334
Colin Crossa1ad8d12016-06-01 17:09:44 -0700335 // Set by TargetMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700336 CompileTarget Target `blueprint:"mutated"`
337 CompileMultiTargets []Target `blueprint:"mutated"`
338 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800339
340 // Set by InitAndroidModule
341 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700342 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700343
344 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800345
346 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800347}
348
349type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800350 // If set to true, build a variant of the module for the host. Defaults to false.
351 Host_supported *bool
352
353 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700354 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800355}
356
Colin Crossc472d572015-03-17 15:06:21 -0700357type Multilib string
358
359const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800360 MultilibBoth Multilib = "both"
361 MultilibFirst Multilib = "first"
362 MultilibCommon Multilib = "common"
363 MultilibCommonFirst Multilib = "common_first"
364 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700365)
366
Colin Crossa1ad8d12016-06-01 17:09:44 -0700367type HostOrDeviceSupported int
368
369const (
370 _ HostOrDeviceSupported = iota
Dan Albert0981b5c2018-08-02 13:46:35 -0700371
372 // Host and HostCross are built by default. Device is not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700373 HostSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700374
375 // Host is built by default. HostCross and Device are not supported.
Dan Albertc6345fb2016-10-20 01:36:11 -0700376 HostSupportedNoCross
Dan Albert0981b5c2018-08-02 13:46:35 -0700377
378 // Device is built by default. Host and HostCross are not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700379 DeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700380
381 // Device is built by default. Host and HostCross are supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700382 HostAndDeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700383
384 // Host, HostCross, and Device are built by default.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700385 HostAndDeviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700386
387 // Nothing is supported. This is not exposed to the user, but used to mark a
388 // host only module as unsupported when the module type is not supported on
389 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Dan Willemsen0b24c742016-10-04 15:13:37 -0700390 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700391)
392
Jiyong Park2db76922017-11-08 16:03:48 +0900393type moduleKind int
394
395const (
396 platformModule moduleKind = iota
397 deviceSpecificModule
398 socSpecificModule
399 productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100400 productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900401)
402
403func (k moduleKind) String() string {
404 switch k {
405 case platformModule:
406 return "platform"
407 case deviceSpecificModule:
408 return "device-specific"
409 case socSpecificModule:
410 return "soc-specific"
411 case productSpecificModule:
412 return "product-specific"
Dario Frenifd05a742018-05-29 13:28:54 +0100413 case productServicesSpecificModule:
414 return "productservices-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900415 default:
416 panic(fmt.Errorf("unknown module kind %d", k))
417 }
418}
419
Colin Cross36242852017-06-23 15:06:31 -0700420func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800421 base := m.base()
422 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700423
Colin Cross36242852017-06-23 15:06:31 -0700424 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700425 &base.nameProperties,
426 &base.commonProperties,
427 &base.variableProperties)
Colin Crossa3a97412019-03-18 12:24:29 -0700428 base.generalProperties = m.GetProperties()
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700429 base.customizableProperties = m.GetProperties()
Colin Cross5049f022015-03-18 13:28:46 -0700430}
431
Colin Cross36242852017-06-23 15:06:31 -0700432func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
433 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700434
435 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800436 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700437 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700438 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700439 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800440
Dan Willemsen218f6562015-07-08 18:13:11 -0700441 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700442 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700443 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800444 }
445
Colin Cross36242852017-06-23 15:06:31 -0700446 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800447}
448
Colin Crossee0bc3b2018-10-02 22:01:37 -0700449func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
450 InitAndroidArchModule(m, hod, defaultMultilib)
451 m.base().commonProperties.UseTargetVariants = false
452}
453
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800454// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800455// modules. It should be included as an anonymous field in every module
456// struct definition. InitAndroidModule should then be called from the module's
457// factory function, and the return values from InitAndroidModule should be
458// returned from the factory function.
459//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800460// The ModuleBase type is responsible for implementing the GenerateBuildActions
461// method to support the blueprint.Module interface. This method will then call
462// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700463// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
464// rather than the usual blueprint.ModuleContext.
465// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800466// system including details about the particular build variant that is to be
467// generated.
468//
469// For example:
470//
471// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800472// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800473// )
474//
475// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800476// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800477// properties struct {
478// MyProperty string
479// }
480// }
481//
Colin Cross36242852017-06-23 15:06:31 -0700482// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800483// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700484// m.AddProperties(&m.properties)
485// android.InitAndroidModule(m)
486// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800487// }
488//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800489// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800490// // Get the CPU architecture for the current build variant.
491// variantArch := ctx.Arch()
492//
493// // ...
494// }
Colin Cross635c3b02016-05-18 15:37:25 -0700495type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800496 // Putting the curiously recurring thing pointing to the thing that contains
497 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700498 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700499 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800500
Colin Crossfc754582016-05-17 16:34:16 -0700501 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800502 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700503 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800504 hostAndDeviceProperties hostAndDeviceProperties
505 generalProperties []interface{}
Colin Crossc17727d2018-10-24 12:42:09 -0700506 archProperties [][]interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700507 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800508
509 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700510 installFiles Paths
511 checkbuildFiles Paths
Jiyong Park52818fc2019-03-18 12:01:38 +0900512 noticeFile OptionalPath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700513
514 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
515 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800516 installTarget WritablePath
517 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700518 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700519
Colin Cross178a5092016-09-13 13:42:32 -0700520 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700521
522 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700523
524 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700525 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800526 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800527 variables map[string]string
Colin Crossa9d8bee2018-10-02 13:59:46 -0700528
529 prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
Colin Cross36242852017-06-23 15:06:31 -0700530}
531
Colin Cross4157e882019-06-06 16:57:04 -0700532func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800533
Colin Cross4157e882019-06-06 16:57:04 -0700534func (m *ModuleBase) AddProperties(props ...interface{}) {
535 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -0700536}
537
Colin Cross4157e882019-06-06 16:57:04 -0700538func (m *ModuleBase) GetProperties() []interface{} {
539 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800540}
541
Colin Cross4157e882019-06-06 16:57:04 -0700542func (m *ModuleBase) BuildParamsForTests() []BuildParams {
543 return m.buildParams
Colin Crosscec81712017-07-13 14:43:27 -0700544}
545
Colin Cross4157e882019-06-06 16:57:04 -0700546func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
547 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800548}
549
Colin Cross4157e882019-06-06 16:57:04 -0700550func (m *ModuleBase) VariablesForTests() map[string]string {
551 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800552}
553
Colin Cross4157e882019-06-06 16:57:04 -0700554func (m *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) {
555 m.prefer32 = prefer32
Colin Crossa9d8bee2018-10-02 13:59:46 -0700556}
557
Colin Crossce75d2c2016-10-06 16:12:58 -0700558// Name returns the name of the module. It may be overridden by individual module types, for
559// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -0700560func (m *ModuleBase) Name() string {
561 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700562}
563
Colin Crossce75d2c2016-10-06 16:12:58 -0700564// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -0700565func (m *ModuleBase) BaseModuleName() string {
566 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700567}
568
Colin Cross4157e882019-06-06 16:57:04 -0700569func (m *ModuleBase) base() *ModuleBase {
570 return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800571}
572
Colin Cross4157e882019-06-06 16:57:04 -0700573func (m *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) {
574 m.commonProperties.CompileTarget = target
575 m.commonProperties.CompileMultiTargets = multiTargets
576 m.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700577}
578
Colin Cross4157e882019-06-06 16:57:04 -0700579func (m *ModuleBase) Target() Target {
580 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800581}
582
Colin Cross4157e882019-06-06 16:57:04 -0700583func (m *ModuleBase) TargetPrimary() bool {
584 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -0700585}
586
Colin Cross4157e882019-06-06 16:57:04 -0700587func (m *ModuleBase) MultiTargets() []Target {
588 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -0700589}
590
Colin Cross4157e882019-06-06 16:57:04 -0700591func (m *ModuleBase) Os() OsType {
592 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800593}
594
Colin Cross4157e882019-06-06 16:57:04 -0700595func (m *ModuleBase) Host() bool {
596 return m.Os().Class == Host || m.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800597}
598
Colin Cross4157e882019-06-06 16:57:04 -0700599func (m *ModuleBase) Arch() Arch {
600 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800601}
602
Colin Cross4157e882019-06-06 16:57:04 -0700603func (m *ModuleBase) ArchSpecific() bool {
604 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -0700605}
606
Colin Cross4157e882019-06-06 16:57:04 -0700607func (m *ModuleBase) OsClassSupported() []OsClass {
608 switch m.commonProperties.HostOrDeviceSupported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700609 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700610 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700611 case HostSupportedNoCross:
612 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700613 case DeviceSupported:
614 return []OsClass{Device}
Dan Albert0981b5c2018-08-02 13:46:35 -0700615 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700616 var supported []OsClass
Colin Cross4157e882019-06-06 16:57:04 -0700617 if Bool(m.hostAndDeviceProperties.Host_supported) ||
618 (m.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
619 m.hostAndDeviceProperties.Host_supported == nil) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700620 supported = append(supported, Host, HostCross)
621 }
Colin Cross4157e882019-06-06 16:57:04 -0700622 if m.hostAndDeviceProperties.Device_supported == nil ||
623 *m.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700624 supported = append(supported, Device)
625 }
626 return supported
627 default:
628 return nil
629 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800630}
631
Colin Cross4157e882019-06-06 16:57:04 -0700632func (m *ModuleBase) DeviceSupported() bool {
633 return m.commonProperties.HostOrDeviceSupported == DeviceSupported ||
634 m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
635 (m.hostAndDeviceProperties.Device_supported == nil ||
636 *m.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800637}
638
Colin Cross4157e882019-06-06 16:57:04 -0700639func (m *ModuleBase) Platform() bool {
640 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.ProductServicesSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900641}
642
Colin Cross4157e882019-06-06 16:57:04 -0700643func (m *ModuleBase) DeviceSpecific() bool {
644 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900645}
646
Colin Cross4157e882019-06-06 16:57:04 -0700647func (m *ModuleBase) SocSpecific() bool {
648 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900649}
650
Colin Cross4157e882019-06-06 16:57:04 -0700651func (m *ModuleBase) ProductSpecific() bool {
652 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900653}
654
Colin Cross4157e882019-06-06 16:57:04 -0700655func (m *ModuleBase) ProductServicesSpecific() bool {
656 return Bool(m.commonProperties.Product_services_specific)
Dario Frenifd05a742018-05-29 13:28:54 +0100657}
658
Colin Cross4157e882019-06-06 16:57:04 -0700659func (m *ModuleBase) Enabled() bool {
660 if m.commonProperties.Enabled == nil {
661 return !m.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800662 }
Colin Cross4157e882019-06-06 16:57:04 -0700663 return *m.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800664}
665
Colin Cross4157e882019-06-06 16:57:04 -0700666func (m *ModuleBase) SkipInstall() {
667 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -0700668}
669
Colin Cross4157e882019-06-06 16:57:04 -0700670func (m *ModuleBase) ExportedToMake() bool {
671 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +0900672}
673
Colin Cross4157e882019-06-06 16:57:04 -0700674func (m *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700675 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800676
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700677 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700678 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800679 ctx.VisitDepsDepthFirstIf(isFileInstaller,
680 func(m blueprint.Module) {
681 fileInstaller := m.(fileInstaller)
682 files := fileInstaller.filesToInstall()
683 result = append(result, files...)
684 })
685
686 return result
687}
688
Colin Cross4157e882019-06-06 16:57:04 -0700689func (m *ModuleBase) filesToInstall() Paths {
690 return m.installFiles
Colin Cross3f40fa42015-01-30 17:27:36 -0800691}
692
Colin Cross4157e882019-06-06 16:57:04 -0700693func (m *ModuleBase) NoAddressSanitizer() bool {
694 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -0800695}
696
Colin Cross4157e882019-06-06 16:57:04 -0700697func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800698 return false
699}
700
Colin Cross4157e882019-06-06 16:57:04 -0700701func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700702 return false
703}
704
Colin Cross4157e882019-06-06 16:57:04 -0700705func (m *ModuleBase) InstallInRecovery() bool {
706 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +0900707}
708
Colin Cross4157e882019-06-06 16:57:04 -0700709func (m *ModuleBase) Owner() string {
710 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900711}
712
Colin Cross4157e882019-06-06 16:57:04 -0700713func (m *ModuleBase) NoticeFile() OptionalPath {
714 return m.noticeFile
Jiyong Park52818fc2019-03-18 12:01:38 +0900715}
716
Colin Cross4157e882019-06-06 16:57:04 -0700717func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700718 allInstalledFiles := Paths{}
719 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800720 ctx.VisitAllModuleVariants(func(module Module) {
721 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700722 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
723 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800724 })
725
Colin Cross0875c522017-11-28 17:34:01 -0800726 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700727
Jeff Gaston088e29e2017-11-29 16:47:17 -0800728 namespacePrefix := ctx.Namespace().(*Namespace).id
729 if namespacePrefix != "" {
730 namespacePrefix = namespacePrefix + "-"
731 }
732
Colin Cross3f40fa42015-01-30 17:27:36 -0800733 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800734 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800735 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700736 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800737 Output: name,
738 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800739 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700740 })
741 deps = append(deps, name)
Colin Cross4157e882019-06-06 16:57:04 -0700742 m.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700743 }
744
745 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800746 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800747 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700748 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800749 Output: name,
750 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700751 })
752 deps = append(deps, name)
Colin Cross4157e882019-06-06 16:57:04 -0700753 m.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700754 }
755
756 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800757 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800758 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800759 suffix = "-soong"
760 }
761
Jeff Gaston088e29e2017-11-29 16:47:17 -0800762 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800763 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700764 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800765 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700766 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800767 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700768
Colin Cross4157e882019-06-06 16:57:04 -0700769 m.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800770 }
771}
772
Colin Cross4157e882019-06-06 16:57:04 -0700773func determineModuleKind(m *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
774 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
775 var deviceSpecific = Bool(m.commonProperties.Device_specific)
776 var productSpecific = Bool(m.commonProperties.Product_specific)
777 var productServicesSpecific = Bool(m.commonProperties.Product_services_specific)
Jiyong Park2db76922017-11-08 16:03:48 +0900778
Dario Frenifd05a742018-05-29 13:28:54 +0100779 msg := "conflicting value set here"
780 if socSpecific && deviceSpecific {
781 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -0700782 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +0900783 ctx.PropertyErrorf("vendor", msg)
784 }
Colin Cross4157e882019-06-06 16:57:04 -0700785 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +0900786 ctx.PropertyErrorf("proprietary", msg)
787 }
Colin Cross4157e882019-06-06 16:57:04 -0700788 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +0900789 ctx.PropertyErrorf("soc_specific", msg)
790 }
791 }
792
Dario Frenifd05a742018-05-29 13:28:54 +0100793 if productSpecific && productServicesSpecific {
794 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.")
795 ctx.PropertyErrorf("product_services_specific", msg)
796 }
797
798 if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) {
799 if productSpecific {
800 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
801 } else {
802 ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.")
803 }
804 if deviceSpecific {
805 ctx.PropertyErrorf("device_specific", msg)
806 } else {
Colin Cross4157e882019-06-06 16:57:04 -0700807 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +0100808 ctx.PropertyErrorf("vendor", msg)
809 }
Colin Cross4157e882019-06-06 16:57:04 -0700810 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +0100811 ctx.PropertyErrorf("proprietary", msg)
812 }
Colin Cross4157e882019-06-06 16:57:04 -0700813 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +0100814 ctx.PropertyErrorf("soc_specific", msg)
815 }
816 }
817 }
818
Jiyong Park2db76922017-11-08 16:03:48 +0900819 if productSpecific {
820 return productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100821 } else if productServicesSpecific {
822 return productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900823 } else if deviceSpecific {
824 return deviceSpecificModule
825 } else if socSpecific {
826 return socSpecificModule
827 } else {
828 return platformModule
829 }
830}
831
Colin Cross0ea8ba82019-06-06 14:33:29 -0700832func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
833 return baseModuleContext{
834 BaseModuleContext: ctx,
835 target: m.commonProperties.CompileTarget,
836 targetPrimary: m.commonProperties.CompilePrimary,
837 multiTargets: m.commonProperties.CompileMultiTargets,
838 kind: determineModuleKind(m, ctx),
839 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800840 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800841}
842
Colin Cross4157e882019-06-06 16:57:04 -0700843func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -0700844 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700845 module: m.module,
Colin Cross7e0a2cb2019-06-06 16:13:11 -0700846 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -0700847 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
848 installDeps: m.computeInstallDeps(blueprintCtx),
849 installFiles: m.installFiles,
850 missingDeps: blueprintCtx.GetMissingDependencies(),
851 variables: make(map[string]string),
Colin Cross3f40fa42015-01-30 17:27:36 -0800852 }
853
Colin Cross4c83e5c2019-02-25 14:54:28 -0800854 if ctx.config.captureBuild {
855 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
856 }
857
Colin Cross67a5c132017-05-09 13:45:28 -0700858 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
859 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800860 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
861 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700862 }
Colin Cross0875c522017-11-28 17:34:01 -0800863 if !ctx.PrimaryArch() {
864 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700865 }
866
867 ctx.Variable(pctx, "moduleDesc", desc)
868
869 s := ""
870 if len(suffix) > 0 {
871 s = " [" + strings.Join(suffix, " ") + "]"
872 }
873 ctx.Variable(pctx, "moduleDescSuffix", s)
874
Dan Willemsen569edc52018-11-19 09:33:29 -0800875 // Some common property checks for properties that will be used later in androidmk.go
Colin Cross4157e882019-06-06 16:57:04 -0700876 if m.commonProperties.Dist.Dest != nil {
877 _, err := validateSafePath(*m.commonProperties.Dist.Dest)
Dan Willemsen569edc52018-11-19 09:33:29 -0800878 if err != nil {
879 ctx.PropertyErrorf("dist.dest", "%s", err.Error())
880 }
881 }
Colin Cross4157e882019-06-06 16:57:04 -0700882 if m.commonProperties.Dist.Dir != nil {
883 _, err := validateSafePath(*m.commonProperties.Dist.Dir)
Dan Willemsen569edc52018-11-19 09:33:29 -0800884 if err != nil {
885 ctx.PropertyErrorf("dist.dir", "%s", err.Error())
886 }
887 }
Colin Cross4157e882019-06-06 16:57:04 -0700888 if m.commonProperties.Dist.Suffix != nil {
889 if strings.Contains(*m.commonProperties.Dist.Suffix, "/") {
Dan Willemsen569edc52018-11-19 09:33:29 -0800890 ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.")
891 }
892 }
893
Colin Cross4157e882019-06-06 16:57:04 -0700894 if m.Enabled() {
Colin Cross7e0a2cb2019-06-06 16:13:11 -0700895 ctx.VisitDirectDeps(func(dep Module) {
896 if !dep.Enabled() {
897 if ctx.Config().AllowMissingDependencies() {
898 ctx.AddMissingDependencies([]string{ctx.OtherModuleName(dep)})
899 } else {
900 ctx.ModuleErrorf("depends on disabled module %q", ctx.OtherModuleName(dep))
901 }
902 }
903 })
904
Colin Cross4157e882019-06-06 16:57:04 -0700905 m.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700906 if ctx.Failed() {
907 return
908 }
909
Colin Cross4157e882019-06-06 16:57:04 -0700910 m.installFiles = append(m.installFiles, ctx.installFiles...)
911 m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
Jaewoong Jung62707f72018-11-16 13:26:43 -0800912
Colin Cross4157e882019-06-06 16:57:04 -0700913 notice := proptools.StringDefault(m.commonProperties.Notice, "NOTICE")
914 if module := SrcIsModule(notice); module != "" {
915 m.noticeFile = ctx.ExpandOptionalSource(&notice, "notice")
Jiyong Park52818fc2019-03-18 12:01:38 +0900916 } else {
917 noticePath := filepath.Join(ctx.ModuleDir(), notice)
Colin Cross4157e882019-06-06 16:57:04 -0700918 m.noticeFile = ExistentPathForSource(ctx, noticePath)
Jaewoong Jung62707f72018-11-16 13:26:43 -0800919 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800920 }
921
Colin Cross4157e882019-06-06 16:57:04 -0700922 if m == ctx.FinalModule().(Module).base() {
923 m.generateModuleTarget(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700924 if ctx.Failed() {
925 return
926 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800927 }
Colin Crosscec81712017-07-13 14:43:27 -0700928
Colin Cross4157e882019-06-06 16:57:04 -0700929 m.buildParams = ctx.buildParams
930 m.ruleParams = ctx.ruleParams
931 m.variables = ctx.variables
Colin Cross3f40fa42015-01-30 17:27:36 -0800932}
933
Colin Cross0ea8ba82019-06-06 14:33:29 -0700934type baseModuleContext struct {
935 blueprint.BaseModuleContext
Colin Cross8b74d172016-09-13 09:59:14 -0700936 target Target
Colin Crossee0bc3b2018-10-02 22:01:37 -0700937 multiTargets []Target
Colin Cross8b74d172016-09-13 09:59:14 -0700938 targetPrimary bool
939 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900940 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700941 config Config
Colin Cross7e0a2cb2019-06-06 16:13:11 -0700942
943 walkPath []Module
Colin Crossf6566ed2015-03-24 11:13:38 -0700944}
945
Colin Cross25de6c32019-06-06 14:29:25 -0700946type moduleContext struct {
Colin Cross7e0a2cb2019-06-06 16:13:11 -0700947 bp blueprint.ModuleContext
Colin Cross0ea8ba82019-06-06 14:33:29 -0700948 baseModuleContext
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700949 installDeps Paths
950 installFiles Paths
951 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800952 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700953 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700954
955 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700956 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800957 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800958 variables map[string]string
Colin Cross6ff51382015-12-17 16:39:19 -0800959}
960
Colin Cross25de6c32019-06-06 14:29:25 -0700961func (m *moduleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross7e0a2cb2019-06-06 16:13:11 -0700962 m.bp.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700963 Rule: ErrorRule,
964 Description: desc,
965 Outputs: outputs,
966 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800967 Args: map[string]string{
968 "error": err.Error(),
969 },
970 })
971 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800972}
973
Colin Cross25de6c32019-06-06 14:29:25 -0700974func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
975 m.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800976}
977
Colin Cross0875c522017-11-28 17:34:01 -0800978func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700979 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700980 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800981 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800982 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700983 Outputs: params.Outputs.Strings(),
984 ImplicitOutputs: params.ImplicitOutputs.Strings(),
985 Inputs: params.Inputs.Strings(),
986 Implicits: params.Implicits.Strings(),
987 OrderOnly: params.OrderOnly.Strings(),
988 Args: params.Args,
989 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700990 }
991
Colin Cross33bfb0a2016-11-21 17:23:08 -0800992 if params.Depfile != nil {
993 bparams.Depfile = params.Depfile.String()
994 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700995 if params.Output != nil {
996 bparams.Outputs = append(bparams.Outputs, params.Output.String())
997 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700998 if params.ImplicitOutput != nil {
999 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
1000 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001001 if params.Input != nil {
1002 bparams.Inputs = append(bparams.Inputs, params.Input.String())
1003 }
1004 if params.Implicit != nil {
1005 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
1006 }
1007
Colin Cross0b9f31f2019-02-28 11:00:01 -08001008 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
1009 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
1010 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
1011 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
1012 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
1013 bparams.Depfile = proptools.NinjaEscapeList([]string{bparams.Depfile})[0]
Colin Crossfe4bc362018-09-12 10:02:13 -07001014
Colin Cross0875c522017-11-28 17:34:01 -08001015 return bparams
1016}
1017
Colin Cross25de6c32019-06-06 14:29:25 -07001018func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
1019 if m.config.captureBuild {
1020 m.variables[name] = value
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001021 }
1022
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001023 m.bp.Variable(pctx.PackageContext, name, value)
Colin Cross0875c522017-11-28 17:34:01 -08001024}
1025
Colin Cross25de6c32019-06-06 14:29:25 -07001026func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
Colin Cross0875c522017-11-28 17:34:01 -08001027 argNames ...string) blueprint.Rule {
1028
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001029 rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
Colin Cross4c83e5c2019-02-25 14:54:28 -08001030
Colin Cross25de6c32019-06-06 14:29:25 -07001031 if m.config.captureBuild {
1032 m.ruleParams[rule] = params
Colin Cross4c83e5c2019-02-25 14:54:28 -08001033 }
1034
1035 return rule
Colin Cross0875c522017-11-28 17:34:01 -08001036}
1037
Colin Cross25de6c32019-06-06 14:29:25 -07001038func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
1039 if m.config.captureBuild {
1040 m.buildParams = append(m.buildParams, params)
Colin Cross0875c522017-11-28 17:34:01 -08001041 }
1042
1043 bparams := convertBuildParams(params)
1044
1045 if bparams.Description != "" {
1046 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
1047 }
1048
Colin Cross25de6c32019-06-06 14:29:25 -07001049 if m.missingDeps != nil {
1050 m.ninjaError(bparams.Description, bparams.Outputs,
Colin Cross67a5c132017-05-09 13:45:28 -07001051 fmt.Errorf("module %s missing dependencies: %s\n",
Colin Cross25de6c32019-06-06 14:29:25 -07001052 m.ModuleName(), strings.Join(m.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -08001053 return
1054 }
1055
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001056 m.bp.Build(pctx.PackageContext, bparams)
1057}
1058
1059func (m *moduleContext) Module() Module {
1060 return m.baseModuleContext.Module()
1061}
1062
1063func (b *baseModuleContext) Module() Module {
1064 module, _ := b.BaseModuleContext.Module().(Module)
1065 return module
1066}
1067
1068func (b *baseModuleContext) Config() Config {
1069 return b.BaseModuleContext.Config().(Config)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001070}
1071
Colin Cross25de6c32019-06-06 14:29:25 -07001072func (m *moduleContext) GetMissingDependencies() []string {
1073 return m.missingDeps
Colin Cross6ff51382015-12-17 16:39:19 -08001074}
1075
Colin Cross25de6c32019-06-06 14:29:25 -07001076func (m *moduleContext) AddMissingDependencies(deps []string) {
Dan Willemsen6553f5e2016-03-10 18:14:25 -08001077 if deps != nil {
Colin Cross25de6c32019-06-06 14:29:25 -07001078 m.missingDeps = append(m.missingDeps, deps...)
1079 m.missingDeps = FirstUniqueStrings(m.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -08001080 }
1081}
1082
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001083func (b *baseModuleContext) validateAndroidModule(module blueprint.Module) Module {
Colin Crossd11fcda2017-10-23 17:59:01 -07001084 aModule, _ := module.(Module)
Colin Crossd11fcda2017-10-23 17:59:01 -07001085 return aModule
1086}
1087
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001088func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
Jiyong Parkf2976302019-04-17 21:47:37 +09001089 type dep struct {
1090 mod blueprint.Module
1091 tag blueprint.DependencyTag
1092 }
1093 var deps []dep
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001094 b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
Colin Cross25de6c32019-06-06 14:29:25 -07001095 if aModule, _ := module.(Module); aModule != nil && aModule.base().BaseModuleName() == name {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001096 returnedTag := b.BaseModuleContext.OtherModuleDependencyTag(aModule)
Jiyong Parkf2976302019-04-17 21:47:37 +09001097 if tag == nil || returnedTag == tag {
1098 deps = append(deps, dep{aModule, returnedTag})
1099 }
1100 }
1101 })
1102 if len(deps) == 1 {
1103 return deps[0].mod, deps[0].tag
1104 } else if len(deps) >= 2 {
1105 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001106 name, b.ModuleName()))
Jiyong Parkf2976302019-04-17 21:47:37 +09001107 } else {
1108 return nil, nil
1109 }
1110}
1111
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001112func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
Colin Cross0ef08162019-05-01 15:50:51 -07001113 var deps []Module
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001114 b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
Colin Cross25de6c32019-06-06 14:29:25 -07001115 if aModule, _ := module.(Module); aModule != nil {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001116 if b.BaseModuleContext.OtherModuleDependencyTag(aModule) == tag {
Colin Cross0ef08162019-05-01 15:50:51 -07001117 deps = append(deps, aModule)
1118 }
1119 }
1120 })
1121 return deps
1122}
1123
Colin Cross25de6c32019-06-06 14:29:25 -07001124func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
1125 module, _ := m.getDirectDepInternal(name, tag)
1126 return module
Jiyong Parkf2976302019-04-17 21:47:37 +09001127}
1128
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001129func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
1130 return b.getDirectDepInternal(name, nil)
Jiyong Parkf2976302019-04-17 21:47:37 +09001131}
1132
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001133func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
1134 b.BaseModuleContext.VisitDirectDeps(visit)
Colin Cross35143d02017-11-16 00:11:20 -08001135}
1136
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001137func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
1138 b.BaseModuleContext.VisitDirectDeps(func(module blueprint.Module) {
1139 if aModule := b.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001140 visit(aModule)
1141 }
1142 })
1143}
1144
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001145func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
1146 b.BaseModuleContext.VisitDirectDeps(func(module blueprint.Module) {
1147 if aModule := b.validateAndroidModule(module); aModule != nil {
1148 if b.BaseModuleContext.OtherModuleDependencyTag(aModule) == tag {
Colin Crossee6143c2017-12-30 17:54:27 -08001149 visit(aModule)
1150 }
1151 }
1152 })
1153}
1154
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001155func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
1156 b.BaseModuleContext.VisitDirectDepsIf(
Colin Crossd11fcda2017-10-23 17:59:01 -07001157 // pred
1158 func(module blueprint.Module) bool {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001159 if aModule := b.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001160 return pred(aModule)
1161 } else {
1162 return false
1163 }
1164 },
1165 // visit
1166 func(module blueprint.Module) {
1167 visit(module.(Module))
1168 })
1169}
1170
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001171func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
1172 b.BaseModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
1173 if aModule := b.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001174 visit(aModule)
1175 }
1176 })
1177}
1178
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001179func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
1180 b.BaseModuleContext.VisitDepsDepthFirstIf(
Colin Crossd11fcda2017-10-23 17:59:01 -07001181 // pred
1182 func(module blueprint.Module) bool {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001183 if aModule := b.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001184 return pred(aModule)
1185 } else {
1186 return false
1187 }
1188 },
1189 // visit
1190 func(module blueprint.Module) {
1191 visit(module.(Module))
1192 })
1193}
1194
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001195func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
1196 b.BaseModuleContext.WalkDeps(visit)
Alex Light778127a2019-02-27 14:19:50 -08001197}
1198
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001199func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
1200 b.walkPath = []Module{b.Module()}
1201 b.BaseModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
1202 childAndroidModule, _ := child.(Module)
1203 parentAndroidModule, _ := parent.(Module)
Colin Crossd11fcda2017-10-23 17:59:01 -07001204 if childAndroidModule != nil && parentAndroidModule != nil {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001205 // record walkPath before visit
1206 for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
1207 b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
1208 }
1209 b.walkPath = append(b.walkPath, childAndroidModule)
Colin Crossd11fcda2017-10-23 17:59:01 -07001210 return visit(childAndroidModule, parentAndroidModule)
1211 } else {
1212 return false
1213 }
1214 })
1215}
1216
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001217func (b *baseModuleContext) GetWalkPath() []Module {
1218 return b.walkPath
1219}
1220
Colin Cross25de6c32019-06-06 14:29:25 -07001221func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001222 m.bp.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross0875c522017-11-28 17:34:01 -08001223 visit(module.(Module))
1224 })
1225}
1226
Colin Cross25de6c32019-06-06 14:29:25 -07001227func (m *moduleContext) PrimaryModule() Module {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001228 return m.bp.PrimaryModule().(Module)
Colin Cross0875c522017-11-28 17:34:01 -08001229}
1230
Colin Cross25de6c32019-06-06 14:29:25 -07001231func (m *moduleContext) FinalModule() Module {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001232 return m.bp.FinalModule().(Module)
1233}
1234
1235func (m *moduleContext) ModuleSubDir() string {
1236 return m.bp.ModuleSubDir()
Colin Cross0875c522017-11-28 17:34:01 -08001237}
1238
Colin Cross0ea8ba82019-06-06 14:33:29 -07001239func (b *baseModuleContext) Target() Target {
Colin Cross25de6c32019-06-06 14:29:25 -07001240 return b.target
Colin Crossa1ad8d12016-06-01 17:09:44 -07001241}
1242
Colin Cross0ea8ba82019-06-06 14:33:29 -07001243func (b *baseModuleContext) TargetPrimary() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001244 return b.targetPrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001245}
1246
Colin Cross0ea8ba82019-06-06 14:33:29 -07001247func (b *baseModuleContext) MultiTargets() []Target {
Colin Cross25de6c32019-06-06 14:29:25 -07001248 return b.multiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001249}
1250
Colin Cross0ea8ba82019-06-06 14:33:29 -07001251func (b *baseModuleContext) Arch() Arch {
Colin Cross25de6c32019-06-06 14:29:25 -07001252 return b.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -08001253}
1254
Colin Cross0ea8ba82019-06-06 14:33:29 -07001255func (b *baseModuleContext) Os() OsType {
Colin Cross25de6c32019-06-06 14:29:25 -07001256 return b.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001257}
1258
Colin Cross0ea8ba82019-06-06 14:33:29 -07001259func (b *baseModuleContext) Host() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001260 return b.target.Os.Class == Host || b.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -07001261}
1262
Colin Cross0ea8ba82019-06-06 14:33:29 -07001263func (b *baseModuleContext) Device() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001264 return b.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -07001265}
1266
Colin Cross0ea8ba82019-06-06 14:33:29 -07001267func (b *baseModuleContext) Darwin() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001268 return b.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -07001269}
1270
Colin Cross0ea8ba82019-06-06 14:33:29 -07001271func (b *baseModuleContext) Fuchsia() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001272 return b.target.Os == Fuchsia
Doug Horn21b94272019-01-16 12:06:11 -08001273}
1274
Colin Cross0ea8ba82019-06-06 14:33:29 -07001275func (b *baseModuleContext) Windows() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001276 return b.target.Os == Windows
Colin Cross3edeee12017-04-04 12:59:48 -07001277}
1278
Colin Cross0ea8ba82019-06-06 14:33:29 -07001279func (b *baseModuleContext) Debug() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001280 return b.debug
Colin Crossf6566ed2015-03-24 11:13:38 -07001281}
1282
Colin Cross0ea8ba82019-06-06 14:33:29 -07001283func (b *baseModuleContext) PrimaryArch() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001284 if len(b.config.Targets[b.target.Os]) <= 1 {
Colin Cross67a5c132017-05-09 13:45:28 -07001285 return true
1286 }
Colin Cross25de6c32019-06-06 14:29:25 -07001287 return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType
Colin Cross1e7d3702016-08-24 15:25:47 -07001288}
1289
Colin Cross0ea8ba82019-06-06 14:33:29 -07001290func (b *baseModuleContext) AConfig() Config {
Colin Cross25de6c32019-06-06 14:29:25 -07001291 return b.config
Colin Cross1332b002015-04-07 17:11:30 -07001292}
1293
Colin Cross0ea8ba82019-06-06 14:33:29 -07001294func (b *baseModuleContext) DeviceConfig() DeviceConfig {
Colin Cross25de6c32019-06-06 14:29:25 -07001295 return DeviceConfig{b.config.deviceConfig}
Colin Cross9272ade2016-08-17 15:24:12 -07001296}
1297
Colin Cross0ea8ba82019-06-06 14:33:29 -07001298func (b *baseModuleContext) Platform() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001299 return b.kind == platformModule
Jiyong Park2db76922017-11-08 16:03:48 +09001300}
1301
Colin Cross0ea8ba82019-06-06 14:33:29 -07001302func (b *baseModuleContext) DeviceSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001303 return b.kind == deviceSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001304}
1305
Colin Cross0ea8ba82019-06-06 14:33:29 -07001306func (b *baseModuleContext) SocSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001307 return b.kind == socSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001308}
1309
Colin Cross0ea8ba82019-06-06 14:33:29 -07001310func (b *baseModuleContext) ProductSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001311 return b.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -08001312}
1313
Colin Cross0ea8ba82019-06-06 14:33:29 -07001314func (b *baseModuleContext) ProductServicesSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001315 return b.kind == productServicesSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +01001316}
1317
Jiyong Park5baac542018-08-28 09:55:37 +09001318// Makes this module a platform module, i.e. not specific to soc, device,
1319// product, or product_services.
Colin Cross4157e882019-06-06 16:57:04 -07001320func (m *ModuleBase) MakeAsPlatform() {
1321 m.commonProperties.Vendor = boolPtr(false)
1322 m.commonProperties.Proprietary = boolPtr(false)
1323 m.commonProperties.Soc_specific = boolPtr(false)
1324 m.commonProperties.Product_specific = boolPtr(false)
1325 m.commonProperties.Product_services_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09001326}
1327
Colin Cross4157e882019-06-06 16:57:04 -07001328func (m *ModuleBase) EnableNativeBridgeSupportByDefault() {
1329 m.commonProperties.Native_bridge_supported = boolPtr(true)
dimitry03dc3f62019-05-09 14:07:34 +02001330}
1331
Colin Cross25de6c32019-06-06 14:29:25 -07001332func (m *moduleContext) InstallInData() bool {
1333 return m.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001334}
1335
Colin Cross25de6c32019-06-06 14:29:25 -07001336func (m *moduleContext) InstallInSanitizerDir() bool {
1337 return m.module.InstallInSanitizerDir()
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001338}
1339
Colin Cross25de6c32019-06-06 14:29:25 -07001340func (m *moduleContext) InstallInRecovery() bool {
1341 return m.module.InstallInRecovery()
Jiyong Parkf9332f12018-02-01 00:54:12 +09001342}
1343
Colin Cross25de6c32019-06-06 14:29:25 -07001344func (m *moduleContext) skipInstall(fullInstallPath OutputPath) bool {
1345 if m.module.base().commonProperties.SkipInstall {
Colin Cross893d8162017-04-26 17:34:03 -07001346 return true
1347 }
1348
Colin Cross3607f212018-05-07 15:28:05 -07001349 // We'll need a solution for choosing which of modules with the same name in different
1350 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1351 // list of namespaces to install in a Soong-only build.
Colin Cross25de6c32019-06-06 14:29:25 -07001352 if !m.module.base().commonProperties.NamespaceExportedToMake {
Colin Cross3607f212018-05-07 15:28:05 -07001353 return true
1354 }
1355
Colin Cross25de6c32019-06-06 14:29:25 -07001356 if m.Device() {
1357 if m.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001358 return true
1359 }
1360
Colin Cross25de6c32019-06-06 14:29:25 -07001361 if m.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001362 return true
1363 }
1364 }
1365
1366 return false
1367}
1368
Colin Cross25de6c32019-06-06 14:29:25 -07001369func (m *moduleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001370 deps ...Path) OutputPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001371 return m.installFile(installPath, name, srcPath, Cp, deps)
Colin Cross5c517922017-08-31 12:29:17 -07001372}
1373
Colin Cross25de6c32019-06-06 14:29:25 -07001374func (m *moduleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
Colin Cross5c517922017-08-31 12:29:17 -07001375 deps ...Path) OutputPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001376 return m.installFile(installPath, name, srcPath, CpExecutable, deps)
Colin Cross5c517922017-08-31 12:29:17 -07001377}
1378
Colin Cross25de6c32019-06-06 14:29:25 -07001379func (m *moduleContext) installFile(installPath OutputPath, name string, srcPath Path,
Colin Cross5c517922017-08-31 12:29:17 -07001380 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001381
Colin Cross25de6c32019-06-06 14:29:25 -07001382 fullInstallPath := installPath.Join(m, name)
1383 m.module.base().hooks.runInstallHooks(m, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001384
Colin Cross25de6c32019-06-06 14:29:25 -07001385 if !m.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001386
Colin Cross25de6c32019-06-06 14:29:25 -07001387 deps = append(deps, m.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001388
Colin Cross89562dc2016-10-03 17:47:19 -07001389 var implicitDeps, orderOnlyDeps Paths
1390
Colin Cross25de6c32019-06-06 14:29:25 -07001391 if m.Host() {
Colin Cross89562dc2016-10-03 17:47:19 -07001392 // Installed host modules might be used during the build, depend directly on their
1393 // dependencies so their timestamp is updated whenever their dependency is updated
1394 implicitDeps = deps
1395 } else {
1396 orderOnlyDeps = deps
1397 }
1398
Colin Cross25de6c32019-06-06 14:29:25 -07001399 m.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001400 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001401 Description: "install " + fullInstallPath.Base(),
1402 Output: fullInstallPath,
1403 Input: srcPath,
1404 Implicits: implicitDeps,
1405 OrderOnly: orderOnlyDeps,
Colin Cross25de6c32019-06-06 14:29:25 -07001406 Default: !m.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001407 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001408
Colin Cross25de6c32019-06-06 14:29:25 -07001409 m.installFiles = append(m.installFiles, fullInstallPath)
Dan Willemsen322acaf2016-01-12 23:07:05 -08001410 }
Colin Cross25de6c32019-06-06 14:29:25 -07001411 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001412 return fullInstallPath
1413}
1414
Colin Cross25de6c32019-06-06 14:29:25 -07001415func (m *moduleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1416 fullInstallPath := installPath.Join(m, name)
1417 m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001418
Colin Cross25de6c32019-06-06 14:29:25 -07001419 if !m.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001420
Alex Lightfb4353d2019-01-17 13:57:45 -08001421 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
1422 if err != nil {
1423 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
1424 }
Colin Cross25de6c32019-06-06 14:29:25 -07001425 m.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001426 Rule: Symlink,
1427 Description: "install symlink " + fullInstallPath.Base(),
1428 Output: fullInstallPath,
1429 OrderOnly: Paths{srcPath},
Colin Cross25de6c32019-06-06 14:29:25 -07001430 Default: !m.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001431 Args: map[string]string{
Alex Lightfb4353d2019-01-17 13:57:45 -08001432 "fromPath": relPath,
Colin Cross12fc4972016-01-11 12:49:11 -08001433 },
1434 })
Colin Cross3854a602016-01-11 12:49:11 -08001435
Colin Cross25de6c32019-06-06 14:29:25 -07001436 m.installFiles = append(m.installFiles, fullInstallPath)
1437 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross12fc4972016-01-11 12:49:11 -08001438 }
Colin Cross3854a602016-01-11 12:49:11 -08001439 return fullInstallPath
1440}
1441
Jiyong Parkf1194352019-02-25 11:05:47 +09001442// installPath/name -> absPath where absPath might be a path that is available only at runtime
1443// (e.g. /apex/...)
Colin Cross25de6c32019-06-06 14:29:25 -07001444func (m *moduleContext) InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath {
1445 fullInstallPath := installPath.Join(m, name)
1446 m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
Jiyong Parkf1194352019-02-25 11:05:47 +09001447
Colin Cross25de6c32019-06-06 14:29:25 -07001448 if !m.skipInstall(fullInstallPath) {
1449 m.Build(pctx, BuildParams{
Jiyong Parkf1194352019-02-25 11:05:47 +09001450 Rule: Symlink,
1451 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
1452 Output: fullInstallPath,
Colin Cross25de6c32019-06-06 14:29:25 -07001453 Default: !m.Config().EmbeddedInMake(),
Jiyong Parkf1194352019-02-25 11:05:47 +09001454 Args: map[string]string{
1455 "fromPath": absPath,
1456 },
1457 })
1458
Colin Cross25de6c32019-06-06 14:29:25 -07001459 m.installFiles = append(m.installFiles, fullInstallPath)
Jiyong Parkf1194352019-02-25 11:05:47 +09001460 }
1461 return fullInstallPath
1462}
1463
Colin Cross25de6c32019-06-06 14:29:25 -07001464func (m *moduleContext) CheckbuildFile(srcPath Path) {
1465 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross3f40fa42015-01-30 17:27:36 -08001466}
1467
Colin Cross3f40fa42015-01-30 17:27:36 -08001468type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001469 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001470}
1471
1472func isFileInstaller(m blueprint.Module) bool {
1473 _, ok := m.(fileInstaller)
1474 return ok
1475}
1476
1477func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001478 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001479 return ok
1480}
Colin Crossfce53272015-04-08 11:21:40 -07001481
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001482func findStringInSlice(str string, slice []string) int {
1483 for i, s := range slice {
1484 if s == str {
1485 return i
Colin Crossfce53272015-04-08 11:21:40 -07001486 }
1487 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001488 return -1
1489}
1490
Colin Cross41955e82019-05-29 14:40:35 -07001491// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
1492// was not a module reference.
1493func SrcIsModule(s string) (module string) {
Colin Cross068e0fe2016-12-13 15:23:47 -08001494 if len(s) > 1 && s[0] == ':' {
1495 return s[1:]
1496 }
1497 return ""
1498}
1499
Colin Cross41955e82019-05-29 14:40:35 -07001500// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
1501// module name and an empty string for the tag, or empty strings if the input was not a module reference.
1502func SrcIsModuleWithTag(s string) (module, tag string) {
1503 if len(s) > 1 && s[0] == ':' {
1504 module = s[1:]
1505 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
1506 if module[len(module)-1] == '}' {
1507 tag = module[tagStart+1 : len(module)-1]
1508 module = module[:tagStart]
1509 return module, tag
1510 }
1511 }
1512 return module, ""
1513 }
1514 return "", ""
Colin Cross068e0fe2016-12-13 15:23:47 -08001515}
1516
Colin Cross41955e82019-05-29 14:40:35 -07001517type sourceOrOutputDependencyTag struct {
1518 blueprint.BaseDependencyTag
1519 tag string
1520}
1521
1522func sourceOrOutputDepTag(tag string) blueprint.DependencyTag {
1523 return sourceOrOutputDependencyTag{tag: tag}
1524}
1525
1526var SourceDepTag = sourceOrOutputDepTag("")
Colin Cross068e0fe2016-12-13 15:23:47 -08001527
Colin Cross366938f2017-12-11 16:29:02 -08001528// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1529// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08001530//
1531// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08001532func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07001533 set := make(map[string]bool)
1534
Colin Cross068e0fe2016-12-13 15:23:47 -08001535 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07001536 if m, t := SrcIsModuleWithTag(s); m != "" {
1537 if _, found := set[s]; found {
1538 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07001539 } else {
Colin Cross41955e82019-05-29 14:40:35 -07001540 set[s] = true
1541 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07001542 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001543 }
1544 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001545}
1546
Colin Cross366938f2017-12-11 16:29:02 -08001547// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1548// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08001549//
1550// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08001551func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1552 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07001553 if m, t := SrcIsModuleWithTag(*s); m != "" {
1554 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
Colin Cross366938f2017-12-11 16:29:02 -08001555 }
1556 }
1557}
1558
Colin Cross41955e82019-05-29 14:40:35 -07001559// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
1560// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property.
Colin Cross068e0fe2016-12-13 15:23:47 -08001561type SourceFileProducer interface {
1562 Srcs() Paths
1563}
1564
Colin Cross41955e82019-05-29 14:40:35 -07001565// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
1566// using the ":module" syntax or ":module{.tag}" syntax and provides a list of otuput files to be used as if they were
1567// listed in the property.
1568type OutputFileProducer interface {
1569 OutputFiles(tag string) (Paths, error)
1570}
1571
Colin Crossfe17f6f2019-03-28 19:30:56 -07001572type HostToolProvider interface {
1573 HostToolPath() OptionalPath
1574}
1575
Colin Cross27b922f2019-03-04 22:35:41 -08001576// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
1577// be tagged with `android:"path" to support automatic source module dependency resolution.
Colin Cross8a497952019-03-05 22:25:09 -08001578//
1579// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
Colin Cross25de6c32019-06-06 14:29:25 -07001580func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
1581 return PathsForModuleSrcExcludes(m, srcFiles, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001582}
1583
Colin Cross2fafa3e2019-03-05 12:39:51 -08001584// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
1585// be tagged with `android:"path" to support automatic source module dependency resolution.
Colin Cross8a497952019-03-05 22:25:09 -08001586//
1587// Deprecated: use PathForModuleSrc instead.
Colin Cross25de6c32019-06-06 14:29:25 -07001588func (m *moduleContext) ExpandSource(srcFile, prop string) Path {
1589 return PathForModuleSrc(m, srcFile)
Colin Cross2fafa3e2019-03-05 12:39:51 -08001590}
1591
1592// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1593// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module
1594// dependency resolution.
Colin Cross25de6c32019-06-06 14:29:25 -07001595func (m *moduleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
Colin Cross2fafa3e2019-03-05 12:39:51 -08001596 if srcFile != nil {
Colin Cross25de6c32019-06-06 14:29:25 -07001597 return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
Colin Cross2fafa3e2019-03-05 12:39:51 -08001598 }
1599 return OptionalPath{}
1600}
1601
Colin Cross25de6c32019-06-06 14:29:25 -07001602func (m *moduleContext) RequiredModuleNames() []string {
1603 return m.module.base().commonProperties.Required
Nan Zhang6d34b302017-02-04 17:47:46 -08001604}
1605
Colin Cross25de6c32019-06-06 14:29:25 -07001606func (m *moduleContext) HostRequiredModuleNames() []string {
1607 return m.module.base().commonProperties.Host_required
Sasha Smundakb6d23052019-04-01 18:37:36 -07001608}
1609
Colin Cross25de6c32019-06-06 14:29:25 -07001610func (m *moduleContext) TargetRequiredModuleNames() []string {
1611 return m.module.base().commonProperties.Target_required
Sasha Smundakb6d23052019-04-01 18:37:36 -07001612}
1613
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001614func (b *baseModuleContext) Glob(globPattern string, excludes []string) Paths {
1615 ret, err := b.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001616 if err != nil {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001617 b.ModuleErrorf("glob: %s", err.Error())
Colin Cross8f101b42015-06-17 15:09:06 -07001618 }
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001619 return pathsForModuleSrcFromFullPath(b, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001620}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001621
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001622func (b *baseModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
1623 ret, err := b.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001624 if err != nil {
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001625 b.ModuleErrorf("glob: %s", err.Error())
Nan Zhang581fd212018-01-10 16:06:12 -08001626 }
Colin Cross7e0a2cb2019-06-06 16:13:11 -07001627 return pathsForModuleSrcFromFullPath(b, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001628}
1629
Colin Cross463a90e2015-06-17 14:20:06 -07001630func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001631 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001632}
1633
Colin Cross0875c522017-11-28 17:34:01 -08001634func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001635 return &buildTargetSingleton{}
1636}
1637
Colin Cross87d8b562017-04-25 10:01:55 -07001638func parentDir(dir string) string {
1639 dir, _ = filepath.Split(dir)
1640 return filepath.Clean(dir)
1641}
1642
Colin Cross1f8c52b2015-06-16 16:38:17 -07001643type buildTargetSingleton struct{}
1644
Colin Cross0875c522017-11-28 17:34:01 -08001645func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1646 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001647
Colin Cross0875c522017-11-28 17:34:01 -08001648 mmTarget := func(dir string) WritablePath {
1649 return PathForPhony(ctx,
1650 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001651 }
1652
Colin Cross0875c522017-11-28 17:34:01 -08001653 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001654
Colin Cross0875c522017-11-28 17:34:01 -08001655 ctx.VisitAllModules(func(module Module) {
1656 blueprintDir := module.base().blueprintDir
1657 installTarget := module.base().installTarget
1658 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001659
Colin Cross0875c522017-11-28 17:34:01 -08001660 if checkbuildTarget != nil {
1661 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1662 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1663 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001664
Colin Cross0875c522017-11-28 17:34:01 -08001665 if installTarget != nil {
1666 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001667 }
1668 })
1669
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001670 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001671 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001672 suffix = "-soong"
1673 }
1674
Colin Cross1f8c52b2015-06-16 16:38:17 -07001675 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001676 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001677 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001678 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001679 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001680 })
1681
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001682 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001683 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001684 return
1685 }
1686
Colin Cross0875c522017-11-28 17:34:01 -08001687 sortedKeys := func(m map[string]Paths) []string {
1688 s := make([]string, 0, len(m))
1689 for k := range m {
1690 s = append(s, k)
1691 }
1692 sort.Strings(s)
1693 return s
1694 }
1695
Colin Cross87d8b562017-04-25 10:01:55 -07001696 // Ensure ancestor directories are in modulesInDir
1697 dirs := sortedKeys(modulesInDir)
1698 for _, dir := range dirs {
1699 dir := parentDir(dir)
1700 for dir != "." && dir != "/" {
1701 if _, exists := modulesInDir[dir]; exists {
1702 break
1703 }
1704 modulesInDir[dir] = nil
1705 dir = parentDir(dir)
1706 }
1707 }
1708
1709 // Make directories build their direct subdirectories
1710 dirs = sortedKeys(modulesInDir)
1711 for _, dir := range dirs {
1712 p := parentDir(dir)
1713 if p != "." && p != "/" {
1714 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1715 }
1716 }
1717
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001718 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1719 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1720 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001721 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001722 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001723 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001724 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001725 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001726 // HACK: checkbuild should be an optional build, but force it
1727 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001728 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001729 })
1730 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001731
1732 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1733 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001734 ctx.VisitAllModules(func(module Module) {
1735 if module.Enabled() {
1736 os := module.Target().Os
1737 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001738 }
1739 })
1740
Colin Cross0875c522017-11-28 17:34:01 -08001741 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001742 for os, deps := range osDeps {
1743 var className string
1744
1745 switch os.Class {
1746 case Host:
1747 className = "host"
1748 case HostCross:
1749 className = "host-cross"
1750 case Device:
1751 className = "target"
1752 default:
1753 continue
1754 }
1755
Colin Cross0875c522017-11-28 17:34:01 -08001756 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001757 osClass[className] = append(osClass[className], name)
1758
Colin Cross0875c522017-11-28 17:34:01 -08001759 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001760 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001761 Output: name,
1762 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001763 })
1764 }
1765
1766 // Wrap those into host|host-cross|target phony rules
1767 osClasses := sortedKeys(osClass)
1768 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001769 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001770 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001771 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001772 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001773 })
1774 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001775}
Colin Crossd779da42015-12-17 18:00:23 -08001776
Brandon Lee5d45c6f2018-08-15 15:35:38 -07001777// Collect information for opening IDE project files in java/jdeps.go.
1778type IDEInfo interface {
1779 IDEInfo(ideInfo *IdeInfo)
1780 BaseModuleName() string
1781}
1782
1783// Extract the base module name from the Import name.
1784// Often the Import name has a prefix "prebuilt_".
1785// Remove the prefix explicitly if needed
1786// until we find a better solution to get the Import name.
1787type IDECustomizedModuleName interface {
1788 IDECustomizedModuleName() string
1789}
1790
1791type IdeInfo struct {
1792 Deps []string `json:"dependencies,omitempty"`
1793 Srcs []string `json:"srcs,omitempty"`
1794 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
1795 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
1796 Jars []string `json:"jars,omitempty"`
1797 Classes []string `json:"class,omitempty"`
1798 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08001799 SrcJars []string `json:"srcjars,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07001800}