2015-03-31 02:20:39 +02:00
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package java
// This file contains the module types for compiling Java for Android, and converts the properties
2017-06-23 01:51:17 +02:00
// into the flags and filenames necessary to pass to the Module. The final creation of the rules
2015-03-31 02:20:39 +02:00
// is handled in builder.go
import (
2018-03-26 23:42:44 +02:00
"fmt"
2017-09-19 02:41:52 +02:00
"path/filepath"
2017-08-02 20:05:49 +02:00
"strconv"
2015-03-31 02:20:39 +02:00
"strings"
"github.com/google/blueprint"
2019-09-06 01:44:18 +02:00
"github.com/google/blueprint/pathtools"
2017-08-30 01:02:06 +02:00
"github.com/google/blueprint/proptools"
2015-03-31 02:20:39 +02:00
2016-05-19 00:37:25 +02:00
"android/soong/android"
2017-06-23 02:20:19 +02:00
"android/soong/java/config"
2018-08-08 01:49:25 +02:00
"android/soong/tradefed"
2015-03-31 02:20:39 +02:00
)
2015-06-17 23:20:06 +02:00
func init ( ) {
2019-12-18 20:51:55 +01:00
RegisterJavaBuildComponents ( android . InitRegistrationContext )
2019-12-13 12:22:16 +01:00
// Register sdk member types.
2020-01-13 22:03:22 +01:00
android . RegisterSdkMemberType ( javaHeaderLibsSdkMemberType )
2019-12-13 12:22:16 +01:00
android . RegisterSdkMemberType ( & implLibrarySdkMemberType {
librarySdkMemberType {
android . SdkMemberTypeBase {
PropertyName : "java_libs" ,
} ,
} ,
} )
2019-12-03 19:06:47 +01:00
android . RegisterSdkMemberType ( & testSdkMemberType {
SdkMemberTypeBase : android . SdkMemberTypeBase {
PropertyName : "java_tests" ,
} ,
} )
2015-06-17 23:20:06 +02:00
}
2019-12-18 20:51:55 +01:00
func RegisterJavaBuildComponents ( ctx android . RegistrationContext ) {
ctx . RegisterModuleType ( "java_defaults" , DefaultsFactory )
ctx . RegisterModuleType ( "java_library" , LibraryFactory )
ctx . RegisterModuleType ( "java_library_static" , LibraryStaticFactory )
ctx . RegisterModuleType ( "java_library_host" , LibraryHostFactory )
ctx . RegisterModuleType ( "java_binary" , BinaryFactory )
ctx . RegisterModuleType ( "java_binary_host" , BinaryHostFactory )
ctx . RegisterModuleType ( "java_test" , TestFactory )
ctx . RegisterModuleType ( "java_test_helper_library" , TestHelperLibraryFactory )
ctx . RegisterModuleType ( "java_test_host" , TestHostFactory )
2019-12-03 19:06:47 +01:00
ctx . RegisterModuleType ( "java_test_import" , JavaTestImportFactory )
2019-12-18 20:51:55 +01:00
ctx . RegisterModuleType ( "java_import" , ImportFactory )
ctx . RegisterModuleType ( "java_import_host" , ImportFactoryHost )
ctx . RegisterModuleType ( "java_device_for_host" , DeviceForHostFactory )
ctx . RegisterModuleType ( "java_host_for_device" , HostForDeviceFactory )
ctx . RegisterModuleType ( "dex_import" , DexImportFactory )
2020-01-31 18:10:36 +01:00
ctx . FinalDepsMutators ( func ( ctx android . RegisterMutatorsContext ) {
ctx . BottomUp ( "dexpreopt_tool_deps" , dexpreoptToolDepsMutator ) . Parallel ( )
} )
2020-01-11 01:37:30 +01:00
2019-12-18 20:51:55 +01:00
ctx . RegisterSingletonType ( "logtags" , LogtagsSingleton )
ctx . RegisterSingletonType ( "kythe_java_extract" , kytheExtractJavaFactory )
}
2019-10-29 07:44:45 +01:00
func ( j * Module ) checkSdkVersion ( ctx android . ModuleContext ) {
if j . SocSpecific ( ) || j . DeviceSpecific ( ) ||
( j . ProductSpecific ( ) && ctx . Config ( ) . EnforceProductPartitionInterface ( ) ) {
if sc , ok := ctx . Module ( ) . ( sdkContext ) ; ok {
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
if ! sc . sdkVersion ( ) . specified ( ) {
2019-10-29 07:44:45 +01:00
ctx . PropertyErrorf ( "sdk_version" ,
"sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set)." )
}
}
}
}
2019-07-11 08:54:27 +02:00
func ( j * Module ) checkPlatformAPI ( ctx android . ModuleContext ) {
if sc , ok := ctx . Module ( ) . ( sdkContext ) ; ok {
usePlatformAPI := proptools . Bool ( j . deviceProperties . Platform_apis )
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
sdkVersionSpecified := sc . sdkVersion ( ) . specified ( )
if usePlatformAPI && sdkVersionSpecified {
ctx . PropertyErrorf ( "platform_apis" , "platform_apis must be false when sdk_version is not empty." )
} else if ! usePlatformAPI && ! sdkVersionSpecified {
ctx . PropertyErrorf ( "platform_apis" , "platform_apis must be true when sdk_version is empty." )
2019-07-11 08:54:27 +02:00
}
}
}
2015-03-31 02:20:39 +02:00
// TODO:
// Autogenerated files:
// Renderscript
// Post-jar passes:
// Proguard
// Rmtypedefs
// DroidDoc
// Findbugs
2017-07-07 23:35:50 +02:00
type CompilerProperties struct {
2015-05-11 22:39:40 +02:00
// list of source files used to compile the Java module. May be .java, .logtags, .proto,
// or .aidl files.
2019-03-05 07:35:41 +01:00
Srcs [ ] string ` android:"path,arch_variant" `
2015-07-01 03:15:24 +02:00
// list of source files that should not be used to build the Java module.
// This is most useful in the arch/multilib variants to remove non-common files
2019-03-05 07:35:41 +01:00
Exclude_srcs [ ] string ` android:"path,arch_variant" `
2015-03-31 02:20:39 +02:00
2015-05-11 22:39:40 +02:00
// list of directories containing Java resources
2017-09-28 02:33:10 +02:00
Java_resource_dirs [ ] string ` android:"arch_variant" `
2015-03-31 02:20:39 +02:00
2017-09-28 02:33:10 +02:00
// list of directories that should be excluded from java_resource_dirs
Exclude_java_resource_dirs [ ] string ` android:"arch_variant" `
2015-07-01 03:15:24 +02:00
2017-09-28 02:42:05 +02:00
// list of files to use as Java resources
2019-03-05 07:35:41 +01:00
Java_resources [ ] string ` android:"path,arch_variant" `
2017-09-28 02:42:05 +02:00
2018-09-13 20:26:19 +02:00
// list of files that should be excluded from java_resources and java_resource_dirs
2019-03-05 07:35:41 +01:00
Exclude_java_resources [ ] string ` android:"path,arch_variant" `
2017-09-28 02:42:05 +02:00
2015-05-11 22:39:40 +02:00
// list of module-specific flags that will be used for javac compiles
Javacflags [ ] string ` android:"arch_variant" `
2015-03-31 02:20:39 +02:00
2018-08-21 17:10:29 +02:00
// list of module-specific flags that will be used for kotlinc compiles
Kotlincflags [ ] string ` android:"arch_variant" `
2015-05-11 22:39:40 +02:00
// list of of java libraries that will be in the classpath
2017-07-19 20:22:16 +02:00
Libs [ ] string ` android:"arch_variant" `
2015-03-31 02:20:39 +02:00
2015-05-11 22:39:40 +02:00
// list of java libraries that will be compiled into the resulting jar
2017-07-19 20:22:16 +02:00
Static_libs [ ] string ` android:"arch_variant" `
2015-03-31 02:20:39 +02:00
2015-05-11 22:39:40 +02:00
// manifest file to be included in resulting jar
2019-03-05 07:35:41 +01:00
Manifest * string ` android:"path" `
2015-03-31 02:20:39 +02:00
2017-06-23 02:01:52 +02:00
// if not blank, run jarjar using the specified rules file
2019-03-05 07:35:41 +01:00
Jarjar_rules * string ` android:"path,arch_variant" `
2017-08-08 22:17:59 +02:00
// If not blank, set the java version passed to javac as -source and -target
Java_version * string
2017-09-01 01:45:16 +02:00
2018-06-27 02:59:05 +02:00
// If set to true, allow this module to be dexed and installed on devices. Has no
// effect on host modules, which are always considered installable.
2017-09-01 01:45:16 +02:00
Installable * bool
2017-09-06 22:41:06 +02:00
2017-09-28 02:42:05 +02:00
// If set to true, include sources used to compile the module in to the final jar
Include_srcs * bool
2019-04-02 11:29:55 +02:00
// If not empty, classes are restricted to the specified packages and their sub-packages.
// This restriction is checked after applying jarjar rules and including static libs.
Permitted_packages [ ] string
2019-01-22 06:37:16 +01:00
// List of modules to use as annotation processors
Plugins [ ] string
2017-09-30 02:58:17 +02:00
2019-11-26 19:08:34 +01:00
// List of modules to export to libraries that directly depend on this library as annotation processors
Exported_plugins [ ] string
2017-11-02 21:28:15 +01:00
// The number of Java source entries each Javac instance can process
Javac_shard_size * int64
2018-02-06 19:34:32 +01:00
// Add host jdk tools.jar to bootclasspath
Use_tools_jar * bool
2017-09-30 02:58:17 +02:00
Openjdk9 struct {
2019-10-17 23:23:50 +02:00
// List of source files that should only be used when passing -source 1.9 or higher
2019-03-05 07:35:41 +01:00
Srcs [ ] string ` android:"path" `
2017-09-30 02:58:17 +02:00
2019-10-17 23:23:50 +02:00
// List of javac flags that should only be used when passing -source 1.9 or higher
2017-09-30 02:58:17 +02:00
Javacflags [ ] string
}
2017-11-22 22:49:43 +01:00
2018-08-16 05:21:55 +02:00
// When compiling language level 9+ .java code in packages that are part of
// a system module, patch_module names the module that your sources and
// dependencies should be patched into. The Android runtime currently
// doesn't implement the JEP 261 module system so this option is only
// supported at compile time. It should only be needed to compile tests in
// packages that exist in libcore and which are inconvenient to move
// elsewhere.
2018-09-19 17:16:19 +02:00
Patch_module * string ` android:"arch_variant" `
2018-08-16 05:21:55 +02:00
2017-11-22 22:49:43 +01:00
Jacoco struct {
// List of classes to include for instrumentation with jacoco to collect coverage
// information at runtime when building with coverage enabled. If unset defaults to all
// classes.
// Supports '*' as the last character of an entry in the list as a wildcard match.
// If preceded by '.' it matches all classes in the package and subpackages, otherwise
// it matches classes in the package that have the class name as a prefix.
Include_filter [ ] string
// List of classes to exclude from instrumentation with jacoco to collect coverage
// information at runtime when building with coverage enabled. Overrides classes selected
// by the include_filter property.
// Supports '*' as the last character of an entry in the list as a wildcard match.
// If preceded by '.' it matches all classes in the package and subpackages, otherwise
// it matches classes in the package that have the class name as a prefix.
Exclude_filter [ ] string
}
2018-01-23 06:27:21 +01:00
Errorprone struct {
// List of javac flags that should only be used when running errorprone.
Javacflags [ ] string
}
2017-12-15 00:22:43 +01:00
Proto struct {
// List of extra options that will be passed to the proto generator.
Output_params [ ] string
}
2017-11-22 22:49:43 +01:00
Instrument bool ` blueprint:"mutated" `
2019-02-21 22:27:37 +01:00
// List of files to include in the META-INF/services folder of the resulting jar.
2019-03-05 07:35:41 +01:00
Services [ ] string ` android:"path,arch_variant" `
2017-06-23 02:01:52 +02:00
}
2017-07-07 23:35:50 +02:00
type CompilerDeviceProperties struct {
2017-06-23 02:01:52 +02:00
// list of module-specific flags that will be used for dex compiles
Dxflags [ ] string ` android:"arch_variant" `
2019-07-11 08:54:27 +02:00
// if not blank, set to the version of the sdk to compile against.
// Defaults to compiling against the current platform.
2017-11-09 06:20:04 +01:00
Sdk_version * string
2015-03-31 02:20:39 +02:00
2018-06-26 00:48:06 +02:00
// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
// Defaults to sdk_version if not set.
Min_sdk_version * string
2018-10-31 23:28:47 +01:00
// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
// Defaults to sdk_version if not set.
Target_sdk_version * string
2019-08-19 07:09:52 +02:00
// Whether to compile against the platform APIs instead of an SDK.
// If true, then sdk_version must be empty. The value of this field
// is ignored when module's type isn't android_app.
2018-05-22 20:12:33 +02:00
Platform_apis * bool
2017-11-14 22:12:14 +01:00
Aidl struct {
// Top level directories to pass to aidl tool
Include_dirs [ ] string
2015-04-08 22:03:43 +02:00
2017-11-14 22:12:14 +01:00
// Directories rooted at the Android.bp file to pass to aidl tool
Local_include_dirs [ ] string
// directories that should be added as include directories for any aidl sources of modules
// that depend on this module, as well as to aidl for this module.
Export_include_dirs [ ] string
2018-03-09 09:29:59 +01:00
// whether to generate traces (for systrace) for this interface
Generate_traces * bool
2018-07-17 00:37:03 +02:00
// whether to generate Binder#GetTransaction name method.
Generate_get_transaction_name * bool
2017-11-14 22:12:14 +01:00
}
2017-10-09 23:59:32 +02:00
// If true, export a copy of the module as a -hostdex module for host testing.
Hostdex * bool
2017-09-30 02:58:17 +02:00
2019-04-24 22:41:45 +02:00
Target struct {
Hostdex struct {
// Additional required dependencies to add to -hostdex modules.
Required [ ] string
}
}
2018-06-27 11:27:45 +02:00
// If set to true, compile dex regardless of installable. Defaults to false.
Compile_dex * bool
2017-12-28 21:23:20 +01:00
Optimize struct {
2018-05-22 20:11:52 +02:00
// If false, disable all optimization. Defaults to true for android_app and android_test
// modules, false for java_library and java_test modules.
2017-12-28 21:23:20 +01:00
Enabled * bool
2019-04-17 02:16:58 +02:00
// True if the module containing this has it set by default.
EnabledByDefault bool ` blueprint:"mutated" `
2017-12-28 21:23:20 +01:00
// If true, optimize for size by removing unused code. Defaults to true for apps,
// false for libraries and tests.
Shrink * bool
// If true, optimize bytecode. Defaults to false.
Optimize * bool
// If true, obfuscate bytecode. Defaults to false.
Obfuscate * bool
// If true, do not use the flag files generated by aapt that automatically keep
// classes referenced by the app manifest. Defaults to false.
No_aapt_flags * bool
// Flags to pass to proguard.
Proguard_flags [ ] string
// Specifies the locations of files containing proguard flags.
2019-03-05 07:35:41 +01:00
Proguard_flags_files [ ] string ` android:"path" `
2017-12-28 21:23:20 +01:00
}
2019-10-11 14:50:28 +02:00
// When targeting 1.9 and above, override the modules to use with --system,
// otherwise provides defaults libraries to add to the bootclasspath.
2017-09-30 02:58:17 +02:00
System_modules * string
2018-10-05 23:20:06 +02:00
2019-10-21 07:53:15 +02:00
// set the name of the output
Stem * string
2018-10-05 23:20:06 +02:00
UncompressDex bool ` blueprint:"mutated" `
2018-11-12 19:13:39 +01:00
IsSDKLibrary bool ` blueprint:"mutated" `
2020-03-25 04:32:24 +01:00
// If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
// Defaults to false.
V4_signature * bool
2015-05-11 22:39:40 +02:00
}
2015-04-08 22:03:43 +02:00
2019-04-17 02:16:58 +02:00
func ( me * CompilerDeviceProperties ) EffectiveOptimizeEnabled ( ) bool {
return BoolDefault ( me . Optimize . Enabled , me . Optimize . EnabledByDefault )
}
2017-06-23 01:51:17 +02:00
// Module contains the properties and members used by all java module types
type Module struct {
2016-05-19 00:37:25 +02:00
android . ModuleBase
2017-07-07 23:35:50 +02:00
android . DefaultableModuleBase
2019-07-25 15:02:35 +02:00
android . ApexModuleBase
Introduce module type 'sdk'
This change introduces a new module type named 'sdk'. It is a logical
group of prebuilt modules that together provide a context (e.g. APIs)
in which Mainline modules (such as APEXes) are built.
A prebuilt module (e.g. java_import) can join an sdk by adding it to the
sdk module as shown below:
sdk {
name: "mysdk#20",
java_libs: ["myjavalib_mysdk_20"],
}
java_import {
name: "myjavalib_mysdk_20",
srcs: ["myjavalib-v20.jar"],
sdk_member_name: "myjavalib",
}
sdk {
name: "mysdk#21",
java_libs: ["myjavalib_mysdk_21"],
}
java_import {
name: "myjavalib_mysdk_21",
srcs: ["myjavalib-v21.jar"],
sdk_member_name: "myjavalib",
}
java_library {
name: "myjavalib",
srcs: ["**/*/*.java"],
}
An APEX can specify the SDK(s) that it wants to build with via the new
'uses_sdks' property.
apex {
name: "myapex",
java_libs: ["libX", "libY"],
uses_sdks: ["mysdk#20"],
}
With this, libX, libY, and their transitive dependencies are all built
with the version 20 of myjavalib (the first java_import module) instead
of the other one (which is for version 21) and java_library having the
same name (which is for ToT).
Bug: 138182343
Test: m (sdk_test.go added)
Change-Id: I7e14c524a7d6a0d9f575fb20822080f39818c01e
2019-07-17 13:08:41 +02:00
android . SdkBase
2015-05-11 22:39:40 +02:00
2017-07-07 23:35:50 +02:00
properties CompilerProperties
2017-09-20 21:59:05 +02:00
protoProperties android . ProtoProperties
2017-07-07 23:35:50 +02:00
deviceProperties CompilerDeviceProperties
2015-03-31 02:20:39 +02:00
2018-08-16 05:40:52 +02:00
// jar file containing header classes including static library dependencies, suitable for
// inserting into the bootclasspath/classpath of another compile
2017-10-19 22:06:22 +02:00
headerJarFile android . Path
2018-08-16 05:40:52 +02:00
// jar file containing implementation classes including static library dependencies but no
// resources
2017-10-19 22:06:22 +02:00
implementationJarFile android . Path
2015-03-31 02:20:39 +02:00
2018-08-16 05:40:52 +02:00
// jar file containing only resources including from static library dependencies
resourceJar android . Path
2019-05-04 00:28:19 +02:00
// args and dependencies to package source files into a srcjar
srcJarArgs [ ] string
srcJarDeps android . Paths
2018-08-16 05:40:52 +02:00
// jar file containing implementation classes and resources including static library
// dependencies
implementationAndResourcesJar android . Path
// output file containing classes.dex and resources
2017-09-15 22:00:47 +02:00
dexJarFile android . Path
2018-11-12 19:13:39 +01:00
// output file that contains classes.dex if it should be in the output file
maybeStrippedDexJarFile android . Path
2017-11-22 22:49:43 +01:00
// output file containing uninstrumented classes that will be instrumented by jacoco
jacocoReportClassesFile android . Path
2017-12-28 21:23:20 +01:00
// output file containing mapping of obfuscated names
proguardDictionary android . Path
2018-08-16 05:40:52 +02:00
// output file of the module, which may be a classes jar or a dex jar
2019-03-20 00:03:11 +01:00
outputFile android . Path
extraOutputFiles android . Paths
2015-04-16 23:09:14 +02:00
2016-05-19 00:37:25 +02:00
exportAidlIncludeDirs android . Paths
2015-04-08 22:03:43 +02:00
2016-05-19 00:37:25 +02:00
logtagsSrcs android . Paths
2015-04-11 02:45:20 +02:00
2015-03-31 02:20:39 +02:00
// installed file for binary dependency
2016-05-19 00:37:25 +02:00
installFile android . Path
2017-11-23 01:20:45 +01:00
// list of .java files and srcjars that was passed to javac
compiledJavaSrcs android . Paths
compiledSrcJars android . Paths
2017-12-28 21:23:20 +01:00
// list of extra progurad flag files
extraProguardFlagFiles android . Paths
2018-05-28 11:02:19 +02:00
2018-10-18 00:10:48 +02:00
// manifest file to use instead of properties.Manifest
overrideManifest android . OptionalPath
2019-11-26 19:08:34 +01:00
// list of SDK lib names that this java module is exporting
2018-05-28 11:02:19 +02:00
exportedSdkLibs [ ] string
2018-08-16 00:35:38 +02:00
2019-11-26 19:08:34 +01:00
// list of plugins that this java module is exporting
exportedPluginJars android . Paths
// list of plugins that this java module is exporting
exportedPluginClasses [ ] string
// list of source files, collected from srcFiles with unique java and all kt files,
2019-09-24 09:41:30 +02:00
// will be used by android.IDEInfo struct
2018-08-16 00:35:38 +02:00
expandIDEInfoCompiledSrcs [ ] string
2018-11-12 19:13:39 +01:00
2019-01-18 20:51:25 +01:00
// expanded Jarjar_rules
expandJarjarRules android . Path
2019-04-02 11:29:55 +02:00
// list of additional targets for checkbuild
additionalCheckedModules android . Paths
2019-05-06 23:04:11 +02:00
// Extra files generated by the module type to be added as java resources.
extraResources android . Paths
2019-01-31 23:12:44 +01:00
hiddenAPI
2018-11-12 19:13:39 +01:00
dexpreopter
2018-11-06 01:49:08 +01:00
// list of the xref extraction files
kytheFiles android . Paths
2020-03-27 20:39:48 +01:00
distFile android . Path
2015-03-31 02:20:39 +02:00
}
2019-05-29 23:40:35 +02:00
func ( j * Module ) OutputFiles ( tag string ) ( android . Paths , error ) {
switch tag {
case "" :
return append ( android . Paths { j . outputFile } , j . extraOutputFiles ... ) , nil
2019-05-29 23:40:58 +02:00
case ".jar" :
return android . Paths { j . implementationAndResourcesJar } , nil
2019-07-30 01:47:42 +02:00
case ".proguard_map" :
return android . Paths { j . proguardDictionary } , nil
2019-05-29 23:40:35 +02:00
default :
return nil , fmt . Errorf ( "unsupported module reference tag %q" , tag )
}
2017-12-05 18:28:08 +01:00
}
2019-05-29 23:40:35 +02:00
var _ android . OutputFileProducer = ( * Module ) ( nil )
2017-12-05 18:28:08 +01:00
2017-07-20 00:53:04 +02:00
type Dependency interface {
2017-10-19 22:06:22 +02:00
HeaderJars ( ) android . Paths
ImplementationJars ( ) android . Paths
2018-08-16 05:40:52 +02:00
ResourceJars ( ) android . Paths
ImplementationAndResourcesJars ( ) android . Paths
2019-01-31 23:12:44 +01:00
DexJar ( ) android . Path
2016-05-19 00:37:25 +02:00
AidlIncludeDirs ( ) android . Paths
2018-05-28 11:02:19 +02:00
ExportedSdkLibs ( ) [ ] string
2019-11-26 19:08:34 +01:00
ExportedPlugins ( ) ( android . Paths , [ ] string )
2019-05-04 00:28:19 +02:00
SrcJarArgs ( ) ( [ ] string , android . Paths )
2019-09-18 00:34:09 +02:00
BaseModuleName ( ) string
2020-01-08 05:35:43 +01:00
JacocoReportClassesFile ( ) android . Path
2015-03-31 02:20:39 +02:00
}
2018-04-10 06:07:10 +02:00
type SdkLibraryDependency interface {
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
SdkHeaderJars ( ctx android . BaseModuleContext , sdkVersion sdkSpec ) android . Paths
SdkImplementationJars ( ctx android . BaseModuleContext , sdkVersion sdkSpec ) android . Paths
2018-04-10 06:07:10 +02:00
}
2018-11-06 01:49:08 +01:00
type xref interface {
XrefJavaFiles ( ) android . Paths
}
func ( j * Module ) XrefJavaFiles ( ) android . Paths {
return j . kytheFiles
}
2017-07-07 23:35:50 +02:00
func InitJavaModule ( module android . DefaultableModule , hod android . HostOrDeviceSupported ) {
android . InitAndroidArchModule ( module , hod , android . MultilibCommon )
android . InitDefaultableModule ( module )
}
2017-07-08 00:59:46 +02:00
type dependencyTag struct {
blueprint . BaseDependencyTag
name string
2015-03-31 02:20:39 +02:00
}
2018-10-03 07:03:40 +02:00
type jniDependencyTag struct {
blueprint . BaseDependencyTag
}
2019-11-08 07:53:48 +01:00
func IsJniDepTag ( depTag blueprint . DependencyTag ) bool {
_ , ok := depTag . ( * jniDependencyTag )
return ok
}
2017-07-08 00:59:46 +02:00
var (
2018-10-16 01:18:06 +02:00
staticLibTag = dependencyTag { name : "staticlib" }
libTag = dependencyTag { name : "javalib" }
2019-10-17 23:23:50 +02:00
java9LibTag = dependencyTag { name : "java9lib" }
2019-01-22 06:37:16 +01:00
pluginTag = dependencyTag { name : "plugin" }
2019-11-26 19:08:34 +01:00
exportedPluginTag = dependencyTag { name : "exported-plugin" }
2018-10-16 01:18:06 +02:00
bootClasspathTag = dependencyTag { name : "bootclasspath" }
systemModulesTag = dependencyTag { name : "system modules" }
frameworkResTag = dependencyTag { name : "framework-res" }
frameworkApkTag = dependencyTag { name : "framework-apk" }
kotlinStdlibTag = dependencyTag { name : "kotlin-stdlib" }
2019-01-18 00:42:52 +01:00
kotlinAnnotationsTag = dependencyTag { name : "kotlin-annotations" }
2018-10-16 01:18:06 +02:00
proguardRaiseTag = dependencyTag { name : "proguard-raise" }
certificateTag = dependencyTag { name : "certificate" }
instrumentationForTag = dependencyTag { name : "instrumentation_for" }
2019-05-16 21:28:22 +02:00
usesLibTag = dependencyTag { name : "uses-library" }
2017-07-08 00:59:46 +02:00
)
2015-03-31 02:20:39 +02:00
2020-01-14 10:38:44 +01:00
func IsLibDepTag ( depTag blueprint . DependencyTag ) bool {
return depTag == libTag
}
func IsStaticLibDepTag ( depTag blueprint . DependencyTag ) bool {
return depTag == staticLibTag
}
2017-09-19 02:41:52 +02:00
type sdkDep struct {
2017-10-02 23:22:08 +02:00
useModule , useFiles , useDefaultLibs , invalidVersion bool
2019-10-17 23:23:50 +02:00
// The modules that will be added to the bootclasspath when targeting 1.8 or lower
bootclasspath [ ] string
2019-10-11 14:50:28 +02:00
// The default system modules to use. Will be an empty string if no system
// modules are to be used.
2017-09-30 02:58:17 +02:00
systemModules string
2019-10-17 23:23:50 +02:00
// The modules that will be added ot the classpath when targeting 1.9 or higher
java9Classpath [ ] string
2018-03-28 23:58:31 +02:00
frameworkResModule string
2018-05-29 23:44:55 +02:00
jars android . Paths
2019-04-18 19:56:44 +02:00
aidl android . OptionalPath
2019-06-07 11:44:37 +02:00
noStandardLibs , noFrameworksLibs bool
}
func ( s sdkDep ) hasStandardLibs ( ) bool {
return ! s . noStandardLibs
}
func ( s sdkDep ) hasFrameworkLibs ( ) bool {
return ! s . noStandardLibs && ! s . noFrameworksLibs
2017-09-19 02:41:52 +02:00
}
2018-10-03 07:03:40 +02:00
type jniLib struct {
2020-03-26 22:01:48 +01:00
name string
path android . Path
target android . Target
coverageFile android . OptionalPath
2018-10-03 07:03:40 +02:00
}
2019-06-06 23:33:29 +02:00
func ( j * Module ) shouldInstrument ( ctx android . BaseModuleContext ) bool {
2018-01-04 00:06:47 +01:00
return j . properties . Instrument && ctx . Config ( ) . IsEnvTrue ( "EMMA_INSTRUMENT" )
}
2019-06-06 23:33:29 +02:00
func ( j * Module ) shouldInstrumentStatic ( ctx android . BaseModuleContext ) bool {
2018-01-04 00:06:47 +01:00
return j . shouldInstrument ( ctx ) &&
( ctx . Config ( ) . IsEnvTrue ( "EMMA_INSTRUMENT_STATIC" ) ||
ctx . Config ( ) . UnbundledBuild ( ) )
}
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
func ( j * Module ) sdkVersion ( ) sdkSpec {
return sdkSpecFrom ( String ( j . deviceProperties . Sdk_version ) )
2018-06-26 00:48:06 +02:00
}
2019-10-11 14:50:28 +02:00
func ( j * Module ) systemModules ( ) string {
return proptools . String ( j . deviceProperties . System_modules )
}
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
func ( j * Module ) minSdkVersion ( ) sdkSpec {
2018-06-26 00:48:06 +02:00
if j . deviceProperties . Min_sdk_version != nil {
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
return sdkSpecFrom ( * j . deviceProperties . Min_sdk_version )
2018-06-26 00:48:06 +02:00
}
return j . sdkVersion ( )
}
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
func ( j * Module ) targetSdkVersion ( ) sdkSpec {
2018-10-31 23:28:47 +01:00
if j . deviceProperties . Target_sdk_version != nil {
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
return sdkSpecFrom ( * j . deviceProperties . Target_sdk_version )
2018-10-31 23:28:47 +01:00
}
return j . sdkVersion ( )
}
2019-12-02 16:43:57 +01:00
func ( j * Module ) AvailableFor ( what string ) bool {
if what == android . AvailableToPlatform && Bool ( j . deviceProperties . Hostdex ) {
// Exception: for hostdex: true libraries, the platform variant is created
// even if it's not marked as available to platform. In that case, the platform
// variant is used only for the hostdex and not installed to the device.
return true
}
return j . ApexModuleBase . AvailableFor ( what )
}
2017-07-08 00:59:46 +02:00
func ( j * Module ) deps ( ctx android . BottomUpMutatorContext ) {
2017-09-30 02:58:17 +02:00
if ctx . Device ( ) {
2019-06-07 11:44:37 +02:00
sdkDep := decodeSdkDep ( ctx , sdkContext ( j ) )
2019-10-28 23:10:03 +01:00
if sdkDep . useDefaultLibs {
ctx . AddVariationDependencies ( nil , bootClasspathTag , config . DefaultBootclasspathLibraries ... )
ctx . AddVariationDependencies ( nil , systemModulesTag , config . DefaultSystemModules )
if sdkDep . hasFrameworkLibs ( ) {
ctx . AddVariationDependencies ( nil , libTag , config . DefaultLibraries ... )
2017-07-08 00:59:46 +02:00
}
2019-10-28 23:10:03 +01:00
} else if sdkDep . useModule {
2019-10-17 23:23:50 +02:00
ctx . AddVariationDependencies ( nil , bootClasspathTag , sdkDep . bootclasspath ... )
2019-10-11 14:50:28 +02:00
ctx . AddVariationDependencies ( nil , systemModulesTag , sdkDep . systemModules )
2019-10-17 23:23:50 +02:00
ctx . AddVariationDependencies ( nil , java9LibTag , sdkDep . java9Classpath ... )
2019-10-28 23:10:03 +01:00
if j . deviceProperties . EffectiveOptimizeEnabled ( ) && sdkDep . hasStandardLibs ( ) {
ctx . AddVariationDependencies ( nil , proguardRaiseTag , config . DefaultBootclasspathLibraries ... )
ctx . AddVariationDependencies ( nil , proguardRaiseTag , config . DefaultLibraries ... )
}
2015-03-31 02:20:39 +02:00
}
2019-10-28 23:10:03 +01:00
2018-02-23 20:18:47 +01:00
if ctx . ModuleName ( ) == "android_stubs_current" ||
ctx . ModuleName ( ) == "android_system_stubs_current" ||
2018-08-07 22:41:10 +02:00
ctx . ModuleName ( ) == "android_test_stubs_current" {
2018-08-29 23:10:52 +02:00
ctx . AddVariationDependencies ( nil , frameworkApkTag , "framework-res" )
2018-02-23 20:18:47 +01:00
}
2015-03-31 02:20:39 +02:00
}
2017-09-30 02:58:17 +02:00
2019-12-09 10:15:47 +01:00
syspropPublicStubs := syspropPublicStubs ( ctx . Config ( ) )
// rewriteSyspropLibs validates if a java module can link against platform's sysprop_library,
// and redirects dependency to public stub depending on the link type.
rewriteSyspropLibs := func ( libs [ ] string , prop string ) [ ] string {
// make a copy
ret := android . CopyOf ( libs )
for idx , lib := range libs {
stub , ok := syspropPublicStubs [ lib ]
if ! ok {
continue
}
linkType , _ := j . getLinkType ( ctx . ModuleName ( ) )
2020-01-14 07:36:21 +01:00
// only platform modules can use internal props
if linkType != javaPlatform {
2019-12-09 10:15:47 +01:00
ret [ idx ] = stub
}
}
return ret
}
ctx . AddVariationDependencies ( nil , libTag , rewriteSyspropLibs ( j . properties . Libs , "libs" ) ... )
ctx . AddVariationDependencies ( nil , staticLibTag , rewriteSyspropLibs ( j . properties . Static_libs , "static_libs" ) ... )
2018-10-03 07:03:40 +02:00
2019-10-16 20:03:10 +02:00
ctx . AddFarVariationDependencies ( ctx . Config ( ) . BuildOSCommonTarget . Variations ( ) , pluginTag , j . properties . Plugins ... )
2019-11-26 19:08:34 +01:00
ctx . AddFarVariationDependencies ( ctx . Config ( ) . BuildOSCommonTarget . Variations ( ) , exportedPluginTag , j . properties . Exported_plugins ... )
2019-01-22 06:37:16 +01:00
2019-03-29 03:30:56 +01:00
android . ProtoDeps ( ctx , & j . protoProperties )
2017-09-20 21:59:05 +02:00
if j . hasSrcExt ( ".proto" ) {
protoDeps ( ctx , & j . protoProperties )
}
2017-08-15 22:34:18 +02:00
if j . hasSrcExt ( ".kt" ) {
// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
// Kotlin files
2019-05-13 20:06:25 +02:00
ctx . AddVariationDependencies ( nil , kotlinStdlibTag ,
"kotlin-stdlib" , "kotlin-stdlib-jdk7" , "kotlin-stdlib-jdk8" )
2019-01-24 01:14:02 +01:00
if len ( j . properties . Plugins ) > 0 {
2019-01-18 00:42:52 +01:00
ctx . AddVariationDependencies ( nil , kotlinAnnotationsTag , "kotlin-annotations" )
}
2017-08-15 22:34:18 +02:00
}
2018-01-04 00:06:47 +01:00
2020-01-07 17:37:02 +01:00
// Framework libraries need special handling in static coverage builds: they should not have
// static dependency on jacoco, otherwise there would be multiple conflicting definitions of
// the same jacoco classes coming from different bootclasspath jars.
if inList ( ctx . ModuleName ( ) , config . InstrumentFrameworkModules ) {
if ctx . Config ( ) . IsEnvTrue ( "EMMA_INSTRUMENT_FRAMEWORK" ) {
j . properties . Instrument = true
}
} else if j . shouldInstrumentStatic ( ctx ) {
2018-08-29 23:10:52 +02:00
ctx . AddVariationDependencies ( nil , staticLibTag , "jacocoagent" )
2018-01-04 00:06:47 +01:00
}
2017-09-20 21:59:05 +02:00
}
func hasSrcExt ( srcs [ ] string , ext string ) bool {
for _ , src := range srcs {
if filepath . Ext ( src ) == ext {
return true
}
}
return false
}
func ( j * Module ) hasSrcExt ( ext string ) bool {
return hasSrcExt ( j . properties . Srcs , ext )
2015-03-31 02:20:39 +02:00
}
2017-06-23 01:51:17 +02:00
func ( j * Module ) aidlFlags ( ctx android . ModuleContext , aidlPreprocess android . OptionalPath ,
2019-04-18 19:56:44 +02:00
aidlIncludeDirs android . Paths ) ( string , android . Paths ) {
2015-04-08 22:03:43 +02:00
2017-11-14 22:12:14 +01:00
aidlIncludes := android . PathsForModuleSrc ( ctx , j . deviceProperties . Aidl . Local_include_dirs )
aidlIncludes = append ( aidlIncludes ,
android . PathsForModuleSrc ( ctx , j . deviceProperties . Aidl . Export_include_dirs ) ... )
aidlIncludes = append ( aidlIncludes ,
android . PathsForSource ( ctx , j . deviceProperties . Aidl . Include_dirs ) ... )
2015-04-08 22:03:43 +02:00
2019-04-18 19:56:44 +02:00
var flags [ ] string
var deps android . Paths
2018-07-26 21:55:08 +02:00
2015-09-24 00:26:20 +02:00
if aidlPreprocess . Valid ( ) {
flags = append ( flags , "-p" + aidlPreprocess . String ( ) )
2019-04-18 19:56:44 +02:00
deps = append ( deps , aidlPreprocess . Path ( ) )
} else if len ( aidlIncludeDirs ) > 0 {
2016-05-19 00:37:25 +02:00
flags = append ( flags , android . JoinWithPrefix ( aidlIncludeDirs . Strings ( ) , "-I" ) )
2015-04-08 22:03:43 +02:00
}
2019-04-18 19:56:44 +02:00
if len ( j . exportAidlIncludeDirs ) > 0 {
flags = append ( flags , android . JoinWithPrefix ( j . exportAidlIncludeDirs . Strings ( ) , "-I" ) )
}
if len ( aidlIncludes ) > 0 {
flags = append ( flags , android . JoinWithPrefix ( aidlIncludes . Strings ( ) , "-I" ) )
}
2016-05-19 00:37:25 +02:00
flags = append ( flags , "-I" + android . PathForModuleSrc ( ctx ) . String ( ) )
2018-02-22 20:47:25 +01:00
if src := android . ExistentPathForSource ( ctx , ctx . ModuleDir ( ) , "src" ) ; src . Valid ( ) {
2017-07-13 23:41:17 +02:00
flags = append ( flags , "-I" + src . String ( ) )
}
2015-04-08 22:03:43 +02:00
2018-03-09 09:29:59 +01:00
if Bool ( j . deviceProperties . Aidl . Generate_traces ) {
flags = append ( flags , "-t" )
}
2018-07-17 00:37:03 +02:00
if Bool ( j . deviceProperties . Aidl . Generate_get_transaction_name ) {
flags = append ( flags , "--transaction_names" )
}
2019-04-18 19:56:44 +02:00
return strings . Join ( flags , " " ) , deps
2015-04-08 22:03:43 +02:00
}
2017-09-06 22:41:06 +02:00
type deps struct {
2018-01-11 01:06:12 +01:00
classpath classpath
2019-10-17 23:23:50 +02:00
java9Classpath classpath
2018-01-11 01:06:12 +01:00
bootClasspath classpath
2018-06-20 07:43:34 +02:00
processorPath classpath
2019-01-22 06:37:16 +01:00
processorClasses [ ] string
2017-09-15 22:00:47 +02:00
staticJars android . Paths
2017-10-19 22:06:22 +02:00
staticHeaderJars android . Paths
2018-08-16 05:40:52 +02:00
staticResourceJars android . Paths
2017-09-15 22:00:47 +02:00
aidlIncludeDirs android . Paths
2018-02-23 20:18:47 +01:00
srcs android . Paths
2017-10-17 03:07:29 +02:00
srcJars android . Paths
2019-07-16 22:57:13 +02:00
systemModules * systemModules
2017-09-15 22:00:47 +02:00
aidlPreprocess android . OptionalPath
2017-08-15 22:34:18 +02:00
kotlinStdlib android . Paths
2019-01-18 00:42:52 +01:00
kotlinAnnotations android . Paths
2019-01-22 06:37:16 +01:00
disableTurbine bool
2017-09-06 22:41:06 +02:00
}
2015-03-31 02:20:39 +02:00
2017-12-05 18:28:08 +01:00
func checkProducesJars ( ctx android . ModuleContext , dep android . SourceFileProducer ) {
for _ , f := range dep . Srcs ( ) {
if f . Ext ( ) != ".jar" {
ctx . ModuleErrorf ( "genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency" ,
ctx . OtherModuleName ( dep . ( blueprint . Module ) ) )
}
}
}
2018-03-05 09:44:10 +01:00
type linkType int
const (
2020-01-30 10:00:15 +01:00
// TODO(jiyong) rename these for better readability. Make the allowed
// and disallowed link types explicit
2018-03-05 09:44:10 +01:00
javaCore linkType = iota
javaSdk
javaSystem
2020-01-30 10:00:15 +01:00
javaModule
2020-02-11 20:36:43 +01:00
javaSystemServer
2018-03-05 09:44:10 +01:00
javaPlatform
)
2019-11-01 07:28:00 +01:00
type linkTypeContext interface {
android . Module
getLinkType ( name string ) ( ret linkType , stubs bool )
}
func ( m * Module ) getLinkType ( name string ) ( ret linkType , stubs bool ) {
2018-06-26 00:48:06 +02:00
ver := m . sdkVersion ( )
2018-03-26 23:42:44 +02:00
switch {
2018-10-20 09:33:17 +02:00
case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
name == "stub-annotations" || name == "private-stub-annotations-jar" ||
2019-05-08 16:10:06 +02:00
name == "core-lambda-stubs" || name == "core-generated-annotation-stubs" :
2018-10-20 09:33:17 +02:00
return javaCore , true
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
case ver . kind == sdkCore :
2018-10-20 09:33:17 +02:00
return javaCore , false
case name == "android_system_stubs_current" :
return javaSystem , true
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
case ver . kind == sdkSystem :
2018-10-20 09:33:17 +02:00
return javaSystem , false
case name == "android_test_stubs_current" :
return javaSystem , true
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
case ver . kind == sdkTest :
2018-10-20 09:33:17 +02:00
return javaPlatform , false
case name == "android_stubs_current" :
return javaSdk , true
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
case ver . kind == sdkPublic :
2018-10-20 09:33:17 +02:00
return javaSdk , false
2020-01-30 10:00:15 +01:00
case name == "android_module_lib_stubs_current" :
return javaModule , true
case ver . kind == sdkModule :
return javaModule , false
2020-03-19 16:23:38 +01:00
case name == "android_system_server_stubs_current" :
2020-02-11 20:36:43 +01:00
return javaSystemServer , true
case ver . kind == sdkSystemServer :
return javaSystemServer , false
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
case ver . kind == sdkPrivate || ver . kind == sdkNone || ver . kind == sdkCorePlatform :
2018-10-20 09:33:17 +02:00
return javaPlatform , false
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
case ! ver . valid ( ) :
panic ( fmt . Errorf ( "sdk_version is invalid. got %q" , ver . raw ) )
2018-03-26 23:42:44 +02:00
default :
2018-10-20 09:33:17 +02:00
return javaSdk , false
2018-03-05 09:44:10 +01:00
}
}
2019-11-01 07:28:00 +01:00
func checkLinkType ( ctx android . ModuleContext , from * Module , to linkTypeContext , tag dependencyTag ) {
2018-03-26 23:42:44 +02:00
if ctx . Host ( ) {
return
}
2019-11-01 07:28:00 +01:00
myLinkType , stubs := from . getLinkType ( ctx . ModuleName ( ) )
2018-10-20 09:33:17 +02:00
if stubs {
return
}
2019-11-01 07:28:00 +01:00
otherLinkType , _ := to . getLinkType ( ctx . OtherModuleName ( to ) )
2018-03-05 09:44:10 +01:00
commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source."
switch myLinkType {
case javaCore :
if otherLinkType != javaCore {
ctx . ModuleErrorf ( "compiles against core Java API, but dependency %q is compiling against non-core Java APIs." + commonMessage ,
ctx . OtherModuleName ( to ) )
}
break
case javaSdk :
if otherLinkType != javaCore && otherLinkType != javaSdk {
ctx . ModuleErrorf ( "compiles against Android API, but dependency %q is compiling against non-public Android API." + commonMessage ,
ctx . OtherModuleName ( to ) )
}
break
case javaSystem :
2020-02-11 20:36:43 +01:00
if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer {
2018-03-05 09:44:10 +01:00
ctx . ModuleErrorf ( "compiles against system API, but dependency %q is compiling against private API." + commonMessage ,
2018-01-30 16:20:13 +01:00
ctx . OtherModuleName ( to ) )
}
2018-03-05 09:44:10 +01:00
break
2020-01-30 10:00:15 +01:00
case javaModule :
2020-02-11 20:36:43 +01:00
if otherLinkType == javaPlatform || otherLinkType == javaSystemServer {
2020-01-30 10:00:15 +01:00
ctx . ModuleErrorf ( "compiles against module API, but dependency %q is compiling against private API." + commonMessage ,
ctx . OtherModuleName ( to ) )
}
break
2020-02-11 20:36:43 +01:00
case javaSystemServer :
if otherLinkType == javaPlatform {
ctx . ModuleErrorf ( "compiles against system server API, but dependency %q is compiling against private API." + commonMessage ,
ctx . OtherModuleName ( to ) )
2020-01-30 10:00:15 +01:00
}
break
2018-03-05 09:44:10 +01:00
case javaPlatform :
// no restriction on link-type
break
2018-01-30 16:20:13 +01:00
}
}
2017-09-06 22:41:06 +02:00
func ( j * Module ) collectDeps ( ctx android . ModuleContext ) deps {
var deps deps
2017-09-19 02:41:52 +02:00
2018-03-06 22:11:51 +01:00
if ctx . Device ( ) {
2018-06-26 00:48:06 +02:00
sdkDep := decodeSdkDep ( ctx , sdkContext ( j ) )
2018-03-06 22:11:51 +01:00
if sdkDep . invalidVersion {
2019-10-17 23:23:50 +02:00
ctx . AddMissingDependencies ( sdkDep . bootclasspath )
ctx . AddMissingDependencies ( sdkDep . java9Classpath )
2018-03-06 22:11:51 +01:00
} else if sdkDep . useFiles {
// sdkDep.jar is actually equivalent to turbine header.jar.
2018-05-29 23:44:55 +02:00
deps . classpath = append ( deps . classpath , sdkDep . jars ... )
2019-04-18 19:56:44 +02:00
deps . aidlPreprocess = sdkDep . aidl
} else {
deps . aidlPreprocess = sdkDep . aidl
2018-03-06 22:11:51 +01:00
}
2017-09-19 02:41:52 +02:00
}
2017-10-24 02:59:01 +02:00
ctx . VisitDirectDeps ( func ( module android . Module ) {
2015-03-31 02:20:39 +02:00
otherName := ctx . OtherModuleName ( module )
2017-07-07 23:47:12 +02:00
tag := ctx . OtherModuleDependencyTag ( module )
2018-10-03 07:03:40 +02:00
if _ , ok := tag . ( * jniDependencyTag ) ; ok {
2018-10-05 00:21:03 +02:00
// Handled by AndroidApp.collectAppDeps
return
}
if tag == certificateTag {
// Handled by AndroidApp.collectAppDeps
2018-10-03 07:03:40 +02:00
return
}
2019-11-01 07:28:00 +01:00
switch module . ( type ) {
2019-12-06 16:16:24 +01:00
case * Library , * AndroidLibrary :
2019-11-01 07:28:00 +01:00
if to , ok := module . ( linkTypeContext ) ; ok {
switch tag {
case bootClasspathTag , libTag , staticLibTag :
checkLinkType ( ctx , j , to , tag . ( dependencyTag ) )
}
2018-03-28 23:58:31 +02:00
}
2018-01-30 16:20:13 +01:00
}
2017-12-05 18:28:08 +01:00
switch dep := module . ( type ) {
2019-02-11 23:03:51 +01:00
case SdkLibraryDependency :
switch tag {
case libTag :
deps . classpath = append ( deps . classpath , dep . SdkHeaderJars ( ctx , j . sdkVersion ( ) ) ... )
// names of sdk libs that are directly depended are exported
j . exportedSdkLibs = append ( j . exportedSdkLibs , otherName )
2019-04-17 20:11:46 +02:00
case staticLibTag :
2019-02-11 23:03:51 +01:00
ctx . ModuleErrorf ( "dependency on java_sdk_library %q can only be in libs" , otherName )
}
2017-12-05 18:28:08 +01:00
case Dependency :
switch tag {
case bootClasspathTag :
deps . bootClasspath = append ( deps . bootClasspath , dep . HeaderJars ( ) ... )
2018-10-16 01:18:06 +02:00
case libTag , instrumentationForTag :
2017-12-05 18:28:08 +01:00
deps . classpath = append ( deps . classpath , dep . HeaderJars ( ) ... )
2018-05-28 11:02:19 +02:00
// sdk lib names from dependencies are re-exported
j . exportedSdkLibs = append ( j . exportedSdkLibs , dep . ExportedSdkLibs ( ) ... )
2019-04-18 19:56:44 +02:00
deps . aidlIncludeDirs = append ( deps . aidlIncludeDirs , dep . AidlIncludeDirs ( ) ... )
2019-11-26 19:08:34 +01:00
pluginJars , pluginClasses := dep . ExportedPlugins ( )
addPlugins ( & deps , pluginJars , pluginClasses ... )
2019-10-17 23:23:50 +02:00
case java9LibTag :
deps . java9Classpath = append ( deps . java9Classpath , dep . HeaderJars ( ) ... )
2017-12-05 18:28:08 +01:00
case staticLibTag :
deps . classpath = append ( deps . classpath , dep . HeaderJars ( ) ... )
deps . staticJars = append ( deps . staticJars , dep . ImplementationJars ( ) ... )
deps . staticHeaderJars = append ( deps . staticHeaderJars , dep . HeaderJars ( ) ... )
2018-08-16 05:40:52 +02:00
deps . staticResourceJars = append ( deps . staticResourceJars , dep . ResourceJars ( ) ... )
2018-05-28 11:02:19 +02:00
// sdk lib names from dependencies are re-exported
j . exportedSdkLibs = append ( j . exportedSdkLibs , dep . ExportedSdkLibs ( ) ... )
2019-04-18 19:56:44 +02:00
deps . aidlIncludeDirs = append ( deps . aidlIncludeDirs , dep . AidlIncludeDirs ( ) ... )
2019-11-26 19:08:34 +01:00
pluginJars , pluginClasses := dep . ExportedPlugins ( )
addPlugins ( & deps , pluginJars , pluginClasses ... )
2019-01-22 06:37:16 +01:00
case pluginTag :
if plugin , ok := dep . ( * Plugin ) ; ok {
if plugin . pluginProperties . Processor_class != nil {
2019-11-26 19:08:34 +01:00
addPlugins ( & deps , plugin . ImplementationAndResourcesJars ( ) , * plugin . pluginProperties . Processor_class )
} else {
addPlugins ( & deps , plugin . ImplementationAndResourcesJars ( ) )
2019-01-22 06:37:16 +01:00
}
deps . disableTurbine = deps . disableTurbine || Bool ( plugin . pluginProperties . Generates_api )
} else {
ctx . PropertyErrorf ( "plugins" , "%q is not a java_plugin module" , otherName )
}
2019-11-26 19:08:34 +01:00
case exportedPluginTag :
if plugin , ok := dep . ( * Plugin ) ; ok {
if plugin . pluginProperties . Generates_api != nil && * plugin . pluginProperties . Generates_api {
ctx . PropertyErrorf ( "exported_plugins" , "Cannot export plugins with generates_api = true, found %v" , otherName )
}
j . exportedPluginJars = append ( j . exportedPluginJars , plugin . ImplementationAndResourcesJars ( ) ... )
if plugin . pluginProperties . Processor_class != nil {
j . exportedPluginClasses = append ( j . exportedPluginClasses , * plugin . pluginProperties . Processor_class )
}
} else {
ctx . PropertyErrorf ( "exported_plugins" , "%q is not a java_plugin module" , otherName )
}
2018-02-23 20:18:47 +01:00
case frameworkApkTag :
if ctx . ModuleName ( ) == "android_stubs_current" ||
ctx . ModuleName ( ) == "android_system_stubs_current" ||
2018-08-07 22:41:10 +02:00
ctx . ModuleName ( ) == "android_test_stubs_current" {
2018-02-23 20:18:47 +01:00
// framework stubs.jar need to depend on framework-res.apk, in order to pull the
// resource files out of there for aapt.
//
// Normally the package rule runs aapt, which includes the resource,
// but we're not running that in our package rule so just copy in the
// resource files here.
2018-08-16 05:40:52 +02:00
deps . staticResourceJars = append ( deps . staticResourceJars , dep . ( * AndroidApp ) . exportPackage )
2018-02-23 20:18:47 +01:00
}
2017-12-05 18:28:08 +01:00
case kotlinStdlibTag :
2019-05-13 20:06:25 +02:00
deps . kotlinStdlib = append ( deps . kotlinStdlib , dep . HeaderJars ( ) ... )
2019-01-18 00:42:52 +01:00
case kotlinAnnotationsTag :
deps . kotlinAnnotations = dep . HeaderJars ( )
2017-12-05 18:28:08 +01:00
}
case android . SourceFileProducer :
switch tag {
case libTag :
checkProducesJars ( ctx , dep )
deps . classpath = append ( deps . classpath , dep . Srcs ( ) ... )
case staticLibTag :
checkProducesJars ( ctx , dep )
deps . classpath = append ( deps . classpath , dep . Srcs ( ) ... )
deps . staticJars = append ( deps . staticJars , dep . Srcs ( ) ... )
deps . staticHeaderJars = append ( deps . staticHeaderJars , dep . Srcs ( ) ... )
}
default :
2017-07-07 23:47:12 +02:00
switch tag {
2019-09-20 14:50:52 +02:00
case bootClasspathTag :
// If a system modules dependency has been added to the bootclasspath
// then add its libs to the bootclasspath.
2019-11-19 20:44:10 +01:00
sm := module . ( SystemModulesProvider )
deps . bootClasspath = append ( deps . bootClasspath , sm . HeaderJars ( ) ... )
2019-09-20 14:50:52 +02:00
2017-09-30 02:58:17 +02:00
case systemModulesTag :
if deps . systemModules != nil {
panic ( "Found two system module dependencies" )
}
2019-11-19 20:44:10 +01:00
sm := module . ( SystemModulesProvider )
outputDir , outputDeps := sm . OutputDirAndDeps ( )
deps . systemModules = & systemModules { outputDir , outputDeps }
2017-07-07 23:47:12 +02:00
}
}
2015-03-31 02:20:39 +02:00
} )
2018-05-28 11:02:19 +02:00
j . exportedSdkLibs = android . FirstUniqueStrings ( j . exportedSdkLibs )
2017-09-06 22:41:06 +02:00
return deps
2015-03-31 02:20:39 +02:00
}
2019-11-26 19:08:34 +01:00
func addPlugins ( deps * deps , pluginJars android . Paths , pluginClasses ... string ) {
deps . processorPath = append ( deps . processorPath , pluginJars ... )
deps . processorClasses = append ( deps . processorClasses , pluginClasses ... )
}
2019-10-28 19:37:20 +01:00
func getJavaVersion ( ctx android . ModuleContext , javaVersion string , sdkContext sdkContext ) javaVersion {
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
sdk , err := sdkContext . sdkVersion ( ) . effectiveVersion ( ctx )
2018-06-26 00:48:06 +02:00
if err != nil {
ctx . PropertyErrorf ( "sdk_version" , "%s" , err )
}
2018-04-18 02:38:36 +02:00
if javaVersion != "" {
2019-10-28 19:37:20 +01:00
return normalizeJavaVersion ( ctx , javaVersion )
2018-04-18 02:38:36 +02:00
} else if ctx . Device ( ) && sdk <= 23 {
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_7
2019-10-17 15:52:07 +02:00
} else if ctx . Device ( ) && sdk <= 29 {
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_8
2019-10-17 23:23:50 +02:00
} else if ctx . Device ( ) && ctx . Config ( ) . UnbundledBuildUsePrebuiltSdks ( ) {
// TODO(b/142896162): once we have prebuilt system modules we can use 1.9 for unbundled builds
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_8
2018-04-18 02:38:36 +02:00
} else {
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_9
2018-04-18 02:38:36 +02:00
}
2019-10-28 19:37:20 +01:00
}
type javaVersion int
const (
JAVA_VERSION_UNSUPPORTED = 0
JAVA_VERSION_6 = 6
JAVA_VERSION_7 = 7
JAVA_VERSION_8 = 8
JAVA_VERSION_9 = 9
)
2018-04-18 02:38:36 +02:00
2019-10-28 19:37:20 +01:00
func ( v javaVersion ) String ( ) string {
switch v {
case JAVA_VERSION_6 :
return "1.6"
case JAVA_VERSION_7 :
return "1.7"
case JAVA_VERSION_8 :
return "1.8"
case JAVA_VERSION_9 :
return "1.9"
default :
return "unsupported"
}
2018-04-18 02:38:36 +02:00
}
2019-10-28 19:37:20 +01:00
// Returns true if javac targeting this version uses system modules instead of a bootclasspath.
func ( v javaVersion ) usesJavaModules ( ) bool {
return v >= 9
}
func normalizeJavaVersion ( ctx android . BaseModuleContext , javaVersion string ) javaVersion {
Normalize and validate the java_version property.
There are two parts to this change.
Normalization: If a module specifies 'java_version: "9"', this is now
normalized into 'java_version: "1.9"'. Users might reasonably assume
that "9" should be valid, since javac treats them as synonyms (and, in
fact, the javac documentation lists "9" as a valid value but doesn't
mention "1.9"). However, the soong code that triggers JPMS support
(i.e. setting -system rather than --boot-class-path) looks for the
string "1.9", so prior to this change modules specifying "9" would
fail with a confusing error ('javac: option --boot-class-path not
allowed with target 1.9'). Normalizing "9" to "1.9" fixes this. (The
change normalizes the other supported values, too, for consistency.)
Validation: This change also makes the build fail-fast with a clear
error message for invalid values. In particular, modules specifying
"10" or "11" fail with an explicit message that this is not supported,
in anticipation of the switch to OpenJDK 11. Prior to this change,
modules setting those values would get the confusing
'--boot-class-path not allowed' error described about since JPMS
support would not be triggered. (That could be fixed by changing the
JPMS logic to trigger on "10" and "11", but that would be dangerous
since support in the rest of the system for v54 and v55 class files is
unproven: it is better to fail explicitly.) (This change also makes it
fail-fast for any unrecognized values.)
Test: make java
Test: make targets with java_version set to "1.8", "8", "1.9", and "9", all succeed ("9" fails without this change)
Test: make targets with java_version set to "10" and "11", fail with the explicit "not supported" message
Test: make target with java_version set to "xxx", fails fast with the "unrecognized" message
Bug: 131683177
Change-Id: I2f5eb496c29d7736c68c01401c3f0967aeae99fc
2019-07-12 14:16:17 +02:00
switch javaVersion {
case "1.6" , "6" :
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_6
Normalize and validate the java_version property.
There are two parts to this change.
Normalization: If a module specifies 'java_version: "9"', this is now
normalized into 'java_version: "1.9"'. Users might reasonably assume
that "9" should be valid, since javac treats them as synonyms (and, in
fact, the javac documentation lists "9" as a valid value but doesn't
mention "1.9"). However, the soong code that triggers JPMS support
(i.e. setting -system rather than --boot-class-path) looks for the
string "1.9", so prior to this change modules specifying "9" would
fail with a confusing error ('javac: option --boot-class-path not
allowed with target 1.9'). Normalizing "9" to "1.9" fixes this. (The
change normalizes the other supported values, too, for consistency.)
Validation: This change also makes the build fail-fast with a clear
error message for invalid values. In particular, modules specifying
"10" or "11" fail with an explicit message that this is not supported,
in anticipation of the switch to OpenJDK 11. Prior to this change,
modules setting those values would get the confusing
'--boot-class-path not allowed' error described about since JPMS
support would not be triggered. (That could be fixed by changing the
JPMS logic to trigger on "10" and "11", but that would be dangerous
since support in the rest of the system for v54 and v55 class files is
unproven: it is better to fail explicitly.) (This change also makes it
fail-fast for any unrecognized values.)
Test: make java
Test: make targets with java_version set to "1.8", "8", "1.9", and "9", all succeed ("9" fails without this change)
Test: make targets with java_version set to "10" and "11", fail with the explicit "not supported" message
Test: make target with java_version set to "xxx", fails fast with the "unrecognized" message
Bug: 131683177
Change-Id: I2f5eb496c29d7736c68c01401c3f0967aeae99fc
2019-07-12 14:16:17 +02:00
case "1.7" , "7" :
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_7
Normalize and validate the java_version property.
There are two parts to this change.
Normalization: If a module specifies 'java_version: "9"', this is now
normalized into 'java_version: "1.9"'. Users might reasonably assume
that "9" should be valid, since javac treats them as synonyms (and, in
fact, the javac documentation lists "9" as a valid value but doesn't
mention "1.9"). However, the soong code that triggers JPMS support
(i.e. setting -system rather than --boot-class-path) looks for the
string "1.9", so prior to this change modules specifying "9" would
fail with a confusing error ('javac: option --boot-class-path not
allowed with target 1.9'). Normalizing "9" to "1.9" fixes this. (The
change normalizes the other supported values, too, for consistency.)
Validation: This change also makes the build fail-fast with a clear
error message for invalid values. In particular, modules specifying
"10" or "11" fail with an explicit message that this is not supported,
in anticipation of the switch to OpenJDK 11. Prior to this change,
modules setting those values would get the confusing
'--boot-class-path not allowed' error described about since JPMS
support would not be triggered. (That could be fixed by changing the
JPMS logic to trigger on "10" and "11", but that would be dangerous
since support in the rest of the system for v54 and v55 class files is
unproven: it is better to fail explicitly.) (This change also makes it
fail-fast for any unrecognized values.)
Test: make java
Test: make targets with java_version set to "1.8", "8", "1.9", and "9", all succeed ("9" fails without this change)
Test: make targets with java_version set to "10" and "11", fail with the explicit "not supported" message
Test: make target with java_version set to "xxx", fails fast with the "unrecognized" message
Bug: 131683177
Change-Id: I2f5eb496c29d7736c68c01401c3f0967aeae99fc
2019-07-12 14:16:17 +02:00
case "1.8" , "8" :
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_8
Normalize and validate the java_version property.
There are two parts to this change.
Normalization: If a module specifies 'java_version: "9"', this is now
normalized into 'java_version: "1.9"'. Users might reasonably assume
that "9" should be valid, since javac treats them as synonyms (and, in
fact, the javac documentation lists "9" as a valid value but doesn't
mention "1.9"). However, the soong code that triggers JPMS support
(i.e. setting -system rather than --boot-class-path) looks for the
string "1.9", so prior to this change modules specifying "9" would
fail with a confusing error ('javac: option --boot-class-path not
allowed with target 1.9'). Normalizing "9" to "1.9" fixes this. (The
change normalizes the other supported values, too, for consistency.)
Validation: This change also makes the build fail-fast with a clear
error message for invalid values. In particular, modules specifying
"10" or "11" fail with an explicit message that this is not supported,
in anticipation of the switch to OpenJDK 11. Prior to this change,
modules setting those values would get the confusing
'--boot-class-path not allowed' error described about since JPMS
support would not be triggered. (That could be fixed by changing the
JPMS logic to trigger on "10" and "11", but that would be dangerous
since support in the rest of the system for v54 and v55 class files is
unproven: it is better to fail explicitly.) (This change also makes it
fail-fast for any unrecognized values.)
Test: make java
Test: make targets with java_version set to "1.8", "8", "1.9", and "9", all succeed ("9" fails without this change)
Test: make targets with java_version set to "10" and "11", fail with the explicit "not supported" message
Test: make target with java_version set to "xxx", fails fast with the "unrecognized" message
Bug: 131683177
Change-Id: I2f5eb496c29d7736c68c01401c3f0967aeae99fc
2019-07-12 14:16:17 +02:00
case "1.9" , "9" :
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_9
Normalize and validate the java_version property.
There are two parts to this change.
Normalization: If a module specifies 'java_version: "9"', this is now
normalized into 'java_version: "1.9"'. Users might reasonably assume
that "9" should be valid, since javac treats them as synonyms (and, in
fact, the javac documentation lists "9" as a valid value but doesn't
mention "1.9"). However, the soong code that triggers JPMS support
(i.e. setting -system rather than --boot-class-path) looks for the
string "1.9", so prior to this change modules specifying "9" would
fail with a confusing error ('javac: option --boot-class-path not
allowed with target 1.9'). Normalizing "9" to "1.9" fixes this. (The
change normalizes the other supported values, too, for consistency.)
Validation: This change also makes the build fail-fast with a clear
error message for invalid values. In particular, modules specifying
"10" or "11" fail with an explicit message that this is not supported,
in anticipation of the switch to OpenJDK 11. Prior to this change,
modules setting those values would get the confusing
'--boot-class-path not allowed' error described about since JPMS
support would not be triggered. (That could be fixed by changing the
JPMS logic to trigger on "10" and "11", but that would be dangerous
since support in the rest of the system for v54 and v55 class files is
unproven: it is better to fail explicitly.) (This change also makes it
fail-fast for any unrecognized values.)
Test: make java
Test: make targets with java_version set to "1.8", "8", "1.9", and "9", all succeed ("9" fails without this change)
Test: make targets with java_version set to "10" and "11", fail with the explicit "not supported" message
Test: make target with java_version set to "xxx", fails fast with the "unrecognized" message
Bug: 131683177
Change-Id: I2f5eb496c29d7736c68c01401c3f0967aeae99fc
2019-07-12 14:16:17 +02:00
case "10" , "11" :
ctx . PropertyErrorf ( "java_version" , "Java language levels above 9 are not supported" )
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_UNSUPPORTED
Normalize and validate the java_version property.
There are two parts to this change.
Normalization: If a module specifies 'java_version: "9"', this is now
normalized into 'java_version: "1.9"'. Users might reasonably assume
that "9" should be valid, since javac treats them as synonyms (and, in
fact, the javac documentation lists "9" as a valid value but doesn't
mention "1.9"). However, the soong code that triggers JPMS support
(i.e. setting -system rather than --boot-class-path) looks for the
string "1.9", so prior to this change modules specifying "9" would
fail with a confusing error ('javac: option --boot-class-path not
allowed with target 1.9'). Normalizing "9" to "1.9" fixes this. (The
change normalizes the other supported values, too, for consistency.)
Validation: This change also makes the build fail-fast with a clear
error message for invalid values. In particular, modules specifying
"10" or "11" fail with an explicit message that this is not supported,
in anticipation of the switch to OpenJDK 11. Prior to this change,
modules setting those values would get the confusing
'--boot-class-path not allowed' error described about since JPMS
support would not be triggered. (That could be fixed by changing the
JPMS logic to trigger on "10" and "11", but that would be dangerous
since support in the rest of the system for v54 and v55 class files is
unproven: it is better to fail explicitly.) (This change also makes it
fail-fast for any unrecognized values.)
Test: make java
Test: make targets with java_version set to "1.8", "8", "1.9", and "9", all succeed ("9" fails without this change)
Test: make targets with java_version set to "10" and "11", fail with the explicit "not supported" message
Test: make target with java_version set to "xxx", fails fast with the "unrecognized" message
Bug: 131683177
Change-Id: I2f5eb496c29d7736c68c01401c3f0967aeae99fc
2019-07-12 14:16:17 +02:00
default :
ctx . PropertyErrorf ( "java_version" , "Unrecognized Java language level" )
2019-10-28 19:37:20 +01:00
return JAVA_VERSION_UNSUPPORTED
Normalize and validate the java_version property.
There are two parts to this change.
Normalization: If a module specifies 'java_version: "9"', this is now
normalized into 'java_version: "1.9"'. Users might reasonably assume
that "9" should be valid, since javac treats them as synonyms (and, in
fact, the javac documentation lists "9" as a valid value but doesn't
mention "1.9"). However, the soong code that triggers JPMS support
(i.e. setting -system rather than --boot-class-path) looks for the
string "1.9", so prior to this change modules specifying "9" would
fail with a confusing error ('javac: option --boot-class-path not
allowed with target 1.9'). Normalizing "9" to "1.9" fixes this. (The
change normalizes the other supported values, too, for consistency.)
Validation: This change also makes the build fail-fast with a clear
error message for invalid values. In particular, modules specifying
"10" or "11" fail with an explicit message that this is not supported,
in anticipation of the switch to OpenJDK 11. Prior to this change,
modules setting those values would get the confusing
'--boot-class-path not allowed' error described about since JPMS
support would not be triggered. (That could be fixed by changing the
JPMS logic to trigger on "10" and "11", but that would be dangerous
since support in the rest of the system for v54 and v55 class files is
unproven: it is better to fail explicitly.) (This change also makes it
fail-fast for any unrecognized values.)
Test: make java
Test: make targets with java_version set to "1.8", "8", "1.9", and "9", all succeed ("9" fails without this change)
Test: make targets with java_version set to "10" and "11", fail with the explicit "not supported" message
Test: make target with java_version set to "xxx", fails fast with the "unrecognized" message
Bug: 131683177
Change-Id: I2f5eb496c29d7736c68c01401c3f0967aeae99fc
2019-07-12 14:16:17 +02:00
}
}
2017-10-19 22:06:22 +02:00
func ( j * Module ) collectBuilderFlags ( ctx android . ModuleContext , deps deps ) javaBuilderFlags {
2015-04-08 22:03:43 +02:00
2015-04-13 22:53:40 +02:00
var flags javaBuilderFlags
Enable Java 9 language support through java_version: "1.9" alone.
Some logic in java.go was conditional on TargetOpenJDK9(), which in
turn relies on a global build flag (EXPERIMENTAL_USE_OPENJDK9=true).
This CL changes the logic in collectBuilderFlags() to check for
javaVersion greater or equal "1.9" instead, which is true when either
EXPERIMENTAL_USE_OPENJDK9=true (global) or javaVersion "1.9" (a
per-build target attribute).
Because the value of flags.javaVersion isn't available there,
TargetOpenJDK9()-dependent logic in Module.deps() was changed to
be unconditional; as far as I understand, this means that system
modules deps will be built regardless of whether they're needed
later in the build. This will probably slow down the build
unnecessarily until the first user of these system modules appears
(expected soon), but probably not by much.
There is some TargetOpenJDK9() related logic remaining in droiddoc.go,
but this doesn't seem to break the build of Java 9 language sources
and is probably no longer needed now that metalava is used for
generating the stubs (thanks to Nan!), and those do not contain any
Java 9 language features.
Bug: 112443425
Test: Checked that Java 9 language support works on AOSP after
this CL without a need for EXPERIMENTAL_USE_OPENJDK9=true,
ie. after also patching CL http://r.android.com/646840 ,
"make docs droid cts" completes, the device boots and
Java9LanguageFeaturesTest passes.
Change-Id: I393b97a7b3bb4c1c3d06580c639e94ff6cf916ff
2018-09-11 17:21:05 +02:00
// javaVersion flag.
flags . javaVersion = getJavaVersion ( ctx , String ( j . properties . Java_version ) , sdkContext ( j ) )
2017-10-19 22:06:22 +02:00
// javac flags.
2015-04-13 22:53:40 +02:00
javacFlags := j . properties . Javacflags
2019-10-28 19:37:20 +01:00
if flags . javaVersion . usesJavaModules ( ) {
2017-09-30 02:58:17 +02:00
javacFlags = append ( javacFlags , j . properties . Openjdk9 . Javacflags ... )
2017-10-19 22:06:22 +02:00
}
2017-11-29 09:27:14 +01:00
if ctx . Config ( ) . MinimizeJavaDebugInfo ( ) {
2017-10-31 21:55:34 +01:00
// Override the -g flag passed globally to remove local variable debug info to reduce
// disk and memory usage.
javacFlags = append ( javacFlags , "-g:source,lines" )
}
2019-11-07 01:18:05 +01:00
javacFlags = append ( javacFlags , "-Xlint:-dep-ann" )
2017-08-08 22:17:59 +02:00
2018-06-20 07:47:35 +02:00
if ctx . Config ( ) . RunErrorProne ( ) {
if config . ErrorProneClasspath == nil {
ctx . ModuleErrorf ( "cannot build with Error Prone, missing external/error_prone?" )
}
errorProneFlags := [ ] string {
"-Xplugin:ErrorProne" ,
"${config.ErrorProneChecks}" ,
}
errorProneFlags = append ( errorProneFlags , j . properties . Errorprone . Javacflags ... )
flags . errorProneExtraJavacFlags = "${config.ErrorProneFlags} " +
"'" + strings . Join ( errorProneFlags , " " ) + "'"
flags . errorProneProcessorPath = classpath ( android . PathsForSource ( ctx , config . ErrorProneClasspath ) )
2018-01-23 06:27:21 +01:00
}
2017-10-19 22:06:22 +02:00
// classpath
2018-01-11 01:06:12 +01:00
flags . bootClasspath = append ( flags . bootClasspath , deps . bootClasspath ... )
flags . classpath = append ( flags . classpath , deps . classpath ... )
2019-10-17 23:23:50 +02:00
flags . java9Classpath = append ( flags . java9Classpath , deps . java9Classpath ... )
2018-06-20 07:43:34 +02:00
flags . processorPath = append ( flags . processorPath , deps . processorPath ... )
2018-01-03 03:14:25 +01:00
2019-01-22 06:37:16 +01:00
flags . processor = strings . Join ( deps . processorClasses , "," )
2019-10-28 19:37:20 +01:00
if len ( flags . bootClasspath ) == 0 && ctx . Host ( ) && ! flags . javaVersion . usesJavaModules ( ) &&
decodeSdkDep ( ctx , sdkContext ( j ) ) . hasStandardLibs ( ) {
2018-01-03 03:14:25 +01:00
// Give host-side tools a version of OpenJDK's standard libraries
// close to what they're targeting. As of Dec 2017, AOSP is only
// bundling OpenJDK 8 and 9, so nothing < 8 is available.
//
// When building with OpenJDK 8, the following should have no
// effect since those jars would be available by default.
//
// When building with OpenJDK 9 but targeting a version < 1.8,
// putting them on the bootclasspath means that:
// a) code can't (accidentally) refer to OpenJDK 9 specific APIs
// b) references to existing APIs are not reinterpreted in an
// OpenJDK 9-specific way, eg. calls to subclasses of
// java.nio.Buffer as in http://b/70862583
java8Home := ctx . Config ( ) . Getenv ( "ANDROID_JAVA8_HOME" )
flags . bootClasspath = append ( flags . bootClasspath ,
android . PathForSource ( ctx , java8Home , "jre/lib/jce.jar" ) ,
android . PathForSource ( ctx , java8Home , "jre/lib/rt.jar" ) )
2018-02-06 19:34:32 +01:00
if Bool ( j . properties . Use_tools_jar ) {
flags . bootClasspath = append ( flags . bootClasspath ,
android . PathForSource ( ctx , java8Home , "lib/tools.jar" ) )
}
2018-01-03 03:14:25 +01:00
}
2019-10-28 19:37:20 +01:00
if j . properties . Patch_module != nil && flags . javaVersion . usesJavaModules ( ) {
2018-12-12 18:01:34 +01:00
// Manually specify build directory in case it is not under the repo root.
// (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so
// just adding a symlink under the root doesn't help.)
patchPaths := ".:" + ctx . Config ( ) . BuildDir ( )
classPath := flags . classpath . FormJavaClassPath ( "" )
if classPath != "" {
patchPaths += ":" + classPath
}
javacFlags = append ( javacFlags , "--patch-module=" + String ( j . properties . Patch_module ) + "=" + patchPaths )
2018-08-16 05:21:55 +02:00
}
2017-10-19 22:06:22 +02:00
// systemModules
2019-07-16 22:57:13 +02:00
flags . systemModules = deps . systemModules
2017-09-30 02:58:17 +02:00
2017-10-19 22:06:22 +02:00
// aidl flags.
2019-04-18 19:56:44 +02:00
flags . aidlFlags , flags . aidlDeps = j . aidlFlags ( ctx , deps . aidlPreprocess , deps . aidlIncludeDirs )
2015-03-31 02:20:39 +02:00
2018-08-16 05:21:55 +02:00
if len ( javacFlags ) > 0 {
// optimization.
ctx . Variable ( pctx , "javacFlags" , strings . Join ( javacFlags , " " ) )
flags . javacFlags = "$javacFlags"
}
2017-10-19 22:06:22 +02:00
return flags
}
2015-04-08 22:03:43 +02:00
2019-05-13 18:23:20 +02:00
func ( j * Module ) compile ( ctx android . ModuleContext , aaptSrcJar android . Path ) {
2017-11-14 22:12:14 +01:00
j . exportAidlIncludeDirs = android . PathsForModuleSrc ( ctx , j . deviceProperties . Aidl . Export_include_dirs )
2017-10-19 22:06:22 +02:00
deps := j . collectDeps ( ctx )
flags := j . collectBuilderFlags ( ctx , deps )
2019-10-28 19:37:20 +01:00
if flags . javaVersion . usesJavaModules ( ) {
2017-10-19 22:06:22 +02:00
j . properties . Srcs = append ( j . properties . Srcs , j . properties . Openjdk9 . Srcs ... )
}
2019-03-06 07:25:09 +01:00
srcFiles := android . PathsForModuleSrcExcludes ( ctx , j . properties . Srcs , j . properties . Exclude_srcs )
2017-09-20 21:59:05 +02:00
if hasSrcExt ( srcFiles . Strings ( ) , ".proto" ) {
2017-12-15 00:22:43 +01:00
flags = protoFlags ( ctx , & j . properties , & j . protoProperties , flags )
2017-09-20 21:59:05 +02:00
}
2017-11-16 08:01:59 +01:00
srcFiles = j . genSources ( ctx , srcFiles , flags )
srcJars := srcFiles . FilterByExt ( ".srcjar" )
2017-10-17 03:07:29 +02:00
srcJars = append ( srcJars , deps . srcJars ... )
2019-05-13 18:23:20 +02:00
if aaptSrcJar != nil {
srcJars = append ( srcJars , aaptSrcJar )
}
2015-04-16 23:09:14 +02:00
2019-01-18 20:51:25 +01:00
if j . properties . Jarjar_rules != nil {
2019-03-06 07:25:09 +01:00
j . expandJarjarRules = android . PathForModuleSrc ( ctx , * j . properties . Jarjar_rules )
2019-01-18 20:51:25 +01:00
}
2017-10-18 23:44:18 +02:00
jarName := ctx . ModuleName ( ) + ".jar"
2018-02-13 15:32:54 +01:00
javaSrcFiles := srcFiles . FilterByExt ( ".java" )
var uniqueSrcFiles android . Paths
set := make ( map [ string ] bool )
for _ , v := range javaSrcFiles {
if _ , found := set [ v . String ( ) ] ; ! found {
set [ v . String ( ) ] = true
uniqueSrcFiles = append ( uniqueSrcFiles , v )
}
}
2019-09-24 09:41:30 +02:00
// Collect .java files for AIDEGen
j . expandIDEInfoCompiledSrcs = append ( j . expandIDEInfoCompiledSrcs , uniqueSrcFiles . Strings ( ) ... )
2018-08-27 21:37:09 +02:00
var kotlinJars android . Paths
2017-08-15 22:34:18 +02:00
if srcFiles . HasExt ( ".kt" ) {
2018-08-21 17:10:29 +02:00
// user defined kotlin flags.
kotlincFlags := j . properties . Kotlincflags
CheckKotlincFlags ( ctx , kotlincFlags )
2017-08-15 22:34:18 +02:00
// If there are kotlin files, compile them first but pass all the kotlin and java files
// kotlinc will use the java files to resolve types referenced by the kotlin files, but
// won't emit any classes for them.
2018-08-21 17:10:29 +02:00
kotlincFlags = append ( kotlincFlags , "-no-stdlib" )
2017-08-15 22:34:18 +02:00
if ctx . Device ( ) {
2018-08-21 17:10:29 +02:00
kotlincFlags = append ( kotlincFlags , "-no-jdk" )
}
if len ( kotlincFlags ) > 0 {
// optimization.
ctx . Variable ( pctx , "kotlincFlags" , strings . Join ( kotlincFlags , " " ) )
flags . kotlincFlags += "$kotlincFlags"
2017-08-15 22:34:18 +02:00
}
2018-02-13 15:32:54 +01:00
var kotlinSrcFiles android . Paths
kotlinSrcFiles = append ( kotlinSrcFiles , uniqueSrcFiles ... )
kotlinSrcFiles = append ( kotlinSrcFiles , srcFiles . FilterByExt ( ".kt" ) ... )
2019-09-24 09:41:30 +02:00
// Collect .kt files for AIDEGen
j . expandIDEInfoCompiledSrcs = append ( j . expandIDEInfoCompiledSrcs , srcFiles . FilterByExt ( ".kt" ) . Strings ( ) ... )
2019-01-18 00:42:52 +01:00
flags . classpath = append ( flags . classpath , deps . kotlinStdlib ... )
flags . classpath = append ( flags . classpath , deps . kotlinAnnotations ... )
flags . kotlincClasspath = append ( flags . kotlincClasspath , flags . bootClasspath ... )
flags . kotlincClasspath = append ( flags . kotlincClasspath , flags . classpath ... )
if len ( flags . processorPath ) > 0 {
// Use kapt for annotation processing
kaptSrcJar := android . PathForModuleOut ( ctx , "kapt" , "kapt-sources.jar" )
kotlinKapt ( ctx , kaptSrcJar , kotlinSrcFiles , srcJars , flags )
srcJars = append ( srcJars , kaptSrcJar )
// Disable annotation processing in javac, it's already been handled by kapt
flags . processorPath = nil
2019-01-24 00:39:50 +01:00
flags . processor = ""
2019-01-18 00:42:52 +01:00
}
2017-08-15 22:34:18 +02:00
2017-10-18 23:44:18 +02:00
kotlinJar := android . PathForModuleOut ( ctx , "kotlin" , jarName )
2019-01-19 00:05:09 +01:00
kotlinCompile ( ctx , kotlinJar , kotlinSrcFiles , srcJars , flags )
2017-08-15 22:34:18 +02:00
if ctx . Failed ( ) {
return
}
// Make javac rule depend on the kotlinc rule
flags . classpath = append ( flags . classpath , kotlinJar )
2018-03-08 14:21:55 +01:00
2017-08-15 22:34:18 +02:00
// Jar kotlin classes into the final jar after javac
2018-08-27 21:37:09 +02:00
kotlinJars = append ( kotlinJars , kotlinJar )
2018-08-28 00:42:25 +02:00
kotlinJars = append ( kotlinJars , deps . kotlinStdlib ... )
2017-08-15 22:34:18 +02:00
}
2018-08-27 21:37:09 +02:00
jars := append ( android . Paths ( nil ) , kotlinJars ... )
2017-11-23 01:20:45 +01:00
// Store the list of .java files that was passed to javac
j . compiledJavaSrcs = uniqueSrcFiles
j . compiledSrcJars = srcJars
2017-11-02 21:28:15 +01:00
enable_sharding := false
2020-02-21 17:16:41 +01:00
var headerJarFileWithoutJarjar android . Path
2019-01-22 06:37:16 +01:00
if ctx . Device ( ) && ! ctx . Config ( ) . IsEnvFalse ( "TURBINE_ENABLED" ) && ! deps . disableTurbine {
2017-11-02 21:28:15 +01:00
if j . properties . Javac_shard_size != nil && * ( j . properties . Javac_shard_size ) > 0 {
enable_sharding = true
2019-01-16 23:34:08 +01:00
// Formerly, there was a check here that prevented annotation processors
// from being used when sharding was enabled, as some annotation processors
// do not function correctly in sharded environments. It was removed to
// allow for the use of annotation processors that do function correctly
// with sharding enabled. See: b/77284273.
2017-11-02 21:28:15 +01:00
}
2020-02-21 17:16:41 +01:00
headerJarFileWithoutJarjar , j . headerJarFile =
j . compileJavaHeader ( ctx , uniqueSrcFiles , srcJars , deps , flags , jarName , kotlinJars )
2018-03-26 23:42:44 +02:00
if ctx . Failed ( ) {
return
2017-10-19 22:06:22 +02:00
}
}
2017-10-25 02:46:00 +02:00
if len ( uniqueSrcFiles ) > 0 || len ( srcJars ) > 0 {
2017-09-28 02:39:56 +02:00
var extraJarDeps android . Paths
2018-06-20 07:47:35 +02:00
if ctx . Config ( ) . RunErrorProne ( ) {
2017-08-14 23:16:06 +02:00
// If error-prone is enabled, add an additional rule to compile the java files into
// a separate set of classes (so that they don't overwrite the normal ones and require
2017-09-28 02:39:56 +02:00
// a rebuild when error-prone is turned off).
2017-08-14 23:16:06 +02:00
// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
// enable error-prone without affecting the output class files.
2017-10-18 23:44:18 +02:00
errorprone := android . PathForModuleOut ( ctx , "errorprone" , jarName )
2017-11-02 21:28:15 +01:00
RunErrorProne ( ctx , errorprone , uniqueSrcFiles , srcJars , flags )
2017-08-14 23:16:06 +02:00
extraJarDeps = append ( extraJarDeps , errorprone )
}
2017-11-02 21:28:15 +01:00
if enable_sharding {
2020-02-21 17:16:41 +01:00
flags . classpath = append ( flags . classpath , headerJarFileWithoutJarjar )
2017-11-02 21:28:15 +01:00
shardSize := int ( * ( j . properties . Javac_shard_size ) )
var shardSrcs [ ] android . Paths
if len ( uniqueSrcFiles ) > 0 {
2019-09-23 23:33:09 +02:00
shardSrcs = android . ShardPaths ( uniqueSrcFiles , shardSize )
2017-11-02 21:28:15 +01:00
for idx , shardSrc := range shardSrcs {
2019-09-06 01:44:18 +02:00
classes := j . compileJavaClasses ( ctx , jarName , idx , shardSrc ,
nil , flags , extraJarDeps )
2017-11-02 21:28:15 +01:00
jars = append ( jars , classes )
}
}
if len ( srcJars ) > 0 {
2019-09-06 01:44:18 +02:00
classes := j . compileJavaClasses ( ctx , jarName , len ( shardSrcs ) ,
nil , srcJars , flags , extraJarDeps )
2017-11-02 21:28:15 +01:00
jars = append ( jars , classes )
}
} else {
2019-09-06 01:44:18 +02:00
classes := j . compileJavaClasses ( ctx , jarName , - 1 , uniqueSrcFiles , srcJars , flags , extraJarDeps )
2017-11-02 21:28:15 +01:00
jars = append ( jars , classes )
}
2017-09-28 02:39:56 +02:00
if ctx . Failed ( ) {
return
}
2015-03-31 02:20:39 +02:00
}
2019-05-04 00:28:19 +02:00
j . srcJarArgs , j . srcJarDeps = resourcePathsToJarArgs ( srcFiles ) , srcFiles
var includeSrcJar android . WritablePath
if Bool ( j . properties . Include_srcs ) {
includeSrcJar = android . PathForModuleOut ( ctx , ctx . ModuleName ( ) + ".srcjar" )
TransformResourcesToJar ( ctx , includeSrcJar , j . srcJarArgs , j . srcJarDeps )
}
2018-09-13 20:26:19 +02:00
dirArgs , dirDeps := ResourceDirsToJarArgs ( ctx , j . properties . Java_resource_dirs ,
j . properties . Exclude_java_resource_dirs , j . properties . Exclude_java_resources )
2017-09-28 02:42:05 +02:00
fileArgs , fileDeps := ResourceFilesToJarArgs ( ctx , j . properties . Java_resources , j . properties . Exclude_java_resources )
2019-05-06 23:04:11 +02:00
extraArgs , extraDeps := resourcePathsToJarArgs ( j . extraResources ) , j . extraResources
2017-09-28 02:42:05 +02:00
var resArgs [ ] string
var resDeps android . Paths
resArgs = append ( resArgs , dirArgs ... )
resDeps = append ( resDeps , dirDeps ... )
resArgs = append ( resArgs , fileArgs ... )
resDeps = append ( resDeps , fileDeps ... )
2019-05-06 23:04:11 +02:00
resArgs = append ( resArgs , extraArgs ... )
resDeps = append ( resDeps , extraDeps ... )
2017-09-28 02:41:35 +02:00
if len ( resArgs ) > 0 {
2017-10-18 23:44:18 +02:00
resourceJar := android . PathForModuleOut ( ctx , "res" , jarName )
2017-10-17 02:09:48 +02:00
TransformResourcesToJar ( ctx , resourceJar , resArgs , resDeps )
2018-08-16 05:40:52 +02:00
j . resourceJar = resourceJar
2017-08-30 23:24:55 +02:00
if ctx . Failed ( ) {
return
}
2018-08-16 05:40:52 +02:00
}
2015-03-31 02:20:39 +02:00
2019-05-04 00:28:19 +02:00
var resourceJars android . Paths
if j . resourceJar != nil {
resourceJars = append ( resourceJars , j . resourceJar )
}
if Bool ( j . properties . Include_srcs ) {
resourceJars = append ( resourceJars , includeSrcJar )
}
resourceJars = append ( resourceJars , deps . staticResourceJars ... )
2018-08-16 05:40:52 +02:00
2019-05-04 00:28:19 +02:00
if len ( resourceJars ) > 1 {
2018-08-16 05:40:52 +02:00
combinedJar := android . PathForModuleOut ( ctx , "res-combined" , jarName )
2019-05-04 00:28:19 +02:00
TransformJarsToJar ( ctx , combinedJar , "for resources" , resourceJars , android . OptionalPath { } ,
2018-08-16 05:40:52 +02:00
false , nil , nil )
j . resourceJar = combinedJar
2019-05-04 00:28:19 +02:00
} else if len ( resourceJars ) == 1 {
j . resourceJar = resourceJars [ 0 ]
2015-03-31 02:20:39 +02:00
}
2015-04-04 01:54:17 +02:00
2019-05-13 18:23:20 +02:00
if len ( deps . staticJars ) > 0 {
jars = append ( jars , deps . staticJars ... )
}
2017-08-30 23:24:55 +02:00
2018-10-18 00:10:48 +02:00
manifest := j . overrideManifest
if ! manifest . Valid ( ) && j . properties . Manifest != nil {
2019-03-06 07:25:09 +01:00
manifest = android . OptionalPathForPath ( android . PathForModuleSrc ( ctx , * j . properties . Manifest ) )
2017-12-12 01:29:02 +01:00
}
2017-09-13 07:50:46 +02:00
2019-03-06 07:25:09 +01:00
services := android . PathsForModuleSrc ( ctx , j . properties . Services )
2019-02-21 22:27:37 +01:00
if len ( services ) > 0 {
servicesJar := android . PathForModuleOut ( ctx , "services" , jarName )
var zipargs [ ] string
for _ , file := range services {
serviceFile := file . String ( )
zipargs = append ( zipargs , "-C" , filepath . Dir ( serviceFile ) , "-f" , serviceFile )
}
ctx . Build ( pctx , android . BuildParams {
Rule : zip ,
Output : servicesJar ,
Implicits : services ,
Args : map [ string ] string {
2019-02-28 20:00:01 +01:00
"jarArgs" : "-P META-INF/services/ " + strings . Join ( proptools . NinjaAndShellEscapeList ( zipargs ) , " " ) ,
2019-02-21 22:27:37 +01:00
} ,
} )
jars = append ( jars , servicesJar )
}
2017-08-30 23:24:55 +02:00
// Combine the classes built from sources, any manifests, and any static libraries into
2017-10-19 22:06:22 +02:00
// classes.jar. If there is only one input jar this step will be skipped.
2018-08-15 20:19:12 +02:00
var outputFile android . ModuleOutPath
2017-10-17 02:09:48 +02:00
if len ( jars ) == 1 && ! manifest . Valid ( ) {
2018-08-15 20:19:12 +02:00
if moduleOutPath , ok := jars [ 0 ] . ( android . ModuleOutPath ) ; ok {
// Optimization: skip the combine step if there is nothing to do
// TODO(ccross): this leaves any module-info.class files, but those should only come from
// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
// any if len(jars) == 1.
outputFile = moduleOutPath
} else {
combinedJar := android . PathForModuleOut ( ctx , "combined" , jarName )
ctx . Build ( pctx , android . BuildParams {
Rule : android . Cp ,
Input : jars [ 0 ] ,
Output : combinedJar ,
} )
outputFile = combinedJar
}
2017-10-17 02:09:48 +02:00
} else {
2017-10-18 23:44:18 +02:00
combinedJar := android . PathForModuleOut ( ctx , "combined" , jarName )
2018-07-12 21:28:41 +02:00
TransformJarsToJar ( ctx , combinedJar , "for javac" , jars , manifest ,
2018-08-28 00:42:25 +02:00
false , nil , nil )
2017-10-17 02:09:48 +02:00
outputFile = combinedJar
}
2017-08-30 23:24:55 +02:00
2018-08-16 05:40:52 +02:00
// jarjar implementation jar if necessary
2019-01-18 20:51:25 +01:00
if j . expandJarjarRules != nil {
2017-09-28 03:03:17 +02:00
// Transform classes.jar into classes-jarjar.jar
2017-10-18 23:44:18 +02:00
jarjarFile := android . PathForModuleOut ( ctx , "jarjar" , jarName )
2019-01-18 20:51:25 +01:00
TransformJarJar ( ctx , jarjarFile , outputFile , j . expandJarjarRules )
2017-10-17 02:09:48 +02:00
outputFile = jarjarFile
2018-08-16 05:40:52 +02:00
// jarjar resource jar if necessary
if j . resourceJar != nil {
resourceJarJarFile := android . PathForModuleOut ( ctx , "res-jarjar" , jarName )
2019-01-18 20:51:25 +01:00
TransformJarJar ( ctx , resourceJarJarFile , j . resourceJar , j . expandJarjarRules )
2018-08-16 05:40:52 +02:00
j . resourceJar = resourceJarJarFile
}
2015-04-04 01:54:17 +02:00
if ctx . Failed ( ) {
return
}
}
2019-04-02 11:29:55 +02:00
// Check package restrictions if necessary.
if len ( j . properties . Permitted_packages ) > 0 {
// Check packages and copy to package-checked file.
pkgckFile := android . PathForModuleOut ( ctx , "package-check.stamp" )
CheckJarPackages ( ctx , pkgckFile , outputFile , j . properties . Permitted_packages )
j . additionalCheckedModules = append ( j . additionalCheckedModules , pkgckFile )
if ctx . Failed ( ) {
return
}
}
2017-10-19 22:06:22 +02:00
j . implementationJarFile = outputFile
if j . headerJarFile == nil {
j . headerJarFile = j . implementationJarFile
}
2015-03-31 02:20:39 +02:00
2020-02-21 08:04:53 +01:00
// Force enable the instrumentation for java code that is built for APEXes ...
// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
// doesn't make sense)
isJacocoAgent := ctx . ModuleName ( ) == "jacocoagent"
if android . DirectlyInAnyApex ( ctx , ctx . ModuleName ( ) ) && ! isJacocoAgent && ! j . IsForPlatform ( ) {
2020-02-18 13:50:44 +01:00
j . properties . Instrument = true
}
2018-01-04 00:06:47 +01:00
if j . shouldInstrument ( ctx ) {
2017-11-22 22:49:43 +01:00
outputFile = j . instrument ( ctx , flags , outputFile , jarName )
}
2018-08-16 05:40:52 +02:00
// merge implementation jar with resources if necessary
implementationAndResourcesJar := outputFile
if j . resourceJar != nil {
2019-04-29 19:22:44 +02:00
jars := android . Paths { j . resourceJar , implementationAndResourcesJar }
2018-08-16 05:40:52 +02:00
combinedJar := android . PathForModuleOut ( ctx , "withres" , jarName )
2019-04-29 19:22:44 +02:00
TransformJarsToJar ( ctx , combinedJar , "for resources" , jars , manifest ,
2018-08-16 05:40:52 +02:00
false , nil , nil )
implementationAndResourcesJar = combinedJar
}
j . implementationAndResourcesJar = implementationAndResourcesJar
2020-02-11 01:16:01 +01:00
// Enable dex compilation for the APEX variants, unless it is disabled explicitly
if android . DirectlyInAnyApex ( ctx , ctx . ModuleName ( ) ) && ! j . IsForPlatform ( ) {
if j . deviceProperties . Compile_dex == nil {
j . deviceProperties . Compile_dex = proptools . BoolPtr ( true )
}
if j . deviceProperties . Hostdex == nil {
j . deviceProperties . Hostdex = proptools . BoolPtr ( true )
}
}
2019-05-31 00:51:14 +02:00
if ctx . Device ( ) && j . hasCode ( ctx ) &&
2019-05-13 18:23:20 +02:00
( Bool ( j . properties . Installable ) || Bool ( j . deviceProperties . Compile_dex ) ) {
2019-01-17 00:15:52 +01:00
// Dex compilation
2018-08-15 20:19:12 +02:00
var dexOutputFile android . ModuleOutPath
2018-06-27 11:27:45 +02:00
dexOutputFile = j . compileDex ( ctx , flags , outputFile , jarName )
2017-10-19 22:06:22 +02:00
if ctx . Failed ( ) {
return
2015-03-31 02:20:39 +02:00
}
2018-08-16 05:40:52 +02:00
2019-07-15 08:29:23 +02:00
// Hidden API CSV generation and dex encoding
dexOutputFile = j . hiddenAPI . hiddenAPI ( ctx , dexOutputFile , j . implementationJarFile ,
j . deviceProperties . UncompressDex )
2019-01-17 00:15:52 +01:00
2018-08-16 05:40:52 +02:00
// merge dex jar with resources if necessary
if j . resourceJar != nil {
jars := android . Paths { dexOutputFile , j . resourceJar }
combinedJar := android . PathForModuleOut ( ctx , "dex-withres" , jarName )
TransformJarsToJar ( ctx , combinedJar , "for dex resources" , jars , android . OptionalPath { } ,
false , nil , nil )
2019-01-23 16:57:21 +01:00
if j . deviceProperties . UncompressDex {
combinedAlignedJar := android . PathForModuleOut ( ctx , "dex-withres-aligned" , jarName )
TransformZipAlign ( ctx , combinedAlignedJar , combinedJar )
dexOutputFile = combinedAlignedJar
} else {
dexOutputFile = combinedJar
}
2018-08-16 05:40:52 +02:00
}
j . dexJarFile = dexOutputFile
2019-01-17 00:15:52 +01:00
// Dexpreopting
2018-11-12 19:13:39 +01:00
dexOutputFile = j . dexpreopt ( ctx , dexOutputFile )
j . maybeStrippedDexJarFile = dexOutputFile
2018-08-15 20:19:12 +02:00
outputFile = dexOutputFile
2018-11-12 19:13:39 +01:00
if ctx . Failed ( ) {
return
}
2018-08-16 05:40:52 +02:00
} else {
outputFile = implementationAndResourcesJar
2017-10-19 22:06:22 +02:00
}
2018-08-16 05:40:52 +02:00
2017-10-19 22:06:22 +02:00
ctx . CheckbuildFile ( outputFile )
2018-08-15 20:19:12 +02:00
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
j . outputFile = outputFile . WithoutRel ( )
2017-10-19 22:06:22 +02:00
}
2015-03-31 02:20:39 +02:00
2019-09-06 01:44:18 +02:00
func ( j * Module ) compileJavaClasses ( ctx android . ModuleContext , jarName string , idx int ,
srcFiles , srcJars android . Paths , flags javaBuilderFlags , extraJarDeps android . Paths ) android . WritablePath {
kzipName := pathtools . ReplaceExtension ( jarName , "kzip" )
if idx >= 0 {
kzipName = strings . TrimSuffix ( jarName , filepath . Ext ( jarName ) ) + strconv . Itoa ( idx ) + ".kzip"
jarName += strconv . Itoa ( idx )
}
classes := android . PathForModuleOut ( ctx , "javac" , jarName )
TransformJavaToClasses ( ctx , classes , idx , srcFiles , srcJars , flags , extraJarDeps )
if ctx . Config ( ) . EmitXrefRules ( ) {
extractionFile := android . PathForModuleOut ( ctx , kzipName )
emitXrefRule ( ctx , extractionFile , idx , srcFiles , srcJars , flags , extraJarDeps )
j . kytheFiles = append ( j . kytheFiles , extractionFile )
}
return classes
}
2018-08-21 17:10:29 +02:00
// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
// since some of these flags may be used internally.
func CheckKotlincFlags ( ctx android . ModuleContext , flags [ ] string ) {
for _ , flag := range flags {
flag = strings . TrimSpace ( flag )
if ! strings . HasPrefix ( flag , "-" ) {
ctx . PropertyErrorf ( "kotlincflags" , "Flag `%s` must start with `-`" , flag )
} else if strings . HasPrefix ( flag , "-Xintellij-plugin-root" ) {
ctx . PropertyErrorf ( "kotlincflags" ,
"Bad flag: `%s`, only use internal compiler for consistency." , flag )
} else if inList ( flag , config . KotlincIllegalFlags ) {
ctx . PropertyErrorf ( "kotlincflags" , "Flag `%s` already used by build system" , flag )
} else if flag == "-include-runtime" {
ctx . PropertyErrorf ( "kotlincflags" , "Bad flag: `%s`, do not include runtime." , flag )
} else {
args := strings . Split ( flag , " " )
if args [ 0 ] == "-kotlin-home" {
ctx . PropertyErrorf ( "kotlincflags" ,
"Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo)." , flag )
}
}
}
}
2017-10-25 02:46:00 +02:00
func ( j * Module ) compileJavaHeader ( ctx android . ModuleContext , srcFiles , srcJars android . Paths ,
2020-02-21 17:16:41 +01:00
deps deps , flags javaBuilderFlags , jarName string ,
extraJars android . Paths ) ( headerJar , jarjarHeaderJar android . Path ) {
2015-03-31 02:20:39 +02:00
2017-10-19 22:06:22 +02:00
var jars android . Paths
2017-10-25 02:46:00 +02:00
if len ( srcFiles ) > 0 || len ( srcJars ) > 0 {
2017-10-19 22:06:22 +02:00
// Compile java sources into turbine.jar.
turbineJar := android . PathForModuleOut ( ctx , "turbine" , jarName )
TransformJavaToHeaderClasses ( ctx , turbineJar , srcFiles , srcJars , flags )
if ctx . Failed ( ) {
2020-02-21 17:16:41 +01:00
return nil , nil
2015-03-31 02:20:39 +02:00
}
2017-10-19 22:06:22 +02:00
jars = append ( jars , turbineJar )
}
2015-03-31 02:20:39 +02:00
2018-08-27 21:37:09 +02:00
jars = append ( jars , extraJars ... )
2017-10-19 22:06:22 +02:00
// Combine any static header libraries into classes-header.jar. If there is only
// one input jar this step will be skipped.
jars = append ( jars , deps . staticHeaderJars ... )
2017-10-24 03:12:27 +02:00
// we cannot skip the combine step for now if there is only one jar
// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
combinedJar := android . PathForModuleOut ( ctx , "turbine-combined" , jarName )
2018-07-12 21:28:41 +02:00
TransformJarsToJar ( ctx , combinedJar , "for turbine" , jars , android . OptionalPath { } ,
2019-05-08 23:30:12 +02:00
false , nil , [ ] string { "META-INF/TRANSITIVE" } )
2017-10-24 03:12:27 +02:00
headerJar = combinedJar
2020-02-21 17:16:41 +01:00
jarjarHeaderJar = combinedJar
2017-10-19 22:06:22 +02:00
2019-01-18 20:51:25 +01:00
if j . expandJarjarRules != nil {
2017-10-19 22:06:22 +02:00
// Transform classes.jar into classes-jarjar.jar
jarjarFile := android . PathForModuleOut ( ctx , "turbine-jarjar" , jarName )
2019-01-18 20:51:25 +01:00
TransformJarJar ( ctx , jarjarFile , headerJar , j . expandJarjarRules )
2020-02-21 17:16:41 +01:00
jarjarHeaderJar = jarjarFile
2017-10-19 22:06:22 +02:00
if ctx . Failed ( ) {
2020-02-21 17:16:41 +01:00
return nil , nil
2017-08-31 21:30:37 +02:00
}
2017-10-19 22:06:22 +02:00
}
2017-08-31 21:30:37 +02:00
2020-02-21 17:16:41 +01:00
return headerJar , jarjarHeaderJar
2017-10-19 22:06:22 +02:00
}
2017-08-31 21:30:37 +02:00
2017-11-22 22:49:43 +01:00
func ( j * Module ) instrument ( ctx android . ModuleContext , flags javaBuilderFlags ,
2018-08-15 20:19:12 +02:00
classesJar android . Path , jarName string ) android . ModuleOutPath {
2017-11-22 22:49:43 +01:00
2017-12-19 22:57:50 +01:00
specs := j . jacocoModuleToZipCommand ( ctx )
2017-11-22 22:49:43 +01:00
2018-01-04 00:59:46 +01:00
jacocoReportClassesFile := android . PathForModuleOut ( ctx , "jacoco-report-classes" , jarName )
2017-11-22 22:49:43 +01:00
instrumentedJar := android . PathForModuleOut ( ctx , "jacoco" , jarName )
jacocoInstrumentJar ( ctx , instrumentedJar , jacocoReportClassesFile , classesJar , specs )
j . jacocoReportClassesFile = jacocoReportClassesFile
return instrumentedJar
}
2018-12-25 07:35:23 +01:00
var _ Dependency = ( * Module ) ( nil )
2015-03-31 02:20:39 +02:00
2017-10-19 22:06:22 +02:00
func ( j * Module ) HeaderJars ( ) android . Paths {
2018-12-25 07:35:23 +01:00
if j . headerJarFile == nil {
return nil
}
2017-10-19 22:06:22 +02:00
return android . Paths { j . headerJarFile }
}
func ( j * Module ) ImplementationJars ( ) android . Paths {
2018-12-24 08:41:04 +01:00
if j . implementationJarFile == nil {
return nil
}
2017-10-19 22:06:22 +02:00
return android . Paths { j . implementationJarFile }
2015-03-31 02:20:39 +02:00
}
2019-01-31 23:12:44 +01:00
func ( j * Module ) DexJar ( ) android . Path {
return j . dexJarFile
}
2018-08-16 05:40:52 +02:00
func ( j * Module ) ResourceJars ( ) android . Paths {
if j . resourceJar == nil {
return nil
}
return android . Paths { j . resourceJar }
}
func ( j * Module ) ImplementationAndResourcesJars ( ) android . Paths {
2018-12-25 07:35:23 +01:00
if j . implementationAndResourcesJar == nil {
return nil
}
2018-08-16 05:40:52 +02:00
return android . Paths { j . implementationAndResourcesJar }
}
2017-06-23 01:51:17 +02:00
func ( j * Module ) AidlIncludeDirs ( ) android . Paths {
2018-12-25 07:35:23 +01:00
// exportAidlIncludeDirs is type android.Paths already
2015-04-08 22:03:43 +02:00
return j . exportAidlIncludeDirs
}
2018-05-28 11:02:19 +02:00
func ( j * Module ) ExportedSdkLibs ( ) [ ] string {
2018-12-25 07:35:23 +01:00
// exportedSdkLibs is type []string
2018-05-28 11:02:19 +02:00
return j . exportedSdkLibs
}
2019-11-26 19:08:34 +01:00
func ( j * Module ) ExportedPlugins ( ) ( android . Paths , [ ] string ) {
return j . exportedPluginJars , j . exportedPluginClasses
}
2019-05-04 00:28:19 +02:00
func ( j * Module ) SrcJarArgs ( ) ( [ ] string , android . Paths ) {
return j . srcJarArgs , j . srcJarDeps
}
2017-06-23 01:51:17 +02:00
var _ logtagsProducer = ( * Module ) ( nil )
2015-04-11 02:45:20 +02:00
2017-06-23 01:51:17 +02:00
func ( j * Module ) logtags ( ) android . Paths {
2015-04-11 02:45:20 +02:00
return j . logtagsSrcs
}
2018-08-16 00:35:38 +02:00
// Collect information for opening IDE project files in java/jdeps.go.
func ( j * Module ) IDEInfo ( dpInfo * android . IdeInfo ) {
dpInfo . Deps = append ( dpInfo . Deps , j . CompilerDeps ( ) ... )
dpInfo . Srcs = append ( dpInfo . Srcs , j . expandIDEInfoCompiledSrcs ... )
2019-05-10 09:48:50 +02:00
dpInfo . SrcJars = append ( dpInfo . SrcJars , j . compiledSrcJars . Strings ( ) ... )
2018-08-16 00:35:38 +02:00
dpInfo . Aidl_include_dirs = append ( dpInfo . Aidl_include_dirs , j . deviceProperties . Aidl . Include_dirs ... )
2019-01-18 20:51:25 +01:00
if j . expandJarjarRules != nil {
dpInfo . Jarjar_rules = append ( dpInfo . Jarjar_rules , j . expandJarjarRules . String ( ) )
2018-08-16 00:35:38 +02:00
}
}
func ( j * Module ) CompilerDeps ( ) [ ] string {
jdeps := [ ] string { }
jdeps = append ( jdeps , j . properties . Libs ... )
jdeps = append ( jdeps , j . properties . Static_libs ... )
return jdeps
}
2019-05-31 00:51:14 +02:00
func ( j * Module ) hasCode ( ctx android . ModuleContext ) bool {
srcFiles := android . PathsForModuleSrcExcludes ( ctx , j . properties . Srcs , j . properties . Exclude_srcs )
return len ( srcFiles ) > 0 || len ( ctx . GetDirectDepsWithTag ( staticLibTag ) ) > 0
}
2019-10-15 08:20:07 +02:00
func ( j * Module ) DepIsInSameApex ( ctx android . BaseModuleContext , dep android . Module ) bool {
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
// Dependencies other than the static linkage are all considered crossing APEX boundary
2020-03-09 22:23:13 +01:00
if staticLibTag == ctx . OtherModuleDependencyTag ( dep ) {
return true
}
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
// Also, a dependency to an sdk member is also considered as such. This is required because
// sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
2020-03-09 22:23:13 +01:00
if sa , ok := dep . ( android . SdkAware ) ; ok && sa . IsInAnySdk ( ) {
return true
}
return false
2019-10-15 08:20:07 +02:00
}
2019-10-29 03:23:10 +01:00
func ( j * Module ) Stem ( ) string {
return proptools . StringDefault ( j . deviceProperties . Stem , j . Name ( ) )
}
2020-01-08 05:35:43 +01:00
func ( j * Module ) JacocoReportClassesFile ( ) android . Path {
return j . jacocoReportClassesFile
}
2020-01-31 18:10:36 +01:00
func ( j * Module ) IsInstallable ( ) bool {
return Bool ( j . properties . Installable )
}
2015-03-31 02:20:39 +02:00
//
// Java libraries (.jar file)
//
2020-03-27 20:39:48 +01:00
type LibraryProperties struct {
Dist struct {
// The tag of the output of this module that should be output.
Tag * string ` android:"arch_variant" `
} ` android:"arch_variant" `
}
2017-07-20 00:53:04 +02:00
type Library struct {
2017-06-23 01:51:17 +02:00
Module
2019-10-16 01:36:40 +02:00
2020-03-27 20:39:48 +01:00
libraryProperties LibraryProperties
2019-10-16 01:36:40 +02:00
InstallMixin func ( ctx android . ModuleContext , installPath android . Path ) ( extraInstallDeps android . Paths )
2015-03-31 02:20:39 +02:00
}
2019-02-22 03:12:14 +01:00
func shouldUncompressDex ( ctx android . ModuleContext , dexpreopter * dexpreopter ) bool {
2020-01-24 13:19:45 +01:00
// Store uncompressed (and aligned) any dex files from jars in APEXes.
if am , ok := ctx . Module ( ) . ( android . ApexModule ) ; ok && ! am . IsForPlatform ( ) {
return true
}
2019-02-12 14:12:16 +01:00
// Store uncompressed (and do not strip) dex files from boot class path jars.
if inList ( ctx . ModuleName ( ) , ctx . Config ( ) . BootJars ( ) ) {
return true
}
// Store uncompressed dex files that are preopted on /system.
2019-02-22 03:12:14 +01:00
if ! dexpreopter . dexpreoptDisabled ( ctx ) && ( ctx . Host ( ) || ! odexOnSystemOther ( ctx , dexpreopter . installPath ) ) {
2018-12-21 16:54:16 +01:00
return true
}
2019-02-07 01:37:12 +01:00
if ctx . Config ( ) . UncompressPrivAppDex ( ) &&
inList ( ctx . ModuleName ( ) , ctx . Config ( ) . ModulesLoadedByPrivilegedModules ( ) ) {
return true
}
2018-12-21 21:59:54 +01:00
return false
}
2017-07-20 00:53:04 +02:00
func ( j * Library ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
2019-10-29 07:44:45 +01:00
j . checkSdkVersion ( ctx )
2019-10-29 03:23:10 +01:00
j . dexpreopter . installPath = android . PathForModuleInstall ( ctx , "framework" , j . Stem ( ) + ".jar" )
2018-11-12 19:13:39 +01:00
j . dexpreopter . isSDKLibrary = j . deviceProperties . IsSDKLibrary
2019-02-22 03:12:14 +01:00
j . dexpreopter . uncompressedDex = shouldUncompressDex ( ctx , & j . dexpreopter )
2019-02-12 14:12:16 +01:00
j . deviceProperties . UncompressDex = j . dexpreopter . uncompressedDex
2019-05-13 18:23:20 +02:00
j . compile ( ctx , nil )
2015-04-16 23:09:14 +02:00
2019-07-25 15:02:35 +02:00
exclusivelyForApex := android . InAnyApex ( ctx . ModuleName ( ) ) && ! j . IsForPlatform ( )
if ( Bool ( j . properties . Installable ) || ctx . Host ( ) ) && ! exclusivelyForApex {
2019-10-16 01:36:40 +02:00
var extraInstallDeps android . Paths
if j . InstallMixin != nil {
extraInstallDeps = j . InstallMixin ( ctx , j . outputFile )
}
2017-09-01 01:45:16 +02:00
j . installFile = ctx . InstallFile ( android . PathForModuleInstall ( ctx , "framework" ) ,
2019-10-16 01:36:40 +02:00
ctx . ModuleName ( ) + ".jar" , j . outputFile , extraInstallDeps ... )
2017-09-01 01:45:16 +02:00
}
2020-03-27 20:39:48 +01:00
// Verify Dist.Tag is set to a supported output
if j . libraryProperties . Dist . Tag != nil {
distFiles , err := j . OutputFiles ( * j . libraryProperties . Dist . Tag )
if err != nil {
ctx . PropertyErrorf ( "dist.tag" , "%s" , err . Error ( ) )
}
j . distFile = distFiles [ 0 ]
}
2015-04-16 23:09:14 +02:00
}
2017-07-20 00:53:04 +02:00
func ( j * Library ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
2017-06-23 01:51:17 +02:00
j . deps ( ctx )
}
2019-11-12 20:39:25 +01:00
const (
2019-12-03 19:06:47 +01:00
aidlIncludeDir = "aidl"
javaDir = "java"
jarFileSuffix = ".jar"
testConfigSuffix = "-AndroidTest.xml"
2019-11-12 20:39:25 +01:00
)
2019-12-05 12:25:53 +01:00
// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
2019-12-03 19:06:47 +01:00
func sdkSnapshotFilePathForJar ( member android . SdkMember ) string {
return sdkSnapshotFilePathForMember ( member , jarFileSuffix )
}
func sdkSnapshotFilePathForMember ( member android . SdkMember , suffix string ) string {
return filepath . Join ( javaDir , member . Name ( ) + suffix )
2019-11-12 20:39:25 +01:00
}
2019-11-28 15:31:38 +01:00
type librarySdkMemberType struct {
2019-12-13 12:22:16 +01:00
android . SdkMemberTypeBase
2019-11-28 15:31:38 +01:00
}
func ( mt * librarySdkMemberType ) AddDependencies ( mctx android . BottomUpMutatorContext , dependencyTag blueprint . DependencyTag , names [ ] string ) {
mctx . AddVariationDependencies ( nil , dependencyTag , names ... )
}
func ( mt * librarySdkMemberType ) IsInstance ( module android . Module ) bool {
_ , ok := module . ( * Library )
return ok
}
2019-12-05 12:25:53 +01:00
func ( mt * librarySdkMemberType ) buildSnapshot (
sdkModuleContext android . ModuleContext ,
builder android . SnapshotBuilder ,
member android . SdkMember ,
jarToExportGetter func ( j * Library ) android . Path ) {
2019-11-28 15:31:38 +01:00
variants := member . Variants ( )
if len ( variants ) != 1 {
sdkModuleContext . ModuleErrorf ( "sdk contains %d variants of member %q but only one is allowed" , len ( variants ) , member . Name ( ) )
for _ , variant := range variants {
sdkModuleContext . ModuleErrorf ( " %q" , variant )
}
}
variant := variants [ 0 ]
j := variant . ( * Library )
2019-12-05 12:25:53 +01:00
exportedJar := jarToExportGetter ( j )
2019-12-03 19:06:47 +01:00
snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar ( member )
2019-12-05 12:25:53 +01:00
builder . CopyToSnapshot ( exportedJar , snapshotRelativeJavaLibPath )
2019-11-12 20:39:25 +01:00
for _ , dir := range j . AidlIncludeDirs ( ) {
// TODO(jiyong): copy parcelable declarations only
aidlFiles , _ := sdkModuleContext . GlobWithDeps ( dir . String ( ) + "/**/*.aidl" , nil )
for _ , file := range aidlFiles {
builder . CopyToSnapshot ( android . PathForSource ( sdkModuleContext , file ) , filepath . Join ( aidlIncludeDir , file ) )
}
}
2019-12-05 19:19:29 +01:00
module := builder . AddPrebuiltModule ( member , "java_import" )
2019-11-27 18:43:54 +01:00
module . AddProperty ( "jars" , [ ] string { snapshotRelativeJavaLibPath } )
2019-11-12 20:39:25 +01:00
}
2020-01-13 22:03:22 +01:00
var javaHeaderLibsSdkMemberType android . SdkMemberType = & headerLibrarySdkMemberType {
librarySdkMemberType {
android . SdkMemberTypeBase {
PropertyName : "java_header_libs" ,
SupportsSdk : true ,
} ,
} ,
}
2019-12-05 12:25:53 +01:00
type headerLibrarySdkMemberType struct {
librarySdkMemberType
}
func ( mt * headerLibrarySdkMemberType ) BuildSnapshot ( sdkModuleContext android . ModuleContext , builder android . SnapshotBuilder , member android . SdkMember ) {
mt . librarySdkMemberType . buildSnapshot ( sdkModuleContext , builder , member , func ( j * Library ) android . Path {
headerJars := j . HeaderJars ( )
if len ( headerJars ) != 1 {
panic ( fmt . Errorf ( "there must be only one header jar from %q" , j . Name ( ) ) )
}
return headerJars [ 0 ]
} )
}
type implLibrarySdkMemberType struct {
librarySdkMemberType
}
func ( mt * implLibrarySdkMemberType ) BuildSnapshot ( sdkModuleContext android . ModuleContext , builder android . SnapshotBuilder , member android . SdkMember ) {
mt . librarySdkMemberType . buildSnapshot ( sdkModuleContext , builder , member , func ( j * Library ) android . Path {
implementationJars := j . ImplementationJars ( )
if len ( implementationJars ) != 1 {
panic ( fmt . Errorf ( "there must be only one implementation jar from %q" , j . Name ( ) ) )
}
return implementationJars [ 0 ]
} )
}
2019-02-12 23:41:32 +01:00
// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
//
// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used
// as a `static_libs` dependency of another module.
//
// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on
// a device.
//
// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
// compiled against the host bootclasspath.
2018-06-27 02:59:05 +02:00
func LibraryFactory ( ) android . Module {
module := & Library { }
2015-03-31 02:20:39 +02:00
2018-06-27 02:59:05 +02:00
module . AddProperties (
& module . Module . properties ,
& module . Module . deviceProperties ,
2018-11-12 19:13:39 +01:00
& module . Module . dexpreoptProperties ,
2020-03-27 20:39:48 +01:00
& module . Module . protoProperties ,
& module . libraryProperties )
2017-06-24 00:06:31 +02:00
2019-07-25 15:02:35 +02:00
android . InitApexModule ( module )
Introduce module type 'sdk'
This change introduces a new module type named 'sdk'. It is a logical
group of prebuilt modules that together provide a context (e.g. APIs)
in which Mainline modules (such as APEXes) are built.
A prebuilt module (e.g. java_import) can join an sdk by adding it to the
sdk module as shown below:
sdk {
name: "mysdk#20",
java_libs: ["myjavalib_mysdk_20"],
}
java_import {
name: "myjavalib_mysdk_20",
srcs: ["myjavalib-v20.jar"],
sdk_member_name: "myjavalib",
}
sdk {
name: "mysdk#21",
java_libs: ["myjavalib_mysdk_21"],
}
java_import {
name: "myjavalib_mysdk_21",
srcs: ["myjavalib-v21.jar"],
sdk_member_name: "myjavalib",
}
java_library {
name: "myjavalib",
srcs: ["**/*/*.java"],
}
An APEX can specify the SDK(s) that it wants to build with via the new
'uses_sdks' property.
apex {
name: "myapex",
java_libs: ["libX", "libY"],
uses_sdks: ["mysdk#20"],
}
With this, libX, libY, and their transitive dependencies are all built
with the version 20 of myjavalib (the first java_import module) instead
of the other one (which is for version 21) and java_library having the
same name (which is for ToT).
Bug: 138182343
Test: m (sdk_test.go added)
Change-Id: I7e14c524a7d6a0d9f575fb20822080f39818c01e
2019-07-17 13:08:41 +02:00
android . InitSdkAwareModule ( module )
2019-11-13 02:50:48 +01:00
InitJavaModule ( module , android . HostAndDeviceSupported )
2018-06-27 02:59:05 +02:00
return module
2015-03-31 02:20:39 +02:00
}
2019-02-12 23:41:32 +01:00
// java_library_static is an obsolete alias for java_library.
func LibraryStaticFactory ( ) android . Module {
return LibraryFactory ( )
}
// java_library_host builds and links sources into a `.jar` file for the host.
//
// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
2017-07-20 00:53:04 +02:00
func LibraryHostFactory ( ) android . Module {
module := & Library { }
2015-03-31 02:20:39 +02:00
2017-09-20 21:59:05 +02:00
module . AddProperties (
& module . Module . properties ,
& module . Module . protoProperties )
2017-06-24 00:06:31 +02:00
2018-06-27 02:59:05 +02:00
module . Module . properties . Installable = proptools . BoolPtr ( true )
2019-07-25 15:02:35 +02:00
android . InitApexModule ( module )
2019-11-13 02:50:48 +01:00
InitJavaModule ( module , android . HostSupported )
2017-06-24 00:06:31 +02:00
return module
2015-03-31 02:20:39 +02:00
}
2018-04-10 03:40:24 +02:00
//
2018-08-15 01:42:33 +02:00
// Java Tests
2018-04-10 03:40:24 +02:00
//
type testProperties struct {
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites [ ] string ` android:"arch_variant" `
2018-08-03 00:00:46 +02:00
// the name of the test configuration (for example "AndroidTest.xml") that should be
// installed with the module.
2019-03-05 07:35:41 +01:00
Test_config * string ` android:"path,arch_variant" `
2018-08-11 01:06:24 +02:00
2018-09-19 11:21:28 +02:00
// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
// should be installed with the module.
2019-03-05 07:35:41 +01:00
Test_config_template * string ` android:"path,arch_variant" `
2018-09-19 11:21:28 +02:00
2018-08-11 01:06:24 +02:00
// list of files or filegroup modules that provide data that should be installed alongside
// the test
2019-03-05 07:35:41 +01:00
Data [ ] string ` android:"path" `
2019-09-26 20:41:36 +02:00
// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
// explicitly.
Auto_gen_config * bool
2018-04-10 03:40:24 +02:00
}
2019-03-20 13:45:53 +01:00
type testHelperLibraryProperties struct {
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites [ ] string ` android:"arch_variant" `
}
2019-12-03 19:06:47 +01:00
type prebuiltTestProperties struct {
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites [ ] string ` android:"arch_variant" `
// the name of the test configuration (for example "AndroidTest.xml") that should be
// installed with the module.
Test_config * string ` android:"path,arch_variant" `
}
2018-04-10 03:40:24 +02:00
type Test struct {
Library
testProperties testProperties
2018-08-08 01:49:25 +02:00
testConfig android . Path
2018-08-11 01:06:24 +02:00
data android . Paths
2018-08-08 01:49:25 +02:00
}
2019-03-20 13:45:53 +01:00
type TestHelperLibrary struct {
Library
testHelperLibraryProperties testHelperLibraryProperties
}
2019-12-03 19:06:47 +01:00
type JavaTestImport struct {
Import
prebuiltTestProperties prebuiltTestProperties
testConfig android . Path
}
2018-08-08 01:49:25 +02:00
func ( j * Test ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
2019-09-26 20:41:36 +02:00
j . testConfig = tradefed . AutoGenJavaTestConfig ( ctx , j . testProperties . Test_config , j . testProperties . Test_config_template ,
j . testProperties . Test_suites , j . testProperties . Auto_gen_config )
2019-03-06 07:25:09 +01:00
j . data = android . PathsForModuleSrc ( ctx , j . testProperties . Data )
2018-08-08 01:49:25 +02:00
j . Library . GenerateAndroidBuildActions ( ctx )
2018-04-10 03:40:24 +02:00
}
2019-03-20 13:45:53 +01:00
func ( j * TestHelperLibrary ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
j . Library . GenerateAndroidBuildActions ( ctx )
}
2019-12-03 19:06:47 +01:00
func ( j * JavaTestImport ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
j . testConfig = tradefed . AutoGenJavaTestConfig ( ctx , j . prebuiltTestProperties . Test_config , nil ,
j . prebuiltTestProperties . Test_suites , nil )
j . Import . GenerateAndroidBuildActions ( ctx )
}
type testSdkMemberType struct {
android . SdkMemberTypeBase
}
func ( mt * testSdkMemberType ) AddDependencies ( mctx android . BottomUpMutatorContext , dependencyTag blueprint . DependencyTag , names [ ] string ) {
mctx . AddVariationDependencies ( nil , dependencyTag , names ... )
}
func ( mt * testSdkMemberType ) IsInstance ( module android . Module ) bool {
_ , ok := module . ( * Test )
return ok
}
func ( mt * testSdkMemberType ) BuildSnapshot ( sdkModuleContext android . ModuleContext , builder android . SnapshotBuilder , member android . SdkMember ) {
variants := member . Variants ( )
if len ( variants ) != 1 {
sdkModuleContext . ModuleErrorf ( "sdk contains %d variants of member %q but only one is allowed" , len ( variants ) , member . Name ( ) )
for _ , variant := range variants {
sdkModuleContext . ModuleErrorf ( " %q" , variant )
}
}
variant := variants [ 0 ]
j := variant . ( * Test )
implementationJars := j . ImplementationJars ( )
if len ( implementationJars ) != 1 {
panic ( fmt . Errorf ( "there must be only one implementation jar from %q" , j . Name ( ) ) )
}
snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar ( member )
builder . CopyToSnapshot ( implementationJars [ 0 ] , snapshotRelativeJavaLibPath )
snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember ( member , testConfigSuffix )
builder . CopyToSnapshot ( j . testConfig , snapshotRelativeTestConfigPath )
module := builder . AddPrebuiltModule ( member , "java_test_import" )
module . AddProperty ( "jars" , [ ] string { snapshotRelativeJavaLibPath } )
module . AddProperty ( "test_config" , snapshotRelativeTestConfigPath )
}
2019-02-12 23:41:32 +01:00
// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
//
// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were
// compiled against the device bootclasspath.
//
// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
// compiled against the host bootclasspath.
2018-04-10 03:40:24 +02:00
func TestFactory ( ) android . Module {
module := & Test { }
module . AddProperties (
& module . Module . properties ,
& module . Module . deviceProperties ,
2018-11-12 19:13:39 +01:00
& module . Module . dexpreoptProperties ,
2018-04-10 03:40:24 +02:00
& module . Module . protoProperties ,
& module . testProperties )
2018-06-27 02:59:05 +02:00
module . Module . properties . Installable = proptools . BoolPtr ( true )
2019-01-06 07:30:13 +01:00
module . Module . dexpreopter . isTest = true
2018-06-27 02:59:05 +02:00
2018-04-10 03:40:24 +02:00
InitJavaModule ( module , android . HostAndDeviceSupported )
return module
}
2019-03-20 13:45:53 +01:00
// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite.
func TestHelperLibraryFactory ( ) android . Module {
module := & TestHelperLibrary { }
module . AddProperties (
& module . Module . properties ,
& module . Module . deviceProperties ,
& module . Module . dexpreoptProperties ,
& module . Module . protoProperties ,
& module . testHelperLibraryProperties )
2019-04-24 22:19:28 +02:00
module . Module . properties . Installable = proptools . BoolPtr ( true )
module . Module . dexpreopter . isTest = true
2019-03-20 13:45:53 +01:00
InitJavaModule ( module , android . HostAndDeviceSupported )
return module
}
2019-12-03 19:06:47 +01:00
// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module
// and makes sure that it is added to the appropriate test suite.
//
// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were
// compiled against an Android classpath.
//
// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
// for host modules.
func JavaTestImportFactory ( ) android . Module {
module := & JavaTestImport { }
module . AddProperties (
& module . Import . properties ,
& module . prebuiltTestProperties )
module . Import . properties . Installable = proptools . BoolPtr ( true )
android . InitPrebuiltModule ( module , & module . properties . Jars )
android . InitApexModule ( module )
android . InitSdkAwareModule ( module )
InitJavaModule ( module , android . HostAndDeviceSupported )
return module
}
2019-02-12 23:41:32 +01:00
// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
// allow running the test with `atest` or a `TEST_MAPPING` file.
//
// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
2018-04-10 03:40:24 +02:00
func TestHostFactory ( ) android . Module {
module := & Test { }
module . AddProperties (
& module . Module . properties ,
& module . Module . protoProperties ,
& module . testProperties )
2018-06-27 02:59:05 +02:00
module . Module . properties . Installable = proptools . BoolPtr ( true )
2018-04-10 03:40:24 +02:00
InitJavaModule ( module , android . HostSupported )
return module
}
2015-03-31 02:20:39 +02:00
//
// Java Binaries (.jar file plus wrapper script)
//
2017-07-20 00:53:04 +02:00
type binaryProperties struct {
2015-05-11 22:39:40 +02:00
// installable script to execute the resulting jar
2019-03-05 07:35:41 +01:00
Wrapper * string ` android:"path" `
2018-10-18 00:10:48 +02:00
// Name of the class containing main to be inserted into the manifest as Main-Class.
Main_class * string
2015-05-11 22:39:40 +02:00
}
2017-07-20 00:53:04 +02:00
type Binary struct {
Library
2015-03-31 02:20:39 +02:00
2017-07-20 00:53:04 +02:00
binaryProperties binaryProperties
2017-08-11 02:09:43 +02:00
2017-12-05 22:42:45 +01:00
isWrapperVariant bool
2017-12-09 04:12:36 +01:00
wrapperFile android . Path
2019-10-02 07:05:35 +02:00
binaryFile android . InstallPath
2015-03-31 02:20:39 +02:00
}
2017-10-26 18:46:21 +02:00
func ( j * Binary ) HostToolPath ( ) android . OptionalPath {
return android . OptionalPathForPath ( j . binaryFile )
}
2017-07-20 00:53:04 +02:00
func ( j * Binary ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
2017-12-05 22:42:45 +01:00
if ctx . Arch ( ) . ArchType == android . Common {
// Compile the jar
2018-10-18 00:10:48 +02:00
if j . binaryProperties . Main_class != nil {
if j . properties . Manifest != nil {
ctx . PropertyErrorf ( "main_class" , "main_class cannot be used when manifest is set" )
}
manifestFile := android . PathForModuleOut ( ctx , "manifest.txt" )
GenerateMainClassManifest ( ctx , manifestFile , String ( j . binaryProperties . Main_class ) )
j . overrideManifest = android . OptionalPathForPath ( manifestFile )
}
2017-12-05 22:42:45 +01:00
j . Library . GenerateAndroidBuildActions ( ctx )
2017-11-03 22:53:31 +01:00
} else {
2017-12-05 22:42:45 +01:00
// Handle the binary wrapper
j . isWrapperVariant = true
2017-12-12 01:29:02 +01:00
if j . binaryProperties . Wrapper != nil {
2019-03-06 07:25:09 +01:00
j . wrapperFile = android . PathForModuleSrc ( ctx , * j . binaryProperties . Wrapper )
2017-12-05 22:42:45 +01:00
} else {
j . wrapperFile = android . PathForSource ( ctx , "build/soong/scripts/jar-wrapper.sh" )
}
// Depend on the installed jar so that the wrapper doesn't get executed by
// another build rule before the jar has been installed.
jarFile := ctx . PrimaryModule ( ) . ( * Binary ) . installFile
j . binaryFile = ctx . InstallExecutable ( android . PathForModuleInstall ( ctx , "bin" ) ,
ctx . ModuleName ( ) , j . wrapperFile , jarFile )
2017-11-03 22:53:31 +01:00
}
2015-03-31 02:20:39 +02:00
}
2017-07-20 00:53:04 +02:00
func ( j * Binary ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
2017-12-05 22:42:45 +01:00
if ctx . Arch ( ) . ArchType == android . Common {
j . deps ( ctx )
}
2017-06-23 01:51:17 +02:00
}
2019-02-12 23:41:32 +01:00
// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host
// as well.
//
// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were
// compiled against the device bootclasspath.
//
// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
// compiled against the host bootclasspath.
2017-07-20 00:53:04 +02:00
func BinaryFactory ( ) android . Module {
module := & Binary { }
2015-03-31 02:20:39 +02:00
2017-06-24 00:06:31 +02:00
module . AddProperties (
2017-06-23 02:01:52 +02:00
& module . Module . properties ,
& module . Module . deviceProperties ,
2018-11-12 19:13:39 +01:00
& module . Module . dexpreoptProperties ,
2017-09-20 21:59:05 +02:00
& module . Module . protoProperties ,
2017-06-23 02:01:52 +02:00
& module . binaryProperties )
2017-06-24 00:06:31 +02:00
2018-06-27 02:59:05 +02:00
module . Module . properties . Installable = proptools . BoolPtr ( true )
2017-12-05 22:42:45 +01:00
android . InitAndroidArchModule ( module , android . HostAndDeviceSupported , android . MultilibCommonFirst )
android . InitDefaultableModule ( module )
2017-06-24 00:06:31 +02:00
return module
2015-03-31 02:20:39 +02:00
}
2019-02-12 23:41:32 +01:00
// java_binary_host builds a `.jar` file and a shell script that executes it for the host.
//
// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
2017-07-20 00:53:04 +02:00
func BinaryHostFactory ( ) android . Module {
module := & Binary { }
2015-03-31 02:20:39 +02:00
2017-06-24 00:06:31 +02:00
module . AddProperties (
2017-06-23 02:01:52 +02:00
& module . Module . properties ,
2017-09-20 21:59:05 +02:00
& module . Module . protoProperties ,
2017-06-23 02:01:52 +02:00
& module . binaryProperties )
2017-06-24 00:06:31 +02:00
2018-06-27 02:59:05 +02:00
module . Module . properties . Installable = proptools . BoolPtr ( true )
2017-12-05 22:42:45 +01:00
android . InitAndroidArchModule ( module , android . HostSupported , android . MultilibCommonFirst )
android . InitDefaultableModule ( module )
2017-06-24 00:06:31 +02:00
return module
2015-03-31 02:20:39 +02:00
}
//
// Java prebuilts
//
2017-08-02 20:05:49 +02:00
type ImportProperties struct {
2019-03-05 07:35:41 +01:00
Jars [ ] string ` android:"path" `
2017-10-20 22:59:18 +02:00
2017-11-09 06:20:04 +01:00
Sdk_version * string
2017-10-21 02:57:49 +02:00
Installable * bool
2018-05-28 11:02:19 +02:00
// List of shared java libs that this module has dependencies to
Libs [ ] string
2018-07-12 21:28:41 +02:00
// List of files to remove from the jar file(s)
Exclude_files [ ] string
// List of directories to remove from the jar file(s)
Exclude_dirs [ ] string
2018-08-28 03:31:46 +02:00
// if set to true, run Jetifier against .jar file. Defaults to false.
2019-03-22 06:21:39 +01:00
Jetifier * bool
2019-10-21 07:53:15 +02:00
// set the name of the output
Stem * string
2017-08-02 20:05:49 +02:00
}
type Import struct {
2016-05-19 00:37:25 +02:00
android . ModuleBase
2018-10-02 22:53:33 +02:00
android . DefaultableModuleBase
2019-07-25 15:02:35 +02:00
android . ApexModuleBase
2017-07-07 23:47:12 +02:00
prebuilt android . Prebuilt
Introduce module type 'sdk'
This change introduces a new module type named 'sdk'. It is a logical
group of prebuilt modules that together provide a context (e.g. APIs)
in which Mainline modules (such as APEXes) are built.
A prebuilt module (e.g. java_import) can join an sdk by adding it to the
sdk module as shown below:
sdk {
name: "mysdk#20",
java_libs: ["myjavalib_mysdk_20"],
}
java_import {
name: "myjavalib_mysdk_20",
srcs: ["myjavalib-v20.jar"],
sdk_member_name: "myjavalib",
}
sdk {
name: "mysdk#21",
java_libs: ["myjavalib_mysdk_21"],
}
java_import {
name: "myjavalib_mysdk_21",
srcs: ["myjavalib-v21.jar"],
sdk_member_name: "myjavalib",
}
java_library {
name: "myjavalib",
srcs: ["**/*/*.java"],
}
An APEX can specify the SDK(s) that it wants to build with via the new
'uses_sdks' property.
apex {
name: "myapex",
java_libs: ["libX", "libY"],
uses_sdks: ["mysdk#20"],
}
With this, libX, libY, and their transitive dependencies are all built
with the version 20 of myjavalib (the first java_import module) instead
of the other one (which is for version 21) and java_library having the
same name (which is for ToT).
Bug: 138182343
Test: m (sdk_test.go added)
Change-Id: I7e14c524a7d6a0d9f575fb20822080f39818c01e
2019-07-17 13:08:41 +02:00
android . SdkBase
2015-03-31 02:20:39 +02:00
2017-08-02 20:05:49 +02:00
properties ImportProperties
2017-08-30 23:24:55 +02:00
combinedClasspathFile android . Path
2018-05-28 11:02:19 +02:00
exportedSdkLibs [ ] string
2015-03-31 02:20:39 +02:00
}
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
func ( j * Import ) sdkVersion ( ) sdkSpec {
return sdkSpecFrom ( String ( j . properties . Sdk_version ) )
2018-06-26 00:48:06 +02:00
}
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
func ( j * Import ) minSdkVersion ( ) sdkSpec {
2018-06-26 00:48:06 +02:00
return j . sdkVersion ( )
}
2017-08-02 20:05:49 +02:00
func ( j * Import ) Prebuilt ( ) * android . Prebuilt {
2017-07-07 23:47:12 +02:00
return & j . prebuilt
}
2017-08-02 20:05:49 +02:00
func ( j * Import ) PrebuiltSrcs ( ) [ ] string {
return j . properties . Jars
}
func ( j * Import ) Name ( ) string {
2017-07-28 00:41:32 +02:00
return j . prebuilt . Name ( j . ModuleBase . Name ( ) )
}
2019-10-29 03:23:10 +01:00
func ( j * Import ) Stem ( ) string {
return proptools . StringDefault ( j . properties . Stem , j . ModuleBase . Name ( ) )
}
2020-01-08 05:35:43 +01:00
func ( a * Import ) JacocoReportClassesFile ( ) android . Path {
return nil
}
2017-08-02 20:05:49 +02:00
func ( j * Import ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
2018-08-29 23:10:52 +02:00
ctx . AddVariationDependencies ( nil , libTag , j . properties . Libs ... )
2016-10-12 23:38:15 +02:00
}
2017-08-02 20:05:49 +02:00
func ( j * Import ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
2019-03-06 07:25:09 +01:00
jars := android . PathsForModuleSrc ( ctx , j . properties . Jars )
2017-08-02 20:05:49 +02:00
2019-10-29 03:23:10 +01:00
jarName := j . Stem ( ) + ".jar"
2018-08-28 03:31:46 +02:00
outputFile := android . PathForModuleOut ( ctx , "combined" , jarName )
2018-07-12 21:28:41 +02:00
TransformJarsToJar ( ctx , outputFile , "for prebuilts" , jars , android . OptionalPath { } ,
false , j . properties . Exclude_files , j . properties . Exclude_dirs )
2019-03-22 06:21:39 +01:00
if Bool ( j . properties . Jetifier ) {
2018-08-28 03:31:46 +02:00
inputFile := outputFile
outputFile = android . PathForModuleOut ( ctx , "jetifier" , jarName )
TransformJetifier ( ctx , outputFile , inputFile )
}
2017-10-17 02:09:48 +02:00
j . combinedClasspathFile = outputFile
2018-05-28 11:02:19 +02:00
ctx . VisitDirectDeps ( func ( module android . Module ) {
otherName := ctx . OtherModuleName ( module )
tag := ctx . OtherModuleDependencyTag ( module )
switch dep := module . ( type ) {
case Dependency :
switch tag {
case libTag , staticLibTag :
// sdk lib names from dependencies are re-exported
j . exportedSdkLibs = append ( j . exportedSdkLibs , dep . ExportedSdkLibs ( ) ... )
}
case SdkLibraryDependency :
switch tag {
case libTag :
// names of sdk libs that are directly depended are exported
j . exportedSdkLibs = append ( j . exportedSdkLibs , otherName )
}
}
} )
j . exportedSdkLibs = android . FirstUniqueStrings ( j . exportedSdkLibs )
2018-08-10 22:42:12 +02:00
if Bool ( j . properties . Installable ) {
ctx . InstallFile ( android . PathForModuleInstall ( ctx , "framework" ) ,
2019-10-21 07:53:15 +02:00
jarName , outputFile )
2018-08-10 22:42:12 +02:00
}
2015-03-31 02:20:39 +02:00
}
2017-08-02 20:05:49 +02:00
var _ Dependency = ( * Import ) ( nil )
2015-03-31 02:20:39 +02:00
2017-10-19 22:06:22 +02:00
func ( j * Import ) HeaderJars ( ) android . Paths {
2018-12-25 07:35:23 +01:00
if j . combinedClasspathFile == nil {
return nil
}
2018-07-12 21:28:41 +02:00
return android . Paths { j . combinedClasspathFile }
2017-10-19 22:06:22 +02:00
}
func ( j * Import ) ImplementationJars ( ) android . Paths {
2018-12-24 08:41:04 +01:00
if j . combinedClasspathFile == nil {
return nil
}
2018-07-12 21:28:41 +02:00
return android . Paths { j . combinedClasspathFile }
2015-03-31 02:20:39 +02:00
}
2018-08-16 05:40:52 +02:00
func ( j * Import ) ResourceJars ( ) android . Paths {
return nil
}
func ( j * Import ) ImplementationAndResourcesJars ( ) android . Paths {
2018-12-25 07:35:23 +01:00
if j . combinedClasspathFile == nil {
return nil
}
2018-08-16 05:40:52 +02:00
return android . Paths { j . combinedClasspathFile }
}
2019-01-31 23:12:44 +01:00
func ( j * Import ) DexJar ( ) android . Path {
return nil
}
2017-08-02 20:05:49 +02:00
func ( j * Import ) AidlIncludeDirs ( ) android . Paths {
2015-04-08 22:03:43 +02:00
return nil
}
2018-05-28 11:02:19 +02:00
func ( j * Import ) ExportedSdkLibs ( ) [ ] string {
return j . exportedSdkLibs
}
2019-11-26 19:08:34 +01:00
func ( j * Import ) ExportedPlugins ( ) ( android . Paths , [ ] string ) {
return nil , nil
}
2019-05-04 00:28:19 +02:00
func ( j * Import ) SrcJarArgs ( ) ( [ ] string , android . Paths ) {
return nil , nil
}
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
func ( j * Import ) DepIsInSameApex ( ctx android . BaseModuleContext , dep android . Module ) bool {
// dependencies other than the static linkage are all considered crossing APEX boundary
2020-03-09 22:23:13 +01:00
if staticLibTag == ctx . OtherModuleDependencyTag ( dep ) {
return true
}
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
// Also, a dependency to an sdk member is also considered as such. This is required because
// sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
2020-03-09 22:23:13 +01:00
if sa , ok := dep . ( android . SdkAware ) ; ok && sa . IsInAnySdk ( ) {
return true
}
return false
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
}
2018-12-25 07:35:23 +01:00
// Add compile time check for interface implementation
var _ android . IDEInfo = ( * Import ) ( nil )
var _ android . IDECustomizedModuleName = ( * Import ) ( nil )
2018-08-16 00:35:38 +02:00
// Collect information for opening IDE project files in java/jdeps.go.
const (
removedPrefix = "prebuilt_"
)
func ( j * Import ) IDEInfo ( dpInfo * android . IdeInfo ) {
dpInfo . Jars = append ( dpInfo . Jars , j . PrebuiltSrcs ( ) ... )
}
func ( j * Import ) IDECustomizedModuleName ( ) string {
// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
// solution to get the Import name.
name := j . Name ( )
if strings . HasPrefix ( name , removedPrefix ) {
2018-10-11 12:33:16 +02:00
name = strings . TrimPrefix ( name , removedPrefix )
2018-08-16 00:35:38 +02:00
}
return name
}
2017-08-02 20:05:49 +02:00
var _ android . PrebuiltInterface = ( * Import ) ( nil )
2015-03-31 02:20:39 +02:00
2019-02-12 23:41:32 +01:00
// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
//
// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were
// compiled against an Android classpath.
//
// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
// for host modules.
2017-08-02 20:05:49 +02:00
func ImportFactory ( ) android . Module {
module := & Import { }
2017-06-24 00:06:31 +02:00
2017-08-02 20:05:49 +02:00
module . AddProperties ( & module . properties )
android . InitPrebuiltModule ( module , & module . properties . Jars )
2019-07-25 15:02:35 +02:00
android . InitApexModule ( module )
Introduce module type 'sdk'
This change introduces a new module type named 'sdk'. It is a logical
group of prebuilt modules that together provide a context (e.g. APIs)
in which Mainline modules (such as APEXes) are built.
A prebuilt module (e.g. java_import) can join an sdk by adding it to the
sdk module as shown below:
sdk {
name: "mysdk#20",
java_libs: ["myjavalib_mysdk_20"],
}
java_import {
name: "myjavalib_mysdk_20",
srcs: ["myjavalib-v20.jar"],
sdk_member_name: "myjavalib",
}
sdk {
name: "mysdk#21",
java_libs: ["myjavalib_mysdk_21"],
}
java_import {
name: "myjavalib_mysdk_21",
srcs: ["myjavalib-v21.jar"],
sdk_member_name: "myjavalib",
}
java_library {
name: "myjavalib",
srcs: ["**/*/*.java"],
}
An APEX can specify the SDK(s) that it wants to build with via the new
'uses_sdks' property.
apex {
name: "myapex",
java_libs: ["libX", "libY"],
uses_sdks: ["mysdk#20"],
}
With this, libX, libY, and their transitive dependencies are all built
with the version 20 of myjavalib (the first java_import module) instead
of the other one (which is for version 21) and java_library having the
same name (which is for ToT).
Bug: 138182343
Test: m (sdk_test.go added)
Change-Id: I7e14c524a7d6a0d9f575fb20822080f39818c01e
2019-07-17 13:08:41 +02:00
android . InitSdkAwareModule ( module )
2019-11-13 02:50:48 +01:00
InitJavaModule ( module , android . HostAndDeviceSupported )
2017-06-24 00:06:31 +02:00
return module
2015-03-31 02:20:39 +02:00
}
2019-02-12 23:41:32 +01:00
// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host
// module.
//
// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were
// compiled against a host bootclasspath.
2017-08-02 20:05:49 +02:00
func ImportFactoryHost ( ) android . Module {
module := & Import { }
module . AddProperties ( & module . properties )
android . InitPrebuiltModule ( module , & module . properties . Jars )
2019-07-25 15:02:35 +02:00
android . InitApexModule ( module )
2019-11-13 02:50:48 +01:00
InitJavaModule ( module , android . HostSupported )
2017-08-02 20:05:49 +02:00
return module
}
2019-02-22 03:12:14 +01:00
// dex_import module
type DexImportProperties struct {
2019-07-15 22:36:55 +02:00
Jars [ ] string ` android:"path" `
2019-10-21 07:53:15 +02:00
// set the name of the output
Stem * string
2019-02-22 03:12:14 +01:00
}
type DexImport struct {
android . ModuleBase
android . DefaultableModuleBase
2019-07-25 15:02:35 +02:00
android . ApexModuleBase
2019-02-22 03:12:14 +01:00
prebuilt android . Prebuilt
properties DexImportProperties
dexJarFile android . Path
maybeStrippedDexJarFile android . Path
dexpreopter
}
func ( j * DexImport ) Prebuilt ( ) * android . Prebuilt {
return & j . prebuilt
}
func ( j * DexImport ) PrebuiltSrcs ( ) [ ] string {
return j . properties . Jars
}
func ( j * DexImport ) Name ( ) string {
return j . prebuilt . Name ( j . ModuleBase . Name ( ) )
}
2019-10-29 03:23:10 +01:00
func ( j * DexImport ) Stem ( ) string {
return proptools . StringDefault ( j . properties . Stem , j . ModuleBase . Name ( ) )
}
2020-01-31 18:10:36 +01:00
func ( j * DexImport ) IsInstallable ( ) bool {
return true
}
2019-02-22 03:12:14 +01:00
func ( j * DexImport ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
if len ( j . properties . Jars ) != 1 {
ctx . PropertyErrorf ( "jars" , "exactly one jar must be provided" )
}
2019-10-29 03:23:10 +01:00
j . dexpreopter . installPath = android . PathForModuleInstall ( ctx , "framework" , j . Stem ( ) + ".jar" )
2019-02-22 03:12:14 +01:00
j . dexpreopter . uncompressedDex = shouldUncompressDex ( ctx , & j . dexpreopter )
inputJar := ctx . ExpandSource ( j . properties . Jars [ 0 ] , "jars" )
dexOutputFile := android . PathForModuleOut ( ctx , ctx . ModuleName ( ) + ".jar" )
if j . dexpreopter . uncompressedDex {
rule := android . NewRuleBuilder ( )
temporary := android . PathForModuleOut ( ctx , ctx . ModuleName ( ) + ".jar.unaligned" )
rule . Temporary ( temporary )
// use zip2zip to uncompress classes*.dex files
rule . Command ( ) .
2019-07-09 02:08:34 +02:00
BuiltTool ( ctx , "zip2zip" ) .
2019-02-22 03:12:14 +01:00
FlagWithInput ( "-i " , inputJar ) .
FlagWithOutput ( "-o " , temporary ) .
FlagWithArg ( "-0 " , "'classes*.dex'" )
// use zipalign to align uncompressed classes*.dex files
rule . Command ( ) .
2019-07-09 02:08:34 +02:00
BuiltTool ( ctx , "zipalign" ) .
2019-02-22 03:12:14 +01:00
Flag ( "-f" ) .
Text ( "4" ) .
Input ( temporary ) .
Output ( dexOutputFile )
rule . DeleteTemporaryFiles ( )
rule . Build ( pctx , ctx , "uncompress_dex" , "uncompress dex" )
} else {
ctx . Build ( pctx , android . BuildParams {
Rule : android . Cp ,
Input : inputJar ,
Output : dexOutputFile ,
} )
}
j . dexJarFile = dexOutputFile
dexOutputFile = j . dexpreopt ( ctx , dexOutputFile )
j . maybeStrippedDexJarFile = dexOutputFile
ctx . InstallFile ( android . PathForModuleInstall ( ctx , "framework" ) ,
ctx . ModuleName ( ) + ".jar" , dexOutputFile )
}
func ( j * DexImport ) DexJar ( ) android . Path {
return j . dexJarFile
}
// dex_import imports a `.jar` file containing classes.dex files.
//
// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
// to the device.
func DexImportFactory ( ) android . Module {
module := & DexImport { }
module . AddProperties ( & module . properties )
android . InitPrebuiltModule ( module , & module . properties . Jars )
2019-07-25 15:02:35 +02:00
android . InitApexModule ( module )
2019-11-13 02:50:48 +01:00
InitJavaModule ( module , android . DeviceSupported )
2019-02-22 03:12:14 +01:00
return module
}
2017-07-07 23:35:50 +02:00
//
// Defaults
//
type Defaults struct {
android . ModuleBase
android . DefaultsModuleBase
2019-07-25 15:02:35 +02:00
android . ApexModuleBase
2017-07-07 23:35:50 +02:00
}
2019-02-12 23:41:32 +01:00
// java_defaults provides a set of properties that can be inherited by other java or android modules.
//
// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`. Each
// property in the defaults module that exists in the depending module will be prepended to the depending module's
// value for that property.
//
// Example:
//
// java_defaults {
// name: "example_defaults",
// srcs: ["common/**/*.java"],
// javacflags: ["-Xlint:all"],
// aaptflags: ["--auto-add-overlay"],
// }
//
// java_library {
// name: "example",
// defaults: ["example_defaults"],
// srcs: ["example/**/*.java"],
// }
//
// is functionally identical to:
//
// java_library {
// name: "example",
// srcs: [
// "common/**/*.java",
// "example/**/*.java",
// ],
// javacflags: ["-Xlint:all"],
// }
2017-07-07 23:35:50 +02:00
func defaultsFactory ( ) android . Module {
return DefaultsFactory ( )
}
2019-12-05 15:07:14 +01:00
func DefaultsFactory ( ) android . Module {
2017-07-07 23:35:50 +02:00
module := & Defaults { }
module . AddProperties (
& CompilerProperties { } ,
& CompilerDeviceProperties { } ,
2018-11-12 19:13:39 +01:00
& DexpreoptProperties { } ,
2018-03-08 22:27:59 +01:00
& android . ProtoProperties { } ,
2018-10-02 22:53:33 +02:00
& aaptProperties { } ,
& androidLibraryProperties { } ,
& appProperties { } ,
& appTestProperties { } ,
2019-03-01 00:35:54 +01:00
& overridableAppProperties { } ,
2018-10-02 22:53:33 +02:00
& ImportProperties { } ,
& AARImportProperties { } ,
& sdkLibraryProperties { } ,
2019-02-22 03:12:14 +01:00
& DexImportProperties { } ,
2019-11-13 02:50:48 +01:00
& android . ApexProperties { } ,
2017-07-07 23:35:50 +02:00
)
android . InitDefaultsModule ( module )
return module
}
2017-11-09 06:20:04 +01:00
2018-11-06 01:49:08 +01:00
func kytheExtractJavaFactory ( ) android . Singleton {
return & kytheExtractJavaSingleton { }
}
type kytheExtractJavaSingleton struct {
}
func ( ks * kytheExtractJavaSingleton ) GenerateBuildActions ( ctx android . SingletonContext ) {
var xrefTargets android . Paths
ctx . VisitAllModules ( func ( module android . Module ) {
if javaModule , ok := module . ( xref ) ; ok {
xrefTargets = append ( xrefTargets , javaModule . XrefJavaFiles ( ) ... )
}
} )
// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
if len ( xrefTargets ) > 0 {
ctx . Build ( pctx , android . BuildParams {
Rule : blueprint . Phony ,
Output : android . PathForPhony ( ctx , "xref_java" ) ,
Inputs : xrefTargets ,
} )
}
}
2017-11-09 06:20:04 +01:00
var Bool = proptools . Bool
2018-04-11 01:14:46 +02:00
var BoolDefault = proptools . BoolDefault
2017-11-09 06:20:04 +01:00
var String = proptools . String
2018-02-20 22:33:42 +01:00
var inList = android . InList