blob: 1d9ba963a1a470716024746128261a6dee296335 [file] [log] [blame]
Jaewoong Jung26342642021-03-17 15:56:23 -07001// Copyright 2021 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
15package java
16
17import (
Yu Liu26a716d2024-08-30 23:40:32 +000018 "encoding/gob"
Jaewoong Jung26342642021-03-17 15:56:23 -070019 "fmt"
20 "path/filepath"
Joe Onorato349ae8d2024-02-05 22:46:00 +000021 "reflect"
22 "slices"
Jaewoong Jung26342642021-03-17 15:56:23 -070023 "strconv"
24 "strings"
25
Colin Crossd788b3e2023-11-28 13:14:56 -080026 "github.com/google/blueprint"
Jaewoong Jung26342642021-03-17 15:56:23 -070027 "github.com/google/blueprint/pathtools"
28 "github.com/google/blueprint/proptools"
29
30 "android/soong/android"
31 "android/soong/dexpreopt"
32 "android/soong/java/config"
33)
34
35// This file contains the definition and the implementation of the base module that most
36// source-based Java module structs embed.
37
38// TODO:
39// Autogenerated files:
40// Renderscript
41// Post-jar passes:
42// Proguard
43// Rmtypedefs
44// DroidDoc
45// Findbugs
46
47// Properties that are common to most Java modules, i.e. whether it's a host or device module.
48type CommonProperties struct {
49 // list of source files used to compile the Java module. May be .java, .kt, .logtags, .proto,
50 // or .aidl files.
51 Srcs []string `android:"path,arch_variant"`
52
53 // list Kotlin of source files containing Kotlin code that should be treated as common code in
54 // a codebase that supports Kotlin multiplatform. See
55 // https://kotlinlang.org/docs/reference/multiplatform.html. May be only be .kt files.
56 Common_srcs []string `android:"path,arch_variant"`
57
58 // list of source files that should not be used to build the Java module.
59 // This is most useful in the arch/multilib variants to remove non-common files
60 Exclude_srcs []string `android:"path,arch_variant"`
61
62 // list of directories containing Java resources
63 Java_resource_dirs []string `android:"arch_variant"`
64
65 // list of directories that should be excluded from java_resource_dirs
66 Exclude_java_resource_dirs []string `android:"arch_variant"`
67
68 // list of files to use as Java resources
69 Java_resources []string `android:"path,arch_variant"`
70
71 // list of files that should be excluded from java_resources and java_resource_dirs
72 Exclude_java_resources []string `android:"path,arch_variant"`
73
74 // list of module-specific flags that will be used for javac compiles
75 Javacflags []string `android:"arch_variant"`
76
77 // list of module-specific flags that will be used for kotlinc compiles
78 Kotlincflags []string `android:"arch_variant"`
79
80 // list of java libraries that will be in the classpath
81 Libs []string `android:"arch_variant"`
82
83 // list of java libraries that will be compiled into the resulting jar
84 Static_libs []string `android:"arch_variant"`
85
Jihoon Kang381c2fa2023-06-01 22:17:32 +000086 // list of java libraries that should not be used to build this module
87 Exclude_static_libs []string `android:"arch_variant"`
88
Jaewoong Jung26342642021-03-17 15:56:23 -070089 // manifest file to be included in resulting jar
90 Manifest *string `android:"path"`
91
92 // if not blank, run jarjar using the specified rules file
93 Jarjar_rules *string `android:"path,arch_variant"`
94
Joe Onoratoa5d17172024-07-20 17:39:56 -070095 // java class names to rename with jarjar when a reverse dependency has a jarjar_prefix
96 // property.
97 Jarjar_rename []string
98
Joe Onorato349ae8d2024-02-05 22:46:00 +000099 // if not blank, used as prefix to generate repackage rule
100 Jarjar_prefix *string
101
Jaewoong Jung26342642021-03-17 15:56:23 -0700102 // If not blank, set the java version passed to javac as -source and -target
103 Java_version *string
104
105 // If set to true, allow this module to be dexed and installed on devices. Has no
106 // effect on host modules, which are always considered installable.
107 Installable *bool
108
109 // If set to true, include sources used to compile the module in to the final jar
110 Include_srcs *bool
111
112 // If not empty, classes are restricted to the specified packages and their sub-packages.
113 // This restriction is checked after applying jarjar rules and including static libs.
114 Permitted_packages []string
115
116 // List of modules to use as annotation processors
117 Plugins []string
118
119 // List of modules to export to libraries that directly depend on this library as annotation
120 // processors. Note that if the plugins set generates_api: true this will disable the turbine
121 // optimization on modules that depend on this module, which will reduce parallelism and cause
122 // more recompilation.
123 Exported_plugins []string
124
125 // The number of Java source entries each Javac instance can process
126 Javac_shard_size *int64
127
128 // Add host jdk tools.jar to bootclasspath
129 Use_tools_jar *bool
130
131 Openjdk9 struct {
132 // List of source files that should only be used when passing -source 1.9 or higher
133 Srcs []string `android:"path"`
134
135 // List of javac flags that should only be used when passing -source 1.9 or higher
136 Javacflags []string
137 }
138
139 // When compiling language level 9+ .java code in packages that are part of
140 // a system module, patch_module names the module that your sources and
141 // dependencies should be patched into. The Android runtime currently
142 // doesn't implement the JEP 261 module system so this option is only
143 // supported at compile time. It should only be needed to compile tests in
144 // packages that exist in libcore and which are inconvenient to move
145 // elsewhere.
Liz Kammer0a470a32023-10-05 17:02:00 -0400146 Patch_module *string
Jaewoong Jung26342642021-03-17 15:56:23 -0700147
148 Jacoco struct {
149 // List of classes to include for instrumentation with jacoco to collect coverage
150 // information at runtime when building with coverage enabled. If unset defaults to all
151 // classes.
152 // Supports '*' as the last character of an entry in the list as a wildcard match.
153 // If preceded by '.' it matches all classes in the package and subpackages, otherwise
154 // it matches classes in the package that have the class name as a prefix.
155 Include_filter []string
156
157 // List of classes to exclude from instrumentation with jacoco to collect coverage
158 // information at runtime when building with coverage enabled. Overrides classes selected
159 // by the include_filter property.
160 // Supports '*' as the last character of an entry in the list as a wildcard match.
161 // If preceded by '.' it matches all classes in the package and subpackages, otherwise
162 // it matches classes in the package that have the class name as a prefix.
163 Exclude_filter []string
164 }
165
166 Errorprone struct {
167 // List of javac flags that should only be used when running errorprone.
168 Javacflags []string
169
170 // List of java_plugin modules that provide extra errorprone checks.
171 Extra_check_modules []string
Cole Faust75fffb12021-06-13 15:23:16 -0700172
Cole Faust2b1536e2021-06-18 12:25:54 -0700173 // This property can be in 3 states. When set to true, errorprone will
174 // be run during the regular build. When set to false, errorprone will
175 // never be run. When unset, errorprone will be run when the RUN_ERROR_PRONE
176 // environment variable is true. Setting this to false will improve build
177 // performance more than adding -XepDisableAllChecks in javacflags.
Cole Faust75fffb12021-06-13 15:23:16 -0700178 Enabled *bool
Jaewoong Jung26342642021-03-17 15:56:23 -0700179 }
180
181 Proto struct {
182 // List of extra options that will be passed to the proto generator.
183 Output_params []string
184 }
185
Sam Delmericoc7593722022-08-31 15:57:52 -0400186 // If true, then jacocoagent is automatically added as a libs dependency so that
187 // r8 will not strip instrumentation classes out of dexed libraries.
Jaewoong Jung26342642021-03-17 15:56:23 -0700188 Instrument bool `blueprint:"mutated"`
Paul Duffin0038a8d2022-05-03 00:28:40 +0000189 // If true, then the module supports statically including the jacocoagent
190 // into the library.
191 Supports_static_instrumentation bool `blueprint:"mutated"`
Jaewoong Jung26342642021-03-17 15:56:23 -0700192
193 // List of files to include in the META-INF/services folder of the resulting jar.
194 Services []string `android:"path,arch_variant"`
195
196 // If true, package the kotlin stdlib into the jar. Defaults to true.
197 Static_kotlin_stdlib *bool `android:"arch_variant"`
198
199 // A list of java_library instances that provide additional hiddenapi annotations for the library.
200 Hiddenapi_additional_annotations []string
Joe Onorato175073c2023-06-01 14:42:59 -0700201
202 // Additional srcJars tacked in by GeneratedJavaLibraryModule
203 Generated_srcjars []android.Path `android:"mutated"`
Mark Whitea15790a2023-08-22 21:28:11 +0000204
Jihoon Kang3921f0b2024-03-12 23:51:37 +0000205 // intermediate aconfig cache file tacked in by GeneratedJavaLibraryModule
206 Aconfig_Cache_files []android.Path `android:"mutated"`
207
Mark Whitea15790a2023-08-22 21:28:11 +0000208 // If true, then only the headers are built and not the implementation jar.
Liz Kammer60772632023-10-05 17:18:44 -0400209 Headers_only *bool
Cole Faust2b64af82023-12-13 18:22:18 -0800210
211 // A list of files or dependencies to make available to the build sandbox. This is
212 // useful if source files are symlinks, the targets of the symlinks must be listed here.
213 // Note that currently not all actions implemented by android_apps are sandboxed, so you
214 // may only see this being necessary in lint builds.
215 Compile_data []string `android:"path"`
Jihoon Kangfe914ed2024-02-12 22:49:21 +0000216
217 // Property signifying whether the module compiles stubs or not.
218 // Should be set to true when srcs of this module are stub files.
219 // This property does not need to be set to true when the module depends on
220 // the stubs via libs, but should be set to true when the module depends on
221 // the stubs via static libs.
222 Is_stubs_module *bool
Makoto Onuki7ded3822024-03-28 14:42:20 -0700223
224 // If true, enable the "Ravenizer" tool on the output jar.
225 // "Ravenizer" is a tool for Ravenwood tests, but it can also be enabled on other kinds
226 // of java targets.
227 Ravenizer struct {
228 Enabled *bool
229 }
Jihoon Kangfa3f0782024-08-21 20:42:18 +0000230
231 // Contributing api surface of the stub module. Is not visible to bp modules, and should
232 // only be set for stub submodules generated by the java_sdk_library
233 Stub_contributing_api *string `blueprint:"mutated"`
Yihan Dong8be09c22024-08-29 15:32:13 +0800234
235 // If true, enable the "ApiMapper" tool on the output jar. "ApiMapper" is a tool to inject
236 // bytecode to log API calls.
237 ApiMapper bool `blueprint:"mutated"`
Jaewoong Jung26342642021-03-17 15:56:23 -0700238}
239
240// Properties that are specific to device modules. Host module factories should not add these when
241// constructing a new module.
242type DeviceProperties struct {
Trevor Radcliffe347e5e42021-11-05 19:30:24 +0000243 // If not blank, set to the version of the sdk to compile against.
Spandan Das1ccf5742022-10-14 16:51:23 +0000244 // Defaults to an empty string, which compiles the module against the private platform APIs.
Trevor Radcliffe347e5e42021-11-05 19:30:24 +0000245 // Values are of one of the following forms:
Vinh Trana9c8f7d2022-04-14 20:18:47 +0000246 // 1) numerical API level, "current", "none", or "core_platform"
247 // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
248 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
249 // If the SDK kind is empty, it will be set to public.
Jaewoong Jung26342642021-03-17 15:56:23 -0700250 Sdk_version *string
251
satayev0a420e72021-11-29 17:25:52 +0000252 // if not blank, set the maximum version of the sdk that the compiled artifacts will run against.
253 // Defaults to empty string "". See sdk_version for possible values.
254 Max_sdk_version *string
255
William Loh5a082f92022-05-17 20:21:50 +0000256 // if not blank, set the maxSdkVersion properties of permission and uses-permission tags.
257 // Defaults to empty string "". See sdk_version for possible values.
258 Replace_max_sdk_version_placeholder *string
259
Jaewoong Jung26342642021-03-17 15:56:23 -0700260 // if not blank, set the targetSdkVersion in the AndroidManifest.xml.
Trevor Radcliffe347e5e42021-11-05 19:30:24 +0000261 // Defaults to sdk_version if not set. See sdk_version for possible values.
Jaewoong Jung26342642021-03-17 15:56:23 -0700262 Target_sdk_version *string
263
264 // Whether to compile against the platform APIs instead of an SDK.
265 // If true, then sdk_version must be empty. The value of this field
Vinh Trand91939e2022-04-18 19:27:17 +0000266 // is ignored when module's type isn't android_app, android_test, or android_test_helper_app.
Jaewoong Jung26342642021-03-17 15:56:23 -0700267 Platform_apis *bool
268
269 Aidl struct {
270 // Top level directories to pass to aidl tool
271 Include_dirs []string
272
273 // Directories rooted at the Android.bp file to pass to aidl tool
274 Local_include_dirs []string
275
276 // directories that should be added as include directories for any aidl sources of modules
277 // that depend on this module, as well as to aidl for this module.
278 Export_include_dirs []string
279
280 // whether to generate traces (for systrace) for this interface
281 Generate_traces *bool
282
283 // whether to generate Binder#GetTransaction name method.
284 Generate_get_transaction_name *bool
285
Thiébaud Weksteende8417c2022-02-10 15:41:46 +1100286 // whether all interfaces should be annotated with required permissions.
287 Enforce_permissions *bool
288
289 // allowlist for interfaces that (temporarily) do not require annotation for permissions.
290 Enforce_permissions_exceptions []string `android:"path"`
291
Jaewoong Jung26342642021-03-17 15:56:23 -0700292 // list of flags that will be passed to the AIDL compiler
293 Flags []string
294 }
295
296 // If true, export a copy of the module as a -hostdex module for host testing.
297 Hostdex *bool
298
299 Target struct {
300 Hostdex struct {
301 // Additional required dependencies to add to -hostdex modules.
302 Required []string
303 }
304 }
305
306 // When targeting 1.9 and above, override the modules to use with --system,
307 // otherwise provides defaults libraries to add to the bootclasspath.
308 System_modules *string
309
Jaewoong Jung26342642021-03-17 15:56:23 -0700310 IsSDKLibrary bool `blueprint:"mutated"`
311
312 // If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
313 // Defaults to false.
314 V4_signature *bool
315
316 // Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the
317 // public stubs library.
318 SyspropPublicStub string `blueprint:"mutated"`
Paul Duffin3f1ae0b2022-07-27 16:27:42 +0000319
320 HiddenAPIPackageProperties
321 HiddenAPIFlagFileProperties
Jaewoong Jung26342642021-03-17 15:56:23 -0700322}
323
yangbill2af0b6e2024-03-15 09:29:29 +0000324// Properties that can be overridden by overriding module (e.g. override_android_app)
325type OverridableProperties struct {
Jooyung Han01d80d82022-01-08 12:16:32 +0900326 // set the name of the output. If not set, `name` is used.
327 // To override a module with this property set, overriding module might need to set this as well.
328 // Otherwise, both the overridden and the overriding modules will have the same output name, which
329 // can cause the duplicate output error.
330 Stem *string
Spandan Dasb9c58352024-05-13 18:29:45 +0000331
332 // if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
333 // Defaults to sdk_version if not set. See sdk_version for possible values.
334 Min_sdk_version *string
Jooyung Han01d80d82022-01-08 12:16:32 +0900335}
336
Jaewoong Jung26342642021-03-17 15:56:23 -0700337// Functionality common to Module and Import
338//
339// It is embedded in Module so its functionality can be used by methods in Module
340// but it is currently only initialized by Import and Library.
341type embeddableInModuleAndImport struct {
342
343 // Functionality related to this being used as a component of a java_sdk_library.
344 EmbeddableSdkLibraryComponent
345}
346
Paul Duffin71b33cc2021-06-23 11:39:47 +0100347func (e *embeddableInModuleAndImport) initModuleAndImport(module android.Module) {
348 e.initSdkLibraryComponent(module)
Jaewoong Jung26342642021-03-17 15:56:23 -0700349}
350
351// Module/Import's DepIsInSameApex(...) delegates to this method.
352//
353// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with
354// the one provided by ApexModuleBase.
355func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
356 // dependencies other than the static linkage are all considered crossing APEX boundary
357 if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
358 return true
359 }
360 return false
361}
362
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +0100363// OptionalDexJarPath can be either unset, hold a valid path to a dex jar file,
364// or an invalid path describing the reason it is invalid.
365//
366// It is unset if a dex jar isn't applicable, i.e. no build rule has been
367// requested to create one.
368//
369// If a dex jar has been requested to be built then it is set, and it may be
370// either a valid android.Path, or invalid with a reason message. The latter
371// happens if the source that should produce the dex file isn't able to.
372//
373// E.g. it is invalid with a reason message if there is a prebuilt APEX that
374// could produce the dex jar through a deapexer module, but the APEX isn't
375// installable so doing so wouldn't be safe.
376type OptionalDexJarPath struct {
377 isSet bool
378 path android.OptionalPath
379}
380
381// IsSet returns true if a path has been set, either invalid or valid.
382func (o OptionalDexJarPath) IsSet() bool {
383 return o.isSet
384}
385
386// Valid returns true if there is a path that is valid.
387func (o OptionalDexJarPath) Valid() bool {
388 return o.isSet && o.path.Valid()
389}
390
391// Path returns the valid path, or panics if it's either not set or is invalid.
392func (o OptionalDexJarPath) Path() android.Path {
393 if !o.isSet {
394 panic("path isn't set")
395 }
396 return o.path.Path()
397}
398
399// PathOrNil returns the path if it's set and valid, or else nil.
400func (o OptionalDexJarPath) PathOrNil() android.Path {
401 if o.Valid() {
402 return o.Path()
403 }
404 return nil
405}
406
407// InvalidReason returns the reason for an invalid path, which is never "". It
408// returns "" for an unset or valid path.
409func (o OptionalDexJarPath) InvalidReason() string {
410 if !o.isSet {
411 return ""
412 }
413 return o.path.InvalidReason()
414}
415
416func (o OptionalDexJarPath) String() string {
417 if !o.isSet {
418 return "<unset>"
419 }
420 return o.path.String()
421}
422
423// makeUnsetDexJarPath returns an unset OptionalDexJarPath.
424func makeUnsetDexJarPath() OptionalDexJarPath {
425 return OptionalDexJarPath{isSet: false}
426}
427
428// makeDexJarPathFromOptionalPath returns an OptionalDexJarPath that is set with
429// the given OptionalPath, which may be valid or invalid.
430func makeDexJarPathFromOptionalPath(path android.OptionalPath) OptionalDexJarPath {
431 return OptionalDexJarPath{isSet: true, path: path}
432}
433
434// makeDexJarPathFromPath returns an OptionalDexJarPath that is set with the
435// valid given path. It returns an unset OptionalDexJarPath if the given path is
436// nil.
437func makeDexJarPathFromPath(path android.Path) OptionalDexJarPath {
438 if path == nil {
439 return makeUnsetDexJarPath()
440 }
441 return makeDexJarPathFromOptionalPath(android.OptionalPathForPath(path))
442}
443
Jaewoong Jung26342642021-03-17 15:56:23 -0700444// Module contains the properties and members used by all java module types
445type Module struct {
446 android.ModuleBase
447 android.DefaultableModuleBase
448 android.ApexModuleBase
Jaewoong Jung26342642021-03-17 15:56:23 -0700449
450 // Functionality common to Module and Import.
451 embeddableInModuleAndImport
452
453 properties CommonProperties
454 protoProperties android.ProtoProperties
455 deviceProperties DeviceProperties
456
yangbill2af0b6e2024-03-15 09:29:29 +0000457 overridableProperties OverridableProperties
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700458 sourceProperties android.SourceProperties
Jooyung Han01d80d82022-01-08 12:16:32 +0900459
Jaewoong Jung26342642021-03-17 15:56:23 -0700460 // jar file containing header classes including static library dependencies, suitable for
461 // inserting into the bootclasspath/classpath of another compile
462 headerJarFile android.Path
463
Joe Onorato349ae8d2024-02-05 22:46:00 +0000464 repackagedHeaderJarFile android.Path
465
Jaewoong Jung26342642021-03-17 15:56:23 -0700466 // jar file containing implementation classes including static library dependencies but no
467 // resources
468 implementationJarFile android.Path
469
470 // jar file containing only resources including from static library dependencies
471 resourceJar android.Path
472
473 // args and dependencies to package source files into a srcjar
474 srcJarArgs []string
475 srcJarDeps android.Paths
476
Anton Hansson0e73f9e2023-09-20 13:39:57 +0000477 // the source files of this module and all its static dependencies
478 transitiveSrcFiles *android.DepSet[android.Path]
479
Jaewoong Jung26342642021-03-17 15:56:23 -0700480 // jar file containing implementation classes and resources including static library
481 // dependencies
482 implementationAndResourcesJar android.Path
483
484 // output file containing classes.dex and resources
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +0100485 dexJarFile OptionalDexJarPath
Jaewoong Jung26342642021-03-17 15:56:23 -0700486
487 // output file containing uninstrumented classes that will be instrumented by jacoco
488 jacocoReportClassesFile android.Path
489
490 // output file of the module, which may be a classes jar or a dex jar
491 outputFile android.Path
492 extraOutputFiles android.Paths
493
Thiébaud Weksteende8417c2022-02-10 15:41:46 +1100494 exportAidlIncludeDirs android.Paths
495 ignoredAidlPermissionList android.Paths
Jaewoong Jung26342642021-03-17 15:56:23 -0700496
497 logtagsSrcs android.Paths
498
499 // installed file for binary dependency
500 installFile android.Path
501
Colin Cross3108ce12021-11-10 14:38:50 -0800502 // installed file for hostdex copy
503 hostdexInstallFile android.InstallPath
504
Chaohui Wangdcbe33c2022-10-11 11:13:30 +0800505 // list of unique .java and .kt source files
506 uniqueSrcFiles android.Paths
507
508 // list of srcjars that was passed to javac
509 compiledSrcJars android.Paths
Jaewoong Jung26342642021-03-17 15:56:23 -0700510
511 // manifest file to use instead of properties.Manifest
512 overrideManifest android.OptionalPath
513
Jaewoong Jung26342642021-03-17 15:56:23 -0700514 // list of plugins that this java module is exporting
515 exportedPluginJars android.Paths
516
517 // list of plugins that this java module is exporting
518 exportedPluginClasses []string
519
520 // if true, the exported plugins generate API and require disabling turbine.
521 exportedDisableTurbine bool
522
523 // list of source files, collected from srcFiles with unique java and all kt files,
524 // will be used by android.IDEInfo struct
525 expandIDEInfoCompiledSrcs []string
526
527 // expanded Jarjar_rules
528 expandJarjarRules android.Path
529
Joe Onorato349ae8d2024-02-05 22:46:00 +0000530 // jarjar rule for inherited jarjar rules
531 repackageJarjarRules android.Path
532
Jaewoong Jung26342642021-03-17 15:56:23 -0700533 // Extra files generated by the module type to be added as java resources.
534 extraResources android.Paths
535
536 hiddenAPI
537 dexer
538 dexpreopter
539 usesLibrary
540 linter
541
542 // list of the xref extraction files
543 kytheFiles android.Paths
544
Jaewoong Jung26342642021-03-17 15:56:23 -0700545 hideApexVariantFromMake bool
Jiyong Park92315372021-04-02 08:45:46 +0900546
547 sdkVersion android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000548 minSdkVersion android.ApiLevel
Spandan Dasa26eda72023-03-02 00:56:06 +0000549 maxSdkVersion android.ApiLevel
Romain Jobredeaux3ec36ad42021-10-29 13:08:48 -0400550
551 sourceExtensions []string
Vadim Spivak3c496f02023-06-08 06:14:59 +0000552
553 annoSrcJars android.Paths
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000554
555 // output file name based on Stem property.
556 // This should be set in every ModuleWithStem's GenerateAndroidBuildActions
557 // or the module should override Stem().
558 stem string
Joe Onorato6fe59eb2023-07-16 13:20:33 -0700559
Joe Onorato349ae8d2024-02-05 22:46:00 +0000560 // Values that will be set in the JarJarProvider data for jarjar repackaging,
561 // and merged with our dependencies' rules.
562 jarjarRenameRules map[string]string
Jihoon Kangfe914ed2024-02-12 22:49:21 +0000563
564 stubsLinkType StubsLinkType
Jihoon Kang3921f0b2024-03-12 23:51:37 +0000565
566 // Paths to the aconfig intermediate cache files that are provided by the
567 // java_aconfig_library or java_library modules that are statically linked
568 // to this module. Does not contain cache files from all transitive dependencies.
569 aconfigCacheFiles android.Paths
Spandan Das8aac9932024-07-18 23:14:13 +0000570
571 // List of soong module dependencies required to compile the current module.
572 // This information is printed out to `Dependencies` field in module_bp_java_deps.json
573 compileDepNames []string
Makoto Onuki7ded3822024-03-28 14:42:20 -0700574
575 ravenizer struct {
576 enabled bool
577 }
Jaewoong Jung26342642021-03-17 15:56:23 -0700578}
579
Jihoon Kangf86fe9a2024-06-26 22:18:10 +0000580var _ android.InstallableModule = (*Module)(nil)
581
582// To satisfy the InstallableModule interface
Jihoon Kang224ea082024-08-12 22:38:16 +0000583func (j *Module) StaticDependencyTags() []blueprint.DependencyTag {
584 return []blueprint.DependencyTag{staticLibTag}
585}
586
587// To satisfy the InstallableModule interface
588func (j *Module) DynamicDependencyTags() []blueprint.DependencyTag {
589 return []blueprint.DependencyTag{libTag, sdkLibTag, bootClasspathTag, systemModulesTag,
590 instrumentationForTag, java9LibTag}
Jihoon Kangf86fe9a2024-06-26 22:18:10 +0000591}
592
593// Overrides android.ModuleBase.InstallInProduct()
594func (j *Module) InstallInProduct() bool {
595 return j.ProductSpecific()
596}
597
Jihoon Kang85bc1932024-07-01 17:04:46 +0000598var _ android.StubsAvailableModule = (*Module)(nil)
599
600// To safisfy the StubsAvailableModule interface
601func (j *Module) IsStubsModule() bool {
602 return proptools.Bool(j.properties.Is_stubs_module)
603}
604
Jiyong Park92315372021-04-02 08:45:46 +0900605func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
606 sdkVersion := j.SdkVersion(ctx)
Jiyong Parkf1691d22021-03-29 20:11:58 +0900607 if sdkVersion.Stable() {
Jaewoong Jung26342642021-03-17 15:56:23 -0700608 return nil
609 }
Jiyong Parkf1691d22021-03-29 20:11:58 +0900610 if sdkVersion.Kind == android.SdkCorePlatform {
Paul Duffin1ea7c9f2021-03-15 09:39:13 +0000611 if useLegacyCorePlatformApi(ctx, j.BaseModuleName()) {
Jaewoong Jung26342642021-03-17 15:56:23 -0700612 return fmt.Errorf("non stable SDK %v - uses legacy core platform", sdkVersion)
613 } else {
614 // Treat stable core platform as stable.
615 return nil
616 }
617 } else {
618 return fmt.Errorf("non stable SDK %v", sdkVersion)
619 }
620}
621
622// checkSdkVersions enforces restrictions around SDK dependencies.
623func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
624 if j.RequiresStableAPIs(ctx) {
Jiyong Parkf1691d22021-03-29 20:11:58 +0900625 if sc, ok := ctx.Module().(android.SdkContext); ok {
Jiyong Park92315372021-04-02 08:45:46 +0900626 if !sc.SdkVersion(ctx).Specified() {
Jaewoong Jung26342642021-03-17 15:56:23 -0700627 ctx.PropertyErrorf("sdk_version",
628 "sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
629 }
630 }
631 }
632
633 // Make sure this module doesn't statically link to modules with lower-ranked SDK link type.
634 // See rank() for details.
635 ctx.VisitDirectDeps(func(module android.Module) {
636 tag := ctx.OtherModuleDependencyTag(module)
637 switch module.(type) {
638 // TODO(satayev): cover other types as well, e.g. imports
639 case *Library, *AndroidLibrary:
640 switch tag {
Liz Kammeref28a4c2022-09-23 16:50:56 -0400641 case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag:
Jaewoong Jung26342642021-03-17 15:56:23 -0700642 j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag))
643 }
644 }
645 })
646}
647
648func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
Jiyong Parkf1691d22021-03-29 20:11:58 +0900649 if sc, ok := ctx.Module().(android.SdkContext); ok {
Jaewoong Jung26342642021-03-17 15:56:23 -0700650 usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900651 sdkVersionSpecified := sc.SdkVersion(ctx).Specified()
Jaewoong Jung26342642021-03-17 15:56:23 -0700652 if usePlatformAPI && sdkVersionSpecified {
Spandan Das60999342021-11-16 04:15:33 +0000653 ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.")
Jaewoong Jung26342642021-03-17 15:56:23 -0700654 } else if !usePlatformAPI && !sdkVersionSpecified {
Spandan Das60999342021-11-16 04:15:33 +0000655 ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true")
Jaewoong Jung26342642021-03-17 15:56:23 -0700656 }
657
658 }
659}
660
Mark Whitea15790a2023-08-22 21:28:11 +0000661func (j *Module) checkHeadersOnly(ctx android.ModuleContext) {
662 if _, ok := ctx.Module().(android.SdkContext); ok {
Liz Kammer60772632023-10-05 17:18:44 -0400663 headersOnly := proptools.Bool(j.properties.Headers_only)
Mark Whitea15790a2023-08-22 21:28:11 +0000664 installable := proptools.Bool(j.properties.Installable)
665
666 if headersOnly && installable {
667 ctx.PropertyErrorf("headers_only", "This module has conflicting settings. headers_only is true which, which means this module doesn't generate an implementation jar. However installable is set to true.")
668 }
669 }
670}
671
Jaewoong Jung26342642021-03-17 15:56:23 -0700672func (j *Module) addHostProperties() {
673 j.AddProperties(
674 &j.properties,
yangbill2af0b6e2024-03-15 09:29:29 +0000675 &j.overridableProperties,
Jaewoong Jung26342642021-03-17 15:56:23 -0700676 &j.protoProperties,
677 &j.usesLibraryProperties,
678 )
679}
680
681func (j *Module) addHostAndDeviceProperties() {
682 j.addHostProperties()
683 j.AddProperties(
684 &j.deviceProperties,
685 &j.dexer.dexProperties,
686 &j.dexpreoptProperties,
687 &j.linter.properties,
688 )
689}
690
Paul Duffin3f1ae0b2022-07-27 16:27:42 +0000691// provideHiddenAPIPropertyInfo populates a HiddenAPIPropertyInfo from hidden API properties and
692// makes it available through the hiddenAPIPropertyInfoProvider.
693func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) {
694 hiddenAPIInfo := newHiddenAPIPropertyInfo()
695
696 // Populate with flag file paths from the properties.
697 hiddenAPIInfo.extractFlagFilesFromProperties(ctx, &j.deviceProperties.HiddenAPIFlagFileProperties)
698
699 // Populate with package rules from the properties.
700 hiddenAPIInfo.extractPackageRulesFromProperties(&j.deviceProperties.HiddenAPIPackageProperties)
701
Colin Cross40213022023-12-13 15:19:49 -0800702 android.SetProvider(ctx, hiddenAPIPropertyInfoProvider, hiddenAPIInfo)
Paul Duffin3f1ae0b2022-07-27 16:27:42 +0000703}
704
mrziwang9f7b9f42024-07-10 12:18:06 -0700705// helper method for java modules to set OutputFilesProvider
706func setOutputFiles(ctx android.ModuleContext, m Module) {
707 ctx.SetOutputFiles(append(android.Paths{m.outputFile}, m.extraOutputFiles...), "")
708 ctx.SetOutputFiles(android.Paths{m.outputFile}, android.DefaultDistTag)
709 ctx.SetOutputFiles(android.Paths{m.implementationAndResourcesJar}, ".jar")
710 ctx.SetOutputFiles(android.Paths{m.headerJarFile}, ".hjar")
711 if m.dexer.proguardDictionary.Valid() {
712 ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map")
713 }
714 ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars")
715 if m.linter.outputs.xml != nil {
716 ctx.SetOutputFiles(android.Paths{m.linter.outputs.xml}, ".lint")
Jaewoong Jung26342642021-03-17 15:56:23 -0700717 }
718}
719
Jaewoong Jung26342642021-03-17 15:56:23 -0700720func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
721 initJavaModule(module, hod, false)
722}
723
724func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
725 initJavaModule(module, hod, true)
726}
727
728func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
729 multilib := android.MultilibCommon
730 if multiTargets {
731 android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
732 } else {
733 android.InitAndroidArchModule(module, hod, multilib)
734 }
735 android.InitDefaultableModule(module)
736}
737
738func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
739 return j.properties.Instrument &&
740 ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
741 ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
742}
743
Yihan Dong8be09c22024-08-29 15:32:13 +0800744func (j *Module) shouldApiMapper() bool {
745 return j.properties.ApiMapper
746}
747
Jaewoong Jung26342642021-03-17 15:56:23 -0700748func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
Paul Duffin0038a8d2022-05-03 00:28:40 +0000749 return j.properties.Supports_static_instrumentation &&
750 j.shouldInstrument(ctx) &&
Jaewoong Jung26342642021-03-17 15:56:23 -0700751 (ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") ||
752 ctx.Config().UnbundledBuild())
753}
754
755func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
756 // Force enable the instrumentation for java code that is built for APEXes ...
757 // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
758 // doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
Colin Crossff694a82023-12-13 15:54:49 -0800759 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
Jaewoong Jung26342642021-03-17 15:56:23 -0700760 isJacocoAgent := ctx.ModuleName() == "jacocoagent"
Jihoon Kang690df2e2024-05-22 04:27:38 +0000761
Jihoon Kang46d66de2024-05-22 22:42:39 +0000762 if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() {
Jaewoong Jung26342642021-03-17 15:56:23 -0700763 if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
764 return true
765 } else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
766 return true
767 }
768 }
769 return false
770}
771
Sam Delmerico1e3f78f2022-09-07 12:07:07 -0400772func (j *Module) setInstrument(value bool) {
773 j.properties.Instrument = value
774}
775
Yihan Dong8be09c22024-08-29 15:32:13 +0800776func (j *Module) setApiMapper(value bool) {
777 j.properties.ApiMapper = value
778}
779
Jiyong Park92315372021-04-02 08:45:46 +0900780func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
781 return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
Jaewoong Jung26342642021-03-17 15:56:23 -0700782}
783
Jiyong Parkf1691d22021-03-29 20:11:58 +0900784func (j *Module) SystemModules() string {
Jaewoong Jung26342642021-03-17 15:56:23 -0700785 return proptools.String(j.deviceProperties.System_modules)
786}
787
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000788func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Spandan Dasb9c58352024-05-13 18:29:45 +0000789 if j.overridableProperties.Min_sdk_version != nil {
790 return android.ApiLevelFrom(ctx, *j.overridableProperties.Min_sdk_version)
Jaewoong Jung26342642021-03-17 15:56:23 -0700791 }
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000792 return j.SdkVersion(ctx).ApiLevel
Jaewoong Jung26342642021-03-17 15:56:23 -0700793}
794
Yu Liuf2b94012023-09-19 15:09:10 -0700795func (j *Module) GetDeviceProperties() *DeviceProperties {
796 return &j.deviceProperties
797}
798
Spandan Dasa26eda72023-03-02 00:56:06 +0000799func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
800 if j.deviceProperties.Max_sdk_version != nil {
801 return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version)
802 }
803 // Default is PrivateApiLevel
804 return android.SdkSpecPrivate.ApiLevel
satayev0a420e72021-11-29 17:25:52 +0000805}
806
Spandan Dasa26eda72023-03-02 00:56:06 +0000807func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
808 if j.deviceProperties.Replace_max_sdk_version_placeholder != nil {
809 return android.ApiLevelFrom(ctx, *j.deviceProperties.Replace_max_sdk_version_placeholder)
810 }
811 // Default is PrivateApiLevel
812 return android.SdkSpecPrivate.ApiLevel
William Loh5a082f92022-05-17 20:21:50 +0000813}
814
Jiyong Parkf1691d22021-03-29 20:11:58 +0900815func (j *Module) MinSdkVersionString() string {
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000816 return j.minSdkVersion.String()
Jiyong Park92315372021-04-02 08:45:46 +0900817}
818
Spandan Dasca70fc42023-03-01 23:38:49 +0000819func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Jiyong Park92315372021-04-02 08:45:46 +0900820 if j.deviceProperties.Target_sdk_version != nil {
Spandan Dasca70fc42023-03-01 23:38:49 +0000821 return android.ApiLevelFrom(ctx, *j.deviceProperties.Target_sdk_version)
Jiyong Park92315372021-04-02 08:45:46 +0900822 }
Spandan Dasca70fc42023-03-01 23:38:49 +0000823 return j.SdkVersion(ctx).ApiLevel
Jaewoong Jung26342642021-03-17 15:56:23 -0700824}
825
826func (j *Module) AvailableFor(what string) bool {
827 if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) {
828 // Exception: for hostdex: true libraries, the platform variant is created
829 // even if it's not marked as available to platform. In that case, the platform
830 // variant is used only for the hostdex and not installed to the device.
831 return true
832 }
833 return j.ApexModuleBase.AvailableFor(what)
834}
835
836func (j *Module) deps(ctx android.BottomUpMutatorContext) {
837 if ctx.Device() {
838 j.linter.deps(ctx)
839
Jiyong Parkf1691d22021-03-29 20:11:58 +0900840 sdkDeps(ctx, android.SdkContext(j), j.dexer)
Jaewoong Jung26342642021-03-17 15:56:23 -0700841
842 if j.deviceProperties.SyspropPublicStub != "" {
843 // This is a sysprop implementation library that has a corresponding sysprop public
844 // stubs library, and a dependency on it so that dependencies on the implementation can
845 // be forwarded to the public stubs library when necessary.
846 ctx.AddVariationDependencies(nil, syspropPublicStubDepTag, j.deviceProperties.SyspropPublicStub)
847 }
848 }
849
850 libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Jihoon Kang381c2fa2023-06-01 22:17:32 +0000851
852 j.properties.Static_libs = android.RemoveListFromList(j.properties.Static_libs, j.properties.Exclude_static_libs)
Jaewoong Jung26342642021-03-17 15:56:23 -0700853 ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
854
855 // Add dependency on libraries that provide additional hidden api annotations.
856 ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
857
Kiyoung Kim9743bab2024-03-28 15:44:56 +0900858 if ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
Jaewoong Jung26342642021-03-17 15:56:23 -0700859 // Require java_sdk_library at inter-partition java dependency to ensure stable
860 // interface between partitions. If inter-partition java_library dependency is detected,
861 // raise build error because java_library doesn't have a stable interface.
862 //
863 // Inputs:
864 // PRODUCT_ENFORCE_INTER_PARTITION_JAVA_SDK_LIBRARY
865 // if true, enable enforcement
866 // PRODUCT_INTER_PARTITION_JAVA_LIBRARY_ALLOWLIST
867 // exception list of java_library names to allow inter-partition dependency
868 for idx := range j.properties.Libs {
869 if libDeps[idx] == nil {
870 continue
871 }
872
873 if javaDep, ok := libDeps[idx].(javaSdkLibraryEnforceContext); ok {
874 // java_sdk_library is always allowed at inter-partition dependency.
875 // So, skip check.
876 if _, ok := javaDep.(*SdkLibrary); ok {
877 continue
878 }
879
880 j.checkPartitionsForJavaDependency(ctx, "libs", javaDep)
881 }
882 }
883 }
884
885 // For library dependencies that are component libraries (like stubs), add the implementation
886 // as a dependency (dexpreopt needs to be against the implementation library, not stubs).
887 for _, dep := range libDeps {
888 if dep != nil {
889 if component, ok := dep.(SdkLibraryComponentDependency); ok {
890 if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000891 // Add library as optional if it's one of the optional compatibility libs or it's
892 // explicitly listed in the optional_uses_libs property.
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100893 tag := usesLibReqTag
Jiakai Zhangf98da192024-04-15 11:15:41 +0000894 if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
895 android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs) {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100896 tag = usesLibOptTag
897 }
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100898 ctx.AddVariationDependencies(nil, tag, *lib)
Jaewoong Jung26342642021-03-17 15:56:23 -0700899 }
900 }
901 }
902 }
903
904 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
905 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...)
906 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
907
908 android.ProtoDeps(ctx, &j.protoProperties)
909 if j.hasSrcExt(".proto") {
910 protoDeps(ctx, &j.protoProperties)
911 }
912
913 if j.hasSrcExt(".kt") {
914 // TODO(ccross): move this to a mutator pass that can tell if generated sources contain
915 // Kotlin files
Colin Cross882d6002024-08-14 10:24:06 -0700916 tag := staticLibTag
917 if !BoolDefault(j.properties.Static_kotlin_stdlib, true) {
918 tag = libTag
919 }
920 ctx.AddVariationDependencies(nil, tag,
921 "kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8", "kotlin-annotations")
Jaewoong Jung26342642021-03-17 15:56:23 -0700922 }
923
924 // Framework libraries need special handling in static coverage builds: they should not have
925 // static dependency on jacoco, otherwise there would be multiple conflicting definitions of
926 // the same jacoco classes coming from different bootclasspath jars.
927 if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
928 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
929 j.properties.Instrument = true
930 }
931 } else if j.shouldInstrumentStatic(ctx) {
932 ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
933 }
Colin Crossa1ff7c62021-09-17 14:11:52 -0700934
935 if j.useCompose() {
936 ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag,
937 "androidx.compose.compiler_compiler-hosted")
938 }
Jaewoong Jung26342642021-03-17 15:56:23 -0700939}
940
941func hasSrcExt(srcs []string, ext string) bool {
942 for _, src := range srcs {
943 if filepath.Ext(src) == ext {
944 return true
945 }
946 }
947
948 return false
949}
950
951func (j *Module) hasSrcExt(ext string) bool {
952 return hasSrcExt(j.properties.Srcs, ext)
953}
954
Thiébaud Weksteende8417c2022-02-10 15:41:46 +1100955func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android.Path) string {
956 var flags string
957
958 if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
959 if !android.InList(aidlFile.String(), j.ignoredAidlPermissionList.Strings()) {
960 flags = "-Wmissing-permission-annotation -Werror"
961 }
962 }
963 return flags
964}
965
Jaewoong Jung26342642021-03-17 15:56:23 -0700966func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Sam Delmerico2351eac2022-05-24 17:10:02 +0000967 aidlIncludeDirs android.Paths, aidlSrcs android.Paths) (string, android.Paths) {
Jaewoong Jung26342642021-03-17 15:56:23 -0700968
969 aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
970 aidlIncludes = append(aidlIncludes,
971 android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...)
972 aidlIncludes = append(aidlIncludes,
973 android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)
974
975 var flags []string
976 var deps android.Paths
Sam Delmerico2351eac2022-05-24 17:10:02 +0000977 var includeDirs android.Paths
Jaewoong Jung26342642021-03-17 15:56:23 -0700978
979 flags = append(flags, j.deviceProperties.Aidl.Flags...)
980
981 if aidlPreprocess.Valid() {
982 flags = append(flags, "-p"+aidlPreprocess.String())
983 deps = append(deps, aidlPreprocess.Path())
984 } else if len(aidlIncludeDirs) > 0 {
Sam Delmerico2351eac2022-05-24 17:10:02 +0000985 includeDirs = append(includeDirs, aidlIncludeDirs...)
Jaewoong Jung26342642021-03-17 15:56:23 -0700986 }
987
988 if len(j.exportAidlIncludeDirs) > 0 {
Sam Delmerico2351eac2022-05-24 17:10:02 +0000989 includeDirs = append(includeDirs, j.exportAidlIncludeDirs...)
Jaewoong Jung26342642021-03-17 15:56:23 -0700990 }
991
992 if len(aidlIncludes) > 0 {
Sam Delmerico2351eac2022-05-24 17:10:02 +0000993 includeDirs = append(includeDirs, aidlIncludes...)
Jaewoong Jung26342642021-03-17 15:56:23 -0700994 }
995
Sam Delmerico2351eac2022-05-24 17:10:02 +0000996 includeDirs = append(includeDirs, android.PathForModuleSrc(ctx))
Jaewoong Jung26342642021-03-17 15:56:23 -0700997 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
Sam Delmerico2351eac2022-05-24 17:10:02 +0000998 includeDirs = append(includeDirs, src.Path())
Jaewoong Jung26342642021-03-17 15:56:23 -0700999 }
Sam Delmerico2351eac2022-05-24 17:10:02 +00001000 flags = append(flags, android.JoinWithPrefix(includeDirs.Strings(), "-I"))
1001 // add flags for dirs containing AIDL srcs that haven't been specified yet
1002 flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))
Jaewoong Jung26342642021-03-17 15:56:23 -07001003
Zim8774ae12022-08-17 11:46:34 +01001004 sdkVersion := (j.SdkVersion(ctx)).Kind
Parth Sane000cbe02022-11-22 13:01:22 +00001005 defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule) || (sdkVersion == android.SdkSystem))
Zim8774ae12022-08-17 11:46:34 +01001006 if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) {
Jaewoong Jung26342642021-03-17 15:56:23 -07001007 flags = append(flags, "-t")
1008 }
1009
1010 if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
1011 flags = append(flags, "--transaction_names")
1012 }
1013
Thiébaud Weksteende8417c2022-02-10 15:41:46 +11001014 if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
1015 exceptions := j.deviceProperties.Aidl.Enforce_permissions_exceptions
1016 j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil)
1017 }
1018
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001019 aidlMinSdkVersion := j.MinSdkVersion(ctx).String()
Jooyung Han07f70c02021-11-06 07:08:45 +09001020 flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion)
1021
Jaewoong Jung26342642021-03-17 15:56:23 -07001022 return strings.Join(flags, " "), deps
1023}
1024
1025func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
1026
1027 var flags javaBuilderFlags
1028
1029 // javaVersion flag.
Jiyong Parkf1691d22021-03-29 20:11:58 +09001030 flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
Jaewoong Jung26342642021-03-17 15:56:23 -07001031
Cole Faust2b1536e2021-06-18 12:25:54 -07001032 epEnabled := j.properties.Errorprone.Enabled
1033 if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) {
Paul Duffin74135582022-10-06 11:01:59 +01001034 if config.ErrorProneClasspath == nil && !ctx.Config().RunningInsideUnitTest() {
Jaewoong Jung26342642021-03-17 15:56:23 -07001035 ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
1036 }
1037
1038 errorProneFlags := []string{
1039 "-Xplugin:ErrorProne",
1040 "${config.ErrorProneChecks}",
1041 }
1042 errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
1043
Colin Cross8bf6cad2022-02-28 13:07:03 -08001044 flags.errorProneExtraJavacFlags = "${config.ErrorProneHeapFlags} ${config.ErrorProneFlags} " +
Jaewoong Jung26342642021-03-17 15:56:23 -07001045 "'" + strings.Join(errorProneFlags, " ") + "'"
1046 flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
1047 }
1048
1049 // classpath
1050 flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
1051 flags.classpath = append(flags.classpath, deps.classpath...)
Colin Cross9bb9bfb2022-03-17 11:12:32 -07001052 flags.dexClasspath = append(flags.dexClasspath, deps.dexClasspath...)
Jaewoong Jung26342642021-03-17 15:56:23 -07001053 flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...)
1054 flags.processorPath = append(flags.processorPath, deps.processorPath...)
1055 flags.errorProneProcessorPath = append(flags.errorProneProcessorPath, deps.errorProneProcessorPath...)
1056
1057 flags.processors = append(flags.processors, deps.processorClasses...)
1058 flags.processors = android.FirstUniqueStrings(flags.processors)
1059
1060 if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() &&
Jiyong Parkf1691d22021-03-29 20:11:58 +09001061 decodeSdkDep(ctx, android.SdkContext(j)).hasStandardLibs() {
Jaewoong Jung26342642021-03-17 15:56:23 -07001062 // Give host-side tools a version of OpenJDK's standard libraries
1063 // close to what they're targeting. As of Dec 2017, AOSP is only
1064 // bundling OpenJDK 8 and 9, so nothing < 8 is available.
1065 //
1066 // When building with OpenJDK 8, the following should have no
1067 // effect since those jars would be available by default.
1068 //
1069 // When building with OpenJDK 9 but targeting a version < 1.8,
1070 // putting them on the bootclasspath means that:
1071 // a) code can't (accidentally) refer to OpenJDK 9 specific APIs
1072 // b) references to existing APIs are not reinterpreted in an
1073 // OpenJDK 9-specific way, eg. calls to subclasses of
1074 // java.nio.Buffer as in http://b/70862583
1075 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1076 flags.bootClasspath = append(flags.bootClasspath,
1077 android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"),
1078 android.PathForSource(ctx, java8Home, "jre/lib/rt.jar"))
1079 if Bool(j.properties.Use_tools_jar) {
1080 flags.bootClasspath = append(flags.bootClasspath,
1081 android.PathForSource(ctx, java8Home, "lib/tools.jar"))
1082 }
1083 }
1084
1085 // systemModules
1086 flags.systemModules = deps.systemModules
1087
Jaewoong Jung26342642021-03-17 15:56:23 -07001088 return flags
1089}
1090
1091func (j *Module) collectJavacFlags(
1092 ctx android.ModuleContext, flags javaBuilderFlags, srcFiles android.Paths) javaBuilderFlags {
1093 // javac flags.
1094 javacFlags := j.properties.Javacflags
Mythri Alle4b9f6182023-10-25 15:17:11 +00001095 var needsDebugInfo bool
Jaewoong Jung26342642021-03-17 15:56:23 -07001096
Mythri Alle4b9f6182023-10-25 15:17:11 +00001097 needsDebugInfo = false
1098 for _, flag := range javacFlags {
1099 if strings.HasPrefix(flag, "-g") {
1100 needsDebugInfo = true
1101 }
1102 }
1103
1104 if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() && !needsDebugInfo {
Jaewoong Jung26342642021-03-17 15:56:23 -07001105 // For non-host binaries, override the -g flag passed globally to remove
1106 // local variable debug info to reduce disk and memory usage.
1107 javacFlags = append(javacFlags, "-g:source,lines")
1108 }
1109 javacFlags = append(javacFlags, "-Xlint:-dep-ann")
1110
1111 if flags.javaVersion.usesJavaModules() {
1112 javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
Liz Kammer9f52f6b2023-10-06 16:47:00 -04001113 } else if len(j.properties.Openjdk9.Javacflags) > 0 {
1114 // java version defaults higher than openjdk 9, these conditionals should no longer be necessary
1115 ctx.PropertyErrorf("openjdk9.javacflags", "JDK version defaults to higher than 9")
1116 }
Jaewoong Jung26342642021-03-17 15:56:23 -07001117
Liz Kammer9f52f6b2023-10-06 16:47:00 -04001118 if flags.javaVersion.usesJavaModules() {
Jaewoong Jung26342642021-03-17 15:56:23 -07001119 if j.properties.Patch_module != nil {
1120 // Manually specify build directory in case it is not under the repo root.
1121 // (javac doesn't seem to expand into symbolic links when searching for patch-module targets, so
1122 // just adding a symlink under the root doesn't help.)
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +02001123 patchPaths := []string{".", ctx.Config().SoongOutDir()}
Jaewoong Jung26342642021-03-17 15:56:23 -07001124
Jaewoong Jung26342642021-03-17 15:56:23 -07001125 classPath := flags.classpath.FormJavaClassPath("")
1126 if classPath != "" {
1127 patchPaths = append(patchPaths, classPath)
1128 }
1129 javacFlags = append(
1130 javacFlags,
1131 "--patch-module="+String(j.properties.Patch_module)+"="+strings.Join(patchPaths, ":"))
1132 }
1133 }
1134
1135 if len(javacFlags) > 0 {
1136 // optimization.
1137 ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
1138 flags.javacFlags = "$javacFlags"
1139 }
1140
1141 return flags
1142}
1143
Romain Jobredeaux3ec36ad42021-10-29 13:08:48 -04001144func (j *Module) AddJSONData(d *map[string]interface{}) {
1145 (&j.ModuleBase).AddJSONData(d)
1146 (*d)["Java"] = map[string]interface{}{
1147 "SourceExtensions": j.sourceExtensions,
1148 }
1149
1150}
1151
usta0391ca42023-09-19 15:51:59 -04001152func (j *Module) addGeneratedSrcJars(path android.Path) {
1153 j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
Joe Onorato175073c2023-06-01 14:42:59 -07001154}
1155
Colin Crossfdaa6722024-08-23 11:58:08 -07001156func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) {
Joe Onorato349ae8d2024-02-05 22:46:00 +00001157 // Auto-propagating jarjar rules
1158 jarjarProviderData := j.collectJarJarRules(ctx)
1159 if jarjarProviderData != nil {
1160 android.SetProvider(ctx, JarJarProvider, *jarjarProviderData)
Zi Wangddb2ee52024-04-02 16:44:02 +00001161 text := getJarJarRuleText(jarjarProviderData)
1162 if text != "" {
1163 ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
1164 android.WriteFileRule(ctx, ruleTextFile, text)
1165 j.repackageJarjarRules = ruleTextFile
Joe Onorato349ae8d2024-02-05 22:46:00 +00001166 }
1167 }
1168
Jaewoong Jung26342642021-03-17 15:56:23 -07001169 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
1170
Makoto Onuki7ded3822024-03-28 14:42:20 -07001171 if re := proptools.Bool(j.properties.Ravenizer.Enabled); re {
1172 j.ravenizer.enabled = re
1173 }
1174
Jaewoong Jung26342642021-03-17 15:56:23 -07001175 deps := j.collectDeps(ctx)
1176 flags := j.collectBuilderFlags(ctx, deps)
1177
1178 if flags.javaVersion.usesJavaModules() {
1179 j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
Liz Kammer9f52f6b2023-10-06 16:47:00 -04001180 } else if len(j.properties.Openjdk9.Javacflags) > 0 {
1181 // java version defaults higher than openjdk 9, these conditionals should no longer be necessary
1182 ctx.PropertyErrorf("openjdk9.srcs", "JDK version defaults to higher than 9")
Jaewoong Jung26342642021-03-17 15:56:23 -07001183 }
Sorin Basca9347ae32021-12-20 11:51:24 +00001184
Jaewoong Jung26342642021-03-17 15:56:23 -07001185 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Romain Jobredeaux3ec36ad42021-10-29 13:08:48 -04001186 j.sourceExtensions = []string{}
1187 for _, ext := range []string{".kt", ".proto", ".aidl", ".java", ".logtags"} {
1188 if hasSrcExt(srcFiles.Strings(), ext) {
1189 j.sourceExtensions = append(j.sourceExtensions, ext)
1190 }
1191 }
Jaewoong Jung26342642021-03-17 15:56:23 -07001192 if hasSrcExt(srcFiles.Strings(), ".proto") {
1193 flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
1194 }
1195
1196 kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil)
1197 if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
1198 ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
1199 }
1200
Sam Delmerico2351eac2022-05-24 17:10:02 +00001201 aidlSrcs := srcFiles.FilterByExt(".aidl")
1202 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs, aidlSrcs)
1203
Thiébaud Weksteen5c26f812022-05-05 14:49:02 +10001204 nonGeneratedSrcJars := srcFiles.FilterByExt(".srcjar")
Jaewoong Jung26342642021-03-17 15:56:23 -07001205 srcFiles = j.genSources(ctx, srcFiles, flags)
1206
1207 // Collect javac flags only after computing the full set of srcFiles to
1208 // ensure that the --patch-module lookup paths are complete.
1209 flags = j.collectJavacFlags(ctx, flags, srcFiles)
1210
1211 srcJars := srcFiles.FilterByExt(".srcjar")
1212 srcJars = append(srcJars, deps.srcJars...)
Colin Cross4eae06d2023-06-20 22:40:02 -07001213 srcJars = append(srcJars, extraSrcJars...)
Joe Onorato175073c2023-06-01 14:42:59 -07001214 srcJars = append(srcJars, j.properties.Generated_srcjars...)
Colin Crossb0ef30a2021-06-29 10:42:00 -07001215 srcFiles = srcFiles.FilterOutByExt(".srcjar")
Jaewoong Jung26342642021-03-17 15:56:23 -07001216
1217 if j.properties.Jarjar_rules != nil {
1218 j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
1219 }
1220
Jihoon Kang1bfb6f22023-07-01 00:13:47 +00001221 jarName := j.Stem() + ".jar"
Jaewoong Jung26342642021-03-17 15:56:23 -07001222
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001223 var uniqueJavaFiles android.Paths
Jaewoong Jung26342642021-03-17 15:56:23 -07001224 set := make(map[string]bool)
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001225 for _, v := range srcFiles.FilterByExt(".java") {
Jaewoong Jung26342642021-03-17 15:56:23 -07001226 if _, found := set[v.String()]; !found {
1227 set[v.String()] = true
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001228 uniqueJavaFiles = append(uniqueJavaFiles, v)
Jaewoong Jung26342642021-03-17 15:56:23 -07001229 }
1230 }
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001231 var uniqueKtFiles android.Paths
1232 for _, v := range srcFiles.FilterByExt(".kt") {
1233 if _, found := set[v.String()]; !found {
1234 set[v.String()] = true
1235 uniqueKtFiles = append(uniqueKtFiles, v)
1236 }
1237 }
1238
1239 var uniqueSrcFiles android.Paths
1240 uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
1241 uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
1242 j.uniqueSrcFiles = uniqueSrcFiles
Colin Cross40213022023-12-13 15:19:49 -08001243 android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: uniqueSrcFiles.Strings()})
Jaewoong Jung26342642021-03-17 15:56:23 -07001244
Colin Crossb5db4012022-03-28 17:12:39 -07001245 // We don't currently run annotation processors in turbine, which means we can't use turbine
1246 // generated header jars when an annotation processor that generates API is enabled. One
1247 // exception (handled further below) is when kotlin sources are enabled, in which case turbine
1248 // is used to run all of the annotation processors.
1249 disableTurbine := deps.disableTurbine
1250
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001251 // Collect .java and .kt files for AIDEGen
Jaewoong Jung26342642021-03-17 15:56:23 -07001252 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
1253
1254 var kotlinJars android.Paths
Colin Cross220a9a12022-03-28 17:08:01 -07001255 var kotlinHeaderJars android.Paths
Jaewoong Jung26342642021-03-17 15:56:23 -07001256
Colin Cross4eae06d2023-06-20 22:40:02 -07001257 // Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
1258 // any dependencies so that it can override any non-final R classes from dependencies with the
1259 // final R classes from the app.
1260 flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
1261
Jihoon Kang3921f0b2024-03-12 23:51:37 +00001262 j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...)
1263
Mark Whitea15790a2023-08-22 21:28:11 +00001264 // If compiling headers then compile them and skip the rest
Liz Kammer60772632023-10-05 17:18:44 -04001265 if proptools.Bool(j.properties.Headers_only) {
Mark Whitea15790a2023-08-22 21:28:11 +00001266 if srcFiles.HasExt(".kt") {
1267 ctx.ModuleErrorf("Compiling headers_only with .kt not supported")
1268 }
1269 if ctx.Config().IsEnvFalse("TURBINE_ENABLED") || disableTurbine {
1270 ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.")
1271 }
1272
Colin Crossedec77c2024-07-26 15:25:40 -07001273 _, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
1274 extraCombinedJars)
1275
1276 combinedHeaderJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
1277 combinedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-turbine")
Mark Whitea15790a2023-08-22 21:28:11 +00001278 if ctx.Failed() {
1279 return
1280 }
Colin Crossedec77c2024-07-26 15:25:40 -07001281 j.headerJarFile = combinedHeaderJarFile
Mark Whitea15790a2023-08-22 21:28:11 +00001282
Colin Crossa6182ab2024-08-21 10:47:44 -07001283 ctx.CheckbuildFile(j.headerJarFile)
1284
Colin Cross7727c7f2024-07-18 15:36:32 -07001285 android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
Jihoon Kang705e63e2024-03-13 01:21:16 +00001286 HeaderJars: android.PathsIfNonNil(j.headerJarFile),
Colin Cross9ffaf282024-08-12 13:50:09 -07001287 TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
1288 TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
Jihoon Kang705e63e2024-03-13 01:21:16 +00001289 AidlIncludeDirs: j.exportAidlIncludeDirs,
1290 ExportedPlugins: j.exportedPluginJars,
1291 ExportedPluginClasses: j.exportedPluginClasses,
1292 ExportedPluginDisableTurbine: j.exportedDisableTurbine,
1293 StubsLinkType: j.stubsLinkType,
1294 AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
Mark Whitea15790a2023-08-22 21:28:11 +00001295 })
1296
1297 j.outputFile = j.headerJarFile
1298 return
1299 }
1300
Jaewoong Jung26342642021-03-17 15:56:23 -07001301 if srcFiles.HasExt(".kt") {
Colin Crossb5db4012022-03-28 17:12:39 -07001302 // When using kotlin sources turbine is used to generate annotation processor sources,
1303 // including for annotation processors that generate API, so we can use turbine for
1304 // java sources too.
1305 disableTurbine = false
1306
Jaewoong Jung26342642021-03-17 15:56:23 -07001307 // user defined kotlin flags.
1308 kotlincFlags := j.properties.Kotlincflags
1309 CheckKotlincFlags(ctx, kotlincFlags)
1310
Aurimas Liutikas24a987f2021-05-17 17:47:10 +00001311 // Workaround for KT-46512
1312 kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class")
Jaewoong Jung26342642021-03-17 15:56:23 -07001313
1314 // If there are kotlin files, compile them first but pass all the kotlin and java files
1315 // kotlinc will use the java files to resolve types referenced by the kotlin files, but
1316 // won't emit any classes for them.
1317 kotlincFlags = append(kotlincFlags, "-no-stdlib")
1318 if ctx.Device() {
1319 kotlincFlags = append(kotlincFlags, "-no-jdk")
1320 }
Colin Crossa1ff7c62021-09-17 14:11:52 -07001321
1322 for _, plugin := range deps.kotlinPlugins {
1323 kotlincFlags = append(kotlincFlags, "-Xplugin="+plugin.String())
1324 }
1325 flags.kotlincDeps = append(flags.kotlincDeps, deps.kotlinPlugins...)
1326
Jaewoong Jung26342642021-03-17 15:56:23 -07001327 if len(kotlincFlags) > 0 {
1328 // optimization.
1329 ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
1330 flags.kotlincFlags += "$kotlincFlags"
1331 }
1332
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001333 // Collect common .kt files for AIDEGen
Jaewoong Jung26342642021-03-17 15:56:23 -07001334 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
1335
Jaewoong Jung26342642021-03-17 15:56:23 -07001336 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
1337 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)
1338
Isaac Chioua23d9942022-04-06 06:14:38 +00001339 if len(flags.processorPath) > 0 {
Jaewoong Jung26342642021-03-17 15:56:23 -07001340 // Use kapt for annotation processing
Isaac Chioua23d9942022-04-06 06:14:38 +00001341 kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
1342 kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001343 kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
Isaac Chioua23d9942022-04-06 06:14:38 +00001344 srcJars = append(srcJars, kaptSrcJar)
1345 kotlinJars = append(kotlinJars, kaptResJar)
Jaewoong Jung26342642021-03-17 15:56:23 -07001346 // Disable annotation processing in javac, it's already been handled by kapt
1347 flags.processorPath = nil
1348 flags.processors = nil
1349 }
1350
1351 kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
Colin Cross220a9a12022-03-28 17:08:01 -07001352 kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001353 kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
Jaewoong Jung26342642021-03-17 15:56:23 -07001354 if ctx.Failed() {
1355 return
1356 }
1357
Colin Cross7707b242024-07-26 12:02:36 -07001358 kotlinJarPath := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
Zi Wangddb2ee52024-04-02 16:44:02 +00001359
Isaac Chioua23d9942022-04-06 06:14:38 +00001360 // Make javac rule depend on the kotlinc rule
1361 flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)
1362
Zi Wangddb2ee52024-04-02 16:44:02 +00001363 kotlinJars = append(kotlinJars, kotlinJarPath)
Colin Cross220a9a12022-03-28 17:08:01 -07001364 kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
Jaewoong Jung26342642021-03-17 15:56:23 -07001365 }
1366
Colin Crossfd620b22024-02-23 10:05:21 -08001367 jars := slices.Clone(kotlinJars)
Jaewoong Jung26342642021-03-17 15:56:23 -07001368
Jaewoong Jung26342642021-03-17 15:56:23 -07001369 j.compiledSrcJars = srcJars
1370
1371 enableSharding := false
Colin Cross3d56ed52021-11-18 22:23:12 -08001372 var headerJarFileWithoutDepsOrJarjar android.Path
Colin Crossb5db4012022-03-28 17:12:39 -07001373 if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine {
Jaewoong Jung26342642021-03-17 15:56:23 -07001374 if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
1375 enableSharding = true
1376 // Formerly, there was a check here that prevented annotation processors
1377 // from being used when sharding was enabled, as some annotation processors
1378 // do not function correctly in sharded environments. It was removed to
1379 // allow for the use of annotation processors that do function correctly
1380 // with sharding enabled. See: b/77284273.
1381 }
Colin Crossd1d8f172024-07-29 11:30:29 -07001382 extraJars := slices.Clone(kotlinHeaderJars)
Colin Crossd1d8f172024-07-29 11:30:29 -07001383 extraJars = append(extraJars, extraCombinedJars...)
Colin Crossedec77c2024-07-26 15:25:40 -07001384 var combinedHeaderJarFile android.Path
1385 headerJarFileWithoutDepsOrJarjar, combinedHeaderJarFile =
Colin Cross4eae06d2023-06-20 22:40:02 -07001386 j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
Colin Crossedec77c2024-07-26 15:25:40 -07001387
1388 j.headerJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
1389 j.repackagedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine")
Jaewoong Jung26342642021-03-17 15:56:23 -07001390 }
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001391 if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 {
Cole Faust2d516df2022-08-24 11:22:52 -07001392 hasErrorproneableFiles := false
1393 for _, ext := range j.sourceExtensions {
1394 if ext != ".proto" && ext != ".aidl" {
1395 // Skip running errorprone on pure proto or pure aidl modules. Some modules take a long time to
1396 // compile, and it's not useful to have warnings on these generated sources.
1397 hasErrorproneableFiles = true
1398 break
1399 }
1400 }
Jaewoong Jung26342642021-03-17 15:56:23 -07001401 var extraJarDeps android.Paths
Cole Faust75fffb12021-06-13 15:23:16 -07001402 if Bool(j.properties.Errorprone.Enabled) {
1403 // If error-prone is enabled, enable errorprone flags on the regular
1404 // build.
1405 flags = enableErrorproneFlags(flags)
Cole Faust2d516df2022-08-24 11:22:52 -07001406 } else if hasErrorproneableFiles && ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil {
Cole Faust75fffb12021-06-13 15:23:16 -07001407 // Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
1408 // a new jar file just for compiling with the errorprone compiler to.
1409 // This is because we don't want to cause the java files to get completely
1410 // rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
1411 // We also don't want to run this if errorprone is enabled by default for
1412 // this module, or else we could have duplicated errorprone messages.
1413 errorproneFlags := enableErrorproneFlags(flags)
Jaewoong Jung26342642021-03-17 15:56:23 -07001414 errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
Vadim Spivak3c496f02023-06-08 06:14:59 +00001415 errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")
Cole Faust75fffb12021-06-13 15:23:16 -07001416
Vadim Spivak3c496f02023-06-08 06:14:59 +00001417 transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
Cole Faust75fffb12021-06-13 15:23:16 -07001418 "errorprone", "errorprone")
1419
Jaewoong Jung26342642021-03-17 15:56:23 -07001420 extraJarDeps = append(extraJarDeps, errorprone)
1421 }
1422
1423 if enableSharding {
Colin Cross3d56ed52021-11-18 22:23:12 -08001424 if headerJarFileWithoutDepsOrJarjar != nil {
1425 flags.classpath = append(classpath{headerJarFileWithoutDepsOrJarjar}, flags.classpath...)
1426 }
Jaewoong Jung26342642021-03-17 15:56:23 -07001427 shardSize := int(*(j.properties.Javac_shard_size))
1428 var shardSrcs []android.Paths
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001429 if len(uniqueJavaFiles) > 0 {
1430 shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize)
Jaewoong Jung26342642021-03-17 15:56:23 -07001431 for idx, shardSrc := range shardSrcs {
1432 classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
1433 nil, flags, extraJarDeps)
Zi Wangddb2ee52024-04-02 16:44:02 +00001434 classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
Jaewoong Jung26342642021-03-17 15:56:23 -07001435 jars = append(jars, classes)
1436 }
1437 }
Colin Crossa052ddb2023-09-25 21:46:58 -07001438 // Assume approximately 5 sources per srcjar.
1439 // For framework-minus-apex in AOSP at the time this was written, there are 266 srcjars, with a mean
1440 // of 5.8 sources per srcjar, but a median of 1, a standard deviation of 10, and a max of 48 source files.
Jaewoong Jung26342642021-03-17 15:56:23 -07001441 if len(srcJars) > 0 {
Colin Crossa052ddb2023-09-25 21:46:58 -07001442 startIdx := len(shardSrcs)
1443 shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5)
1444 for idx, shardSrcJars := range shardSrcJarsList {
1445 classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
1446 nil, shardSrcJars, flags, extraJarDeps)
Zi Wangddb2ee52024-04-02 16:44:02 +00001447 classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
Colin Crossa052ddb2023-09-25 21:46:58 -07001448 jars = append(jars, classes)
1449 }
Jaewoong Jung26342642021-03-17 15:56:23 -07001450 }
1451 } else {
Chaohui Wangdcbe33c2022-10-11 11:13:30 +08001452 classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
Zi Wangddb2ee52024-04-02 16:44:02 +00001453 classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
Jaewoong Jung26342642021-03-17 15:56:23 -07001454 jars = append(jars, classes)
1455 }
1456 if ctx.Failed() {
1457 return
1458 }
1459 }
1460
Colin Crossfd620b22024-02-23 10:05:21 -08001461 jars = append(jars, extraCombinedJars...)
1462
Jaewoong Jung26342642021-03-17 15:56:23 -07001463 j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
1464
1465 var includeSrcJar android.WritablePath
1466 if Bool(j.properties.Include_srcs) {
1467 includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar")
1468 TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps)
1469 }
1470
1471 dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
1472 j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
1473 fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
1474 extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources
1475
1476 var resArgs []string
1477 var resDeps android.Paths
1478
1479 resArgs = append(resArgs, dirArgs...)
1480 resDeps = append(resDeps, dirDeps...)
1481
1482 resArgs = append(resArgs, fileArgs...)
1483 resDeps = append(resDeps, fileDeps...)
1484
1485 resArgs = append(resArgs, extraArgs...)
1486 resDeps = append(resDeps, extraDeps...)
1487
1488 if len(resArgs) > 0 {
1489 resourceJar := android.PathForModuleOut(ctx, "res", jarName)
1490 TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
1491 j.resourceJar = resourceJar
1492 if ctx.Failed() {
1493 return
1494 }
1495 }
1496
1497 var resourceJars android.Paths
1498 if j.resourceJar != nil {
1499 resourceJars = append(resourceJars, j.resourceJar)
1500 }
1501 if Bool(j.properties.Include_srcs) {
1502 resourceJars = append(resourceJars, includeSrcJar)
1503 }
1504 resourceJars = append(resourceJars, deps.staticResourceJars...)
1505
1506 if len(resourceJars) > 1 {
1507 combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
1508 TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
1509 false, nil, nil)
1510 j.resourceJar = combinedJar
1511 } else if len(resourceJars) == 1 {
1512 j.resourceJar = resourceJars[0]
1513 }
1514
1515 if len(deps.staticJars) > 0 {
1516 jars = append(jars, deps.staticJars...)
1517 }
1518
Colin Crossfdaa6722024-08-23 11:58:08 -07001519 jars = append(jars, extraDepCombinedJars...)
1520
Jaewoong Jung26342642021-03-17 15:56:23 -07001521 manifest := j.overrideManifest
1522 if !manifest.Valid() && j.properties.Manifest != nil {
1523 manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
1524 }
1525
1526 services := android.PathsForModuleSrc(ctx, j.properties.Services)
1527 if len(services) > 0 {
1528 servicesJar := android.PathForModuleOut(ctx, "services", jarName)
1529 var zipargs []string
1530 for _, file := range services {
1531 serviceFile := file.String()
1532 zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
1533 }
1534 rule := zip
1535 args := map[string]string{
1536 "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
1537 }
1538 if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") {
1539 rule = zipRE
1540 args["implicits"] = strings.Join(services.Strings(), ",")
1541 }
1542 ctx.Build(pctx, android.BuildParams{
1543 Rule: rule,
1544 Output: servicesJar,
1545 Implicits: services,
1546 Args: args,
1547 })
1548 jars = append(jars, servicesJar)
1549 }
1550
1551 // Combine the classes built from sources, any manifests, and any static libraries into
1552 // classes.jar. If there is only one input jar this step will be skipped.
Colin Cross7707b242024-07-26 12:02:36 -07001553 var outputFile android.Path
Jaewoong Jung26342642021-03-17 15:56:23 -07001554
1555 if len(jars) == 1 && !manifest.Valid() {
1556 // Optimization: skip the combine step as there is nothing to do
1557 // TODO(ccross): this leaves any module-info.class files, but those should only come from
1558 // prebuilt dependencies until we support modules in the platform build, so there shouldn't be
1559 // any if len(jars) == 1.
1560
Jihoon Kang1147b312023-06-08 23:25:57 +00001561 // moduleStubLinkType determines if the module is the TopLevelStubLibrary generated
1562 // from sdk_library. The TopLevelStubLibrary contains only one static lib,
1563 // either with .from-source or .from-text suffix.
1564 // outputFile should be agnostic to the build configuration,
1565 // thus "combine" the single static lib in order to prevent the static lib from being exposed
1566 // to the copy rules.
Jihoon Kangfa3f0782024-08-21 20:42:18 +00001567 stub, _ := moduleStubLinkType(j)
Jihoon Kang1147b312023-06-08 23:25:57 +00001568
Colin Cross7707b242024-07-26 12:02:36 -07001569 if stub {
Jaewoong Jung26342642021-03-17 15:56:23 -07001570 combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
1571 ctx.Build(pctx, android.BuildParams{
1572 Rule: android.Cp,
1573 Input: jars[0],
1574 Output: combinedJar,
1575 })
Colin Cross7707b242024-07-26 12:02:36 -07001576 outputFile = combinedJar
1577 } else {
1578 outputFile = jars[0]
Jaewoong Jung26342642021-03-17 15:56:23 -07001579 }
1580 } else {
1581 combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
1582 TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
1583 false, nil, nil)
Colin Cross7707b242024-07-26 12:02:36 -07001584 outputFile = combinedJar
Jaewoong Jung26342642021-03-17 15:56:23 -07001585 }
1586
1587 // jarjar implementation jar if necessary
Colin Crossedec77c2024-07-26 15:25:40 -07001588 jarjarFile := j.jarjarIfNecessary(ctx, outputFile, jarName, "")
1589 outputFile = jarjarFile
Jaewoong Jung26342642021-03-17 15:56:23 -07001590
Colin Crossedec77c2024-07-26 15:25:40 -07001591 // jarjar resource jar if necessary
1592 if j.resourceJar != nil {
1593 resourceJarJarFile := j.jarjarIfNecessary(ctx, j.resourceJar, jarName, "resource")
1594 j.resourceJar = resourceJarJarFile
1595 }
Jaewoong Jung26342642021-03-17 15:56:23 -07001596
Colin Crossedec77c2024-07-26 15:25:40 -07001597 if ctx.Failed() {
1598 return
Jaewoong Jung26342642021-03-17 15:56:23 -07001599 }
1600
Makoto Onuki7ded3822024-03-28 14:42:20 -07001601 if j.ravenizer.enabled {
1602 ravenizerInput := outputFile
1603 ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", jarName)
1604 ctx.Build(pctx, android.BuildParams{
1605 Rule: ravenizer,
1606 Description: "ravenizer",
1607 Input: ravenizerInput,
1608 Output: ravenizerOutput,
1609 })
1610 outputFile = ravenizerOutput
1611 }
1612
Yihan Dong8be09c22024-08-29 15:32:13 +08001613 if j.shouldApiMapper() {
1614 inputFile := outputFile
1615 apiMapperFile := android.PathForModuleOut(ctx, "apimapper", jarName)
1616 ctx.Build(pctx, android.BuildParams{
1617 Rule: apimapper,
1618 Description: "apimapper",
1619 Input: inputFile,
1620 Output: apiMapperFile,
1621 })
1622 outputFile = apiMapperFile
1623 }
1624
Jaewoong Jung26342642021-03-17 15:56:23 -07001625 // Check package restrictions if necessary.
1626 if len(j.properties.Permitted_packages) > 0 {
Paul Duffin08a18bf2021-10-01 13:19:58 +01001627 // Time stamp file created by the package check rule.
Jaewoong Jung26342642021-03-17 15:56:23 -07001628 pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
Paul Duffin08a18bf2021-10-01 13:19:58 +01001629
1630 // Create a rule to copy the output jar to another path and add a validate dependency that
1631 // will check that the jar only contains the permitted packages. The new location will become
1632 // the output file of this module.
1633 inputFile := outputFile
Colin Cross7707b242024-07-26 12:02:36 -07001634 packageCheckOutputFile := android.PathForModuleOut(ctx, "package-check", jarName)
Paul Duffin08a18bf2021-10-01 13:19:58 +01001635 ctx.Build(pctx, android.BuildParams{
1636 Rule: android.Cp,
1637 Input: inputFile,
Colin Cross7707b242024-07-26 12:02:36 -07001638 Output: packageCheckOutputFile,
Paul Duffin08a18bf2021-10-01 13:19:58 +01001639 // Make sure that any dependency on the output file will cause ninja to run the package check
1640 // rule.
1641 Validation: pkgckFile,
1642 })
Colin Cross7707b242024-07-26 12:02:36 -07001643 outputFile = packageCheckOutputFile
Paul Duffin08a18bf2021-10-01 13:19:58 +01001644
1645 // Check packages and create a timestamp file when complete.
Jaewoong Jung26342642021-03-17 15:56:23 -07001646 CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
Jaewoong Jung26342642021-03-17 15:56:23 -07001647
1648 if ctx.Failed() {
1649 return
1650 }
1651 }
1652
1653 j.implementationJarFile = outputFile
1654 if j.headerJarFile == nil {
Colin Crossf06d8dc2023-07-18 22:11:07 -07001655 // If this module couldn't generate a header jar (for example due to api generating annotation processors)
1656 // then use the implementation jar. Run it through zip2zip first to remove any files in META-INF/services
1657 // so that javac on modules that depend on this module don't pick up annotation processors (which may be
1658 // missing their implementations) from META-INF/services/javax.annotation.processing.Processor.
1659 headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
1660 convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
1661 j.headerJarFile = headerJarFile
Jaewoong Jung26342642021-03-17 15:56:23 -07001662 }
1663
Yuntao Xu5b009ae2021-05-13 12:42:24 -07001664 // enforce syntax check to jacoco filters for any build (http://b/183622051)
1665 specs := j.jacocoModuleToZipCommand(ctx)
1666 if ctx.Failed() {
1667 return
1668 }
1669
Jaewoong Jung26342642021-03-17 15:56:23 -07001670 if j.shouldInstrument(ctx) {
Yuntao Xu5b009ae2021-05-13 12:42:24 -07001671 outputFile = j.instrument(ctx, flags, outputFile, jarName, specs)
Jaewoong Jung26342642021-03-17 15:56:23 -07001672 }
1673
1674 // merge implementation jar with resources if necessary
1675 implementationAndResourcesJar := outputFile
1676 if j.resourceJar != nil {
1677 jars := android.Paths{j.resourceJar, implementationAndResourcesJar}
Colin Cross7707b242024-07-26 12:02:36 -07001678 combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
Jaewoong Jung26342642021-03-17 15:56:23 -07001679 TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest,
1680 false, nil, nil)
1681 implementationAndResourcesJar = combinedJar
1682 }
1683
1684 j.implementationAndResourcesJar = implementationAndResourcesJar
1685
1686 // Enable dex compilation for the APEX variants, unless it is disabled explicitly
Paul Duffine7b1f5b2022-06-29 10:15:52 +00001687 compileDex := j.dexProperties.Compile_dex
Colin Crossff694a82023-12-13 15:54:49 -08001688 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
Jaewoong Jung26342642021-03-17 15:56:23 -07001689 if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() {
Paul Duffine7b1f5b2022-06-29 10:15:52 +00001690 if compileDex == nil {
1691 compileDex = proptools.BoolPtr(true)
Jaewoong Jung26342642021-03-17 15:56:23 -07001692 }
1693 if j.deviceProperties.Hostdex == nil {
1694 j.deviceProperties.Hostdex = proptools.BoolPtr(true)
1695 }
1696 }
1697
Paul Duffine7b1f5b2022-06-29 10:15:52 +00001698 if ctx.Device() && (Bool(j.properties.Installable) || Bool(compileDex)) {
Jaewoong Jung26342642021-03-17 15:56:23 -07001699 if j.hasCode(ctx) {
1700 if j.shouldInstrumentStatic(ctx) {
Colin Cross312634e2023-11-21 15:13:56 -08001701 j.dexer.extraProguardFlagsFiles = append(j.dexer.extraProguardFlagsFiles,
Jaewoong Jung26342642021-03-17 15:56:23 -07001702 android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
1703 }
1704 // Dex compilation
Colin Cross7707b242024-07-26 12:02:36 -07001705 var dexOutputFile android.Path
Spandan Dasc404cc72023-02-23 18:05:05 +00001706 params := &compileDexParams{
1707 flags: flags,
1708 sdkVersion: j.SdkVersion(ctx),
1709 minSdkVersion: j.MinSdkVersion(ctx),
1710 classesJar: implementationAndResourcesJar,
1711 jarName: jarName,
1712 }
Spandan Das15a67112024-05-30 00:07:40 +00001713 if j.GetProfileGuided() && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting() {
1714 ctx.PropertyErrorf("enable_profile_rewriting",
1715 "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on. The attached profile should be sourced from an unoptimized/unobfuscated APK.",
1716 )
1717 }
Spandan Das3dbda182024-05-20 22:23:10 +00001718 if j.EnableProfileRewriting() {
1719 profile := j.GetProfile()
1720 if profile == "" || !j.GetProfileGuided() {
1721 ctx.PropertyErrorf("enable_profile_rewriting", "Profile and Profile_guided must be set when enable_profile_rewriting is true")
1722 }
1723 params.artProfileInput = &profile
1724 }
1725 dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params)
Jaewoong Jung26342642021-03-17 15:56:23 -07001726 if ctx.Failed() {
1727 return
1728 }
1729
Spandan Das3dbda182024-05-20 22:23:10 +00001730 // If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
1731 if dexArtProfileOutput != nil {
Colin Cross7707b242024-07-26 12:02:36 -07001732 j.dexpreopter.SetRewrittenProfile(dexArtProfileOutput)
Spandan Das3dbda182024-05-20 22:23:10 +00001733 }
1734
Jaewoong Jung26342642021-03-17 15:56:23 -07001735 // merge dex jar with resources if necessary
1736 if j.resourceJar != nil {
1737 jars := android.Paths{dexOutputFile, j.resourceJar}
Colin Cross7707b242024-07-26 12:02:36 -07001738 combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
Jaewoong Jung26342642021-03-17 15:56:23 -07001739 TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
1740 false, nil, nil)
1741 if *j.dexProperties.Uncompress_dex {
Colin Cross7707b242024-07-26 12:02:36 -07001742 combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
Cole Faust51d7bfd2023-09-07 05:31:32 +00001743 TransformZipAlign(ctx, combinedAlignedJar, combinedJar, nil)
Jaewoong Jung26342642021-03-17 15:56:23 -07001744 dexOutputFile = combinedAlignedJar
1745 } else {
1746 dexOutputFile = combinedJar
1747 }
1748 }
1749
Paul Duffin4de94502021-05-16 05:21:16 +01001750 // Initialize the hiddenapi structure.
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001751
1752 j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), j.implementationJarFile, j.dexProperties.Uncompress_dex)
Paul Duffin4de94502021-05-16 05:21:16 +01001753
1754 // Encode hidden API flags in dex file, if needed.
1755 dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
1756
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001757 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
Jaewoong Jung26342642021-03-17 15:56:23 -07001758
1759 // Dexpreopting
Jihoon Kanga3a05462024-04-05 00:36:44 +00001760 libName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
1761 if j.SdkLibraryName() != nil && strings.HasSuffix(ctx.ModuleName(), ".impl") {
1762 libName = strings.TrimSuffix(libName, ".impl")
1763 }
1764 j.dexpreopt(ctx, libName, dexOutputFile)
Jaewoong Jung26342642021-03-17 15:56:23 -07001765
1766 outputFile = dexOutputFile
Colin Crossa6182ab2024-08-21 10:47:44 -07001767
1768 ctx.CheckbuildFile(dexOutputFile)
Jaewoong Jung26342642021-03-17 15:56:23 -07001769 } else {
1770 // There is no code to compile into a dex jar, make sure the resources are propagated
1771 // to the APK if this is an app.
1772 outputFile = implementationAndResourcesJar
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001773 j.dexJarFile = makeDexJarPathFromPath(j.resourceJar)
Jaewoong Jung26342642021-03-17 15:56:23 -07001774 }
1775
1776 if ctx.Failed() {
1777 return
1778 }
1779 } else {
1780 outputFile = implementationAndResourcesJar
1781 }
1782
1783 if ctx.Device() {
Zi Wange1166f02023-11-06 11:43:17 -08001784 lintSDKVersion := func(apiLevel android.ApiLevel) android.ApiLevel {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001785 if !apiLevel.IsPreview() {
Zi Wange1166f02023-11-06 11:43:17 -08001786 return apiLevel
Jaewoong Jung26342642021-03-17 15:56:23 -07001787 } else {
Zi Wange1166f02023-11-06 11:43:17 -08001788 return ctx.Config().DefaultAppTargetSdk(ctx)
Jaewoong Jung26342642021-03-17 15:56:23 -07001789 }
1790 }
1791
1792 j.linter.name = ctx.ModuleName()
Thiébaud Weksteen5c26f812022-05-05 14:49:02 +10001793 j.linter.srcs = append(srcFiles, nonGeneratedSrcJars...)
1794 j.linter.srcJars, _ = android.FilterPathList(srcJars, nonGeneratedSrcJars)
Jaewoong Jung26342642021-03-17 15:56:23 -07001795 j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
1796 j.linter.classes = j.implementationJarFile
Spandan Dasba7e5322022-04-22 17:28:25 +00001797 j.linter.minSdkVersion = lintSDKVersion(j.MinSdkVersion(ctx))
Spandan Dasca70fc42023-03-01 23:38:49 +00001798 j.linter.targetSdkVersion = lintSDKVersion(j.TargetSdkVersion(ctx))
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001799 j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx).ApiLevel)
Pedro Loureiro18233a22021-06-08 18:11:21 +00001800 j.linter.compileSdkKind = j.SdkVersion(ctx).Kind
Jaewoong Jung26342642021-03-17 15:56:23 -07001801 j.linter.javaLanguageLevel = flags.javaVersion.String()
1802 j.linter.kotlinLanguageLevel = "1.3"
Cole Faust2b64af82023-12-13 18:22:18 -08001803 j.linter.compile_data = android.PathsForModuleSrc(ctx, j.properties.Compile_data)
Jaewoong Jung26342642021-03-17 15:56:23 -07001804 if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
1805 j.linter.buildModuleReportZip = true
1806 }
1807 j.linter.lint(ctx)
1808 }
1809
Anton Hansson0e73f9e2023-09-20 13:39:57 +00001810 j.collectTransitiveSrcFiles(ctx, srcFiles)
1811
Colin Crossa6182ab2024-08-21 10:47:44 -07001812 ctx.CheckbuildFile(j.implementationJarFile)
1813 ctx.CheckbuildFile(j.headerJarFile)
Jaewoong Jung26342642021-03-17 15:56:23 -07001814
Colin Cross7727c7f2024-07-18 15:36:32 -07001815 android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
Jihoon Kang705e63e2024-03-13 01:21:16 +00001816 HeaderJars: android.PathsIfNonNil(j.headerJarFile),
1817 RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile),
Colin Cross9ffaf282024-08-12 13:50:09 -07001818 TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
1819 TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
Jihoon Kang705e63e2024-03-13 01:21:16 +00001820 ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
1821 ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
1822 ResourceJars: android.PathsIfNonNil(j.resourceJar),
1823 AidlIncludeDirs: j.exportAidlIncludeDirs,
1824 SrcJarArgs: j.srcJarArgs,
1825 SrcJarDeps: j.srcJarDeps,
1826 TransitiveSrcFiles: j.transitiveSrcFiles,
1827 ExportedPlugins: j.exportedPluginJars,
1828 ExportedPluginClasses: j.exportedPluginClasses,
1829 ExportedPluginDisableTurbine: j.exportedDisableTurbine,
1830 JacocoReportClassesFile: j.jacocoReportClassesFile,
1831 StubsLinkType: j.stubsLinkType,
Jihoon Kang3921f0b2024-03-12 23:51:37 +00001832 AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
Jaewoong Jung26342642021-03-17 15:56:23 -07001833 })
1834
1835 // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
1836 j.outputFile = outputFile.WithoutRel()
1837}
1838
Colin Crossa1ff7c62021-09-17 14:11:52 -07001839func (j *Module) useCompose() bool {
1840 return android.InList("androidx.compose.runtime_runtime", j.properties.Static_libs)
1841}
1842
Colin Crosscde55342024-03-27 14:11:51 -07001843func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []*android.DepSet[android.Path]) {
Sam Delmerico95d70942023-08-02 18:00:35 -04001844 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -08001845 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -04001846 depTag := ctx.OtherModuleDependencyTag(m)
1847
1848 if depProguardInfo.UnconditionallyExportedProguardFlags != nil {
1849 transitiveUnconditionalExportedFlags = append(transitiveUnconditionalExportedFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
1850 transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
1851 }
1852
1853 if depTag == staticLibTag && depProguardInfo.ProguardFlagsFiles != nil {
1854 transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.ProguardFlagsFiles)
1855 }
1856 })
1857
Colin Crosscde55342024-03-27 14:11:51 -07001858 return transitiveProguardFlags, transitiveUnconditionalExportedFlags
1859}
1860
1861func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
1862 transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
1863
Sam Delmerico95d70942023-08-02 18:00:35 -04001864 directUnconditionalExportedFlags := android.Paths{}
1865 proguardFlagsForThisModule := android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)
1866 exportUnconditionally := proptools.Bool(j.dexProperties.Optimize.Export_proguard_flags_files)
1867 if exportUnconditionally {
1868 // if we explicitly export, then our unconditional exports are the same as our transitive flags
1869 transitiveUnconditionalExportedFlags = transitiveProguardFlags
1870 directUnconditionalExportedFlags = proguardFlagsForThisModule
1871 }
1872
1873 return ProguardSpecInfo{
1874 Export_proguard_flags_files: exportUnconditionally,
1875 ProguardFlagsFiles: android.NewDepSet[android.Path](
1876 android.POSTORDER,
1877 proguardFlagsForThisModule,
1878 transitiveProguardFlags,
1879 ),
1880 UnconditionallyExportedProguardFlags: android.NewDepSet[android.Path](
1881 android.POSTORDER,
1882 directUnconditionalExportedFlags,
1883 transitiveUnconditionalExportedFlags,
1884 ),
1885 }
1886
1887}
1888
Cole Faust75fffb12021-06-13 15:23:16 -07001889// Returns a copy of the supplied flags, but with all the errorprone-related
1890// fields copied to the regular build's fields.
1891func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags {
1892 flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)
1893
1894 if len(flags.errorProneExtraJavacFlags) > 0 {
1895 if len(flags.javacFlags) > 0 {
1896 flags.javacFlags += " " + flags.errorProneExtraJavacFlags
1897 } else {
1898 flags.javacFlags = flags.errorProneExtraJavacFlags
1899 }
1900 }
1901 return flags
1902}
1903
Jaewoong Jung26342642021-03-17 15:56:23 -07001904func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
Colin Cross7707b242024-07-26 12:02:36 -07001905 srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.Path {
Jaewoong Jung26342642021-03-17 15:56:23 -07001906
1907 kzipName := pathtools.ReplaceExtension(jarName, "kzip")
Vadim Spivak3c496f02023-06-08 06:14:59 +00001908 annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar")
Jaewoong Jung26342642021-03-17 15:56:23 -07001909 if idx >= 0 {
1910 kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
Vadim Spivak3c496f02023-06-08 06:14:59 +00001911 annoSrcJar = android.PathForModuleOut(ctx, "javac", "anno-"+strconv.Itoa(idx)+".srcjar")
Jaewoong Jung26342642021-03-17 15:56:23 -07001912 jarName += strconv.Itoa(idx)
1913 }
1914
Colin Cross7707b242024-07-26 12:02:36 -07001915 classes := android.PathForModuleOut(ctx, "javac", jarName)
Vadim Spivak3c496f02023-06-08 06:14:59 +00001916 TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)
Jaewoong Jung26342642021-03-17 15:56:23 -07001917
Cole Faust9decf832024-06-11 11:45:53 -07001918 if ctx.Config().EmitXrefRules() && ctx.Module() == ctx.PrimaryModule() {
Jaewoong Jung26342642021-03-17 15:56:23 -07001919 extractionFile := android.PathForModuleOut(ctx, kzipName)
1920 emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps)
1921 j.kytheFiles = append(j.kytheFiles, extractionFile)
1922 }
1923
Vadim Spivak3c496f02023-06-08 06:14:59 +00001924 if len(flags.processorPath) > 0 {
1925 j.annoSrcJars = append(j.annoSrcJars, annoSrcJar)
1926 }
1927
Jaewoong Jung26342642021-03-17 15:56:23 -07001928 return classes
1929}
1930
1931// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
1932// since some of these flags may be used internally.
1933func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
1934 for _, flag := range flags {
1935 flag = strings.TrimSpace(flag)
1936
1937 if !strings.HasPrefix(flag, "-") {
1938 ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
1939 } else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
1940 ctx.PropertyErrorf("kotlincflags",
1941 "Bad flag: `%s`, only use internal compiler for consistency.", flag)
1942 } else if inList(flag, config.KotlincIllegalFlags) {
1943 ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
1944 } else if flag == "-include-runtime" {
1945 ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
1946 } else {
1947 args := strings.Split(flag, " ")
1948 if args[0] == "-kotlin-home" {
1949 ctx.PropertyErrorf("kotlincflags",
1950 "Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
1951 }
1952 }
1953 }
1954}
1955
1956func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
1957 deps deps, flags javaBuilderFlags, jarName string,
Colin Crossedec77c2024-07-26 15:25:40 -07001958 extraJars android.Paths) (headerJar android.Path, combinedHeaderJar android.Path) {
Jaewoong Jung26342642021-03-17 15:56:23 -07001959
1960 var jars android.Paths
1961 if len(srcFiles) > 0 || len(srcJars) > 0 {
1962 // Compile java sources into turbine.jar.
1963 turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
1964 TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
Jaewoong Jung26342642021-03-17 15:56:23 -07001965 jars = append(jars, turbineJar)
Colin Cross3d56ed52021-11-18 22:23:12 -08001966 headerJar = turbineJar
Jaewoong Jung26342642021-03-17 15:56:23 -07001967 }
1968
1969 jars = append(jars, extraJars...)
1970
1971 // Combine any static header libraries into classes-header.jar. If there is only
1972 // one input jar this step will be skipped.
1973 jars = append(jars, deps.staticHeaderJars...)
1974
1975 // we cannot skip the combine step for now if there is only one jar
1976 // since we have to strip META-INF/TRANSITIVE dir from turbine.jar
Colin Crossedec77c2024-07-26 15:25:40 -07001977 combinedHeaderJarOutputPath := android.PathForModuleOut(ctx, "turbine-combined", jarName)
1978 TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
Jaewoong Jung26342642021-03-17 15:56:23 -07001979 false, nil, []string{"META-INF/TRANSITIVE"})
Jaewoong Jung26342642021-03-17 15:56:23 -07001980
Colin Crossa6182ab2024-08-21 10:47:44 -07001981 ctx.CheckbuildFile(combinedHeaderJarOutputPath)
1982
Colin Crossedec77c2024-07-26 15:25:40 -07001983 return headerJar, combinedHeaderJarOutputPath
Jaewoong Jung26342642021-03-17 15:56:23 -07001984}
1985
1986func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
Colin Cross7707b242024-07-26 12:02:36 -07001987 classesJar android.Path, jarName string, specs string) android.Path {
Jaewoong Jung26342642021-03-17 15:56:23 -07001988
1989 jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName)
Colin Cross7707b242024-07-26 12:02:36 -07001990 instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName)
Jaewoong Jung26342642021-03-17 15:56:23 -07001991
1992 jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)
1993
1994 j.jacocoReportClassesFile = jacocoReportClassesFile
1995
1996 return instrumentedJar
1997}
1998
Colin Cross9ffaf282024-08-12 13:50:09 -07001999type providesTransitiveHeaderJarsForR8 struct {
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002000 // set of header jars for all transitive libs deps
Colin Cross9ffaf282024-08-12 13:50:09 -07002001 transitiveLibsHeaderJarsForR8 *android.DepSet[android.Path]
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002002 // set of header jars for all transitive static libs deps
Colin Cross9ffaf282024-08-12 13:50:09 -07002003 transitiveStaticLibsHeaderJarsForR8 *android.DepSet[android.Path]
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002004}
2005
Colin Cross9ffaf282024-08-12 13:50:09 -07002006// collectTransitiveHeaderJarsForR8 visits direct dependencies and collects all transitive libs and static_libs
2007// header jars. The semantics of the collected jars are odd (it collects combined jars that contain the static
2008// libs, but also the static libs, and it collects transitive libs dependencies of static_libs), so these
2009// are only used to expand the --lib arguments to R8.
2010func (j *providesTransitiveHeaderJarsForR8) collectTransitiveHeaderJarsForR8(ctx android.ModuleContext) {
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002011 directLibs := android.Paths{}
2012 directStaticLibs := android.Paths{}
Colin Crossc85750b2022-04-21 12:50:51 -07002013 transitiveLibs := []*android.DepSet[android.Path]{}
2014 transitiveStaticLibs := []*android.DepSet[android.Path]{}
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002015 ctx.VisitDirectDeps(func(module android.Module) {
2016 // don't add deps of the prebuilt version of the same library
2017 if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) {
2018 return
2019 }
2020
Colin Cross7727c7f2024-07-18 15:36:32 -07002021 if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
2022 tag := ctx.OtherModuleDependencyTag(module)
2023 _, isUsesLibDep := tag.(usesLibraryDependencyTag)
2024 if tag == libTag || tag == r8LibraryJarTag || isUsesLibDep {
2025 directLibs = append(directLibs, dep.HeaderJars...)
2026 } else if tag == staticLibTag {
2027 directStaticLibs = append(directStaticLibs, dep.HeaderJars...)
2028 } else {
2029 // Don't propagate transitive libs for other kinds of dependencies.
2030 return
2031 }
Jared Dukeefb6d602023-10-27 18:47:10 +00002032
Colin Cross9ffaf282024-08-12 13:50:09 -07002033 if dep.TransitiveLibsHeaderJarsForR8 != nil {
2034 transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJarsForR8)
Colin Cross7727c7f2024-07-18 15:36:32 -07002035 }
Colin Cross9ffaf282024-08-12 13:50:09 -07002036 if dep.TransitiveStaticLibsHeaderJarsForR8 != nil {
2037 transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8)
Colin Cross7727c7f2024-07-18 15:36:32 -07002038 }
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002039 }
2040 })
Colin Cross9ffaf282024-08-12 13:50:09 -07002041 j.transitiveLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
2042 j.transitiveStaticLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directStaticLibs, transitiveStaticLibs)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002043}
2044
Jaewoong Jung26342642021-03-17 15:56:23 -07002045func (j *Module) HeaderJars() android.Paths {
2046 if j.headerJarFile == nil {
2047 return nil
2048 }
2049 return android.Paths{j.headerJarFile}
2050}
2051
2052func (j *Module) ImplementationJars() android.Paths {
2053 if j.implementationJarFile == nil {
2054 return nil
2055 }
2056 return android.Paths{j.implementationJarFile}
2057}
2058
Spandan Das59a4a2b2024-01-09 21:35:56 +00002059func (j *Module) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
Jaewoong Jung26342642021-03-17 15:56:23 -07002060 return j.dexJarFile
2061}
2062
2063func (j *Module) DexJarInstallPath() android.Path {
2064 return j.installFile
2065}
2066
2067func (j *Module) ImplementationAndResourcesJars() android.Paths {
2068 if j.implementationAndResourcesJar == nil {
2069 return nil
2070 }
2071 return android.Paths{j.implementationAndResourcesJar}
2072}
2073
2074func (j *Module) AidlIncludeDirs() android.Paths {
2075 // exportAidlIncludeDirs is type android.Paths already
2076 return j.exportAidlIncludeDirs
2077}
2078
2079func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
2080 return j.classLoaderContexts
2081}
2082
2083// Collect information for opening IDE project files in java/jdeps.go.
Cole Faustb36d31d2024-08-27 16:04:28 -07002084func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
Spandan Dasb4cd5df2024-08-08 21:57:22 +00002085 // jarjar rules will repackage the sources. To prevent misleading results, IdeInfo should contain the
2086 // repackaged jar instead of the input sources.
Jaewoong Jung26342642021-03-17 15:56:23 -07002087 if j.expandJarjarRules != nil {
2088 dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
Spandan Dasb4cd5df2024-08-08 21:57:22 +00002089 dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String())
2090 } else {
2091 dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
2092 dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
2093 dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...)
Jaewoong Jung26342642021-03-17 15:56:23 -07002094 }
Spandan Dasb4cd5df2024-08-08 21:57:22 +00002095 dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
2096 dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
Yikef6282022022-04-13 20:41:01 +08002097 dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...)
2098 dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...)
Jaewoong Jung26342642021-03-17 15:56:23 -07002099}
2100
2101func (j *Module) CompilerDeps() []string {
Spandan Das8aac9932024-07-18 23:14:13 +00002102 return j.compileDepNames
Jaewoong Jung26342642021-03-17 15:56:23 -07002103}
2104
2105func (j *Module) hasCode(ctx android.ModuleContext) bool {
2106 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
2107 return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
2108}
2109
2110// Implements android.ApexModule
2111func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
2112 return j.depIsInSameApex(ctx, dep)
2113}
2114
2115// Implements android.ApexModule
satayev758968a2021-12-06 11:42:40 +00002116func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
Spandan Das7fa982c2023-02-24 18:38:56 +00002117 sdkVersionSpec := j.SdkVersion(ctx)
Spandan Das8c9ae7e2023-03-03 21:20:36 +00002118 minSdkVersion := j.MinSdkVersion(ctx)
2119 if !minSdkVersion.Specified() {
Jaewoong Jung26342642021-03-17 15:56:23 -07002120 return fmt.Errorf("min_sdk_version is not specified")
2121 }
Spandan Das7fa982c2023-02-24 18:38:56 +00002122 // If the module is compiling against core (via sdk_version), skip comparison check.
2123 if sdkVersionSpec.Kind == android.SdkCore {
Jaewoong Jung26342642021-03-17 15:56:23 -07002124 return nil
2125 }
Spandan Das7fa982c2023-02-24 18:38:56 +00002126 if minSdkVersion.GreaterThan(sdkVersion) {
2127 return fmt.Errorf("newer SDK(%v)", minSdkVersion)
Jaewoong Jung26342642021-03-17 15:56:23 -07002128 }
2129 return nil
2130}
2131
2132func (j *Module) Stem() string {
Jihoon Kang1bfb6f22023-07-01 00:13:47 +00002133 if j.stem == "" {
2134 panic("Stem() called before stem property was set")
2135 }
2136 return j.stem
Jaewoong Jung26342642021-03-17 15:56:23 -07002137}
2138
Jaewoong Jung26342642021-03-17 15:56:23 -07002139func (j *Module) JacocoReportClassesFile() android.Path {
2140 return j.jacocoReportClassesFile
2141}
2142
Anton Hansson0e73f9e2023-09-20 13:39:57 +00002143func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
2144 var fromDeps []*android.DepSet[android.Path]
2145 ctx.VisitDirectDeps(func(module android.Module) {
2146 tag := ctx.OtherModuleDependencyTag(module)
2147 if tag == staticLibTag {
Colin Cross7727c7f2024-07-18 15:36:32 -07002148 if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
2149 if depInfo.TransitiveSrcFiles != nil {
2150 fromDeps = append(fromDeps, depInfo.TransitiveSrcFiles)
2151 }
Anton Hansson0e73f9e2023-09-20 13:39:57 +00002152 }
2153 }
2154 })
2155
2156 j.transitiveSrcFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps)
2157}
2158
Jaewoong Jung26342642021-03-17 15:56:23 -07002159func (j *Module) IsInstallable() bool {
2160 return Bool(j.properties.Installable)
2161}
2162
2163type sdkLinkType int
2164
2165const (
2166 // TODO(jiyong) rename these for better readability. Make the allowed
2167 // and disallowed link types explicit
2168 // order is important here. See rank()
2169 javaCore sdkLinkType = iota
2170 javaSdk
2171 javaSystem
2172 javaModule
2173 javaSystemServer
2174 javaPlatform
2175)
2176
2177func (lt sdkLinkType) String() string {
2178 switch lt {
2179 case javaCore:
2180 return "core Java API"
2181 case javaSdk:
2182 return "Android API"
2183 case javaSystem:
2184 return "system API"
2185 case javaModule:
2186 return "module API"
2187 case javaSystemServer:
2188 return "system server API"
2189 case javaPlatform:
2190 return "private API"
2191 default:
2192 panic(fmt.Errorf("unrecognized linktype: %d", lt))
2193 }
2194}
2195
2196// rank determines the total order among sdkLinkType. An SDK link type of rank A can link to
2197// another SDK link type of rank B only when B <= A. For example, a module linking to Android SDK
2198// can't statically depend on modules that use Platform API.
2199func (lt sdkLinkType) rank() int {
2200 return int(lt)
2201}
2202
2203type moduleWithSdkDep interface {
2204 android.Module
Jiyong Park92315372021-04-02 08:45:46 +09002205 getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool)
Jaewoong Jung26342642021-03-17 15:56:23 -07002206}
2207
Jihoon Kangfa3f0782024-08-21 20:42:18 +00002208func sdkLinkTypeFromSdkKind(k android.SdkKind) sdkLinkType {
2209 switch k {
2210 case android.SdkCore:
2211 return javaCore
2212 case android.SdkSystem:
2213 return javaSystem
2214 case android.SdkPublic:
2215 return javaSdk
2216 case android.SdkModule:
2217 return javaModule
2218 case android.SdkSystemServer:
2219 return javaSystemServer
2220 case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest:
2221 return javaPlatform
2222 default:
2223 return javaSdk
2224 }
2225}
2226
Jiyong Park92315372021-04-02 08:45:46 +09002227func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) {
Jaewoong Jung26342642021-03-17 15:56:23 -07002228 switch name {
Jihoon Kang91c83952023-05-30 19:12:28 +00002229 case android.SdkCore.DefaultJavaLibraryName(),
2230 "legacy.core.platform.api.stubs",
2231 "stable.core.platform.api.stubs",
Jaewoong Jung26342642021-03-17 15:56:23 -07002232 "stub-annotations", "private-stub-annotations-jar",
Jihoon Kang91c83952023-05-30 19:12:28 +00002233 "core-lambda-stubs",
Jihoon Kangb5078312023-03-29 23:25:49 +00002234 "core-generated-annotation-stubs":
Jaewoong Jung26342642021-03-17 15:56:23 -07002235 return javaCore, true
Jihoon Kang91c83952023-05-30 19:12:28 +00002236 case android.SdkPublic.DefaultJavaLibraryName():
Jaewoong Jung26342642021-03-17 15:56:23 -07002237 return javaSdk, true
Jihoon Kang91c83952023-05-30 19:12:28 +00002238 case android.SdkSystem.DefaultJavaLibraryName():
Jaewoong Jung26342642021-03-17 15:56:23 -07002239 return javaSystem, true
Jihoon Kang91c83952023-05-30 19:12:28 +00002240 case android.SdkModule.DefaultJavaLibraryName():
Jaewoong Jung26342642021-03-17 15:56:23 -07002241 return javaModule, true
Jihoon Kang91c83952023-05-30 19:12:28 +00002242 case android.SdkSystemServer.DefaultJavaLibraryName():
Jaewoong Jung26342642021-03-17 15:56:23 -07002243 return javaSystemServer, true
Jihoon Kang91c83952023-05-30 19:12:28 +00002244 case android.SdkTest.DefaultJavaLibraryName():
Jaewoong Jung26342642021-03-17 15:56:23 -07002245 return javaSystem, true
2246 }
2247
Jihoon Kangfa3f0782024-08-21 20:42:18 +00002248 if stub, linkType := moduleStubLinkType(m); stub {
Jaewoong Jung26342642021-03-17 15:56:23 -07002249 return linkType, true
2250 }
2251
Jiyong Park92315372021-04-02 08:45:46 +09002252 ver := m.SdkVersion(ctx)
Jiyong Parkf1691d22021-03-29 20:11:58 +09002253 if !ver.Valid() {
2254 panic(fmt.Errorf("sdk_version is invalid. got %q", ver.Raw))
Jaewoong Jung26342642021-03-17 15:56:23 -07002255 }
Jihoon Kangfa3f0782024-08-21 20:42:18 +00002256
2257 return sdkLinkTypeFromSdkKind(ver.Kind), false
Jaewoong Jung26342642021-03-17 15:56:23 -07002258}
2259
2260// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than
2261// this module's. See the comment on rank() for details and an example.
2262func (j *Module) checkSdkLinkType(
2263 ctx android.ModuleContext, dep moduleWithSdkDep, tag dependencyTag) {
2264 if ctx.Host() {
2265 return
2266 }
2267
Jiyong Park92315372021-04-02 08:45:46 +09002268 myLinkType, stubs := j.getSdkLinkType(ctx, ctx.ModuleName())
Jaewoong Jung26342642021-03-17 15:56:23 -07002269 if stubs {
2270 return
2271 }
Jiyong Park92315372021-04-02 08:45:46 +09002272 depLinkType, _ := dep.getSdkLinkType(ctx, ctx.OtherModuleName(dep))
Jaewoong Jung26342642021-03-17 15:56:23 -07002273
2274 if myLinkType.rank() < depLinkType.rank() {
2275 ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
2276 "In order to fix this, consider adjusting sdk_version: OR platform_apis: "+
2277 "property of the source or target module so that target module is built "+
2278 "with the same or smaller API set when compared to the source.",
2279 myLinkType, ctx.OtherModuleName(dep), depLinkType)
2280 }
2281}
2282
2283func (j *Module) collectDeps(ctx android.ModuleContext) deps {
2284 var deps deps
2285
2286 if ctx.Device() {
Jiyong Parkf1691d22021-03-29 20:11:58 +09002287 sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
Jaewoong Jung26342642021-03-17 15:56:23 -07002288 if sdkDep.invalidVersion {
2289 ctx.AddMissingDependencies(sdkDep.bootclasspath)
2290 ctx.AddMissingDependencies(sdkDep.java9Classpath)
2291 } else if sdkDep.useFiles {
2292 // sdkDep.jar is actually equivalent to turbine header.jar.
2293 deps.classpath = append(deps.classpath, sdkDep.jars...)
Colin Cross9bb9bfb2022-03-17 11:12:32 -07002294 deps.dexClasspath = append(deps.dexClasspath, sdkDep.jars...)
Jaewoong Jung26342642021-03-17 15:56:23 -07002295 deps.aidlPreprocess = sdkDep.aidl
Spandan Das6e8bd1c2024-08-09 00:07:03 +00002296 // Add the sdk module dependency to `compileDepNames`.
2297 // This ensures that the dependency is reported in `module_bp_java_deps.json`
2298 // TODO (b/358608607): Move this to decodeSdkDep
2299 sdkSpec := android.SdkContext(j).SdkVersion(ctx)
2300 j.compileDepNames = append(j.compileDepNames, fmt.Sprintf("sdk_%s_%s_android", sdkSpec.Kind.String(), sdkSpec.ApiLevel.String()))
Jaewoong Jung26342642021-03-17 15:56:23 -07002301 } else {
2302 deps.aidlPreprocess = sdkDep.aidl
2303 }
2304 }
2305
Jiyong Park92315372021-04-02 08:45:46 +09002306 sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName())
Jaewoong Jung26342642021-03-17 15:56:23 -07002307
Colin Cross9ffaf282024-08-12 13:50:09 -07002308 j.collectTransitiveHeaderJarsForR8(ctx)
Jaewoong Jung26342642021-03-17 15:56:23 -07002309 ctx.VisitDirectDeps(func(module android.Module) {
2310 otherName := ctx.OtherModuleName(module)
2311 tag := ctx.OtherModuleDependencyTag(module)
2312
2313 if IsJniDepTag(tag) {
2314 // Handled by AndroidApp.collectAppDeps
2315 return
2316 }
2317 if tag == certificateTag {
2318 // Handled by AndroidApp.collectAppDeps
2319 return
2320 }
2321
2322 if dep, ok := module.(SdkLibraryDependency); ok {
2323 switch tag {
Liz Kammeref28a4c2022-09-23 16:50:56 -04002324 case sdkLibTag, libTag:
Colin Cross9bb9bfb2022-03-17 11:12:32 -07002325 depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))
2326 deps.classpath = append(deps.classpath, depHeaderJars...)
2327 deps.dexClasspath = append(deps.dexClasspath, depHeaderJars...)
Jaewoong Jung26342642021-03-17 15:56:23 -07002328 case staticLibTag:
2329 ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
2330 }
Colin Cross313aa542023-12-13 13:47:44 -08002331 } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
2332 if sdkLinkType != javaPlatform {
2333 if syspropDep, ok := android.OtherModuleProvider(ctx, module, SyspropPublicStubInfoProvider); ok {
2334 // dep is a sysprop implementation library, but this module is not linking against
2335 // the platform, so it gets the sysprop public stubs library instead. Replace
2336 // dep with the JavaInfo from the SyspropPublicStubInfoProvider.
2337 dep = syspropDep.JavaInfo
2338 }
Jaewoong Jung26342642021-03-17 15:56:23 -07002339 }
2340 switch tag {
2341 case bootClasspathTag:
2342 deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
Liz Kammeref28a4c2022-09-23 16:50:56 -04002343 case sdkLibTag, libTag, instrumentationForTag:
Sam Delmerico0d1c4a02022-04-26 18:34:55 +00002344 if _, ok := module.(*Plugin); ok {
2345 ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
2346 }
Jaewoong Jung26342642021-03-17 15:56:23 -07002347 deps.classpath = append(deps.classpath, dep.HeaderJars...)
Colin Cross9bb9bfb2022-03-17 11:12:32 -07002348 deps.dexClasspath = append(deps.dexClasspath, dep.HeaderJars...)
Joe Onorato349ae8d2024-02-05 22:46:00 +00002349 if len(dep.RepackagedHeaderJars) == 1 && !slices.Contains(dep.HeaderJars, dep.RepackagedHeaderJars[0]) {
2350 deps.classpath = append(deps.classpath, dep.RepackagedHeaderJars...)
2351 deps.dexClasspath = append(deps.dexClasspath, dep.RepackagedHeaderJars...)
2352 }
Jaewoong Jung26342642021-03-17 15:56:23 -07002353 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
2354 addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
2355 deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
2356 case java9LibTag:
2357 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
2358 case staticLibTag:
Sam Delmerico0d1c4a02022-04-26 18:34:55 +00002359 if _, ok := module.(*Plugin); ok {
2360 ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName)
2361 }
Jaewoong Jung26342642021-03-17 15:56:23 -07002362 deps.classpath = append(deps.classpath, dep.HeaderJars...)
2363 deps.staticJars = append(deps.staticJars, dep.ImplementationJars...)
2364 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...)
2365 deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...)
2366 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
2367 addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
2368 // Turbine doesn't run annotation processors, so any module that uses an
2369 // annotation processor that generates API is incompatible with the turbine
2370 // optimization.
2371 deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
Jihoon Kang705e63e2024-03-13 01:21:16 +00002372 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
Jaewoong Jung26342642021-03-17 15:56:23 -07002373 case pluginTag:
2374 if plugin, ok := module.(*Plugin); ok {
2375 if plugin.pluginProperties.Processor_class != nil {
2376 addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)
2377 } else {
2378 addPlugins(&deps, dep.ImplementationAndResourcesJars)
2379 }
2380 // Turbine doesn't run annotation processors, so any module that uses an
2381 // annotation processor that generates API is incompatible with the turbine
2382 // optimization.
2383 deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
2384 } else {
2385 ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
2386 }
2387 case errorpronePluginTag:
2388 if _, ok := module.(*Plugin); ok {
2389 deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
2390 } else {
2391 ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
2392 }
2393 case exportedPluginTag:
2394 if plugin, ok := module.(*Plugin); ok {
2395 j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
2396 if plugin.pluginProperties.Processor_class != nil {
2397 j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
2398 }
2399 // Turbine doesn't run annotation processors, so any module that uses an
2400 // annotation processor that generates API is incompatible with the turbine
2401 // optimization.
2402 j.exportedDisableTurbine = Bool(plugin.pluginProperties.Generates_api)
2403 } else {
2404 ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
2405 }
Colin Crossa1ff7c62021-09-17 14:11:52 -07002406 case kotlinPluginTag:
2407 deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
Jaewoong Jung26342642021-03-17 15:56:23 -07002408 case syspropPublicStubDepTag:
2409 // This is a sysprop implementation library, forward the JavaInfoProvider from
2410 // the corresponding sysprop public stub library as SyspropPublicStubInfoProvider.
Colin Cross40213022023-12-13 15:19:49 -08002411 android.SetProvider(ctx, SyspropPublicStubInfoProvider, SyspropPublicStubInfo{
Jaewoong Jung26342642021-03-17 15:56:23 -07002412 JavaInfo: dep,
2413 })
2414 }
2415 } else if dep, ok := module.(android.SourceFileProducer); ok {
2416 switch tag {
Liz Kammeref28a4c2022-09-23 16:50:56 -04002417 case sdkLibTag, libTag:
Jaewoong Jung26342642021-03-17 15:56:23 -07002418 checkProducesJars(ctx, dep)
2419 deps.classpath = append(deps.classpath, dep.Srcs()...)
Colin Cross9bb9bfb2022-03-17 11:12:32 -07002420 deps.dexClasspath = append(deps.classpath, dep.Srcs()...)
Jaewoong Jung26342642021-03-17 15:56:23 -07002421 case staticLibTag:
2422 checkProducesJars(ctx, dep)
2423 deps.classpath = append(deps.classpath, dep.Srcs()...)
2424 deps.staticJars = append(deps.staticJars, dep.Srcs()...)
2425 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
2426 }
Jihoon Kang705e63e2024-03-13 01:21:16 +00002427 } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
Jihoon Kang3921f0b2024-03-12 23:51:37 +00002428 switch tag {
2429 case staticLibTag:
2430 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
2431 }
Jaewoong Jung26342642021-03-17 15:56:23 -07002432 } else {
2433 switch tag {
2434 case bootClasspathTag:
2435 // If a system modules dependency has been added to the bootclasspath
2436 // then add its libs to the bootclasspath.
Colin Crossb61c2262024-08-08 14:04:42 -07002437 if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
2438 depHeaderJars := sm.HeaderJars
2439 deps.bootClasspath = append(deps.bootClasspath, depHeaderJars...)
2440 } else {
2441 ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider",
2442 ctx.OtherModuleName(module))
2443 }
Jaewoong Jung26342642021-03-17 15:56:23 -07002444
2445 case systemModulesTag:
2446 if deps.systemModules != nil {
2447 panic("Found two system module dependencies")
2448 }
Colin Crossb61c2262024-08-08 14:04:42 -07002449 if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
2450 deps.systemModules = &systemModules{sm.OutputDir, sm.OutputDirDeps}
2451 } else {
2452 ctx.PropertyErrorf("system modules dependency %q does not provide SystemModulesProvider",
2453 ctx.OtherModuleName(module))
2454 }
Paul Duffin53a70a42022-01-11 14:35:55 +00002455
2456 case instrumentationForTag:
2457 ctx.PropertyErrorf("instrumentation_for", "dependency %q of type %q does not provide JavaInfo so is unsuitable for use with this property", ctx.OtherModuleName(module), ctx.OtherModuleType(module))
Jaewoong Jung26342642021-03-17 15:56:23 -07002458 }
2459 }
2460
Spandan Das8aac9932024-07-18 23:14:13 +00002461 if android.InList(tag, compileDependencyTags) {
2462 // Add the dependency name to compileDepNames so that it can be recorded in module_bp_java_deps.json
2463 j.compileDepNames = append(j.compileDepNames, otherName)
2464 }
2465
Jaewoong Jung26342642021-03-17 15:56:23 -07002466 addCLCFromDep(ctx, module, j.classLoaderContexts)
Jiakai Zhang36937082024-04-15 11:15:50 +00002467 addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary)
Jaewoong Jung26342642021-03-17 15:56:23 -07002468 })
2469
2470 return deps
2471}
2472
Joe Onorato349ae8d2024-02-05 22:46:00 +00002473// Provider for jarjar renaming rules.
2474//
2475// Modules can set their jarjar renaming rules with addJarJarRenameRule, and those renamings will be
2476// passed to all rdeps. The typical way that these renamings will NOT be inherited is when a module
2477// links against stubs -- these are not passed through stubs. The classes will remain unrenamed on
2478// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
2479// be renamed from that module.
2480// TODO: Add another property to suppress the forwarding of
LaMont Jones63683e42024-02-08 14:30:45 -08002481type DependencyUse int
2482
2483const (
2484 RenameUseInvalid DependencyUse = iota
2485 RenameUseInclude
2486 RenameUseExclude
2487)
2488
2489type RenameUseElement struct {
2490 DepName string
2491 RenameUse DependencyUse
2492 Why string // token for determining where in the logic the decision was made.
2493}
2494
Joe Onorato349ae8d2024-02-05 22:46:00 +00002495type JarJarProviderData struct {
2496 // Mapping of class names: original --> renamed. If the value is "", the class will be
2497 // renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
2498 // attribute). Rdeps of that module will inherit the renaming.
LaMont Jones63683e42024-02-08 14:30:45 -08002499 Rename map[string]string
2500 RenameUse []RenameUseElement
Joe Onorato349ae8d2024-02-05 22:46:00 +00002501}
2502
2503func (this JarJarProviderData) GetDebugString() string {
2504 result := ""
Inseob Kim3c0c9d72024-02-28 14:28:59 +09002505 for _, k := range android.SortedKeys(this.Rename) {
2506 v := this.Rename[k]
Joe Onorato349ae8d2024-02-05 22:46:00 +00002507 if strings.Contains(k, "android.companion.virtual.flags.FakeFeatureFlagsImpl") {
2508 result += k + "--&gt;" + v + ";"
2509 }
2510 }
2511 return result
2512}
2513
2514var JarJarProvider = blueprint.NewProvider[JarJarProviderData]()
2515
2516var overridableJarJarPrefix = "com.android.internal.hidden_from_bootclasspath"
2517
2518func init() {
2519 android.SetJarJarPrefixHandler(mergeJarJarPrefixes)
Yu Liu26a716d2024-08-30 23:40:32 +00002520
2521 gob.Register(BaseJarJarProviderData{})
Joe Onorato349ae8d2024-02-05 22:46:00 +00002522}
2523
2524// BaseJarJarProviderData contains information that will propagate across dependencies regardless of
2525// whether they are java modules or not.
2526type BaseJarJarProviderData struct {
2527 JarJarProviderData JarJarProviderData
2528}
2529
2530func (this BaseJarJarProviderData) GetDebugString() string {
2531 return this.JarJarProviderData.GetDebugString()
2532}
2533
2534var BaseJarJarProvider = blueprint.NewProvider[BaseJarJarProviderData]()
2535
2536// mergeJarJarPrefixes is called immediately before module.GenerateAndroidBuildActions is called.
2537// Since there won't be a JarJarProvider, we create the BaseJarJarProvider if any of our deps have
2538// either JarJarProvider or BaseJarJarProvider.
2539func mergeJarJarPrefixes(ctx android.ModuleContext) {
2540 mod := ctx.Module()
2541 // Explicitly avoid propagating into some module types.
2542 switch reflect.TypeOf(mod).String() {
2543 case "*java.Droidstubs":
2544 return
2545 }
2546 jarJarData := collectDirectDepsProviders(ctx)
2547 if jarJarData != nil {
2548 providerData := BaseJarJarProviderData{
2549 JarJarProviderData: *jarJarData,
2550 }
2551 android.SetProvider(ctx, BaseJarJarProvider, providerData)
2552 }
2553
2554}
2555
2556// Add a jarjar renaming rule to this module, to be inherited to all dependent modules.
2557func (module *Module) addJarJarRenameRule(original string, renamed string) {
2558 if module.jarjarRenameRules == nil {
2559 module.jarjarRenameRules = make(map[string]string)
2560 }
2561 module.jarjarRenameRules[original] = renamed
2562}
2563
2564func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
2565 // Gather repackage information from deps
2566 // If the dep jas a JarJarProvider, it is used. Otherwise, any BaseJarJarProvider is used.
LaMont Jones63683e42024-02-08 14:30:45 -08002567
2568 module := ctx.Module()
2569 moduleName := module.Name()
2570
Joe Onorato349ae8d2024-02-05 22:46:00 +00002571 ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
LaMont Jones63683e42024-02-08 14:30:45 -08002572 tag := ctx.OtherModuleDependencyTag(m)
2573 // This logic mirrors that in (*Module).collectDeps above. There are several places
2574 // where we explicitly return RenameUseExclude, even though it is the default, to
2575 // indicate that it has been verified to be the case.
2576 //
2577 // Note well: there are probably cases that are getting to the unconditional return
2578 // and are therefore wrong.
2579 shouldIncludeRenames := func() (DependencyUse, string) {
2580 if moduleName == m.Name() {
2581 return RenameUseInclude, "name" // If we have the same module name, include the renames.
2582 }
2583 if sc, ok := module.(android.SdkContext); ok {
2584 if ctx.Device() {
2585 sdkDep := decodeSdkDep(ctx, sc)
2586 if !sdkDep.invalidVersion && sdkDep.useFiles {
2587 return RenameUseExclude, "useFiles"
Joe Onorato349ae8d2024-02-05 22:46:00 +00002588 }
2589 }
LaMont Jones63683e42024-02-08 14:30:45 -08002590 }
2591 if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
2592 return RenameUseExclude, "tags"
2593 }
2594 if _, ok := m.(SdkLibraryDependency); ok {
2595 switch tag {
2596 case sdkLibTag, libTag:
2597 return RenameUseExclude, "sdklibdep" // matches collectDeps()
2598 }
2599 return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
2600 } else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
2601 switch ji.StubsLinkType {
2602 case Stubs:
2603 return RenameUseExclude, "info"
2604 case Implementation:
2605 return RenameUseInclude, "info"
2606 default:
LaMont Jones09721862024-06-11 10:30:50 -07002607 //fmt.Printf("collectDirectDepsProviders: %v -> %v StubsLinkType unknown\n", module, m)
LaMont Jones63683e42024-02-08 14:30:45 -08002608 // Fall through to the heuristic logic.
2609 }
2610 switch reflect.TypeOf(m).String() {
2611 case "*java.GeneratedJavaLibraryModule":
2612 // Probably a java_aconfig_library module.
2613 // TODO: make this check better.
2614 return RenameUseInclude, "reflect"
2615 }
2616 switch tag {
2617 case bootClasspathTag:
2618 return RenameUseExclude, "tagswitch"
2619 case sdkLibTag, libTag, instrumentationForTag:
2620 return RenameUseInclude, "tagswitch"
2621 case java9LibTag:
2622 return RenameUseExclude, "tagswitch"
2623 case staticLibTag:
2624 return RenameUseInclude, "tagswitch"
2625 case pluginTag:
2626 return RenameUseInclude, "tagswitch"
2627 case errorpronePluginTag:
2628 return RenameUseInclude, "tagswitch"
2629 case exportedPluginTag:
2630 return RenameUseInclude, "tagswitch"
LaMont Jones63683e42024-02-08 14:30:45 -08002631 case kotlinPluginTag:
2632 return RenameUseInclude, "tagswitch"
2633 default:
2634 return RenameUseExclude, "tagswitch"
2635 }
2636 } else if _, ok := m.(android.SourceFileProducer); ok {
2637 switch tag {
2638 case sdkLibTag, libTag, staticLibTag:
2639 return RenameUseInclude, "srcfile"
2640 default:
2641 return RenameUseExclude, "srcfile"
2642 }
Yu Liu67a28422024-03-05 00:36:31 +00002643 } else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
Jihoon Kang03d014f2024-02-16 22:22:18 +00002644 return RenameUseInclude, "aconfig_declarations_group"
LaMont Jones63683e42024-02-08 14:30:45 -08002645 } else {
2646 switch tag {
2647 case bootClasspathTag:
2648 return RenameUseExclude, "else"
2649 case systemModulesTag:
2650 return RenameUseInclude, "else"
2651 }
2652 }
2653 // If we got here, choose the safer option, which may lead to a build failure, rather
2654 // than runtime failures on the device.
2655 return RenameUseExclude, "end"
2656 }
2657
2658 if result == nil {
2659 result = &JarJarProviderData{
2660 Rename: make(map[string]string),
2661 RenameUse: make([]RenameUseElement, 0),
2662 }
2663 }
2664 how, why := shouldIncludeRenames()
2665 result.RenameUse = append(result.RenameUse, RenameUseElement{DepName: m.Name(), RenameUse: how, Why: why})
2666 if how != RenameUseInclude {
2667 // Nothing to merge.
2668 return
2669 }
2670
2671 merge := func(theirs *JarJarProviderData) {
2672 for orig, renamed := range theirs.Rename {
Joe Onorato349ae8d2024-02-05 22:46:00 +00002673 if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
2674 result.Rename[orig] = renamed
2675 } else if preexisting != "" && renamed != "" && preexisting != renamed {
2676 if strings.HasPrefix(preexisting, overridableJarJarPrefix) {
2677 result.Rename[orig] = renamed
2678 } else if !strings.HasPrefix(renamed, overridableJarJarPrefix) {
2679 ctx.ModuleErrorf("1. Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting, ctx.ModuleName(), m.Name())
2680 continue
2681 }
2682 }
2683 }
2684 }
2685 if theirs, ok := android.OtherModuleProvider(ctx, m, JarJarProvider); ok {
2686 merge(&theirs)
2687 } else if theirs, ok := android.OtherModuleProvider(ctx, m, BaseJarJarProvider); ok {
2688 // TODO: if every java.Module should have a JarJarProvider, and we find only the
2689 // BaseJarJarProvider, then there is a bug. Consider seeing if m can be cast
2690 // to java.Module.
2691 merge(&theirs.JarJarProviderData)
2692 }
2693 })
2694 return
2695}
2696
2697func (this Module) GetDebugString() string {
2698 return "sdk_version=" + proptools.String(this.deviceProperties.Sdk_version)
2699}
2700
2701// Merge the jarjar rules we inherit from our dependencies, any that have been added directly to
2702// us, and if it's been set, apply the jarjar_prefix property to rename them.
2703func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData {
2704 // Gather repackage information from deps
2705 result := collectDirectDepsProviders(ctx)
2706
Joe Onoratoa5d17172024-07-20 17:39:56 -07002707 add := func(orig string, renamed string) {
Joe Onorato349ae8d2024-02-05 22:46:00 +00002708 if result == nil {
2709 result = &JarJarProviderData{
2710 Rename: make(map[string]string),
2711 }
2712 }
2713 if renamed != "" {
2714 if preexisting, exists := (*result).Rename[orig]; exists && preexisting != renamed {
2715 ctx.ModuleErrorf("Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting)
Joe Onoratoa5d17172024-07-20 17:39:56 -07002716 return
Joe Onorato349ae8d2024-02-05 22:46:00 +00002717 }
2718 }
2719 (*result).Rename[orig] = renamed
2720 }
2721
Joe Onoratoa5d17172024-07-20 17:39:56 -07002722 // Update that with entries we've stored for ourself
2723 for orig, renamed := range module.jarjarRenameRules {
2724 add(orig, renamed)
2725 }
2726
2727 // Update that with entries given in the jarjar_rename property.
2728 for _, orig := range module.properties.Jarjar_rename {
2729 add(orig, "")
2730 }
2731
Joe Onorato349ae8d2024-02-05 22:46:00 +00002732 // If there are no renamings, then jarjar_prefix does nothing, so skip the extra work.
2733 if result == nil {
2734 return nil
2735 }
2736
2737 // If they've given us a jarjar_prefix property, then we will use that to rename any classes
2738 // that have not yet been renamed.
2739 prefix := proptools.String(module.properties.Jarjar_prefix)
2740 if prefix != "" {
2741 if prefix[0] == '.' {
2742 ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not start with '.'")
2743 return nil
2744 }
2745 if prefix[len(prefix)-1] == '.' {
2746 ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not end with '.'")
2747 return nil
2748 }
2749
2750 var updated map[string]string
2751 for orig, renamed := range (*result).Rename {
2752 if renamed == "" {
2753 if updated == nil {
2754 updated = make(map[string]string)
2755 }
2756 updated[orig] = prefix + "." + orig
2757 }
2758 }
2759 for orig, renamed := range updated {
2760 (*result).Rename[orig] = renamed
2761 }
2762 }
2763
2764 return result
2765}
2766
2767// Get the jarjar rule text for a given provider for the fully resolved rules. Classes that map
2768// to "" won't be in this list because they shouldn't be renamed yet.
2769func getJarJarRuleText(provider *JarJarProviderData) string {
2770 result := ""
Inseob Kim3c0c9d72024-02-28 14:28:59 +09002771 for _, orig := range android.SortedKeys(provider.Rename) {
2772 renamed := provider.Rename[orig]
Joe Onorato349ae8d2024-02-05 22:46:00 +00002773 if renamed != "" {
2774 result += "rule " + orig + " " + renamed + "\n"
2775 }
2776 }
2777 return result
2778}
2779
Zi Wangddb2ee52024-04-02 16:44:02 +00002780// Repackage the flags if the jarjar rule txt for the flags is generated
Colin Cross7707b242024-07-26 12:02:36 -07002781func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) android.Path {
Zi Wangddb2ee52024-04-02 16:44:02 +00002782 if j.repackageJarjarRules == nil {
2783 return infile
2784 }
Colin Crossedec77c2024-07-26 15:25:40 -07002785 repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName)
Zi Wangddb2ee52024-04-02 16:44:02 +00002786 TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
2787 return repackagedJarjarFile
2788}
2789
Colin Crossedec77c2024-07-26 15:25:40 -07002790func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) android.Path {
2791 if j.expandJarjarRules == nil {
2792 return infile
2793 }
2794 jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName)
2795 TransformJarJar(ctx, jarjarFile, infile, j.expandJarjarRules)
2796 return jarjarFile
2797
2798}
2799
Jaewoong Jung26342642021-03-17 15:56:23 -07002800func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
2801 deps.processorPath = append(deps.processorPath, pluginJars...)
2802 deps.processorClasses = append(deps.processorClasses, pluginClasses...)
2803}
2804
2805// TODO(b/132357300) Generalize SdkLibrarComponentDependency to non-SDK libraries and merge with
2806// this interface.
2807type ProvidesUsesLib interface {
2808 ProvidesUsesLib() *string
2809}
2810
2811func (j *Module) ProvidesUsesLib() *string {
2812 return j.usesLibraryProperties.Provides_uses_lib
2813}
satayev1c564cc2021-05-25 19:50:30 +01002814
2815type ModuleWithStem interface {
2816 Stem() string
2817}
2818
2819var _ ModuleWithStem = (*Module)(nil)
Jiakai Zhangf98da192024-04-15 11:15:41 +00002820
2821type ModuleWithUsesLibrary interface {
2822 UsesLibrary() *usesLibrary
2823}
2824
2825func (j *Module) UsesLibrary() *usesLibrary {
2826 return &j.usesLibrary
2827}
2828
2829var _ ModuleWithUsesLibrary = (*Module)(nil)