blob: 88eba87db7e1fc2a3f77212d8ce2dd7c20f6019a [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 Cross6ff51382015-12-17 16:39:19 -080021 "strings"
Colin Crossaabf6792017-11-29 00:27:14 -080022 "text/scanner"
Colin Crossf6566ed2015-03-24 11:13:38 -070023
24 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070025 "github.com/google/blueprint/pathtools"
Colin Crossfe4bc362018-09-12 10:02:13 -070026 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080027)
28
29var (
30 DeviceSharedLibrary = "shared_library"
31 DeviceStaticLibrary = "static_library"
32 DeviceExecutable = "executable"
33 HostSharedLibrary = "host_shared_library"
34 HostStaticLibrary = "host_static_library"
35 HostExecutable = "host_executable"
36)
37
Colin Crossae887032017-10-23 17:16:14 -070038type BuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070039 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080040 Deps blueprint.Deps
41 Depfile WritablePath
Colin Cross67a5c132017-05-09 13:45:28 -070042 Description string
Dan Willemsen9f3c5742016-11-03 14:28:31 -070043 Output WritablePath
44 Outputs WritablePaths
45 ImplicitOutput WritablePath
46 ImplicitOutputs WritablePaths
47 Input Path
48 Inputs Paths
49 Implicit Path
50 Implicits Paths
51 OrderOnly Paths
52 Default bool
53 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070054}
55
Colin Crossae887032017-10-23 17:16:14 -070056type ModuleBuildParams BuildParams
57
Colin Cross0ea8ba82019-06-06 14:33:29 -070058// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
Colin Cross380c69a2019-06-10 17:49:58 +000059// a Config instead of an interface{}, plus some extra methods that return Android-specific information
Colin Cross0ea8ba82019-06-06 14:33:29 -070060// about the current module.
61type BaseModuleContext interface {
62 ModuleName() string
63 ModuleDir() string
64 ModuleType() string
65 Config() Config
66
67 ContainsProperty(name string) bool
68 Errorf(pos scanner.Position, fmt string, args ...interface{})
69 ModuleErrorf(fmt string, args ...interface{})
70 PropertyErrorf(property, fmt string, args ...interface{})
71 Failed() bool
72
73 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
74 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
75 // builder whenever a file matching the pattern as added or removed, without rerunning if a
76 // file that does not match the pattern is added to a searched directory.
77 GlobWithDeps(pattern string, excludes []string) ([]string, error)
78
79 Fs() pathtools.FileSystem
80 AddNinjaFileDeps(deps ...string)
81
Colin Crossa1ad8d12016-06-01 17:09:44 -070082 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070083 TargetPrimary() bool
Colin Crossee0bc3b2018-10-02 22:01:37 -070084 MultiTargets() []Target
Colin Crossf6566ed2015-03-24 11:13:38 -070085 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070086 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070087 Host() bool
88 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070089 Darwin() bool
Doug Horn21b94272019-01-16 12:06:11 -080090 Fuchsia() bool
Colin Cross3edeee12017-04-04 12:59:48 -070091 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070092 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070093 PrimaryArch() bool
Jiyong Park2db76922017-11-08 16:03:48 +090094 Platform() bool
95 DeviceSpecific() bool
96 SocSpecific() bool
97 ProductSpecific() bool
Dario Frenifd05a742018-05-29 13:28:54 +010098 ProductServicesSpecific() bool
Colin Cross1332b002015-04-07 17:11:30 -070099 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -0700100 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -0700101}
102
Colin Cross0ea8ba82019-06-06 14:33:29 -0700103// Deprecated: use BaseModuleContext instead
Colin Cross635c3b02016-05-18 15:37:25 -0700104type BaseContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -0800105 BaseModuleContext
Colin Crossaabf6792017-11-29 00:27:14 -0800106}
107
Colin Cross635c3b02016-05-18 15:37:25 -0700108type ModuleContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -0800109 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800110
Colin Crossae887032017-10-23 17:16:14 -0700111 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800112 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700113
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700114 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross366938f2017-12-11 16:29:02 -0800115 ExpandSource(srcFile, prop string) Path
Colin Cross2383f3b2018-02-06 14:40:13 -0800116 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
Colin Cross380c69a2019-06-10 17:49:58 +0000117 Glob(globPattern string, excludes []string) Paths
118 GlobFiles(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700119
Colin Cross5c517922017-08-31 12:29:17 -0700120 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
121 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800122 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Jiyong Parkf1194352019-02-25 11:05:47 +0900123 InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700124 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800125
126 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700127
Colin Cross8d8f8e22016-08-03 11:57:50 -0700128 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700129 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900130 InstallInRecovery() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800131
132 RequiredModuleNames() []string
Sasha Smundakb6d23052019-04-01 18:37:36 -0700133 HostRequiredModuleNames() []string
134 TargetRequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700135
Colin Cross380c69a2019-06-10 17:49:58 +0000136 // android.ModuleContext methods
137 // These are duplicated instead of embedded so that can eventually be wrapped to take an
138 // android.Module instead of a blueprint.Module
139 OtherModuleName(m blueprint.Module) string
140 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
141 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
142
143 GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
144 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
145 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
146
Colin Cross3f68a132017-10-23 17:10:29 -0700147 ModuleSubDir() string
148
Colin Cross380c69a2019-06-10 17:49:58 +0000149 VisitDirectDepsBlueprint(visit func(blueprint.Module))
150 VisitDirectDeps(visit func(Module))
151 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
152 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
153 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
154 VisitDepsDepthFirst(visit func(Module))
155 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
156 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
157 WalkDeps(visit func(Module, Module) bool)
158 WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
159
Colin Cross0875c522017-11-28 17:34:01 -0800160 Variable(pctx PackageContext, name, value string)
161 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700162 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
163 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800164 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700165
Colin Cross0875c522017-11-28 17:34:01 -0800166 PrimaryModule() Module
167 FinalModule() Module
168 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700169
170 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800171 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800172}
173
Colin Cross635c3b02016-05-18 15:37:25 -0700174type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800175 blueprint.Module
176
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700177 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
178 // but GenerateAndroidBuildActions also has access to Android-specific information.
179 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700180 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700181
Colin Cross1e676be2016-10-12 14:38:15 -0700182 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800183
Colin Cross635c3b02016-05-18 15:37:25 -0700184 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800185 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700186 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800187 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700188 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900189 InstallInRecovery() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800190 SkipInstall()
Jiyong Park374510b2018-03-19 18:23:01 +0900191 ExportedToMake() bool
Jiyong Park52818fc2019-03-18 12:01:38 +0900192 NoticeFile() OptionalPath
Colin Cross36242852017-06-23 15:06:31 -0700193
194 AddProperties(props ...interface{})
195 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700196
Colin Crossae887032017-10-23 17:16:14 -0700197 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800198 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800199 VariablesForTests() map[string]string
Colin Cross3f40fa42015-01-30 17:27:36 -0800200}
201
Colin Crossfc754582016-05-17 16:34:16 -0700202type nameProperties struct {
203 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800204 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700205}
206
207type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800208 // emit build rules for this module
209 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800210
Paul Duffin2e61fa62019-03-28 14:10:57 +0000211 // Controls the visibility of this module to other modules. Allowable values are one or more of
212 // these formats:
213 //
214 // ["//visibility:public"]: Anyone can use this module.
215 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
216 // this module.
217 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
218 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
219 // this module. Note that sub-packages do not have access to the rule; for example,
220 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
221 // is a special module and must be used verbatim. It represents all of the modules in the
222 // package.
223 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
224 // or other or in one of their sub-packages have access to this module. For example,
225 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
226 // to depend on this rule (but not //independent:evil)
227 // ["//project"]: This is shorthand for ["//project:__pkg__"]
228 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
229 // //project is the module's package. e.g. using [":__subpackages__"] in
230 // packages/apps/Settings/Android.bp is equivalent to
231 // //packages/apps/Settings:__subpackages__.
232 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
233 // for now. It is an error if it is used in a module.
234 // See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
235 // more details.
236 Visibility []string
237
Colin Cross7d5136f2015-05-11 13:39:40 -0700238 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800239 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
240 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
241 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700242 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700243
244 Target struct {
245 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700246 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700247 }
248 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700249 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700250 }
251 }
252
Colin Crossee0bc3b2018-10-02 22:01:37 -0700253 UseTargetVariants bool `blueprint:"mutated"`
254 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800255
Dan Willemsen782a2d12015-12-21 14:55:28 -0800256 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700257 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800258
Colin Cross55708f32017-03-20 13:23:34 -0700259 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700260 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700261
Jiyong Park2db76922017-11-08 16:03:48 +0900262 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
263 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
264 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700265 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700266
Jiyong Park2db76922017-11-08 16:03:48 +0900267 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
268 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
269 Soc_specific *bool
270
271 // whether this module is specific to a device, not only for SoC, but also for off-chip
272 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
273 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
274 // This implies `soc_specific:true`.
275 Device_specific *bool
276
277 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900278 // network operator, etc). When set to true, it is installed into /product (or
279 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900280 Product_specific *bool
281
Dario Frenifd05a742018-05-29 13:28:54 +0100282 // whether this module provides services owned by the OS provider to the core platform. When set
Dario Freni95cf7672018-08-17 00:57:57 +0100283 // to true, it is installed into /product_services (or /system/product_services if
284 // product_services partition does not exist).
285 Product_services_specific *bool
Dario Frenifd05a742018-05-29 13:28:54 +0100286
Jiyong Parkf9332f12018-02-01 00:54:12 +0900287 // Whether this module is installed to recovery partition
288 Recovery *bool
289
dimitry1f33e402019-03-26 12:39:31 +0100290 // Whether this module is built for non-native architecures (also known as native bridge binary)
291 Native_bridge_supported *bool `android:"arch_variant"`
292
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700293 // init.rc files to be installed if this module is installed
Colin Cross27b922f2019-03-04 22:35:41 -0800294 Init_rc []string `android:"path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700295
Steven Moreland57a23d22018-04-04 15:42:19 -0700296 // VINTF manifest fragments to be installed if this module is installed
Colin Cross27b922f2019-03-04 22:35:41 -0800297 Vintf_fragments []string `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700298
Chris Wolfe998306e2016-08-15 14:47:23 -0400299 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700300 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400301
Sasha Smundakb6d23052019-04-01 18:37:36 -0700302 // names of other modules to install on host if this module is installed
303 Host_required []string `android:"arch_variant"`
304
305 // names of other modules to install on target if this module is installed
306 Target_required []string `android:"arch_variant"`
307
Colin Cross5aac3622017-08-31 15:07:09 -0700308 // relative path to a file to include in the list of notices for the device
Colin Cross27b922f2019-03-04 22:35:41 -0800309 Notice *string `android:"path"`
Colin Cross5aac3622017-08-31 15:07:09 -0700310
Dan Willemsen569edc52018-11-19 09:33:29 -0800311 Dist struct {
312 // copy the output of this module to the $DIST_DIR when `dist` is specified on the
313 // command line and any of these targets are also on the command line, or otherwise
314 // built
315 Targets []string `android:"arch_variant"`
316
317 // The name of the output artifact. This defaults to the basename of the output of
318 // the module.
319 Dest *string `android:"arch_variant"`
320
321 // The directory within the dist directory to store the artifact. Defaults to the
322 // top level directory ("").
323 Dir *string `android:"arch_variant"`
324
325 // A suffix to add to the artifact file name (before any extension).
326 Suffix *string `android:"arch_variant"`
327 } `android:"arch_variant"`
328
Colin Crossa1ad8d12016-06-01 17:09:44 -0700329 // Set by TargetMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700330 CompileTarget Target `blueprint:"mutated"`
331 CompileMultiTargets []Target `blueprint:"mutated"`
332 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800333
334 // Set by InitAndroidModule
335 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700336 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700337
338 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800339
340 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800341}
342
343type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800344 // If set to true, build a variant of the module for the host. Defaults to false.
345 Host_supported *bool
346
347 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700348 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800349}
350
Colin Crossc472d572015-03-17 15:06:21 -0700351type Multilib string
352
353const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800354 MultilibBoth Multilib = "both"
355 MultilibFirst Multilib = "first"
356 MultilibCommon Multilib = "common"
357 MultilibCommonFirst Multilib = "common_first"
358 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700359)
360
Colin Crossa1ad8d12016-06-01 17:09:44 -0700361type HostOrDeviceSupported int
362
363const (
364 _ HostOrDeviceSupported = iota
Dan Albert0981b5c2018-08-02 13:46:35 -0700365
366 // Host and HostCross are built by default. Device is not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700367 HostSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700368
369 // Host is built by default. HostCross and Device are not supported.
Dan Albertc6345fb2016-10-20 01:36:11 -0700370 HostSupportedNoCross
Dan Albert0981b5c2018-08-02 13:46:35 -0700371
372 // Device is built by default. Host and HostCross are not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700373 DeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700374
375 // Device is built by default. Host and HostCross are supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700376 HostAndDeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700377
378 // Host, HostCross, and Device are built by default.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700379 HostAndDeviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700380
381 // Nothing is supported. This is not exposed to the user, but used to mark a
382 // host only module as unsupported when the module type is not supported on
383 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Dan Willemsen0b24c742016-10-04 15:13:37 -0700384 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700385)
386
Jiyong Park2db76922017-11-08 16:03:48 +0900387type moduleKind int
388
389const (
390 platformModule moduleKind = iota
391 deviceSpecificModule
392 socSpecificModule
393 productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100394 productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900395)
396
397func (k moduleKind) String() string {
398 switch k {
399 case platformModule:
400 return "platform"
401 case deviceSpecificModule:
402 return "device-specific"
403 case socSpecificModule:
404 return "soc-specific"
405 case productSpecificModule:
406 return "product-specific"
Dario Frenifd05a742018-05-29 13:28:54 +0100407 case productServicesSpecificModule:
408 return "productservices-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900409 default:
410 panic(fmt.Errorf("unknown module kind %d", k))
411 }
412}
413
Colin Cross36242852017-06-23 15:06:31 -0700414func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800415 base := m.base()
416 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700417
Colin Cross36242852017-06-23 15:06:31 -0700418 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700419 &base.nameProperties,
420 &base.commonProperties,
421 &base.variableProperties)
Colin Crossa3a97412019-03-18 12:24:29 -0700422 base.generalProperties = m.GetProperties()
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700423 base.customizableProperties = m.GetProperties()
Colin Cross5049f022015-03-18 13:28:46 -0700424}
425
Colin Cross36242852017-06-23 15:06:31 -0700426func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
427 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700428
429 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800430 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700431 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700432 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700433 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800434
Dan Willemsen218f6562015-07-08 18:13:11 -0700435 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700436 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700437 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 }
439
Colin Cross36242852017-06-23 15:06:31 -0700440 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800441}
442
Colin Crossee0bc3b2018-10-02 22:01:37 -0700443func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
444 InitAndroidArchModule(m, hod, defaultMultilib)
445 m.base().commonProperties.UseTargetVariants = false
446}
447
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800448// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800449// modules. It should be included as an anonymous field in every module
450// struct definition. InitAndroidModule should then be called from the module's
451// factory function, and the return values from InitAndroidModule should be
452// returned from the factory function.
453//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800454// The ModuleBase type is responsible for implementing the GenerateBuildActions
455// method to support the blueprint.Module interface. This method will then call
456// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700457// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
458// rather than the usual blueprint.ModuleContext.
459// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800460// system including details about the particular build variant that is to be
461// generated.
462//
463// For example:
464//
465// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800466// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800467// )
468//
469// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800470// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800471// properties struct {
472// MyProperty string
473// }
474// }
475//
Colin Cross36242852017-06-23 15:06:31 -0700476// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800477// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700478// m.AddProperties(&m.properties)
479// android.InitAndroidModule(m)
480// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800481// }
482//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800483// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800484// // Get the CPU architecture for the current build variant.
485// variantArch := ctx.Arch()
486//
487// // ...
488// }
Colin Cross635c3b02016-05-18 15:37:25 -0700489type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800490 // Putting the curiously recurring thing pointing to the thing that contains
491 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700492 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700493 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800494
Colin Crossfc754582016-05-17 16:34:16 -0700495 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800496 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700497 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800498 hostAndDeviceProperties hostAndDeviceProperties
499 generalProperties []interface{}
Colin Crossc17727d2018-10-24 12:42:09 -0700500 archProperties [][]interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700501 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800502
503 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700504 installFiles Paths
505 checkbuildFiles Paths
Jiyong Park52818fc2019-03-18 12:01:38 +0900506 noticeFile OptionalPath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700507
508 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
509 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800510 installTarget WritablePath
511 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700512 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700513
Colin Cross178a5092016-09-13 13:42:32 -0700514 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700515
516 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700517
518 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700519 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800520 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800521 variables map[string]string
Colin Crossa9d8bee2018-10-02 13:59:46 -0700522
523 prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
Colin Cross36242852017-06-23 15:06:31 -0700524}
525
Colin Cross4157e882019-06-06 16:57:04 -0700526func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800527
Colin Cross4157e882019-06-06 16:57:04 -0700528func (m *ModuleBase) AddProperties(props ...interface{}) {
529 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -0700530}
531
Colin Cross4157e882019-06-06 16:57:04 -0700532func (m *ModuleBase) GetProperties() []interface{} {
533 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800534}
535
Colin Cross4157e882019-06-06 16:57:04 -0700536func (m *ModuleBase) BuildParamsForTests() []BuildParams {
537 return m.buildParams
Colin Crosscec81712017-07-13 14:43:27 -0700538}
539
Colin Cross4157e882019-06-06 16:57:04 -0700540func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
541 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800542}
543
Colin Cross4157e882019-06-06 16:57:04 -0700544func (m *ModuleBase) VariablesForTests() map[string]string {
545 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800546}
547
Colin Cross4157e882019-06-06 16:57:04 -0700548func (m *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) {
549 m.prefer32 = prefer32
Colin Crossa9d8bee2018-10-02 13:59:46 -0700550}
551
Colin Crossce75d2c2016-10-06 16:12:58 -0700552// Name returns the name of the module. It may be overridden by individual module types, for
553// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -0700554func (m *ModuleBase) Name() string {
555 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700556}
557
Colin Crossce75d2c2016-10-06 16:12:58 -0700558// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -0700559func (m *ModuleBase) BaseModuleName() string {
560 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700561}
562
Colin Cross4157e882019-06-06 16:57:04 -0700563func (m *ModuleBase) base() *ModuleBase {
564 return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800565}
566
Colin Cross4157e882019-06-06 16:57:04 -0700567func (m *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) {
568 m.commonProperties.CompileTarget = target
569 m.commonProperties.CompileMultiTargets = multiTargets
570 m.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700571}
572
Colin Cross4157e882019-06-06 16:57:04 -0700573func (m *ModuleBase) Target() Target {
574 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800575}
576
Colin Cross4157e882019-06-06 16:57:04 -0700577func (m *ModuleBase) TargetPrimary() bool {
578 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -0700579}
580
Colin Cross4157e882019-06-06 16:57:04 -0700581func (m *ModuleBase) MultiTargets() []Target {
582 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -0700583}
584
Colin Cross4157e882019-06-06 16:57:04 -0700585func (m *ModuleBase) Os() OsType {
586 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800587}
588
Colin Cross4157e882019-06-06 16:57:04 -0700589func (m *ModuleBase) Host() bool {
590 return m.Os().Class == Host || m.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800591}
592
Colin Cross4157e882019-06-06 16:57:04 -0700593func (m *ModuleBase) Arch() Arch {
594 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800595}
596
Colin Cross4157e882019-06-06 16:57:04 -0700597func (m *ModuleBase) ArchSpecific() bool {
598 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -0700599}
600
Colin Cross4157e882019-06-06 16:57:04 -0700601func (m *ModuleBase) OsClassSupported() []OsClass {
602 switch m.commonProperties.HostOrDeviceSupported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700603 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700604 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700605 case HostSupportedNoCross:
606 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700607 case DeviceSupported:
608 return []OsClass{Device}
Dan Albert0981b5c2018-08-02 13:46:35 -0700609 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700610 var supported []OsClass
Colin Cross4157e882019-06-06 16:57:04 -0700611 if Bool(m.hostAndDeviceProperties.Host_supported) ||
612 (m.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
613 m.hostAndDeviceProperties.Host_supported == nil) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700614 supported = append(supported, Host, HostCross)
615 }
Colin Cross4157e882019-06-06 16:57:04 -0700616 if m.hostAndDeviceProperties.Device_supported == nil ||
617 *m.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700618 supported = append(supported, Device)
619 }
620 return supported
621 default:
622 return nil
623 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800624}
625
Colin Cross4157e882019-06-06 16:57:04 -0700626func (m *ModuleBase) DeviceSupported() bool {
627 return m.commonProperties.HostOrDeviceSupported == DeviceSupported ||
628 m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
629 (m.hostAndDeviceProperties.Device_supported == nil ||
630 *m.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800631}
632
Colin Cross4157e882019-06-06 16:57:04 -0700633func (m *ModuleBase) Platform() bool {
634 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.ProductServicesSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900635}
636
Colin Cross4157e882019-06-06 16:57:04 -0700637func (m *ModuleBase) DeviceSpecific() bool {
638 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900639}
640
Colin Cross4157e882019-06-06 16:57:04 -0700641func (m *ModuleBase) SocSpecific() bool {
642 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900643}
644
Colin Cross4157e882019-06-06 16:57:04 -0700645func (m *ModuleBase) ProductSpecific() bool {
646 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900647}
648
Colin Cross4157e882019-06-06 16:57:04 -0700649func (m *ModuleBase) ProductServicesSpecific() bool {
650 return Bool(m.commonProperties.Product_services_specific)
Dario Frenifd05a742018-05-29 13:28:54 +0100651}
652
Colin Cross4157e882019-06-06 16:57:04 -0700653func (m *ModuleBase) Enabled() bool {
654 if m.commonProperties.Enabled == nil {
655 return !m.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800656 }
Colin Cross4157e882019-06-06 16:57:04 -0700657 return *m.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800658}
659
Colin Cross4157e882019-06-06 16:57:04 -0700660func (m *ModuleBase) SkipInstall() {
661 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -0700662}
663
Colin Cross4157e882019-06-06 16:57:04 -0700664func (m *ModuleBase) ExportedToMake() bool {
665 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +0900666}
667
Colin Cross4157e882019-06-06 16:57:04 -0700668func (m *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700669 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800670
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700671 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700672 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800673 ctx.VisitDepsDepthFirstIf(isFileInstaller,
674 func(m blueprint.Module) {
675 fileInstaller := m.(fileInstaller)
676 files := fileInstaller.filesToInstall()
677 result = append(result, files...)
678 })
679
680 return result
681}
682
Colin Cross4157e882019-06-06 16:57:04 -0700683func (m *ModuleBase) filesToInstall() Paths {
684 return m.installFiles
Colin Cross3f40fa42015-01-30 17:27:36 -0800685}
686
Colin Cross4157e882019-06-06 16:57:04 -0700687func (m *ModuleBase) NoAddressSanitizer() bool {
688 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -0800689}
690
Colin Cross4157e882019-06-06 16:57:04 -0700691func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800692 return false
693}
694
Colin Cross4157e882019-06-06 16:57:04 -0700695func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700696 return false
697}
698
Colin Cross4157e882019-06-06 16:57:04 -0700699func (m *ModuleBase) InstallInRecovery() bool {
700 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +0900701}
702
Colin Cross4157e882019-06-06 16:57:04 -0700703func (m *ModuleBase) Owner() string {
704 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900705}
706
Colin Cross4157e882019-06-06 16:57:04 -0700707func (m *ModuleBase) NoticeFile() OptionalPath {
708 return m.noticeFile
Jiyong Park52818fc2019-03-18 12:01:38 +0900709}
710
Colin Cross4157e882019-06-06 16:57:04 -0700711func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700712 allInstalledFiles := Paths{}
713 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800714 ctx.VisitAllModuleVariants(func(module Module) {
715 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700716 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
717 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800718 })
719
Colin Cross0875c522017-11-28 17:34:01 -0800720 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700721
Jeff Gaston088e29e2017-11-29 16:47:17 -0800722 namespacePrefix := ctx.Namespace().(*Namespace).id
723 if namespacePrefix != "" {
724 namespacePrefix = namespacePrefix + "-"
725 }
726
Colin Cross3f40fa42015-01-30 17:27:36 -0800727 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800728 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800729 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700730 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800731 Output: name,
732 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800733 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700734 })
735 deps = append(deps, name)
Colin Cross4157e882019-06-06 16:57:04 -0700736 m.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700737 }
738
739 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800740 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800741 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700742 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800743 Output: name,
744 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700745 })
746 deps = append(deps, name)
Colin Cross4157e882019-06-06 16:57:04 -0700747 m.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700748 }
749
750 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800751 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800752 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800753 suffix = "-soong"
754 }
755
Jeff Gaston088e29e2017-11-29 16:47:17 -0800756 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800757 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700758 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800759 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700760 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800761 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700762
Colin Cross4157e882019-06-06 16:57:04 -0700763 m.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800764 }
765}
766
Colin Cross4157e882019-06-06 16:57:04 -0700767func determineModuleKind(m *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
768 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
769 var deviceSpecific = Bool(m.commonProperties.Device_specific)
770 var productSpecific = Bool(m.commonProperties.Product_specific)
771 var productServicesSpecific = Bool(m.commonProperties.Product_services_specific)
Jiyong Park2db76922017-11-08 16:03:48 +0900772
Dario Frenifd05a742018-05-29 13:28:54 +0100773 msg := "conflicting value set here"
774 if socSpecific && deviceSpecific {
775 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -0700776 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +0900777 ctx.PropertyErrorf("vendor", msg)
778 }
Colin Cross4157e882019-06-06 16:57:04 -0700779 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +0900780 ctx.PropertyErrorf("proprietary", msg)
781 }
Colin Cross4157e882019-06-06 16:57:04 -0700782 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +0900783 ctx.PropertyErrorf("soc_specific", msg)
784 }
785 }
786
Dario Frenifd05a742018-05-29 13:28:54 +0100787 if productSpecific && productServicesSpecific {
788 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.")
789 ctx.PropertyErrorf("product_services_specific", msg)
790 }
791
792 if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) {
793 if productSpecific {
794 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
795 } else {
796 ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.")
797 }
798 if deviceSpecific {
799 ctx.PropertyErrorf("device_specific", msg)
800 } else {
Colin Cross4157e882019-06-06 16:57:04 -0700801 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +0100802 ctx.PropertyErrorf("vendor", msg)
803 }
Colin Cross4157e882019-06-06 16:57:04 -0700804 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +0100805 ctx.PropertyErrorf("proprietary", msg)
806 }
Colin Cross4157e882019-06-06 16:57:04 -0700807 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +0100808 ctx.PropertyErrorf("soc_specific", msg)
809 }
810 }
811 }
812
Jiyong Park2db76922017-11-08 16:03:48 +0900813 if productSpecific {
814 return productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100815 } else if productServicesSpecific {
816 return productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900817 } else if deviceSpecific {
818 return deviceSpecificModule
819 } else if socSpecific {
820 return socSpecificModule
821 } else {
822 return platformModule
823 }
824}
825
Colin Cross0ea8ba82019-06-06 14:33:29 -0700826func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
827 return baseModuleContext{
828 BaseModuleContext: ctx,
829 target: m.commonProperties.CompileTarget,
830 targetPrimary: m.commonProperties.CompilePrimary,
831 multiTargets: m.commonProperties.CompileMultiTargets,
832 kind: determineModuleKind(m, ctx),
833 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800834 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800835}
836
Colin Cross4157e882019-06-06 16:57:04 -0700837func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -0700838 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -0700839 module: m.module,
Colin Cross380c69a2019-06-10 17:49:58 +0000840 ModuleContext: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -0700841 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
842 installDeps: m.computeInstallDeps(blueprintCtx),
843 installFiles: m.installFiles,
844 missingDeps: blueprintCtx.GetMissingDependencies(),
845 variables: make(map[string]string),
Colin Cross3f40fa42015-01-30 17:27:36 -0800846 }
847
Colin Cross4c83e5c2019-02-25 14:54:28 -0800848 if ctx.config.captureBuild {
849 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
850 }
851
Colin Cross67a5c132017-05-09 13:45:28 -0700852 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
853 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800854 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
855 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700856 }
Colin Cross0875c522017-11-28 17:34:01 -0800857 if !ctx.PrimaryArch() {
858 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700859 }
860
861 ctx.Variable(pctx, "moduleDesc", desc)
862
863 s := ""
864 if len(suffix) > 0 {
865 s = " [" + strings.Join(suffix, " ") + "]"
866 }
867 ctx.Variable(pctx, "moduleDescSuffix", s)
868
Dan Willemsen569edc52018-11-19 09:33:29 -0800869 // Some common property checks for properties that will be used later in androidmk.go
Colin Cross4157e882019-06-06 16:57:04 -0700870 if m.commonProperties.Dist.Dest != nil {
871 _, err := validateSafePath(*m.commonProperties.Dist.Dest)
Dan Willemsen569edc52018-11-19 09:33:29 -0800872 if err != nil {
873 ctx.PropertyErrorf("dist.dest", "%s", err.Error())
874 }
875 }
Colin Cross4157e882019-06-06 16:57:04 -0700876 if m.commonProperties.Dist.Dir != nil {
877 _, err := validateSafePath(*m.commonProperties.Dist.Dir)
Dan Willemsen569edc52018-11-19 09:33:29 -0800878 if err != nil {
879 ctx.PropertyErrorf("dist.dir", "%s", err.Error())
880 }
881 }
Colin Cross4157e882019-06-06 16:57:04 -0700882 if m.commonProperties.Dist.Suffix != nil {
883 if strings.Contains(*m.commonProperties.Dist.Suffix, "/") {
Dan Willemsen569edc52018-11-19 09:33:29 -0800884 ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.")
885 }
886 }
887
Colin Cross4157e882019-06-06 16:57:04 -0700888 if m.Enabled() {
889 m.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700890 if ctx.Failed() {
891 return
892 }
893
Colin Cross4157e882019-06-06 16:57:04 -0700894 m.installFiles = append(m.installFiles, ctx.installFiles...)
895 m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
Jaewoong Jung62707f72018-11-16 13:26:43 -0800896
Colin Cross4157e882019-06-06 16:57:04 -0700897 notice := proptools.StringDefault(m.commonProperties.Notice, "NOTICE")
898 if module := SrcIsModule(notice); module != "" {
899 m.noticeFile = ctx.ExpandOptionalSource(&notice, "notice")
Jiyong Park52818fc2019-03-18 12:01:38 +0900900 } else {
901 noticePath := filepath.Join(ctx.ModuleDir(), notice)
Colin Cross4157e882019-06-06 16:57:04 -0700902 m.noticeFile = ExistentPathForSource(ctx, noticePath)
Jaewoong Jung62707f72018-11-16 13:26:43 -0800903 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800904 }
905
Colin Cross4157e882019-06-06 16:57:04 -0700906 if m == ctx.FinalModule().(Module).base() {
907 m.generateModuleTarget(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700908 if ctx.Failed() {
909 return
910 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800911 }
Colin Crosscec81712017-07-13 14:43:27 -0700912
Colin Cross4157e882019-06-06 16:57:04 -0700913 m.buildParams = ctx.buildParams
914 m.ruleParams = ctx.ruleParams
915 m.variables = ctx.variables
Colin Cross3f40fa42015-01-30 17:27:36 -0800916}
917
Colin Cross0ea8ba82019-06-06 14:33:29 -0700918type baseModuleContext struct {
919 blueprint.BaseModuleContext
Colin Cross8b74d172016-09-13 09:59:14 -0700920 target Target
Colin Crossee0bc3b2018-10-02 22:01:37 -0700921 multiTargets []Target
Colin Cross8b74d172016-09-13 09:59:14 -0700922 targetPrimary bool
923 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900924 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700925 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700926}
927
Colin Cross25de6c32019-06-06 14:29:25 -0700928type moduleContext struct {
Colin Cross380c69a2019-06-10 17:49:58 +0000929 blueprint.ModuleContext
Colin Cross0ea8ba82019-06-06 14:33:29 -0700930 baseModuleContext
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700931 installDeps Paths
932 installFiles Paths
933 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800934 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700935 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700936
937 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700938 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800939 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800940 variables map[string]string
Colin Cross6ff51382015-12-17 16:39:19 -0800941}
942
Colin Cross25de6c32019-06-06 14:29:25 -0700943func (m *moduleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross380c69a2019-06-10 17:49:58 +0000944 m.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700945 Rule: ErrorRule,
946 Description: desc,
947 Outputs: outputs,
948 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800949 Args: map[string]string{
950 "error": err.Error(),
951 },
952 })
953 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800954}
955
Colin Cross380c69a2019-06-10 17:49:58 +0000956func (m *moduleContext) Config() Config {
957 return m.ModuleContext.Config().(Config)
958}
959
Colin Cross25de6c32019-06-06 14:29:25 -0700960func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
961 m.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800962}
963
Colin Cross0875c522017-11-28 17:34:01 -0800964func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700965 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700966 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800967 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800968 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700969 Outputs: params.Outputs.Strings(),
970 ImplicitOutputs: params.ImplicitOutputs.Strings(),
971 Inputs: params.Inputs.Strings(),
972 Implicits: params.Implicits.Strings(),
973 OrderOnly: params.OrderOnly.Strings(),
974 Args: params.Args,
975 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700976 }
977
Colin Cross33bfb0a2016-11-21 17:23:08 -0800978 if params.Depfile != nil {
979 bparams.Depfile = params.Depfile.String()
980 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700981 if params.Output != nil {
982 bparams.Outputs = append(bparams.Outputs, params.Output.String())
983 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700984 if params.ImplicitOutput != nil {
985 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
986 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700987 if params.Input != nil {
988 bparams.Inputs = append(bparams.Inputs, params.Input.String())
989 }
990 if params.Implicit != nil {
991 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
992 }
993
Colin Cross0b9f31f2019-02-28 11:00:01 -0800994 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
995 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
996 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
997 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
998 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
999 bparams.Depfile = proptools.NinjaEscapeList([]string{bparams.Depfile})[0]
Colin Crossfe4bc362018-09-12 10:02:13 -07001000
Colin Cross0875c522017-11-28 17:34:01 -08001001 return bparams
1002}
1003
Colin Cross25de6c32019-06-06 14:29:25 -07001004func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
1005 if m.config.captureBuild {
1006 m.variables[name] = value
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001007 }
1008
Colin Cross380c69a2019-06-10 17:49:58 +00001009 m.ModuleContext.Variable(pctx.PackageContext, name, value)
Colin Cross0875c522017-11-28 17:34:01 -08001010}
1011
Colin Cross25de6c32019-06-06 14:29:25 -07001012func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
Colin Cross0875c522017-11-28 17:34:01 -08001013 argNames ...string) blueprint.Rule {
1014
Colin Cross380c69a2019-06-10 17:49:58 +00001015 rule := m.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
Colin Cross4c83e5c2019-02-25 14:54:28 -08001016
Colin Cross25de6c32019-06-06 14:29:25 -07001017 if m.config.captureBuild {
1018 m.ruleParams[rule] = params
Colin Cross4c83e5c2019-02-25 14:54:28 -08001019 }
1020
1021 return rule
Colin Cross0875c522017-11-28 17:34:01 -08001022}
1023
Colin Cross25de6c32019-06-06 14:29:25 -07001024func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
1025 if m.config.captureBuild {
1026 m.buildParams = append(m.buildParams, params)
Colin Cross0875c522017-11-28 17:34:01 -08001027 }
1028
1029 bparams := convertBuildParams(params)
1030
1031 if bparams.Description != "" {
1032 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
1033 }
1034
Colin Cross25de6c32019-06-06 14:29:25 -07001035 if m.missingDeps != nil {
1036 m.ninjaError(bparams.Description, bparams.Outputs,
Colin Cross67a5c132017-05-09 13:45:28 -07001037 fmt.Errorf("module %s missing dependencies: %s\n",
Colin Cross25de6c32019-06-06 14:29:25 -07001038 m.ModuleName(), strings.Join(m.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -08001039 return
1040 }
1041
Colin Cross380c69a2019-06-10 17:49:58 +00001042 m.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001043}
1044
Colin Cross25de6c32019-06-06 14:29:25 -07001045func (m *moduleContext) GetMissingDependencies() []string {
1046 return m.missingDeps
Colin Cross6ff51382015-12-17 16:39:19 -08001047}
1048
Colin Cross25de6c32019-06-06 14:29:25 -07001049func (m *moduleContext) AddMissingDependencies(deps []string) {
Dan Willemsen6553f5e2016-03-10 18:14:25 -08001050 if deps != nil {
Colin Cross25de6c32019-06-06 14:29:25 -07001051 m.missingDeps = append(m.missingDeps, deps...)
1052 m.missingDeps = FirstUniqueStrings(m.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -08001053 }
1054}
1055
Colin Cross380c69a2019-06-10 17:49:58 +00001056func (m *moduleContext) validateAndroidModule(module blueprint.Module) Module {
Colin Crossd11fcda2017-10-23 17:59:01 -07001057 aModule, _ := module.(Module)
Colin Cross380c69a2019-06-10 17:49:58 +00001058 if aModule == nil {
1059 m.ModuleErrorf("module %q not an android module", m.OtherModuleName(aModule))
1060 return nil
1061 }
1062
1063 if !aModule.Enabled() {
1064 if m.Config().AllowMissingDependencies() {
1065 m.AddMissingDependencies([]string{m.OtherModuleName(aModule)})
1066 } else {
1067 m.ModuleErrorf("depends on disabled module %q", m.OtherModuleName(aModule))
1068 }
1069 return nil
1070 }
1071
Colin Crossd11fcda2017-10-23 17:59:01 -07001072 return aModule
1073}
1074
Colin Cross380c69a2019-06-10 17:49:58 +00001075func (m *moduleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
Jiyong Parkf2976302019-04-17 21:47:37 +09001076 type dep struct {
1077 mod blueprint.Module
1078 tag blueprint.DependencyTag
1079 }
1080 var deps []dep
Colin Cross380c69a2019-06-10 17:49:58 +00001081 m.VisitDirectDepsBlueprint(func(module blueprint.Module) {
Colin Cross25de6c32019-06-06 14:29:25 -07001082 if aModule, _ := module.(Module); aModule != nil && aModule.base().BaseModuleName() == name {
Colin Cross380c69a2019-06-10 17:49:58 +00001083 returnedTag := m.ModuleContext.OtherModuleDependencyTag(aModule)
Jiyong Parkf2976302019-04-17 21:47:37 +09001084 if tag == nil || returnedTag == tag {
1085 deps = append(deps, dep{aModule, returnedTag})
1086 }
1087 }
1088 })
1089 if len(deps) == 1 {
1090 return deps[0].mod, deps[0].tag
1091 } else if len(deps) >= 2 {
1092 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
Colin Cross380c69a2019-06-10 17:49:58 +00001093 name, m.ModuleName()))
Jiyong Parkf2976302019-04-17 21:47:37 +09001094 } else {
1095 return nil, nil
1096 }
1097}
1098
Colin Cross380c69a2019-06-10 17:49:58 +00001099func (m *moduleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
Colin Cross0ef08162019-05-01 15:50:51 -07001100 var deps []Module
Colin Cross380c69a2019-06-10 17:49:58 +00001101 m.VisitDirectDepsBlueprint(func(module blueprint.Module) {
Colin Cross25de6c32019-06-06 14:29:25 -07001102 if aModule, _ := module.(Module); aModule != nil {
Colin Cross380c69a2019-06-10 17:49:58 +00001103 if m.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
Colin Cross0ef08162019-05-01 15:50:51 -07001104 deps = append(deps, aModule)
1105 }
1106 }
1107 })
1108 return deps
1109}
1110
Colin Cross25de6c32019-06-06 14:29:25 -07001111func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
1112 module, _ := m.getDirectDepInternal(name, tag)
1113 return module
Jiyong Parkf2976302019-04-17 21:47:37 +09001114}
1115
Colin Cross380c69a2019-06-10 17:49:58 +00001116func (m *moduleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
1117 return m.getDirectDepInternal(name, nil)
Jiyong Parkf2976302019-04-17 21:47:37 +09001118}
1119
Colin Cross380c69a2019-06-10 17:49:58 +00001120func (m *moduleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
1121 m.ModuleContext.VisitDirectDeps(visit)
Colin Cross35143d02017-11-16 00:11:20 -08001122}
1123
Colin Cross380c69a2019-06-10 17:49:58 +00001124func (m *moduleContext) VisitDirectDeps(visit func(Module)) {
1125 m.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
1126 if aModule := m.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001127 visit(aModule)
1128 }
1129 })
1130}
1131
Colin Cross380c69a2019-06-10 17:49:58 +00001132func (m *moduleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
1133 m.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
1134 if aModule := m.validateAndroidModule(module); aModule != nil {
1135 if m.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
Colin Crossee6143c2017-12-30 17:54:27 -08001136 visit(aModule)
1137 }
1138 }
1139 })
1140}
1141
Colin Cross380c69a2019-06-10 17:49:58 +00001142func (m *moduleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
1143 m.ModuleContext.VisitDirectDepsIf(
Colin Crossd11fcda2017-10-23 17:59:01 -07001144 // pred
1145 func(module blueprint.Module) bool {
Colin Cross380c69a2019-06-10 17:49:58 +00001146 if aModule := m.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001147 return pred(aModule)
1148 } else {
1149 return false
1150 }
1151 },
1152 // visit
1153 func(module blueprint.Module) {
1154 visit(module.(Module))
1155 })
1156}
1157
Colin Cross380c69a2019-06-10 17:49:58 +00001158func (m *moduleContext) VisitDepsDepthFirst(visit func(Module)) {
1159 m.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
1160 if aModule := m.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001161 visit(aModule)
1162 }
1163 })
1164}
1165
Colin Cross380c69a2019-06-10 17:49:58 +00001166func (m *moduleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
1167 m.ModuleContext.VisitDepsDepthFirstIf(
Colin Crossd11fcda2017-10-23 17:59:01 -07001168 // pred
1169 func(module blueprint.Module) bool {
Colin Cross380c69a2019-06-10 17:49:58 +00001170 if aModule := m.validateAndroidModule(module); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001171 return pred(aModule)
1172 } else {
1173 return false
1174 }
1175 },
1176 // visit
1177 func(module blueprint.Module) {
1178 visit(module.(Module))
1179 })
1180}
1181
Colin Cross380c69a2019-06-10 17:49:58 +00001182func (m *moduleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
1183 m.ModuleContext.WalkDeps(visit)
Alex Light778127a2019-02-27 14:19:50 -08001184}
1185
Colin Cross380c69a2019-06-10 17:49:58 +00001186func (m *moduleContext) WalkDeps(visit func(Module, Module) bool) {
1187 m.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
1188 childAndroidModule := m.validateAndroidModule(child)
1189 parentAndroidModule := m.validateAndroidModule(parent)
Colin Crossd11fcda2017-10-23 17:59:01 -07001190 if childAndroidModule != nil && parentAndroidModule != nil {
1191 return visit(childAndroidModule, parentAndroidModule)
1192 } else {
1193 return false
1194 }
1195 })
1196}
1197
Colin Cross25de6c32019-06-06 14:29:25 -07001198func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
Colin Cross380c69a2019-06-10 17:49:58 +00001199 m.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross0875c522017-11-28 17:34:01 -08001200 visit(module.(Module))
1201 })
1202}
1203
Colin Cross25de6c32019-06-06 14:29:25 -07001204func (m *moduleContext) PrimaryModule() Module {
Colin Cross380c69a2019-06-10 17:49:58 +00001205 return m.ModuleContext.PrimaryModule().(Module)
Colin Cross0875c522017-11-28 17:34:01 -08001206}
1207
Colin Cross25de6c32019-06-06 14:29:25 -07001208func (m *moduleContext) FinalModule() Module {
Colin Cross380c69a2019-06-10 17:49:58 +00001209 return m.ModuleContext.FinalModule().(Module)
Colin Cross0875c522017-11-28 17:34:01 -08001210}
1211
Colin Cross0ea8ba82019-06-06 14:33:29 -07001212func (b *baseModuleContext) Target() Target {
Colin Cross25de6c32019-06-06 14:29:25 -07001213 return b.target
Colin Crossa1ad8d12016-06-01 17:09:44 -07001214}
1215
Colin Cross0ea8ba82019-06-06 14:33:29 -07001216func (b *baseModuleContext) TargetPrimary() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001217 return b.targetPrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001218}
1219
Colin Cross0ea8ba82019-06-06 14:33:29 -07001220func (b *baseModuleContext) MultiTargets() []Target {
Colin Cross25de6c32019-06-06 14:29:25 -07001221 return b.multiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001222}
1223
Colin Cross0ea8ba82019-06-06 14:33:29 -07001224func (b *baseModuleContext) Arch() Arch {
Colin Cross25de6c32019-06-06 14:29:25 -07001225 return b.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -08001226}
1227
Colin Cross0ea8ba82019-06-06 14:33:29 -07001228func (b *baseModuleContext) Os() OsType {
Colin Cross25de6c32019-06-06 14:29:25 -07001229 return b.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001230}
1231
Colin Cross0ea8ba82019-06-06 14:33:29 -07001232func (b *baseModuleContext) Host() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001233 return b.target.Os.Class == Host || b.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -07001234}
1235
Colin Cross0ea8ba82019-06-06 14:33:29 -07001236func (b *baseModuleContext) Device() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001237 return b.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -07001238}
1239
Colin Cross0ea8ba82019-06-06 14:33:29 -07001240func (b *baseModuleContext) Darwin() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001241 return b.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -07001242}
1243
Colin Cross0ea8ba82019-06-06 14:33:29 -07001244func (b *baseModuleContext) Fuchsia() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001245 return b.target.Os == Fuchsia
Doug Horn21b94272019-01-16 12:06:11 -08001246}
1247
Colin Cross0ea8ba82019-06-06 14:33:29 -07001248func (b *baseModuleContext) Windows() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001249 return b.target.Os == Windows
Colin Cross3edeee12017-04-04 12:59:48 -07001250}
1251
Colin Cross0ea8ba82019-06-06 14:33:29 -07001252func (b *baseModuleContext) Debug() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001253 return b.debug
Colin Crossf6566ed2015-03-24 11:13:38 -07001254}
1255
Colin Cross0ea8ba82019-06-06 14:33:29 -07001256func (b *baseModuleContext) PrimaryArch() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001257 if len(b.config.Targets[b.target.Os]) <= 1 {
Colin Cross67a5c132017-05-09 13:45:28 -07001258 return true
1259 }
Colin Cross25de6c32019-06-06 14:29:25 -07001260 return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType
Colin Cross1e7d3702016-08-24 15:25:47 -07001261}
1262
Colin Cross0ea8ba82019-06-06 14:33:29 -07001263func (b *baseModuleContext) AConfig() Config {
Colin Cross25de6c32019-06-06 14:29:25 -07001264 return b.config
Colin Cross1332b002015-04-07 17:11:30 -07001265}
1266
Colin Cross0ea8ba82019-06-06 14:33:29 -07001267func (b *baseModuleContext) DeviceConfig() DeviceConfig {
Colin Cross25de6c32019-06-06 14:29:25 -07001268 return DeviceConfig{b.config.deviceConfig}
Colin Cross9272ade2016-08-17 15:24:12 -07001269}
1270
Colin Cross0ea8ba82019-06-06 14:33:29 -07001271func (b *baseModuleContext) Platform() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001272 return b.kind == platformModule
Jiyong Park2db76922017-11-08 16:03:48 +09001273}
1274
Colin Cross0ea8ba82019-06-06 14:33:29 -07001275func (b *baseModuleContext) DeviceSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001276 return b.kind == deviceSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001277}
1278
Colin Cross0ea8ba82019-06-06 14:33:29 -07001279func (b *baseModuleContext) SocSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001280 return b.kind == socSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001281}
1282
Colin Cross0ea8ba82019-06-06 14:33:29 -07001283func (b *baseModuleContext) ProductSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001284 return b.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -08001285}
1286
Colin Cross0ea8ba82019-06-06 14:33:29 -07001287func (b *baseModuleContext) ProductServicesSpecific() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001288 return b.kind == productServicesSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +01001289}
1290
Jiyong Park5baac542018-08-28 09:55:37 +09001291// Makes this module a platform module, i.e. not specific to soc, device,
1292// product, or product_services.
Colin Cross4157e882019-06-06 16:57:04 -07001293func (m *ModuleBase) MakeAsPlatform() {
1294 m.commonProperties.Vendor = boolPtr(false)
1295 m.commonProperties.Proprietary = boolPtr(false)
1296 m.commonProperties.Soc_specific = boolPtr(false)
1297 m.commonProperties.Product_specific = boolPtr(false)
1298 m.commonProperties.Product_services_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09001299}
1300
Colin Cross4157e882019-06-06 16:57:04 -07001301func (m *ModuleBase) EnableNativeBridgeSupportByDefault() {
1302 m.commonProperties.Native_bridge_supported = boolPtr(true)
dimitry03dc3f62019-05-09 14:07:34 +02001303}
1304
Colin Cross25de6c32019-06-06 14:29:25 -07001305func (m *moduleContext) InstallInData() bool {
1306 return m.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001307}
1308
Colin Cross25de6c32019-06-06 14:29:25 -07001309func (m *moduleContext) InstallInSanitizerDir() bool {
1310 return m.module.InstallInSanitizerDir()
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001311}
1312
Colin Cross25de6c32019-06-06 14:29:25 -07001313func (m *moduleContext) InstallInRecovery() bool {
1314 return m.module.InstallInRecovery()
Jiyong Parkf9332f12018-02-01 00:54:12 +09001315}
1316
Colin Cross25de6c32019-06-06 14:29:25 -07001317func (m *moduleContext) skipInstall(fullInstallPath OutputPath) bool {
1318 if m.module.base().commonProperties.SkipInstall {
Colin Cross893d8162017-04-26 17:34:03 -07001319 return true
1320 }
1321
Colin Cross3607f212018-05-07 15:28:05 -07001322 // We'll need a solution for choosing which of modules with the same name in different
1323 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1324 // list of namespaces to install in a Soong-only build.
Colin Cross25de6c32019-06-06 14:29:25 -07001325 if !m.module.base().commonProperties.NamespaceExportedToMake {
Colin Cross3607f212018-05-07 15:28:05 -07001326 return true
1327 }
1328
Colin Cross25de6c32019-06-06 14:29:25 -07001329 if m.Device() {
1330 if m.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001331 return true
1332 }
1333
Colin Cross25de6c32019-06-06 14:29:25 -07001334 if m.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001335 return true
1336 }
1337 }
1338
1339 return false
1340}
1341
Colin Cross25de6c32019-06-06 14:29:25 -07001342func (m *moduleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001343 deps ...Path) OutputPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001344 return m.installFile(installPath, name, srcPath, Cp, deps)
Colin Cross5c517922017-08-31 12:29:17 -07001345}
1346
Colin Cross25de6c32019-06-06 14:29:25 -07001347func (m *moduleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
Colin Cross5c517922017-08-31 12:29:17 -07001348 deps ...Path) OutputPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001349 return m.installFile(installPath, name, srcPath, CpExecutable, deps)
Colin Cross5c517922017-08-31 12:29:17 -07001350}
1351
Colin Cross25de6c32019-06-06 14:29:25 -07001352func (m *moduleContext) installFile(installPath OutputPath, name string, srcPath Path,
Colin Cross5c517922017-08-31 12:29:17 -07001353 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001354
Colin Cross25de6c32019-06-06 14:29:25 -07001355 fullInstallPath := installPath.Join(m, name)
1356 m.module.base().hooks.runInstallHooks(m, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001357
Colin Cross25de6c32019-06-06 14:29:25 -07001358 if !m.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001359
Colin Cross25de6c32019-06-06 14:29:25 -07001360 deps = append(deps, m.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001361
Colin Cross89562dc2016-10-03 17:47:19 -07001362 var implicitDeps, orderOnlyDeps Paths
1363
Colin Cross25de6c32019-06-06 14:29:25 -07001364 if m.Host() {
Colin Cross89562dc2016-10-03 17:47:19 -07001365 // Installed host modules might be used during the build, depend directly on their
1366 // dependencies so their timestamp is updated whenever their dependency is updated
1367 implicitDeps = deps
1368 } else {
1369 orderOnlyDeps = deps
1370 }
1371
Colin Cross25de6c32019-06-06 14:29:25 -07001372 m.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001373 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001374 Description: "install " + fullInstallPath.Base(),
1375 Output: fullInstallPath,
1376 Input: srcPath,
1377 Implicits: implicitDeps,
1378 OrderOnly: orderOnlyDeps,
Colin Cross25de6c32019-06-06 14:29:25 -07001379 Default: !m.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001380 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001381
Colin Cross25de6c32019-06-06 14:29:25 -07001382 m.installFiles = append(m.installFiles, fullInstallPath)
Dan Willemsen322acaf2016-01-12 23:07:05 -08001383 }
Colin Cross25de6c32019-06-06 14:29:25 -07001384 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001385 return fullInstallPath
1386}
1387
Colin Cross25de6c32019-06-06 14:29:25 -07001388func (m *moduleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1389 fullInstallPath := installPath.Join(m, name)
1390 m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001391
Colin Cross25de6c32019-06-06 14:29:25 -07001392 if !m.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001393
Alex Lightfb4353d2019-01-17 13:57:45 -08001394 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
1395 if err != nil {
1396 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
1397 }
Colin Cross25de6c32019-06-06 14:29:25 -07001398 m.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001399 Rule: Symlink,
1400 Description: "install symlink " + fullInstallPath.Base(),
1401 Output: fullInstallPath,
1402 OrderOnly: Paths{srcPath},
Colin Cross25de6c32019-06-06 14:29:25 -07001403 Default: !m.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001404 Args: map[string]string{
Alex Lightfb4353d2019-01-17 13:57:45 -08001405 "fromPath": relPath,
Colin Cross12fc4972016-01-11 12:49:11 -08001406 },
1407 })
Colin Cross3854a602016-01-11 12:49:11 -08001408
Colin Cross25de6c32019-06-06 14:29:25 -07001409 m.installFiles = append(m.installFiles, fullInstallPath)
1410 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross12fc4972016-01-11 12:49:11 -08001411 }
Colin Cross3854a602016-01-11 12:49:11 -08001412 return fullInstallPath
1413}
1414
Jiyong Parkf1194352019-02-25 11:05:47 +09001415// installPath/name -> absPath where absPath might be a path that is available only at runtime
1416// (e.g. /apex/...)
Colin Cross25de6c32019-06-06 14:29:25 -07001417func (m *moduleContext) InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath {
1418 fullInstallPath := installPath.Join(m, name)
1419 m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
Jiyong Parkf1194352019-02-25 11:05:47 +09001420
Colin Cross25de6c32019-06-06 14:29:25 -07001421 if !m.skipInstall(fullInstallPath) {
1422 m.Build(pctx, BuildParams{
Jiyong Parkf1194352019-02-25 11:05:47 +09001423 Rule: Symlink,
1424 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
1425 Output: fullInstallPath,
Colin Cross25de6c32019-06-06 14:29:25 -07001426 Default: !m.Config().EmbeddedInMake(),
Jiyong Parkf1194352019-02-25 11:05:47 +09001427 Args: map[string]string{
1428 "fromPath": absPath,
1429 },
1430 })
1431
Colin Cross25de6c32019-06-06 14:29:25 -07001432 m.installFiles = append(m.installFiles, fullInstallPath)
Jiyong Parkf1194352019-02-25 11:05:47 +09001433 }
1434 return fullInstallPath
1435}
1436
Colin Cross25de6c32019-06-06 14:29:25 -07001437func (m *moduleContext) CheckbuildFile(srcPath Path) {
1438 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross3f40fa42015-01-30 17:27:36 -08001439}
1440
Colin Cross3f40fa42015-01-30 17:27:36 -08001441type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001442 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001443}
1444
1445func isFileInstaller(m blueprint.Module) bool {
1446 _, ok := m.(fileInstaller)
1447 return ok
1448}
1449
1450func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001451 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001452 return ok
1453}
Colin Crossfce53272015-04-08 11:21:40 -07001454
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001455func findStringInSlice(str string, slice []string) int {
1456 for i, s := range slice {
1457 if s == str {
1458 return i
Colin Crossfce53272015-04-08 11:21:40 -07001459 }
1460 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001461 return -1
1462}
1463
Colin Cross41955e82019-05-29 14:40:35 -07001464// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
1465// was not a module reference.
1466func SrcIsModule(s string) (module string) {
Colin Cross068e0fe2016-12-13 15:23:47 -08001467 if len(s) > 1 && s[0] == ':' {
1468 return s[1:]
1469 }
1470 return ""
1471}
1472
Colin Cross41955e82019-05-29 14:40:35 -07001473// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
1474// module name and an empty string for the tag, or empty strings if the input was not a module reference.
1475func SrcIsModuleWithTag(s string) (module, tag string) {
1476 if len(s) > 1 && s[0] == ':' {
1477 module = s[1:]
1478 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
1479 if module[len(module)-1] == '}' {
1480 tag = module[tagStart+1 : len(module)-1]
1481 module = module[:tagStart]
1482 return module, tag
1483 }
1484 }
1485 return module, ""
1486 }
1487 return "", ""
Colin Cross068e0fe2016-12-13 15:23:47 -08001488}
1489
Colin Cross41955e82019-05-29 14:40:35 -07001490type sourceOrOutputDependencyTag struct {
1491 blueprint.BaseDependencyTag
1492 tag string
1493}
1494
1495func sourceOrOutputDepTag(tag string) blueprint.DependencyTag {
1496 return sourceOrOutputDependencyTag{tag: tag}
1497}
1498
1499var SourceDepTag = sourceOrOutputDepTag("")
Colin Cross068e0fe2016-12-13 15:23:47 -08001500
Colin Cross366938f2017-12-11 16:29:02 -08001501// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1502// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08001503//
1504// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08001505func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07001506 set := make(map[string]bool)
1507
Colin Cross068e0fe2016-12-13 15:23:47 -08001508 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07001509 if m, t := SrcIsModuleWithTag(s); m != "" {
1510 if _, found := set[s]; found {
1511 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07001512 } else {
Colin Cross41955e82019-05-29 14:40:35 -07001513 set[s] = true
1514 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07001515 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001516 }
1517 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001518}
1519
Colin Cross366938f2017-12-11 16:29:02 -08001520// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1521// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08001522//
1523// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08001524func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1525 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07001526 if m, t := SrcIsModuleWithTag(*s); m != "" {
1527 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
Colin Cross366938f2017-12-11 16:29:02 -08001528 }
1529 }
1530}
1531
Colin Cross41955e82019-05-29 14:40:35 -07001532// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
1533// 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 -08001534type SourceFileProducer interface {
1535 Srcs() Paths
1536}
1537
Colin Cross41955e82019-05-29 14:40:35 -07001538// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
1539// using the ":module" syntax or ":module{.tag}" syntax and provides a list of otuput files to be used as if they were
1540// listed in the property.
1541type OutputFileProducer interface {
1542 OutputFiles(tag string) (Paths, error)
1543}
1544
Colin Crossfe17f6f2019-03-28 19:30:56 -07001545type HostToolProvider interface {
1546 HostToolPath() OptionalPath
1547}
1548
Colin Cross27b922f2019-03-04 22:35:41 -08001549// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
1550// be tagged with `android:"path" to support automatic source module dependency resolution.
Colin Cross8a497952019-03-05 22:25:09 -08001551//
1552// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
Colin Cross25de6c32019-06-06 14:29:25 -07001553func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
1554 return PathsForModuleSrcExcludes(m, srcFiles, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001555}
1556
Colin Cross2fafa3e2019-03-05 12:39:51 -08001557// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
1558// be tagged with `android:"path" to support automatic source module dependency resolution.
Colin Cross8a497952019-03-05 22:25:09 -08001559//
1560// Deprecated: use PathForModuleSrc instead.
Colin Cross25de6c32019-06-06 14:29:25 -07001561func (m *moduleContext) ExpandSource(srcFile, prop string) Path {
1562 return PathForModuleSrc(m, srcFile)
Colin Cross2fafa3e2019-03-05 12:39:51 -08001563}
1564
1565// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1566// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module
1567// dependency resolution.
Colin Cross25de6c32019-06-06 14:29:25 -07001568func (m *moduleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
Colin Cross2fafa3e2019-03-05 12:39:51 -08001569 if srcFile != nil {
Colin Cross25de6c32019-06-06 14:29:25 -07001570 return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
Colin Cross2fafa3e2019-03-05 12:39:51 -08001571 }
1572 return OptionalPath{}
1573}
1574
Colin Cross25de6c32019-06-06 14:29:25 -07001575func (m *moduleContext) RequiredModuleNames() []string {
1576 return m.module.base().commonProperties.Required
Nan Zhang6d34b302017-02-04 17:47:46 -08001577}
1578
Colin Cross25de6c32019-06-06 14:29:25 -07001579func (m *moduleContext) HostRequiredModuleNames() []string {
1580 return m.module.base().commonProperties.Host_required
Sasha Smundakb6d23052019-04-01 18:37:36 -07001581}
1582
Colin Cross25de6c32019-06-06 14:29:25 -07001583func (m *moduleContext) TargetRequiredModuleNames() []string {
1584 return m.module.base().commonProperties.Target_required
Sasha Smundakb6d23052019-04-01 18:37:36 -07001585}
1586
Colin Cross380c69a2019-06-10 17:49:58 +00001587func (m *moduleContext) Glob(globPattern string, excludes []string) Paths {
1588 ret, err := m.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001589 if err != nil {
Colin Cross380c69a2019-06-10 17:49:58 +00001590 m.ModuleErrorf("glob: %s", err.Error())
Colin Cross8f101b42015-06-17 15:09:06 -07001591 }
Colin Cross380c69a2019-06-10 17:49:58 +00001592 return pathsForModuleSrcFromFullPath(m, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001593}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001594
Colin Cross380c69a2019-06-10 17:49:58 +00001595func (m *moduleContext) GlobFiles(globPattern string, excludes []string) Paths {
1596 ret, err := m.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001597 if err != nil {
Colin Cross380c69a2019-06-10 17:49:58 +00001598 m.ModuleErrorf("glob: %s", err.Error())
Nan Zhang581fd212018-01-10 16:06:12 -08001599 }
Colin Cross380c69a2019-06-10 17:49:58 +00001600 return pathsForModuleSrcFromFullPath(m, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001601}
1602
Colin Cross463a90e2015-06-17 14:20:06 -07001603func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001604 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001605}
1606
Colin Cross0875c522017-11-28 17:34:01 -08001607func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001608 return &buildTargetSingleton{}
1609}
1610
Colin Cross87d8b562017-04-25 10:01:55 -07001611func parentDir(dir string) string {
1612 dir, _ = filepath.Split(dir)
1613 return filepath.Clean(dir)
1614}
1615
Colin Cross1f8c52b2015-06-16 16:38:17 -07001616type buildTargetSingleton struct{}
1617
Colin Cross0875c522017-11-28 17:34:01 -08001618func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1619 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001620
Colin Cross0875c522017-11-28 17:34:01 -08001621 mmTarget := func(dir string) WritablePath {
1622 return PathForPhony(ctx,
1623 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001624 }
1625
Colin Cross0875c522017-11-28 17:34:01 -08001626 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001627
Colin Cross0875c522017-11-28 17:34:01 -08001628 ctx.VisitAllModules(func(module Module) {
1629 blueprintDir := module.base().blueprintDir
1630 installTarget := module.base().installTarget
1631 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001632
Colin Cross0875c522017-11-28 17:34:01 -08001633 if checkbuildTarget != nil {
1634 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1635 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1636 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001637
Colin Cross0875c522017-11-28 17:34:01 -08001638 if installTarget != nil {
1639 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001640 }
1641 })
1642
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001643 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001644 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001645 suffix = "-soong"
1646 }
1647
Colin Cross1f8c52b2015-06-16 16:38:17 -07001648 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001649 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001650 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001651 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001652 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001653 })
1654
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001655 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001656 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001657 return
1658 }
1659
Colin Cross87d8b562017-04-25 10:01:55 -07001660 // Ensure ancestor directories are in modulesInDir
Inseob Kim1a365c62019-06-08 15:47:51 +09001661 dirs := SortedStringKeys(modulesInDir)
Colin Cross87d8b562017-04-25 10:01:55 -07001662 for _, dir := range dirs {
1663 dir := parentDir(dir)
1664 for dir != "." && dir != "/" {
1665 if _, exists := modulesInDir[dir]; exists {
1666 break
1667 }
1668 modulesInDir[dir] = nil
1669 dir = parentDir(dir)
1670 }
1671 }
1672
1673 // Make directories build their direct subdirectories
Colin Cross87d8b562017-04-25 10:01:55 -07001674 for _, dir := range dirs {
1675 p := parentDir(dir)
1676 if p != "." && p != "/" {
1677 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1678 }
1679 }
1680
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001681 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1682 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1683 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001684 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001685 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001686 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001687 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001688 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001689 // HACK: checkbuild should be an optional build, but force it
1690 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001691 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001692 })
1693 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001694
1695 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1696 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001697 ctx.VisitAllModules(func(module Module) {
1698 if module.Enabled() {
1699 os := module.Target().Os
1700 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001701 }
1702 })
1703
Colin Cross0875c522017-11-28 17:34:01 -08001704 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001705 for os, deps := range osDeps {
1706 var className string
1707
1708 switch os.Class {
1709 case Host:
1710 className = "host"
1711 case HostCross:
1712 className = "host-cross"
1713 case Device:
1714 className = "target"
1715 default:
1716 continue
1717 }
1718
Colin Cross0875c522017-11-28 17:34:01 -08001719 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001720 osClass[className] = append(osClass[className], name)
1721
Colin Cross0875c522017-11-28 17:34:01 -08001722 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001723 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001724 Output: name,
1725 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001726 })
1727 }
1728
1729 // Wrap those into host|host-cross|target phony rules
Inseob Kim1a365c62019-06-08 15:47:51 +09001730 for _, class := range SortedStringKeys(osClass) {
Colin Cross0875c522017-11-28 17:34:01 -08001731 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001732 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001733 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001734 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001735 })
1736 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001737}
Colin Crossd779da42015-12-17 18:00:23 -08001738
Brandon Lee5d45c6f2018-08-15 15:35:38 -07001739// Collect information for opening IDE project files in java/jdeps.go.
1740type IDEInfo interface {
1741 IDEInfo(ideInfo *IdeInfo)
1742 BaseModuleName() string
1743}
1744
1745// Extract the base module name from the Import name.
1746// Often the Import name has a prefix "prebuilt_".
1747// Remove the prefix explicitly if needed
1748// until we find a better solution to get the Import name.
1749type IDECustomizedModuleName interface {
1750 IDECustomizedModuleName() string
1751}
1752
1753type IdeInfo struct {
1754 Deps []string `json:"dependencies,omitempty"`
1755 Srcs []string `json:"srcs,omitempty"`
1756 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
1757 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
1758 Jars []string `json:"jars,omitempty"`
1759 Classes []string `json:"class,omitempty"`
1760 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08001761 SrcJars []string `json:"srcjars,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07001762}