2015-03-31 08:20:39 +08: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 07:51:17 +08:00
// into the flags and filenames necessary to pass to the Module. The final creation of the rules
2015-03-31 08:20:39 +08:00
// is handled in builder.go
import (
2017-09-19 08:41:52 +08:00
"path/filepath"
2017-08-03 02:05:49 +08:00
"strconv"
2015-03-31 08:20:39 +08:00
"strings"
"github.com/google/blueprint"
2017-08-30 07:02:06 +08:00
"github.com/google/blueprint/proptools"
2015-03-31 08:20:39 +08:00
2016-05-19 06:37:25 +08:00
"android/soong/android"
2017-06-23 08:20:19 +08:00
"android/soong/java/config"
2015-03-31 08:20:39 +08:00
)
2015-06-18 05:20:06 +08:00
func init ( ) {
2017-07-08 05:35:50 +08:00
android . RegisterModuleType ( "java_defaults" , defaultsFactory )
2017-10-03 09:10:21 +08:00
android . RegisterModuleType ( "java_library" , LibraryFactory ( true ) )
android . RegisterModuleType ( "java_library_static" , LibraryFactory ( false ) )
2017-07-20 06:53:04 +08:00
android . RegisterModuleType ( "java_library_host" , LibraryHostFactory )
android . RegisterModuleType ( "java_binary" , BinaryFactory )
android . RegisterModuleType ( "java_binary_host" , BinaryHostFactory )
2017-08-03 02:05:49 +08:00
android . RegisterModuleType ( "java_import" , ImportFactory )
android . RegisterModuleType ( "java_import_host" , ImportFactoryHost )
2016-10-13 05:28:16 +08:00
android . RegisterSingletonType ( "logtags" , LogtagsSingleton )
2015-06-18 05:20:06 +08:00
}
2015-03-31 08:20:39 +08:00
// TODO:
// Autogenerated files:
// Renderscript
// Post-jar passes:
// Proguard
// Rmtypedefs
// DroidDoc
// Findbugs
2017-07-08 05:35:50 +08:00
type CompilerProperties struct {
2015-05-12 04:39:40 +08:00
// list of source files used to compile the Java module. May be .java, .logtags, .proto,
// or .aidl files.
2015-07-01 09:15:24 +08:00
Srcs [ ] string ` android:"arch_variant" `
// 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
Exclude_srcs [ ] string ` android:"arch_variant" `
2015-03-31 08:20:39 +08:00
2015-05-12 04:39:40 +08:00
// list of directories containing Java resources
2017-09-28 08:33:10 +08:00
Java_resource_dirs [ ] string ` android:"arch_variant" `
2015-03-31 08:20:39 +08:00
2017-09-28 08:33:10 +08:00
// list of directories that should be excluded from java_resource_dirs
Exclude_java_resource_dirs [ ] string ` android:"arch_variant" `
2015-07-01 09:15:24 +08:00
2017-09-28 08:42:05 +08:00
// list of files to use as Java resources
Java_resources [ ] string ` android:"arch_variant" `
// list of files that should be excluded from java_resources
Exclude_java_resources [ ] string ` android:"arch_variant" `
2017-10-02 11:33:03 +08:00
// don't build against the default libraries (bootclasspath, legacy-test, core-junit,
2015-05-12 04:39:40 +08:00
// ext, and framework for device targets)
2017-08-30 07:02:06 +08:00
No_standard_libs * bool
2015-03-31 08:20:39 +08:00
2017-10-02 11:33:03 +08:00
// don't build against the framework libraries (legacy-test, core-junit,
// ext, and framework for device targets)
No_framework_libs * bool
2018-03-08 21:21:55 +08:00
// Use renamed kotlin stdlib (com.android.kotlin.*). This allows kotlin usage without colliding
// with app-provided kotlin stdlib.
Renamed_kotlin_stdlib * bool
2015-05-12 04:39:40 +08:00
// list of module-specific flags that will be used for javac compiles
Javacflags [ ] string ` android:"arch_variant" `
2015-03-31 08:20:39 +08:00
2015-05-12 04:39:40 +08:00
// list of of java libraries that will be in the classpath
2017-07-20 02:22:16 +08:00
Libs [ ] string ` android:"arch_variant" `
2015-03-31 08:20:39 +08:00
2015-05-12 04:39:40 +08:00
// list of java libraries that will be compiled into the resulting jar
2017-07-20 02:22:16 +08:00
Static_libs [ ] string ` android:"arch_variant" `
2015-03-31 08:20:39 +08:00
2015-05-12 04:39:40 +08:00
// manifest file to be included in resulting jar
2015-09-24 06:26:20 +08:00
Manifest * string
2015-03-31 08:20:39 +08:00
2017-06-23 08:01:52 +08:00
// if not blank, run jarjar using the specified rules file
2017-10-18 04:55:55 +08:00
Jarjar_rules * string ` android:"arch_variant" `
2017-08-09 04:17:59 +08:00
// If not blank, set the java version passed to javac as -source and -target
Java_version * string
2017-09-01 07:45:16 +08:00
// If set to false, don't allow this module to be installed. Defaults to true.
Installable * bool
2017-09-07 04:41:06 +08:00
2017-09-28 08:42:05 +08:00
// If set to true, include sources used to compile the module in to the final jar
Include_srcs * bool
2017-09-07 04:41:06 +08:00
// List of modules to use as annotation processors
Annotation_processors [ ] string
// List of classes to pass to javac to use as annotation processors
Annotation_processor_classes [ ] string
2017-09-30 08:58:17 +08:00
2017-11-03 04:28:15 +08:00
// The number of Java source entries each Javac instance can process
Javac_shard_size * int64
2018-02-07 02:34:32 +08:00
// Add host jdk tools.jar to bootclasspath
Use_tools_jar * bool
2017-09-30 08:58:17 +08:00
Openjdk9 struct {
// List of source files that should only be used when passing -source 1.9
Srcs [ ] string
// List of javac flags that should only be used when passing -source 1.9
Javacflags [ ] string
}
2017-11-23 05:49:43 +08: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 13:27:21 +08:00
Errorprone struct {
// List of javac flags that should only be used when running errorprone.
Javacflags [ ] string
}
2017-12-15 07:22:43 +08:00
Proto struct {
// List of extra options that will be passed to the proto generator.
Output_params [ ] string
}
2017-11-23 05:49:43 +08:00
Instrument bool ` blueprint:"mutated" `
2017-06-23 08:01:52 +08:00
}
2017-07-08 05:35:50 +08:00
type CompilerDeviceProperties struct {
2017-06-23 08:01:52 +08:00
// list of module-specific flags that will be used for dex compiles
Dxflags [ ] string ` android:"arch_variant" `
2015-05-12 04:39:40 +08:00
// if not blank, set to the version of the sdk to compile against
2017-11-09 13:20:04 +08:00
Sdk_version * string
2015-03-31 08:20:39 +08:00
2017-11-15 05:12:14 +08:00
Aidl struct {
// Top level directories to pass to aidl tool
Include_dirs [ ] string
2015-04-09 04:03:43 +08:00
2017-11-15 05:12:14 +08: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 16:29:59 +08:00
// whether to generate traces (for systrace) for this interface
Generate_traces * bool
2017-11-15 05:12:14 +08:00
}
2017-10-10 05:59:32 +08:00
// If true, export a copy of the module as a -hostdex module for host testing.
Hostdex * bool
2017-09-30 08:58:17 +08:00
2017-12-06 07:31:19 +08:00
Dex_preopt struct {
// If false, prevent dexpreopting and stripping the dex file from the final jar. Defaults to
// true.
Enabled * bool
// If true, generate an app image (.art file) for this module.
App_image * bool
// If true, use a checked-in profile to guide optimization. Defaults to false unless
// a matching profile is set or a profile is found in PRODUCT_DEX_PREOPT_PROFILE_DIR
// that matches the name of this module, in which case it is defaulted to true.
Profile_guided * bool
// If set, provides the path to profile relative to the Android.bp file. If not set,
// defaults to searching for a file that matches the name of this module in the default
// profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found.
Profile * string
}
2017-10-20 05:18:58 +08:00
2017-12-29 04:23:20 +08:00
Optimize struct {
// If false, disable all optimization. Defaults to true for apps, false for
// libraries and tests.
Enabled * bool
// 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.
Proguard_flags_files [ ] string
}
2017-09-30 08:58:17 +08:00
// When targeting 1.9, override the modules to use with --system
System_modules * string
2015-05-12 04:39:40 +08:00
}
2015-04-09 04:03:43 +08:00
2017-06-23 07:51:17 +08:00
// Module contains the properties and members used by all java module types
type Module struct {
2016-05-19 06:37:25 +08:00
android . ModuleBase
2017-07-08 05:35:50 +08:00
android . DefaultableModuleBase
2015-05-12 04:39:40 +08:00
2017-07-08 05:35:50 +08:00
properties CompilerProperties
2017-09-21 03:59:05 +08:00
protoProperties android . ProtoProperties
2017-07-08 05:35:50 +08:00
deviceProperties CompilerDeviceProperties
2015-03-31 08:20:39 +08:00
2017-10-20 04:06:22 +08:00
// header jar file suitable for inserting into the bootclasspath/classpath of another compile
headerJarFile android . Path
// full implementation jar file suitable for static dependency of another module compile
implementationJarFile android . Path
2015-03-31 08:20:39 +08:00
2017-09-16 04:00:47 +08:00
// output file containing classes.dex
dexJarFile android . Path
2017-11-23 05:49:43 +08:00
// output file containing uninstrumented classes that will be instrumented by jacoco
jacocoReportClassesFile android . Path
2017-12-29 04:23:20 +08:00
// output file containing mapping of obfuscated names
proguardDictionary android . Path
2015-04-17 05:09:14 +08:00
// output file suitable for installing or running
2016-05-19 06:37:25 +08:00
outputFile android . Path
2015-04-17 05:09:14 +08:00
2016-05-19 06:37:25 +08:00
exportAidlIncludeDirs android . Paths
2015-04-09 04:03:43 +08:00
2016-05-19 06:37:25 +08:00
logtagsSrcs android . Paths
2015-04-11 08:45:20 +08:00
2015-03-31 08:20:39 +08:00
// installed file for binary dependency
2016-05-19 06:37:25 +08:00
installFile android . Path
2017-11-23 08:20:45 +08:00
// list of .java files and srcjars that was passed to javac
compiledJavaSrcs android . Paths
compiledSrcJars android . Paths
2017-12-29 04:23:20 +08:00
// list of extra progurad flag files
extraProguardFlagFiles android . Paths
2015-03-31 08:20:39 +08:00
}
2017-12-06 01:28:08 +08:00
func ( j * Module ) Srcs ( ) android . Paths {
return android . Paths { j . implementationJarFile }
}
var _ android . SourceFileProducer = ( * Module ) ( nil )
2017-07-20 06:53:04 +08:00
type Dependency interface {
2017-10-20 04:06:22 +08:00
HeaderJars ( ) android . Paths
ImplementationJars ( ) android . Paths
2016-05-19 06:37:25 +08:00
AidlIncludeDirs ( ) android . Paths
2015-03-31 08:20:39 +08:00
}
2018-02-24 03:18:47 +08:00
type SrcDependency interface {
CompiledSrcs ( ) android . Paths
CompiledSrcJars ( ) android . Paths
}
func ( j * Module ) CompiledSrcs ( ) android . Paths {
return j . compiledJavaSrcs
}
func ( j * Module ) CompiledSrcJars ( ) android . Paths {
return j . compiledSrcJars
}
var _ SrcDependency = ( * Module ) ( nil )
2017-07-08 05:35:50 +08:00
func InitJavaModule ( module android . DefaultableModule , hod android . HostOrDeviceSupported ) {
android . InitAndroidArchModule ( module , hod , android . MultilibCommon )
android . InitDefaultableModule ( module )
}
2017-07-08 06:59:46 +08:00
type dependencyTag struct {
blueprint . BaseDependencyTag
name string
2015-03-31 08:20:39 +08:00
}
2017-07-08 06:59:46 +08:00
var (
2017-09-16 04:00:47 +08:00
staticLibTag = dependencyTag { name : "staticlib" }
libTag = dependencyTag { name : "javalib" }
bootClasspathTag = dependencyTag { name : "bootclasspath" }
2017-09-30 08:58:17 +08:00
systemModulesTag = dependencyTag { name : "system modules" }
2017-09-16 04:00:47 +08:00
frameworkResTag = dependencyTag { name : "framework-res" }
2018-02-24 03:18:47 +08:00
frameworkApkTag = dependencyTag { name : "framework-apk" }
2017-08-16 04:34:18 +08:00
kotlinStdlibTag = dependencyTag { name : "kotlin-stdlib" }
2017-12-29 04:23:20 +08:00
proguardRaiseTag = dependencyTag { name : "proguard-raise" }
2017-07-08 06:59:46 +08:00
)
2015-03-31 08:20:39 +08:00
2017-09-19 08:41:52 +08:00
type sdkDep struct {
2017-10-03 05:22:08 +08:00
useModule , useFiles , useDefaultLibs , invalidVersion bool
2017-09-30 08:58:17 +08:00
module string
systemModules string
jar android . Path
aidl android . Path
2017-09-19 08:41:52 +08:00
}
2017-09-30 08:58:17 +08:00
func sdkStringToNumber ( ctx android . BaseContext , v string ) int {
2017-09-19 08:41:52 +08:00
switch v {
2018-01-30 23:20:13 +08:00
case "" , "current" , "system_current" , "test_current" , "core_current" :
2018-01-15 14:05:10 +08:00
return android . FutureApiLevel
2017-09-19 08:41:52 +08:00
default :
2017-10-17 15:34:51 +08:00
if i , err := strconv . Atoi ( android . GetNumericSdkVersion ( v ) ) ; err != nil {
2017-09-19 08:41:52 +08:00
ctx . PropertyErrorf ( "sdk_version" , "invalid sdk version" )
2017-09-30 08:58:17 +08:00
return - 1
} else {
return i
2017-09-19 08:41:52 +08:00
}
}
2017-09-30 08:58:17 +08:00
}
2018-01-04 07:06:47 +08:00
func ( j * Module ) shouldInstrument ( ctx android . BaseContext ) bool {
return j . properties . Instrument && ctx . Config ( ) . IsEnvTrue ( "EMMA_INSTRUMENT" )
}
func ( j * Module ) shouldInstrumentStatic ( ctx android . BaseContext ) bool {
return j . shouldInstrument ( ctx ) &&
( ctx . Config ( ) . IsEnvTrue ( "EMMA_INSTRUMENT_STATIC" ) ||
ctx . Config ( ) . UnbundledBuild ( ) )
}
2017-09-30 08:58:17 +08:00
func decodeSdkDep ( ctx android . BaseContext , v string ) sdkDep {
i := sdkStringToNumber ( ctx , v )
if i == - 1 {
// Invalid sdk version, error handled by sdkStringToNumber.
return sdkDep { }
}
2017-09-19 08:41:52 +08:00
2018-01-15 14:05:10 +08:00
// Ensures that the specificed system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor apks)
// or PRODUCT_SYSTEMSDK_VERSIONS (for other apks or when BOARD_SYSTEMSDK_VERSIONS is not set)
if strings . HasPrefix ( v , "system_" ) && i != android . FutureApiLevel {
allowed_versions := ctx . DeviceConfig ( ) . PlatformSystemSdkVersions ( )
if ctx . DeviceSpecific ( ) || ctx . SocSpecific ( ) {
if len ( ctx . DeviceConfig ( ) . SystemSdkVersions ( ) ) > 0 {
allowed_versions = ctx . DeviceConfig ( ) . SystemSdkVersions ( )
}
}
version := strings . TrimPrefix ( v , "system_" )
if len ( allowed_versions ) > 0 && ! android . InList ( version , allowed_versions ) {
ctx . PropertyErrorf ( "sdk_version" , "incompatible sdk version %q. System SDK version should be one of %q" ,
v , allowed_versions )
}
}
2017-09-19 08:41:52 +08:00
toFile := func ( v string ) sdkDep {
2018-01-30 23:20:13 +08:00
isCore := strings . HasPrefix ( v , "core_" )
if isCore {
v = strings . TrimPrefix ( v , "core_" )
}
2017-09-19 08:41:52 +08:00
dir := filepath . Join ( "prebuilts/sdk" , v )
jar := filepath . Join ( dir , "android.jar" )
2018-01-30 23:20:13 +08:00
if isCore {
jar = filepath . Join ( dir , "core.jar" )
}
2017-09-19 08:41:52 +08:00
aidl := filepath . Join ( dir , "framework.aidl" )
2018-02-23 03:47:25 +08:00
jarPath := android . ExistentPathForSource ( ctx , jar )
aidlPath := android . ExistentPathForSource ( ctx , aidl )
2017-10-03 05:22:08 +08:00
2017-11-29 16:27:14 +08:00
if ( ! jarPath . Valid ( ) || ! aidlPath . Valid ( ) ) && ctx . Config ( ) . AllowMissingDependencies ( ) {
2017-10-03 05:22:08 +08:00
return sdkDep {
invalidVersion : true ,
module : "sdk_v" + v ,
}
}
2017-09-19 08:41:52 +08:00
if ! jarPath . Valid ( ) {
ctx . PropertyErrorf ( "sdk_version" , "invalid sdk version %q, %q does not exist" , v , jar )
return sdkDep { }
}
2017-10-03 05:22:08 +08:00
2017-09-19 08:41:52 +08:00
if ! aidlPath . Valid ( ) {
ctx . PropertyErrorf ( "sdk_version" , "invalid sdk version %q, %q does not exist" , v , aidl )
return sdkDep { }
}
2017-10-03 05:22:08 +08:00
2017-09-19 08:41:52 +08:00
return sdkDep {
useFiles : true ,
jar : jarPath . Path ( ) ,
aidl : aidlPath . Path ( ) ,
}
}
2017-10-21 05:00:31 +08:00
//toModule := func(m string) sdkDep {
// return sdkDep{
// useModule: true,
// module: m,
// systemModules: m + "_system_modules",
// }
//}
2017-09-19 08:41:52 +08:00
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . UnbundledBuild ( ) && v != "" {
2017-09-19 08:41:52 +08:00
return toFile ( v )
}
switch v {
case "" :
return sdkDep {
useDefaultLibs : true ,
}
2017-10-21 05:00:31 +08:00
// TODO(ccross): re-enable these once we generate stubs, until then
// use the stubs in prebuilts/sdk/*current
//case "current":
// return toModule("android_stubs_current")
//case "system_current":
// return toModule("android_system_stubs_current")
//case "test_current":
// return toModule("android_test_stubs_current")
2017-09-19 08:41:52 +08:00
default :
return toFile ( v )
}
}
2017-07-08 06:59:46 +08:00
func ( j * Module ) deps ( ctx android . BottomUpMutatorContext ) {
2017-09-30 08:58:17 +08:00
if ctx . Device ( ) {
if ! proptools . Bool ( j . properties . No_standard_libs ) {
2017-11-09 13:20:04 +08:00
sdkDep := decodeSdkDep ( ctx , String ( j . deviceProperties . Sdk_version ) )
2017-09-19 08:41:52 +08:00
if sdkDep . useDefaultLibs {
2017-09-24 10:57:16 +08:00
ctx . AddDependency ( ctx . Module ( ) , bootClasspathTag , config . DefaultBootclasspathLibraries ... )
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . TargetOpenJDK9 ( ) {
2017-09-30 08:58:17 +08:00
ctx . AddDependency ( ctx . Module ( ) , systemModulesTag , config . DefaultSystemModules )
}
2017-10-02 11:33:03 +08:00
if ! proptools . Bool ( j . properties . No_framework_libs ) {
ctx . AddDependency ( ctx . Module ( ) , libTag , config . DefaultLibraries ... )
}
2017-09-30 08:58:17 +08:00
} else if sdkDep . useModule {
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . TargetOpenJDK9 ( ) {
2017-09-30 08:58:17 +08:00
ctx . AddDependency ( ctx . Module ( ) , systemModulesTag , sdkDep . systemModules )
}
2017-09-19 08:41:52 +08:00
ctx . AddDependency ( ctx . Module ( ) , bootClasspathTag , sdkDep . module )
2017-12-29 04:23:20 +08:00
if Bool ( j . deviceProperties . Optimize . Enabled ) {
ctx . AddDependency ( ctx . Module ( ) , proguardRaiseTag , config . DefaultBootclasspathLibraries ... )
ctx . AddDependency ( ctx . Module ( ) , proguardRaiseTag , config . DefaultLibraries ... )
}
2017-07-08 06:59:46 +08:00
}
2017-09-30 08:58:17 +08:00
} else if j . deviceProperties . System_modules == nil {
ctx . PropertyErrorf ( "no_standard_libs" ,
"system_modules is required to be set when no_standard_libs is true, did you mean no_framework_libs?" )
2017-11-29 16:27:14 +08:00
} else if * j . deviceProperties . System_modules != "none" && ctx . Config ( ) . TargetOpenJDK9 ( ) {
2017-09-30 08:58:17 +08:00
ctx . AddDependency ( ctx . Module ( ) , systemModulesTag , * j . deviceProperties . System_modules )
2015-03-31 08:20:39 +08:00
}
2017-11-23 08:20:45 +08:00
if ctx . ModuleName ( ) == "framework" {
ctx . AddDependency ( ctx . Module ( ) , frameworkResTag , "framework-res" )
}
2018-02-24 03:18:47 +08:00
if ctx . ModuleName ( ) == "android_stubs_current" ||
ctx . ModuleName ( ) == "android_system_stubs_current" ||
ctx . ModuleName ( ) == "android_test_stubs_current" {
ctx . AddDependency ( ctx . Module ( ) , frameworkApkTag , "framework-res" )
}
2015-03-31 08:20:39 +08:00
}
2017-09-30 08:58:17 +08:00
2017-07-20 06:53:04 +08:00
ctx . AddDependency ( ctx . Module ( ) , libTag , j . properties . Libs ... )
ctx . AddDependency ( ctx . Module ( ) , staticLibTag , j . properties . Static_libs ... )
2017-09-16 04:00:47 +08:00
ctx . AddDependency ( ctx . Module ( ) , libTag , j . properties . Annotation_processors ... )
2017-08-31 04:27:57 +08:00
android . ExtractSourcesDeps ( ctx , j . properties . Srcs )
2018-02-10 05:03:53 +08:00
android . ExtractSourcesDeps ( ctx , j . properties . Exclude_srcs )
2017-09-28 08:42:05 +08:00
android . ExtractSourcesDeps ( ctx , j . properties . Java_resources )
2017-12-12 08:29:02 +08:00
android . ExtractSourceDeps ( ctx , j . properties . Manifest )
2017-09-21 03:59:05 +08:00
if j . hasSrcExt ( ".proto" ) {
protoDeps ( ctx , & j . protoProperties )
}
2017-08-16 04:34:18 +08:00
if j . hasSrcExt ( ".kt" ) {
// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
// Kotlin files
ctx . AddDependency ( ctx . Module ( ) , kotlinStdlibTag , "kotlin-stdlib" )
}
2018-01-04 07:06:47 +08:00
if j . shouldInstrumentStatic ( ctx ) {
ctx . AddDependency ( ctx . Module ( ) , staticLibTag , "jacocoagent" )
}
2017-09-21 03:59:05 +08:00
}
func hasSrcExt ( srcs [ ] string , ext string ) bool {
for _ , src := range srcs {
if filepath . Ext ( src ) == ext {
return true
}
}
return false
}
2017-11-03 04:28:15 +08:00
func shardPaths ( paths android . Paths , shardSize int ) [ ] android . Paths {
ret := make ( [ ] android . Paths , 0 , ( len ( paths ) + shardSize - 1 ) / shardSize )
for len ( paths ) > shardSize {
ret = append ( ret , paths [ 0 : shardSize ] )
paths = paths [ shardSize : ]
}
if len ( paths ) > 0 {
ret = append ( ret , paths )
}
return ret
}
2017-09-21 03:59:05 +08:00
func ( j * Module ) hasSrcExt ( ext string ) bool {
return hasSrcExt ( j . properties . Srcs , ext )
2015-03-31 08:20:39 +08:00
}
2017-06-23 07:51:17 +08:00
func ( j * Module ) aidlFlags ( ctx android . ModuleContext , aidlPreprocess android . OptionalPath ,
2016-05-19 06:37:25 +08:00
aidlIncludeDirs android . Paths ) [ ] string {
2015-04-09 04:03:43 +08:00
2017-11-15 05:12:14 +08: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-09 04:03:43 +08:00
var flags [ ] string
2015-09-24 06:26:20 +08:00
if aidlPreprocess . Valid ( ) {
flags = append ( flags , "-p" + aidlPreprocess . String ( ) )
2015-04-09 04:03:43 +08:00
} else {
2016-05-19 06:37:25 +08:00
flags = append ( flags , android . JoinWithPrefix ( aidlIncludeDirs . Strings ( ) , "-I" ) )
2015-04-09 04:03:43 +08:00
}
2016-05-19 06:37:25 +08:00
flags = append ( flags , android . JoinWithPrefix ( j . exportAidlIncludeDirs . Strings ( ) , "-I" ) )
2017-11-15 05:12:14 +08:00
flags = append ( flags , android . JoinWithPrefix ( aidlIncludes . Strings ( ) , "-I" ) )
2016-05-19 06:37:25 +08:00
flags = append ( flags , "-I" + android . PathForModuleSrc ( ctx ) . String ( ) )
2018-02-23 03:47:25 +08:00
if src := android . ExistentPathForSource ( ctx , ctx . ModuleDir ( ) , "src" ) ; src . Valid ( ) {
2017-07-14 05:41:17 +08:00
flags = append ( flags , "-I" + src . String ( ) )
}
2015-04-09 04:03:43 +08:00
2018-03-09 16:29:59 +08:00
if Bool ( j . deviceProperties . Aidl . Generate_traces ) {
flags = append ( flags , "-t" )
}
2015-04-14 04:53:40 +08:00
return flags
2015-04-09 04:03:43 +08:00
}
2017-09-07 04:41:06 +08:00
type deps struct {
2018-01-11 08:06:12 +08:00
classpath classpath
bootClasspath classpath
2017-09-16 04:00:47 +08:00
staticJars android . Paths
2017-10-20 04:06:22 +08:00
staticHeaderJars android . Paths
2017-09-16 04:00:47 +08:00
staticJarResources android . Paths
aidlIncludeDirs android . Paths
2018-02-24 03:18:47 +08:00
srcs android . Paths
2017-10-17 09:07:29 +08:00
srcJars android . Paths
2017-09-30 08:58:17 +08:00
systemModules android . Path
2017-09-16 04:00:47 +08:00
aidlPreprocess android . OptionalPath
2017-08-16 04:34:18 +08:00
kotlinStdlib android . Paths
2017-09-07 04:41:06 +08:00
}
2015-03-31 08:20:39 +08:00
2017-12-06 01:28:08 +08: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 16:44:10 +08:00
type linkType int
const (
javaCore linkType = iota
javaSdk
javaSystem
javaPlatform
)
func getLinkType ( m * Module ) linkType {
ver := String ( m . deviceProperties . Sdk_version )
if strings . HasPrefix ( ver , "core_" ) {
return javaCore
} else if strings . HasPrefix ( ver , "system_" ) {
return javaSystem
} else if _ , err := strconv . Atoi ( ver ) ; err == nil || ver == "current" {
return javaSdk
} else {
// test_current falls back here as well
return javaPlatform
}
}
2018-01-30 23:20:13 +08:00
func checkLinkType ( ctx android . ModuleContext , from * Module , to * Library , tag dependencyTag ) {
2018-03-05 16:44:10 +08:00
myLinkType := getLinkType ( from )
otherLinkType := getLinkType ( & to . Module )
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 :
if otherLinkType == javaPlatform {
ctx . ModuleErrorf ( "compiles against system API, but dependency %q is compiling against private API." + commonMessage ,
2018-01-30 23:20:13 +08:00
ctx . OtherModuleName ( to ) )
}
2018-03-05 16:44:10 +08:00
break
case javaPlatform :
// no restriction on link-type
break
2018-01-30 23:20:13 +08:00
}
}
2017-09-07 04:41:06 +08:00
func ( j * Module ) collectDeps ( ctx android . ModuleContext ) deps {
var deps deps
2017-09-19 08:41:52 +08:00
2018-03-07 05:11:51 +08:00
if ctx . Device ( ) {
sdkDep := decodeSdkDep ( ctx , String ( j . deviceProperties . Sdk_version ) )
if sdkDep . invalidVersion {
ctx . AddMissingDependencies ( [ ] string { sdkDep . module } )
} else if sdkDep . useFiles {
// sdkDep.jar is actually equivalent to turbine header.jar.
deps . classpath = append ( deps . classpath , sdkDep . jar )
deps . aidlIncludeDirs = append ( deps . aidlIncludeDirs , sdkDep . aidl )
}
2017-09-19 08:41:52 +08:00
}
2017-10-24 08:59:01 +08:00
ctx . VisitDirectDeps ( func ( module android . Module ) {
2015-03-31 08:20:39 +08:00
otherName := ctx . OtherModuleName ( module )
2017-07-08 05:47:12 +08:00
tag := ctx . OtherModuleDependencyTag ( module )
2018-01-30 23:20:13 +08:00
if to , ok := module . ( * Library ) ; ok {
checkLinkType ( ctx , j , to , tag . ( dependencyTag ) )
}
2017-12-06 01:28:08 +08:00
switch dep := module . ( type ) {
case Dependency :
switch tag {
case bootClasspathTag :
deps . bootClasspath = append ( deps . bootClasspath , dep . HeaderJars ( ) ... )
case libTag :
deps . classpath = append ( deps . classpath , dep . HeaderJars ( ) ... )
case staticLibTag :
deps . classpath = append ( deps . classpath , dep . HeaderJars ( ) ... )
deps . staticJars = append ( deps . staticJars , dep . ImplementationJars ( ) ... )
deps . staticHeaderJars = append ( deps . staticHeaderJars , dep . HeaderJars ( ) ... )
case frameworkResTag :
if ctx . ModuleName ( ) == "framework" {
// framework.jar has a one-off dependency on the R.java and Manifest.java files
// generated by framework-res.apk
deps . srcJars = append ( deps . srcJars , dep . ( * AndroidApp ) . aaptSrcJar )
}
2018-02-24 03:18:47 +08:00
case frameworkApkTag :
if ctx . ModuleName ( ) == "android_stubs_current" ||
ctx . ModuleName ( ) == "android_system_stubs_current" ||
ctx . ModuleName ( ) == "android_test_stubs_current" {
// 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.
deps . staticJarResources = append ( deps . staticJarResources , dep . ( * AndroidApp ) . exportPackage )
}
2017-12-06 01:28:08 +08:00
case kotlinStdlibTag :
deps . kotlinStdlib = dep . HeaderJars ( )
}
deps . aidlIncludeDirs = append ( deps . aidlIncludeDirs , dep . AidlIncludeDirs ( ) ... )
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 ( ) ... )
case android . DefaultsDepTag , android . SourceDepTag :
// Nothing to do
default :
ctx . ModuleErrorf ( "dependency on genrule %q may only be in srcs, libs, or static_libs" , otherName )
}
default :
2017-07-08 05:47:12 +08:00
switch tag {
case android . DefaultsDepTag , android . SourceDepTag :
2017-09-14 06:46:47 +08:00
// Nothing to do
2017-09-30 08:58:17 +08:00
case systemModulesTag :
if deps . systemModules != nil {
panic ( "Found two system module dependencies" )
}
sm := module . ( * SystemModules )
if sm . outputFile == nil {
panic ( "Missing directory for system module dependency" )
}
deps . systemModules = sm . outputFile
2017-07-08 05:47:12 +08:00
default :
ctx . ModuleErrorf ( "depends on non-java module %q" , otherName )
}
}
2015-03-31 08:20:39 +08:00
} )
2017-09-07 04:41:06 +08:00
return deps
2015-03-31 08:20:39 +08:00
}
2017-10-20 04:06:22 +08:00
func ( j * Module ) collectBuilderFlags ( ctx android . ModuleContext , deps deps ) javaBuilderFlags {
2015-04-09 04:03:43 +08:00
2015-04-14 04:53:40 +08:00
var flags javaBuilderFlags
2017-10-20 04:06:22 +08:00
// javac flags.
2015-04-14 04:53:40 +08:00
javacFlags := j . properties . Javacflags
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . TargetOpenJDK9 ( ) {
2017-09-30 08:58:17 +08:00
javacFlags = append ( javacFlags , j . properties . Openjdk9 . Javacflags ... )
2017-10-20 04:06:22 +08:00
}
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . MinimizeJavaDebugInfo ( ) {
2017-11-01 04:55:34 +08: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" )
}
2017-10-20 04:06:22 +08:00
if len ( javacFlags ) > 0 {
// optimization.
ctx . Variable ( pctx , "javacFlags" , strings . Join ( javacFlags , " " ) )
flags . javacFlags = "$javacFlags"
2017-09-07 03:52:16 +08:00
}
2017-08-09 04:17:59 +08:00
2018-01-23 13:27:21 +08:00
if len ( j . properties . Errorprone . Javacflags ) > 0 {
flags . errorProneExtraJavacFlags = strings . Join ( j . properties . Errorprone . Javacflags , " " )
}
2017-10-20 04:06:22 +08:00
// javaVersion flag.
2017-11-09 13:20:04 +08:00
sdk := sdkStringToNumber ( ctx , String ( j . deviceProperties . Sdk_version ) )
2017-08-09 04:17:59 +08:00
if j . properties . Java_version != nil {
flags . javaVersion = * j . properties . Java_version
2017-09-30 08:58:17 +08:00
} else if ctx . Device ( ) && sdk <= 23 {
flags . javaVersion = "1.7"
2017-11-29 16:27:14 +08:00
} else if ctx . Device ( ) && sdk <= 26 || ! ctx . Config ( ) . TargetOpenJDK9 ( ) {
2017-09-30 08:58:17 +08:00
flags . javaVersion = "1.8"
2018-01-15 14:05:10 +08:00
} else if ctx . Device ( ) && String ( j . deviceProperties . Sdk_version ) != "" && sdk == android . FutureApiLevel {
2017-10-21 05:00:31 +08:00
// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
flags . javaVersion = "1.8"
2017-08-09 04:17:59 +08:00
} else {
2017-09-30 08:58:17 +08:00
flags . javaVersion = "1.9"
2017-08-09 04:17:59 +08:00
}
2017-10-20 04:06:22 +08:00
// classpath
2018-01-11 08:06:12 +08:00
flags . bootClasspath = append ( flags . bootClasspath , deps . bootClasspath ... )
flags . classpath = append ( flags . classpath , deps . classpath ... )
2018-01-03 10:14:25 +08:00
if len ( flags . bootClasspath ) == 0 && ctx . Host ( ) && ! ctx . Config ( ) . TargetOpenJDK9 ( ) &&
! Bool ( j . properties . No_standard_libs ) &&
inList ( flags . javaVersion , [ ] string { "1.6" , "1.7" , "1.8" } ) {
// 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-07 02:34:32 +08:00
if Bool ( j . properties . Use_tools_jar ) {
flags . bootClasspath = append ( flags . bootClasspath ,
android . PathForSource ( ctx , java8Home , "lib/tools.jar" ) )
}
2018-01-03 10:14:25 +08:00
}
2017-10-20 04:06:22 +08:00
// systemModules
2017-09-30 08:58:17 +08:00
if deps . systemModules != nil {
flags . systemModules = append ( flags . systemModules , deps . systemModules )
}
2017-10-20 04:06:22 +08:00
// aidl flags.
2017-09-07 04:41:06 +08:00
aidlFlags := j . aidlFlags ( ctx , deps . aidlPreprocess , deps . aidlIncludeDirs )
2015-04-14 04:53:40 +08:00
if len ( aidlFlags ) > 0 {
2017-10-20 04:06:22 +08:00
// optimization.
2015-04-14 04:53:40 +08:00
ctx . Variable ( pctx , "aidlFlags" , strings . Join ( aidlFlags , " " ) )
flags . aidlFlags = "$aidlFlags"
2015-03-31 08:20:39 +08:00
}
2017-10-20 04:06:22 +08:00
return flags
}
2015-04-09 04:03:43 +08:00
2017-11-23 08:19:37 +08:00
func ( j * Module ) compile ( ctx android . ModuleContext , extraSrcJars ... android . Path ) {
2017-10-20 04:06:22 +08:00
2017-11-15 05:12:14 +08:00
j . exportAidlIncludeDirs = android . PathsForModuleSrc ( ctx , j . deviceProperties . Aidl . Export_include_dirs )
2017-10-20 04:06:22 +08:00
deps := j . collectDeps ( ctx )
flags := j . collectBuilderFlags ( ctx , deps )
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . TargetOpenJDK9 ( ) {
2017-10-20 04:06:22 +08:00
j . properties . Srcs = append ( j . properties . Srcs , j . properties . Openjdk9 . Srcs ... )
}
srcFiles := ctx . ExpandSources ( j . properties . Srcs , j . properties . Exclude_srcs )
2017-09-21 03:59:05 +08:00
if hasSrcExt ( srcFiles . Strings ( ) , ".proto" ) {
2017-12-15 07:22:43 +08:00
flags = protoFlags ( ctx , & j . properties , & j . protoProperties , flags )
2017-09-21 03:59:05 +08:00
}
2017-11-16 15:01:59 +08:00
srcFiles = j . genSources ( ctx , srcFiles , flags )
srcJars := srcFiles . FilterByExt ( ".srcjar" )
2017-10-17 09:07:29 +08:00
srcJars = append ( srcJars , deps . srcJars ... )
2017-11-23 08:19:37 +08:00
srcJars = append ( srcJars , extraSrcJars ... )
2015-04-17 05:09:14 +08:00
2017-08-31 05:24:55 +08:00
var jars android . Paths
2017-10-19 05:44:18 +08:00
jarName := ctx . ModuleName ( ) + ".jar"
2018-02-13 22:32:54 +08: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 )
}
}
2017-08-16 04:34:18 +08:00
if srcFiles . HasExt ( ".kt" ) {
// 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.
flags . kotlincFlags = "-no-stdlib"
2018-03-08 21:21:55 +08:00
2017-08-16 04:34:18 +08:00
if ctx . Device ( ) {
flags . kotlincFlags += " -no-jdk"
}
2018-02-13 22:32:54 +08:00
var kotlinSrcFiles android . Paths
kotlinSrcFiles = append ( kotlinSrcFiles , uniqueSrcFiles ... )
kotlinSrcFiles = append ( kotlinSrcFiles , srcFiles . FilterByExt ( ".kt" ) ... )
2018-03-06 00:06:42 +08:00
flags . kotlincClasspath = append ( flags . kotlincClasspath , deps . bootClasspath ... )
2017-08-16 04:34:18 +08:00
flags . kotlincClasspath = append ( flags . kotlincClasspath , deps . kotlinStdlib ... )
flags . kotlincClasspath = append ( flags . kotlincClasspath , deps . classpath ... )
2017-10-19 05:44:18 +08:00
kotlinJar := android . PathForModuleOut ( ctx , "kotlin" , jarName )
2018-02-13 22:32:54 +08:00
TransformKotlinToClasses ( ctx , kotlinJar , kotlinSrcFiles , srcJars , flags )
2017-08-16 04:34:18 +08:00
if ctx . Failed ( ) {
return
}
// Make javac rule depend on the kotlinc rule
flags . classpath = append ( flags . classpath , kotlinJar )
2018-03-08 21:21:55 +08:00
2017-08-16 04:34:18 +08:00
// Jar kotlin classes into the final jar after javac
jars = append ( jars , kotlinJar )
2018-03-08 21:21:55 +08:00
// Don't add kotlin-stdlib if using (on-device) renamed stdlib
// (it's expected to be on device bootclasspath)
if ! proptools . Bool ( j . properties . Renamed_kotlin_stdlib ) {
jars = append ( jars , deps . kotlinStdlib ... )
}
2017-08-16 04:34:18 +08:00
}
2017-11-23 08:20:45 +08:00
// Store the list of .java files that was passed to javac
j . compiledJavaSrcs = uniqueSrcFiles
j . compiledSrcJars = srcJars
2017-11-03 04:28:15 +08:00
enable_sharding := false
2017-11-29 16:27:14 +08:00
if ctx . Device ( ) && ! ctx . Config ( ) . IsEnvFalse ( "TURBINE_ENABLED" ) {
2017-11-03 04:28:15 +08:00
if j . properties . Javac_shard_size != nil && * ( j . properties . Javac_shard_size ) > 0 {
enable_sharding = true
if len ( j . properties . Annotation_processors ) != 0 ||
len ( j . properties . Annotation_processor_classes ) != 0 {
ctx . PropertyErrorf ( "javac_shard_size" ,
"%q cannot be set when annotation processors are enabled." ,
j . properties . Javac_shard_size )
}
}
2017-10-20 04:06:22 +08:00
// If sdk jar is java module, then directly return classesJar as header.jar
if j . Name ( ) != "android_stubs_current" && j . Name ( ) != "android_system_stubs_current" &&
j . Name ( ) != "android_test_stubs_current" {
j . headerJarFile = j . compileJavaHeader ( ctx , uniqueSrcFiles , srcJars , deps , flags , jarName )
if ctx . Failed ( ) {
return
}
}
}
2017-10-25 08:46:00 +08:00
if len ( uniqueSrcFiles ) > 0 || len ( srcJars ) > 0 {
2017-09-28 08:39:56 +08:00
var extraJarDeps android . Paths
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . IsEnvTrue ( "RUN_ERROR_PRONE" ) {
2017-08-15 05:16:06 +08: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 08:39:56 +08:00
// a rebuild when error-prone is turned off).
2017-08-15 05:16:06 +08: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-19 05:44:18 +08:00
errorprone := android . PathForModuleOut ( ctx , "errorprone" , jarName )
2017-11-03 04:28:15 +08:00
RunErrorProne ( ctx , errorprone , uniqueSrcFiles , srcJars , flags )
2017-08-15 05:16:06 +08:00
extraJarDeps = append ( extraJarDeps , errorprone )
}
2017-11-03 04:28:15 +08:00
if enable_sharding {
2018-01-11 08:06:12 +08:00
flags . classpath = append ( flags . classpath , j . headerJarFile )
2017-11-03 04:28:15 +08:00
shardSize := int ( * ( j . properties . Javac_shard_size ) )
var shardSrcs [ ] android . Paths
if len ( uniqueSrcFiles ) > 0 {
shardSrcs = shardPaths ( uniqueSrcFiles , shardSize )
for idx , shardSrc := range shardSrcs {
classes := android . PathForModuleOut ( ctx , "javac" , jarName + strconv . Itoa ( idx ) )
TransformJavaToClasses ( ctx , classes , idx , shardSrc , nil , flags , extraJarDeps )
jars = append ( jars , classes )
}
}
if len ( srcJars ) > 0 {
classes := android . PathForModuleOut ( ctx , "javac" , jarName + strconv . Itoa ( len ( shardSrcs ) ) )
TransformJavaToClasses ( ctx , classes , len ( shardSrcs ) , nil , srcJars , flags , extraJarDeps )
jars = append ( jars , classes )
}
} else {
classes := android . PathForModuleOut ( ctx , "javac" , jarName )
TransformJavaToClasses ( ctx , classes , - 1 , uniqueSrcFiles , srcJars , flags , extraJarDeps )
jars = append ( jars , classes )
}
2017-09-28 08:39:56 +08:00
if ctx . Failed ( ) {
return
}
2015-03-31 08:20:39 +08:00
}
2017-09-28 08:42:05 +08:00
dirArgs , dirDeps := ResourceDirsToJarArgs ( ctx , j . properties . Java_resource_dirs , j . properties . Exclude_java_resource_dirs )
fileArgs , fileDeps := ResourceFilesToJarArgs ( ctx , j . properties . Java_resources , j . properties . Exclude_java_resources )
var resArgs [ ] string
var resDeps android . Paths
resArgs = append ( resArgs , dirArgs ... )
resDeps = append ( resDeps , dirDeps ... )
resArgs = append ( resArgs , fileArgs ... )
resDeps = append ( resDeps , fileDeps ... )
if proptools . Bool ( j . properties . Include_srcs ) {
2017-10-04 04:14:07 +08:00
srcArgs , srcDeps := SourceFilesToJarArgs ( ctx , j . properties . Srcs , j . properties . Exclude_srcs )
2017-09-28 08:42:05 +08:00
resArgs = append ( resArgs , srcArgs ... )
resDeps = append ( resDeps , srcDeps ... )
}
2017-09-28 08:41:35 +08:00
if len ( resArgs ) > 0 {
2017-10-19 05:44:18 +08:00
resourceJar := android . PathForModuleOut ( ctx , "res" , jarName )
2017-10-17 08:09:48 +08:00
TransformResourcesToJar ( ctx , resourceJar , resArgs , resDeps )
2017-08-31 05:24:55 +08:00
if ctx . Failed ( ) {
return
}
2015-03-31 08:20:39 +08:00
2017-08-31 05:24:55 +08:00
jars = append ( jars , resourceJar )
2015-03-31 08:20:39 +08:00
}
2015-04-04 07:54:17 +08:00
2017-09-16 04:00:47 +08:00
// static classpath jars have the resources in them, so the resource jars aren't necessary here
2017-09-07 04:41:06 +08:00
jars = append ( jars , deps . staticJars ... )
2018-02-24 03:18:47 +08:00
jars = append ( jars , deps . staticJarResources ... )
2017-08-31 05:24:55 +08:00
2017-12-12 08:29:02 +08:00
var manifest android . OptionalPath
if j . properties . Manifest != nil {
manifest = android . OptionalPathForPath ( ctx . ExpandSource ( * j . properties . Manifest , "manifest" ) )
}
2017-09-13 13:50:46 +08:00
2017-08-31 05:24:55 +08:00
// Combine the classes built from sources, any manifests, and any static libraries into
2017-10-20 04:06:22 +08:00
// classes.jar. If there is only one input jar this step will be skipped.
2017-10-17 08:09:48 +08:00
var outputFile android . Path
if len ( jars ) == 1 && ! manifest . Valid ( ) {
// Optimization: skip the combine step if there is nothing to do
2017-12-22 05:52:58 +08:00
// 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.
2017-10-17 08:09:48 +08:00
outputFile = jars [ 0 ]
} else {
2017-10-19 05:44:18 +08:00
combinedJar := android . PathForModuleOut ( ctx , "combined" , jarName )
2017-10-20 04:06:22 +08:00
TransformJarsToJar ( ctx , combinedJar , "for javac" , jars , manifest , false , nil )
2017-10-17 08:09:48 +08:00
outputFile = combinedJar
}
2017-08-31 05:24:55 +08:00
2018-03-08 21:21:55 +08:00
// Use renamed kotlin standard library?
if srcFiles . HasExt ( ".kt" ) && proptools . Bool ( j . properties . Renamed_kotlin_stdlib ) {
jarjarFile := android . PathForModuleOut ( ctx , "kotlin-renamed" , jarName )
TransformJarJar ( ctx , jarjarFile , outputFile ,
android . PathForSource ( ctx , "external/kotlinc/jarjar-rules.txt" ) )
outputFile = jarjarFile
if ctx . Failed ( ) {
return
}
}
2015-09-24 06:26:20 +08:00
if j . properties . Jarjar_rules != nil {
2016-05-19 06:37:25 +08:00
jarjar_rules := android . PathForModuleSrc ( ctx , * j . properties . Jarjar_rules )
2017-09-28 09:03:17 +08:00
// Transform classes.jar into classes-jarjar.jar
2017-10-19 05:44:18 +08:00
jarjarFile := android . PathForModuleOut ( ctx , "jarjar" , jarName )
2017-10-17 08:09:48 +08:00
TransformJarJar ( ctx , jarjarFile , outputFile , jarjar_rules )
outputFile = jarjarFile
2015-04-04 07:54:17 +08:00
if ctx . Failed ( ) {
return
}
}
2017-10-20 04:06:22 +08:00
j . implementationJarFile = outputFile
if j . headerJarFile == nil {
j . headerJarFile = j . implementationJarFile
}
2015-03-31 08:20:39 +08:00
2017-11-29 16:27:14 +08:00
if ctx . Config ( ) . IsEnvTrue ( "EMMA_INSTRUMENT_FRAMEWORK" ) {
2017-11-23 05:49:43 +08:00
if inList ( ctx . ModuleName ( ) , config . InstrumentFrameworkModules ) {
j . properties . Instrument = true
}
}
2018-01-04 07:06:47 +08:00
if j . shouldInstrument ( ctx ) {
2017-11-23 05:49:43 +08:00
outputFile = j . instrument ( ctx , flags , outputFile , jarName )
}
2017-10-04 08:17:07 +08:00
if ctx . Device ( ) && j . installable ( ) {
2017-12-23 07:56:08 +08:00
outputFile = j . compileDex ( ctx , flags , outputFile , jarName )
2017-10-20 04:06:22 +08:00
if ctx . Failed ( ) {
return
2015-03-31 08:20:39 +08:00
}
2017-10-20 04:06:22 +08:00
}
ctx . CheckbuildFile ( outputFile )
j . outputFile = outputFile
}
2015-03-31 08:20:39 +08:00
2017-10-25 08:46:00 +08:00
func ( j * Module ) compileJavaHeader ( ctx android . ModuleContext , srcFiles , srcJars android . Paths ,
2017-10-20 04:06:22 +08:00
deps deps , flags javaBuilderFlags , jarName string ) android . Path {
2015-03-31 08:20:39 +08:00
2017-10-20 04:06:22 +08:00
var jars android . Paths
2017-10-25 08:46:00 +08:00
if len ( srcFiles ) > 0 || len ( srcJars ) > 0 {
2017-10-20 04:06:22 +08:00
// Compile java sources into turbine.jar.
turbineJar := android . PathForModuleOut ( ctx , "turbine" , jarName )
TransformJavaToHeaderClasses ( ctx , turbineJar , srcFiles , srcJars , flags )
if ctx . Failed ( ) {
return nil
2015-03-31 08:20:39 +08:00
}
2017-10-20 04:06:22 +08:00
jars = append ( jars , turbineJar )
}
2015-03-31 08:20:39 +08:00
2017-10-20 04:06:22 +08:00
// Combine any static header libraries into classes-header.jar. If there is only
// one input jar this step will be skipped.
var headerJar android . Path
jars = append ( jars , deps . staticHeaderJars ... )
2017-10-24 09:12:27 +08: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 )
TransformJarsToJar ( ctx , combinedJar , "for turbine" , jars , android . OptionalPath { } , false , [ ] string { "META-INF" } )
headerJar = combinedJar
2017-10-20 04:06:22 +08:00
if j . properties . Jarjar_rules != nil {
jarjar_rules := android . PathForModuleSrc ( ctx , * j . properties . Jarjar_rules )
// Transform classes.jar into classes-jarjar.jar
jarjarFile := android . PathForModuleOut ( ctx , "turbine-jarjar" , jarName )
TransformJarJar ( ctx , jarjarFile , headerJar , jarjar_rules )
headerJar = jarjarFile
if ctx . Failed ( ) {
return nil
2017-09-01 03:30:37 +08:00
}
2017-10-20 04:06:22 +08:00
}
2017-09-01 03:30:37 +08:00
2017-10-20 04:06:22 +08:00
return headerJar
}
2017-09-01 03:30:37 +08:00
2017-11-23 05:49:43 +08:00
func ( j * Module ) instrument ( ctx android . ModuleContext , flags javaBuilderFlags ,
classesJar android . Path , jarName string ) android . Path {
2017-12-20 05:57:50 +08:00
specs := j . jacocoModuleToZipCommand ( ctx )
2017-11-23 05:49:43 +08:00
2018-01-04 07:59:46 +08:00
jacocoReportClassesFile := android . PathForModuleOut ( ctx , "jacoco-report-classes" , jarName )
2017-11-23 05:49:43 +08:00
instrumentedJar := android . PathForModuleOut ( ctx , "jacoco" , jarName )
jacocoInstrumentJar ( ctx , instrumentedJar , jacocoReportClassesFile , classesJar , specs )
j . jacocoReportClassesFile = jacocoReportClassesFile
return instrumentedJar
}
// Returns a sdk version as a string that is guaranteed to be a parseable as a number. For
// modules targeting an unreleased SDK (meaning it does not yet have a number) it returns "10000".
func ( j * Module ) minSdkVersionNumber ( ctx android . ModuleContext ) string {
switch String ( j . deviceProperties . Sdk_version ) {
2018-01-30 23:20:13 +08:00
case "" , "current" , "test_current" , "system_current" , "core_current" :
2017-11-29 16:27:14 +08:00
return strconv . Itoa ( ctx . Config ( ) . DefaultAppTargetSdkInt ( ) )
2017-11-23 05:49:43 +08:00
default :
2017-10-17 15:34:51 +08:00
return android . GetNumericSdkVersion ( String ( j . deviceProperties . Sdk_version ) )
2017-11-23 05:49:43 +08:00
}
}
2017-09-28 08:59:10 +08:00
func ( j * Module ) installable ( ) bool {
return j . properties . Installable == nil || * j . properties . Installable
}
2017-07-20 06:53:04 +08:00
var _ Dependency = ( * Library ) ( nil )
2015-03-31 08:20:39 +08:00
2017-10-20 04:06:22 +08:00
func ( j * Module ) HeaderJars ( ) android . Paths {
return android . Paths { j . headerJarFile }
}
func ( j * Module ) ImplementationJars ( ) android . Paths {
return android . Paths { j . implementationJarFile }
2015-03-31 08:20:39 +08:00
}
2017-06-23 07:51:17 +08:00
func ( j * Module ) AidlIncludeDirs ( ) android . Paths {
2015-04-09 04:03:43 +08:00
return j . exportAidlIncludeDirs
}
2017-06-23 07:51:17 +08:00
var _ logtagsProducer = ( * Module ) ( nil )
2015-04-11 08:45:20 +08:00
2017-06-23 07:51:17 +08:00
func ( j * Module ) logtags ( ) android . Paths {
2015-04-11 08:45:20 +08:00
return j . logtagsSrcs
}
2015-03-31 08:20:39 +08:00
//
// Java libraries (.jar file)
//
2017-07-20 06:53:04 +08:00
type Library struct {
2017-06-23 07:51:17 +08:00
Module
2015-03-31 08:20:39 +08:00
}
2017-07-20 06:53:04 +08:00
func ( j * Library ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
2017-06-23 07:51:17 +08:00
j . compile ( ctx )
2015-04-17 05:09:14 +08:00
2017-09-28 08:59:10 +08:00
if j . installable ( ) {
2017-09-01 07:45:16 +08:00
j . installFile = ctx . InstallFile ( android . PathForModuleInstall ( ctx , "framework" ) ,
ctx . ModuleName ( ) + ".jar" , j . outputFile )
}
2015-04-17 05:09:14 +08:00
}
2017-07-20 06:53:04 +08:00
func ( j * Library ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
2017-06-23 07:51:17 +08:00
j . deps ( ctx )
}
2017-10-03 09:10:21 +08:00
func LibraryFactory ( installable bool ) func ( ) android . Module {
return func ( ) android . Module {
module := & Library { }
2015-03-31 08:20:39 +08:00
2017-10-03 09:10:21 +08:00
if ! installable {
module . properties . Installable = proptools . BoolPtr ( false )
}
2015-03-31 08:20:39 +08:00
2017-10-03 09:10:21 +08:00
module . AddProperties (
& module . Module . properties ,
2017-09-21 03:59:05 +08:00
& module . Module . deviceProperties ,
& module . Module . protoProperties )
2017-06-24 06:06:31 +08:00
2017-10-03 09:10:21 +08:00
InitJavaModule ( module , android . HostAndDeviceSupported )
return module
}
2015-03-31 08:20:39 +08:00
}
2017-07-20 06:53:04 +08:00
func LibraryHostFactory ( ) android . Module {
module := & Library { }
2015-03-31 08:20:39 +08:00
2017-09-21 03:59:05 +08:00
module . AddProperties (
& module . Module . properties ,
& module . Module . protoProperties )
2017-06-24 06:06:31 +08:00
2017-07-08 05:35:50 +08:00
InitJavaModule ( module , android . HostSupported )
2017-06-24 06:06:31 +08:00
return module
2015-03-31 08:20:39 +08:00
}
//
// Java Binaries (.jar file plus wrapper script)
//
2017-07-20 06:53:04 +08:00
type binaryProperties struct {
2015-05-12 04:39:40 +08:00
// installable script to execute the resulting jar
2017-11-09 13:20:04 +08:00
Wrapper * string
2015-05-12 04:39:40 +08:00
}
2017-07-20 06:53:04 +08:00
type Binary struct {
Library
2015-03-31 08:20:39 +08:00
2017-07-20 06:53:04 +08:00
binaryProperties binaryProperties
2017-08-11 08:09:43 +08:00
2017-12-06 05:42:45 +08:00
isWrapperVariant bool
2017-12-09 11:12:36 +08:00
wrapperFile android . Path
2017-08-11 08:09:43 +08:00
binaryFile android . OutputPath
2015-03-31 08:20:39 +08:00
}
2017-10-27 00:46:21 +08:00
func ( j * Binary ) HostToolPath ( ) android . OptionalPath {
return android . OptionalPathForPath ( j . binaryFile )
}
2017-07-20 06:53:04 +08:00
func ( j * Binary ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
2017-12-06 05:42:45 +08:00
if ctx . Arch ( ) . ArchType == android . Common {
// Compile the jar
j . Library . GenerateAndroidBuildActions ( ctx )
2017-11-04 05:53:31 +08:00
} else {
2017-12-06 05:42:45 +08:00
// Handle the binary wrapper
j . isWrapperVariant = true
2017-12-12 08:29:02 +08:00
if j . binaryProperties . Wrapper != nil {
j . wrapperFile = ctx . ExpandSource ( * j . binaryProperties . Wrapper , "wrapper" )
2017-12-06 05:42:45 +08: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-04 05:53:31 +08:00
}
2015-03-31 08:20:39 +08:00
}
2017-07-20 06:53:04 +08:00
func ( j * Binary ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
2017-12-06 05:42:45 +08:00
if ctx . Arch ( ) . ArchType == android . Common {
j . deps ( ctx )
2017-12-09 11:12:36 +08:00
} else {
2017-12-12 08:29:02 +08:00
android . ExtractSourceDeps ( ctx , j . binaryProperties . Wrapper )
2017-12-06 05:42:45 +08:00
}
2017-06-23 07:51:17 +08:00
}
2017-07-20 06:53:04 +08:00
func BinaryFactory ( ) android . Module {
module := & Binary { }
2015-03-31 08:20:39 +08:00
2017-06-24 06:06:31 +08:00
module . AddProperties (
2017-06-23 08:01:52 +08:00
& module . Module . properties ,
& module . Module . deviceProperties ,
2017-09-21 03:59:05 +08:00
& module . Module . protoProperties ,
2017-06-23 08:01:52 +08:00
& module . binaryProperties )
2017-06-24 06:06:31 +08:00
2017-12-06 05:42:45 +08:00
android . InitAndroidArchModule ( module , android . HostAndDeviceSupported , android . MultilibCommonFirst )
android . InitDefaultableModule ( module )
2017-06-24 06:06:31 +08:00
return module
2015-03-31 08:20:39 +08:00
}
2017-07-20 06:53:04 +08:00
func BinaryHostFactory ( ) android . Module {
module := & Binary { }
2015-03-31 08:20:39 +08:00
2017-06-24 06:06:31 +08:00
module . AddProperties (
2017-06-23 08:01:52 +08:00
& module . Module . properties ,
2017-09-21 03:59:05 +08:00
& module . Module . protoProperties ,
2017-06-23 08:01:52 +08:00
& module . binaryProperties )
2017-06-24 06:06:31 +08:00
2017-12-06 05:42:45 +08:00
android . InitAndroidArchModule ( module , android . HostSupported , android . MultilibCommonFirst )
android . InitDefaultableModule ( module )
2017-06-24 06:06:31 +08:00
return module
2015-03-31 08:20:39 +08:00
}
//
// Java prebuilts
//
2017-08-03 02:05:49 +08:00
type ImportProperties struct {
Jars [ ] string
2017-10-21 04:59:18 +08:00
2017-11-09 13:20:04 +08:00
Sdk_version * string
2017-10-21 08:57:49 +08:00
Installable * bool
2017-08-03 02:05:49 +08:00
}
type Import struct {
2016-05-19 06:37:25 +08:00
android . ModuleBase
2017-07-08 05:47:12 +08:00
prebuilt android . Prebuilt
2015-03-31 08:20:39 +08:00
2017-08-03 02:05:49 +08:00
properties ImportProperties
2017-08-31 05:24:55 +08:00
classpathFiles android . Paths
combinedClasspathFile android . Path
2015-03-31 08:20:39 +08:00
}
2017-08-03 02:05:49 +08:00
func ( j * Import ) Prebuilt ( ) * android . Prebuilt {
2017-07-08 05:47:12 +08:00
return & j . prebuilt
}
2017-08-03 02:05:49 +08:00
func ( j * Import ) PrebuiltSrcs ( ) [ ] string {
return j . properties . Jars
}
func ( j * Import ) Name ( ) string {
2017-07-28 06:41:32 +08:00
return j . prebuilt . Name ( j . ModuleBase . Name ( ) )
}
2017-08-03 02:05:49 +08:00
func ( j * Import ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
2016-10-13 05:38:15 +08:00
}
2017-08-03 02:05:49 +08:00
func ( j * Import ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
j . classpathFiles = android . PathsForModuleSrc ( ctx , j . properties . Jars )
2017-10-17 08:09:48 +08:00
outputFile := android . PathForModuleOut ( ctx , "classes.jar" )
2017-10-20 04:06:22 +08:00
TransformJarsToJar ( ctx , outputFile , "for prebuilts" , j . classpathFiles , android . OptionalPath { } , false , nil )
2017-10-17 08:09:48 +08:00
j . combinedClasspathFile = outputFile
2015-03-31 08:20:39 +08:00
}
2017-08-03 02:05:49 +08:00
var _ Dependency = ( * Import ) ( nil )
2015-03-31 08:20:39 +08:00
2017-10-20 04:06:22 +08:00
func ( j * Import ) HeaderJars ( ) android . Paths {
return j . classpathFiles
}
func ( j * Import ) ImplementationJars ( ) android . Paths {
2017-08-03 02:05:49 +08:00
return j . classpathFiles
2015-03-31 08:20:39 +08:00
}
2017-08-03 02:05:49 +08:00
func ( j * Import ) AidlIncludeDirs ( ) android . Paths {
2015-04-09 04:03:43 +08:00
return nil
}
2017-08-03 02:05:49 +08:00
var _ android . PrebuiltInterface = ( * Import ) ( nil )
2015-03-31 08:20:39 +08:00
2017-08-03 02:05:49 +08:00
func ImportFactory ( ) android . Module {
module := & Import { }
2017-06-24 06:06:31 +08:00
2017-08-03 02:05:49 +08:00
module . AddProperties ( & module . properties )
android . InitPrebuiltModule ( module , & module . properties . Jars )
2017-06-24 06:06:31 +08:00
android . InitAndroidArchModule ( module , android . HostAndDeviceSupported , android . MultilibCommon )
return module
2015-03-31 08:20:39 +08:00
}
2017-08-03 02:05:49 +08:00
func ImportFactoryHost ( ) android . Module {
module := & Import { }
module . AddProperties ( & module . properties )
android . InitPrebuiltModule ( module , & module . properties . Jars )
android . InitAndroidArchModule ( module , android . HostSupported , android . MultilibCommon )
return module
}
2017-07-08 05:35:50 +08:00
//
// Defaults
//
type Defaults struct {
android . ModuleBase
android . DefaultsModuleBase
}
func ( * Defaults ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
}
func ( d * Defaults ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
}
func defaultsFactory ( ) android . Module {
return DefaultsFactory ( )
}
func DefaultsFactory ( props ... interface { } ) android . Module {
module := & Defaults { }
module . AddProperties ( props ... )
module . AddProperties (
& CompilerProperties { } ,
& CompilerDeviceProperties { } ,
2018-03-09 05:27:59 +08:00
& android . ProtoProperties { } ,
2017-07-08 05:35:50 +08:00
)
android . InitDefaultsModule ( module )
return module
}
2017-11-09 13:20:04 +08:00
var Bool = proptools . Bool
var String = proptools . String
2018-02-21 05:33:42 +08:00
var inList = android . InList