667f688f36
As it turns out, AIDL originally passed and returned success when it was asked to compile an unstructured parcelable even though no output files were created. The build system currently can't handle this because it is expecting outputs here, so I am adding this argument here which will cause the compiler to exit and error earlier as expected. Notice also that the make implementation of the AIDL build system also passes in this argument. Test: m framework (which invokes this many times) Bug: N/A Change-Id: Ia9b5280dc3593756784035a523399545c9947d80
1650 lines
51 KiB
Go
1650 lines
51 KiB
Go
// 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
|
|
// into the flags and filenames necessary to pass to the Module. The final creation of the rules
|
|
// is handled in builder.go
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/google/blueprint"
|
|
"github.com/google/blueprint/proptools"
|
|
|
|
"android/soong/android"
|
|
"android/soong/java/config"
|
|
)
|
|
|
|
func init() {
|
|
android.RegisterModuleType("java_defaults", defaultsFactory)
|
|
|
|
android.RegisterModuleType("java_library", LibraryFactory)
|
|
android.RegisterModuleType("java_library_static", LibraryFactory)
|
|
android.RegisterModuleType("java_library_host", LibraryHostFactory)
|
|
android.RegisterModuleType("java_binary", BinaryFactory)
|
|
android.RegisterModuleType("java_binary_host", BinaryHostFactory)
|
|
android.RegisterModuleType("java_test", TestFactory)
|
|
android.RegisterModuleType("java_test_host", TestHostFactory)
|
|
android.RegisterModuleType("java_import", ImportFactory)
|
|
android.RegisterModuleType("java_import_host", ImportFactoryHost)
|
|
|
|
android.RegisterSingletonType("logtags", LogtagsSingleton)
|
|
}
|
|
|
|
// TODO:
|
|
// Autogenerated files:
|
|
// Renderscript
|
|
// Post-jar passes:
|
|
// Proguard
|
|
// Rmtypedefs
|
|
// DroidDoc
|
|
// Findbugs
|
|
|
|
type CompilerProperties struct {
|
|
// list of source files used to compile the Java module. May be .java, .logtags, .proto,
|
|
// or .aidl files.
|
|
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"`
|
|
|
|
// list of directories containing Java resources
|
|
Java_resource_dirs []string `android:"arch_variant"`
|
|
|
|
// list of directories that should be excluded from java_resource_dirs
|
|
Exclude_java_resource_dirs []string `android:"arch_variant"`
|
|
|
|
// 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"`
|
|
|
|
// don't build against the default libraries (bootclasspath, legacy-test, core-junit,
|
|
// ext, and framework for device targets)
|
|
No_standard_libs *bool
|
|
|
|
// don't build against the framework libraries (legacy-test, core-junit,
|
|
// ext, and framework for device targets)
|
|
No_framework_libs *bool
|
|
|
|
// Use renamed kotlin stdlib (com.android.kotlin.*). This allows kotlin usage without colliding
|
|
// with app-provided kotlin stdlib.
|
|
Renamed_kotlin_stdlib *bool
|
|
|
|
// list of module-specific flags that will be used for javac compiles
|
|
Javacflags []string `android:"arch_variant"`
|
|
|
|
// list of of java libraries that will be in the classpath
|
|
Libs []string `android:"arch_variant"`
|
|
|
|
// list of java libraries that will be compiled into the resulting jar
|
|
Static_libs []string `android:"arch_variant"`
|
|
|
|
// manifest file to be included in resulting jar
|
|
Manifest *string
|
|
|
|
// if not blank, run jarjar using the specified rules file
|
|
Jarjar_rules *string `android:"arch_variant"`
|
|
|
|
// If not blank, set the java version passed to javac as -source and -target
|
|
Java_version *string
|
|
|
|
// 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.
|
|
Installable *bool
|
|
|
|
// If set to true, include sources used to compile the module in to the final jar
|
|
Include_srcs *bool
|
|
|
|
// 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
|
|
|
|
// The number of Java source entries each Javac instance can process
|
|
Javac_shard_size *int64
|
|
|
|
// Add host jdk tools.jar to bootclasspath
|
|
Use_tools_jar *bool
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
Errorprone struct {
|
|
// List of javac flags that should only be used when running errorprone.
|
|
Javacflags []string
|
|
}
|
|
|
|
Proto struct {
|
|
// List of extra options that will be passed to the proto generator.
|
|
Output_params []string
|
|
}
|
|
|
|
Instrument bool `blueprint:"mutated"`
|
|
}
|
|
|
|
type CompilerDeviceProperties struct {
|
|
// list of module-specific flags that will be used for dex compiles
|
|
Dxflags []string `android:"arch_variant"`
|
|
|
|
// if not blank, set to the version of the sdk to compile against. Defaults to compiling against the current
|
|
// sdk if platform_apis is not set.
|
|
Sdk_version *string
|
|
|
|
// 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
|
|
|
|
// if true, compile against the platform APIs instead of an SDK.
|
|
Platform_apis *bool
|
|
|
|
Aidl struct {
|
|
// Top level directories to pass to aidl tool
|
|
Include_dirs []string
|
|
|
|
// 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
|
|
|
|
// whether to generate traces (for systrace) for this interface
|
|
Generate_traces *bool
|
|
|
|
// whether to generate Binder#GetTransaction name method.
|
|
Generate_get_transaction_name *bool
|
|
}
|
|
|
|
// If true, export a copy of the module as a -hostdex module for host testing.
|
|
Hostdex *bool
|
|
|
|
// If set to true, compile dex regardless of installable. Defaults to false.
|
|
Compile_dex *bool
|
|
|
|
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
|
|
}
|
|
|
|
Optimize struct {
|
|
// If false, disable all optimization. Defaults to true for android_app and android_test
|
|
// modules, false for java_library and java_test modules.
|
|
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
|
|
}
|
|
|
|
// When targeting 1.9, override the modules to use with --system
|
|
System_modules *string
|
|
}
|
|
|
|
// Module contains the properties and members used by all java module types
|
|
type Module struct {
|
|
android.ModuleBase
|
|
android.DefaultableModuleBase
|
|
|
|
properties CompilerProperties
|
|
protoProperties android.ProtoProperties
|
|
deviceProperties CompilerDeviceProperties
|
|
|
|
// 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
|
|
|
|
// output file containing classes.dex
|
|
dexJarFile android.Path
|
|
|
|
// output file containing uninstrumented classes that will be instrumented by jacoco
|
|
jacocoReportClassesFile android.Path
|
|
|
|
// output file containing mapping of obfuscated names
|
|
proguardDictionary android.Path
|
|
|
|
// output file suitable for installing or running
|
|
outputFile android.Path
|
|
|
|
exportAidlIncludeDirs android.Paths
|
|
|
|
logtagsSrcs android.Paths
|
|
|
|
// installed file for binary dependency
|
|
installFile android.Path
|
|
|
|
// list of .java files and srcjars that was passed to javac
|
|
compiledJavaSrcs android.Paths
|
|
compiledSrcJars android.Paths
|
|
|
|
// list of extra progurad flag files
|
|
extraProguardFlagFiles android.Paths
|
|
|
|
// list of SDK lib names that this java moudule is exporting
|
|
exportedSdkLibs []string
|
|
}
|
|
|
|
func (j *Module) Srcs() android.Paths {
|
|
return android.Paths{j.implementationJarFile}
|
|
}
|
|
|
|
var _ android.SourceFileProducer = (*Module)(nil)
|
|
|
|
type Dependency interface {
|
|
HeaderJars() android.Paths
|
|
ImplementationJars() android.Paths
|
|
AidlIncludeDirs() android.Paths
|
|
ExportedSdkLibs() []string
|
|
}
|
|
|
|
type SdkLibraryDependency interface {
|
|
HeaderJars(linkType linkType) android.Paths
|
|
ImplementationJars(linkType linkType) android.Paths
|
|
}
|
|
|
|
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)
|
|
|
|
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
|
|
android.InitAndroidArchModule(module, hod, android.MultilibCommon)
|
|
android.InitDefaultableModule(module)
|
|
}
|
|
|
|
type dependencyTag struct {
|
|
blueprint.BaseDependencyTag
|
|
name string
|
|
}
|
|
|
|
var (
|
|
staticLibTag = dependencyTag{name: "staticlib"}
|
|
libTag = dependencyTag{name: "javalib"}
|
|
annoTag = dependencyTag{name: "annotation processor"}
|
|
bootClasspathTag = dependencyTag{name: "bootclasspath"}
|
|
systemModulesTag = dependencyTag{name: "system modules"}
|
|
frameworkResTag = dependencyTag{name: "framework-res"}
|
|
frameworkApkTag = dependencyTag{name: "framework-apk"}
|
|
kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"}
|
|
proguardRaiseTag = dependencyTag{name: "proguard-raise"}
|
|
)
|
|
|
|
type sdkDep struct {
|
|
useModule, useFiles, useDefaultLibs, invalidVersion bool
|
|
|
|
modules []string
|
|
systemModules string
|
|
|
|
frameworkResModule string
|
|
|
|
jars android.Paths
|
|
aidl android.Path
|
|
}
|
|
|
|
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())
|
|
}
|
|
|
|
func (j *Module) sdkVersion() string {
|
|
return String(j.deviceProperties.Sdk_version)
|
|
}
|
|
|
|
func (j *Module) minSdkVersion() string {
|
|
if j.deviceProperties.Min_sdk_version != nil {
|
|
return *j.deviceProperties.Min_sdk_version
|
|
}
|
|
return j.sdkVersion()
|
|
}
|
|
|
|
type sdkContext interface {
|
|
// sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set.
|
|
sdkVersion() string
|
|
// minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set.
|
|
minSdkVersion() string
|
|
}
|
|
|
|
func sdkVersionOrDefault(ctx android.BaseContext, v string) string {
|
|
switch v {
|
|
case "", "current", "system_current", "test_current", "core_current":
|
|
return ctx.Config().DefaultAppTargetSdk()
|
|
default:
|
|
return v
|
|
}
|
|
}
|
|
|
|
// Returns a sdk version as a number. For modules targeting an unreleased SDK (meaning it does not yet have a number)
|
|
// it returns android.FutureApiLevel (10000).
|
|
func sdkVersionToNumber(ctx android.BaseContext, v string) (int, error) {
|
|
switch v {
|
|
case "", "current", "test_current", "system_current", "core_current":
|
|
return ctx.Config().DefaultAppTargetSdkInt(), nil
|
|
default:
|
|
n := android.GetNumericSdkVersion(v)
|
|
if i, err := strconv.Atoi(n); err != nil {
|
|
return -1, fmt.Errorf("invalid sdk version %q", n)
|
|
} else {
|
|
return i, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
func sdkVersionToNumberAsString(ctx android.BaseContext, v string) (string, error) {
|
|
n, err := sdkVersionToNumber(ctx, v)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return strconv.Itoa(n), nil
|
|
}
|
|
|
|
func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep {
|
|
v := sdkContext.sdkVersion()
|
|
i, err := sdkVersionToNumber(ctx, v)
|
|
if err != nil {
|
|
ctx.PropertyErrorf("sdk_version", "%s", err)
|
|
return sdkDep{}
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
}
|
|
|
|
toPrebuilt := func(sdk string) sdkDep {
|
|
var api, v string
|
|
if strings.Contains(sdk, "_") {
|
|
t := strings.Split(sdk, "_")
|
|
api = t[0]
|
|
v = t[1]
|
|
} else {
|
|
api = "public"
|
|
v = sdk
|
|
}
|
|
dir := filepath.Join("prebuilts", "sdk", v, api)
|
|
jar := filepath.Join(dir, "android.jar")
|
|
// There's no aidl for other SDKs yet.
|
|
// TODO(77525052): Add aidl files for other SDKs too.
|
|
public_dir := filepath.Join("prebuilts", "sdk", v, "public")
|
|
aidl := filepath.Join(public_dir, "framework.aidl")
|
|
jarPath := android.ExistentPathForSource(ctx, jar)
|
|
aidlPath := android.ExistentPathForSource(ctx, aidl)
|
|
lambdaStubsPath := android.PathForSource(ctx, config.SdkLambdaStubsPath)
|
|
|
|
if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
|
|
return sdkDep{
|
|
invalidVersion: true,
|
|
modules: []string{fmt.Sprintf("sdk_%s_%s_android", api, v)},
|
|
}
|
|
}
|
|
|
|
if !jarPath.Valid() {
|
|
ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, jar)
|
|
return sdkDep{}
|
|
}
|
|
|
|
if !aidlPath.Valid() {
|
|
ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, aidl)
|
|
return sdkDep{}
|
|
}
|
|
|
|
return sdkDep{
|
|
useFiles: true,
|
|
jars: android.Paths{jarPath.Path(), lambdaStubsPath},
|
|
aidl: aidlPath.Path(),
|
|
}
|
|
}
|
|
|
|
toModule := func(m, r string) sdkDep {
|
|
ret := sdkDep{
|
|
useModule: true,
|
|
modules: []string{m, config.DefaultLambdaStubsLibrary},
|
|
systemModules: m + "_system_modules",
|
|
frameworkResModule: r,
|
|
}
|
|
if m == "core.current.stubs" {
|
|
ret.systemModules = "core-system-modules"
|
|
}
|
|
return ret
|
|
}
|
|
|
|
if ctx.Config().UnbundledBuild() && v != "" {
|
|
return toPrebuilt(v)
|
|
}
|
|
|
|
switch v {
|
|
case "":
|
|
return sdkDep{
|
|
useDefaultLibs: true,
|
|
frameworkResModule: "framework-res",
|
|
}
|
|
case "current":
|
|
return toModule("android_stubs_current", "framework-res")
|
|
case "system_current":
|
|
return toModule("android_system_stubs_current", "framework-res")
|
|
case "test_current":
|
|
return toModule("android_test_stubs_current", "framework-res")
|
|
case "core_current":
|
|
return toModule("core.current.stubs", "")
|
|
default:
|
|
return toPrebuilt(v)
|
|
}
|
|
}
|
|
|
|
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
|
|
if ctx.Device() {
|
|
if !Bool(j.properties.No_standard_libs) {
|
|
sdkDep := decodeSdkDep(ctx, sdkContext(j))
|
|
if sdkDep.useDefaultLibs {
|
|
ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
|
|
if ctx.Config().TargetOpenJDK9() {
|
|
ctx.AddDependency(ctx.Module(), systemModulesTag, config.DefaultSystemModules)
|
|
}
|
|
if !Bool(j.properties.No_framework_libs) {
|
|
ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...)
|
|
}
|
|
} else if sdkDep.useModule {
|
|
if ctx.Config().TargetOpenJDK9() {
|
|
ctx.AddDependency(ctx.Module(), systemModulesTag, sdkDep.systemModules)
|
|
}
|
|
ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.modules...)
|
|
if Bool(j.deviceProperties.Optimize.Enabled) {
|
|
ctx.AddDependency(ctx.Module(), proguardRaiseTag, config.DefaultBootclasspathLibraries...)
|
|
ctx.AddDependency(ctx.Module(), proguardRaiseTag, config.DefaultLibraries...)
|
|
}
|
|
}
|
|
} 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?")
|
|
} else if *j.deviceProperties.System_modules != "none" && ctx.Config().TargetOpenJDK9() {
|
|
ctx.AddDependency(ctx.Module(), systemModulesTag, *j.deviceProperties.System_modules)
|
|
}
|
|
if ctx.ModuleName() == "framework" {
|
|
ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
|
|
}
|
|
if ctx.ModuleName() == "android_stubs_current" ||
|
|
ctx.ModuleName() == "android_system_stubs_current" ||
|
|
ctx.ModuleName() == "android_test_stubs_current" ||
|
|
ctx.ModuleName() == "metalava_android_stubs_current" ||
|
|
ctx.ModuleName() == "metalava_android_system_stubs_current" ||
|
|
ctx.ModuleName() == "metalava_android_test_stubs_current" {
|
|
ctx.AddDependency(ctx.Module(), frameworkApkTag, "framework-res")
|
|
}
|
|
}
|
|
|
|
ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
|
|
ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
|
|
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
|
{Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant},
|
|
}, annoTag, j.properties.Annotation_processors...)
|
|
android.ExtractSourcesDeps(ctx, j.properties.Srcs)
|
|
android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
|
|
android.ExtractSourcesDeps(ctx, j.properties.Java_resources)
|
|
android.ExtractSourceDeps(ctx, j.properties.Manifest)
|
|
|
|
if j.hasSrcExt(".proto") {
|
|
protoDeps(ctx, &j.protoProperties)
|
|
}
|
|
|
|
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")
|
|
}
|
|
|
|
if j.shouldInstrumentStatic(ctx) {
|
|
ctx.AddDependency(ctx.Module(), staticLibTag, "jacocoagent")
|
|
}
|
|
}
|
|
|
|
func hasSrcExt(srcs []string, ext string) bool {
|
|
for _, src := range srcs {
|
|
if filepath.Ext(src) == ext {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func (j *Module) hasSrcExt(ext string) bool {
|
|
return hasSrcExt(j.properties.Srcs, ext)
|
|
}
|
|
|
|
func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
|
|
aidlIncludeDirs android.Paths) []string {
|
|
|
|
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)...)
|
|
|
|
flags := []string{"-b"}
|
|
|
|
if aidlPreprocess.Valid() {
|
|
flags = append(flags, "-p"+aidlPreprocess.String())
|
|
} else {
|
|
flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
|
|
}
|
|
|
|
flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
|
|
flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
|
|
flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
|
|
if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
|
|
flags = append(flags, "-I"+src.String())
|
|
}
|
|
|
|
if Bool(j.deviceProperties.Aidl.Generate_traces) {
|
|
flags = append(flags, "-t")
|
|
}
|
|
|
|
if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
|
|
flags = append(flags, "--transaction_names")
|
|
}
|
|
|
|
return flags
|
|
}
|
|
|
|
type deps struct {
|
|
classpath classpath
|
|
bootClasspath classpath
|
|
processorPath classpath
|
|
staticJars android.Paths
|
|
staticHeaderJars android.Paths
|
|
staticJarResources android.Paths
|
|
aidlIncludeDirs android.Paths
|
|
srcs android.Paths
|
|
srcJars android.Paths
|
|
systemModules android.Path
|
|
aidlPreprocess android.OptionalPath
|
|
kotlinStdlib android.Paths
|
|
}
|
|
|
|
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)))
|
|
}
|
|
}
|
|
}
|
|
|
|
type linkType int
|
|
|
|
const (
|
|
javaCore linkType = iota
|
|
javaSdk
|
|
javaSystem
|
|
javaPlatform
|
|
)
|
|
|
|
func getLinkType(m *Module, name string) linkType {
|
|
ver := m.sdkVersion()
|
|
noStdLibs := Bool(m.properties.No_standard_libs)
|
|
switch {
|
|
case name == "core.current.stubs" || ver == "core_current" || noStdLibs || name == "stub-annotations" ||
|
|
name == "private-stub-annotations-jar":
|
|
return javaCore
|
|
case name == "android_system_stubs_current" || strings.HasPrefix(ver, "system_") || name == "metalava_android_system_stubs_current":
|
|
return javaSystem
|
|
case name == "android_test_stubs_current" || strings.HasPrefix(ver, "test_") || name == "metalava_android_test_stubs_current":
|
|
return javaPlatform
|
|
case name == "android_stubs_current" || ver == "current" || name == "metalava_android_stubs_current":
|
|
return javaSdk
|
|
case ver == "":
|
|
return javaPlatform
|
|
default:
|
|
if _, err := strconv.Atoi(ver); err != nil {
|
|
panic(fmt.Errorf("expected sdk_version to be a number, got %q", ver))
|
|
}
|
|
return javaSdk
|
|
}
|
|
}
|
|
|
|
func checkLinkType(ctx android.ModuleContext, from *Module, to *Library, tag dependencyTag) {
|
|
if ctx.Host() {
|
|
return
|
|
}
|
|
|
|
myLinkType := getLinkType(from, ctx.ModuleName())
|
|
otherLinkType := getLinkType(&to.Module, ctx.OtherModuleName(to))
|
|
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,
|
|
ctx.OtherModuleName(to))
|
|
}
|
|
break
|
|
case javaPlatform:
|
|
// no restriction on link-type
|
|
break
|
|
}
|
|
}
|
|
|
|
func (j *Module) collectDeps(ctx android.ModuleContext) deps {
|
|
var deps deps
|
|
|
|
if ctx.Device() {
|
|
sdkDep := decodeSdkDep(ctx, sdkContext(j))
|
|
if sdkDep.invalidVersion {
|
|
ctx.AddMissingDependencies(sdkDep.modules)
|
|
} else if sdkDep.useFiles {
|
|
// sdkDep.jar is actually equivalent to turbine header.jar.
|
|
deps.classpath = append(deps.classpath, sdkDep.jars...)
|
|
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, sdkDep.aidl)
|
|
}
|
|
}
|
|
|
|
ctx.VisitDirectDeps(func(module android.Module) {
|
|
otherName := ctx.OtherModuleName(module)
|
|
tag := ctx.OtherModuleDependencyTag(module)
|
|
|
|
if to, ok := module.(*Library); ok {
|
|
switch tag {
|
|
case bootClasspathTag, libTag, staticLibTag:
|
|
checkLinkType(ctx, j, to, tag.(dependencyTag))
|
|
}
|
|
}
|
|
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()...)
|
|
// sdk lib names from dependencies are re-exported
|
|
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
|
|
case staticLibTag:
|
|
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
|
|
deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
|
|
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
|
|
// sdk lib names from dependencies are re-exported
|
|
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
|
|
case annoTag:
|
|
deps.processorPath = append(deps.processorPath, dep.ImplementationJars()...)
|
|
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)
|
|
}
|
|
case frameworkApkTag:
|
|
if ctx.ModuleName() == "android_stubs_current" ||
|
|
ctx.ModuleName() == "android_system_stubs_current" ||
|
|
ctx.ModuleName() == "android_test_stubs_current" ||
|
|
ctx.ModuleName() == "metalava_android_stubs_current" ||
|
|
ctx.ModuleName() == "metalava_android_system_stubs_current" ||
|
|
ctx.ModuleName() == "metalava_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)
|
|
}
|
|
case kotlinStdlibTag:
|
|
deps.kotlinStdlib = dep.HeaderJars()
|
|
}
|
|
|
|
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
|
|
case SdkLibraryDependency:
|
|
switch tag {
|
|
case libTag:
|
|
deps.classpath = append(deps.classpath, dep.HeaderJars(getLinkType(j, ctx.ModuleName()))...)
|
|
// names of sdk libs that are directly depended are exported
|
|
j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
|
|
default:
|
|
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
|
|
}
|
|
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:
|
|
switch tag {
|
|
case android.DefaultsDepTag, android.SourceDepTag:
|
|
// Nothing to do
|
|
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
|
|
default:
|
|
ctx.ModuleErrorf("depends on non-java module %q", otherName)
|
|
}
|
|
}
|
|
})
|
|
|
|
j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
|
|
|
|
return deps
|
|
}
|
|
|
|
func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string {
|
|
var ret string
|
|
sdk, err := sdkVersionToNumber(ctx, sdkContext.sdkVersion())
|
|
if err != nil {
|
|
ctx.PropertyErrorf("sdk_version", "%s", err)
|
|
}
|
|
if javaVersion != "" {
|
|
ret = javaVersion
|
|
} else if ctx.Device() && sdk <= 23 {
|
|
ret = "1.7"
|
|
} else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() {
|
|
ret = "1.8"
|
|
} else if ctx.Device() && sdkContext.sdkVersion() != "" && sdk == android.FutureApiLevel {
|
|
// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
|
|
ret = "1.8"
|
|
} else {
|
|
ret = "1.9"
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
|
|
|
|
var flags javaBuilderFlags
|
|
|
|
// javac flags.
|
|
javacFlags := j.properties.Javacflags
|
|
if ctx.Config().TargetOpenJDK9() {
|
|
javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
|
|
}
|
|
if ctx.Config().MinimizeJavaDebugInfo() {
|
|
// Override the -g flag passed globally to remove local variable debug info to reduce
|
|
// disk and memory usage.
|
|
javacFlags = append(javacFlags, "-g:source,lines")
|
|
}
|
|
if len(javacFlags) > 0 {
|
|
// optimization.
|
|
ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
|
|
flags.javacFlags = "$javacFlags"
|
|
}
|
|
|
|
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))
|
|
}
|
|
|
|
// javaVersion flag.
|
|
flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
|
|
|
|
// classpath
|
|
flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
|
|
flags.classpath = append(flags.classpath, deps.classpath...)
|
|
flags.processorPath = append(flags.processorPath, deps.processorPath...)
|
|
|
|
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"))
|
|
if Bool(j.properties.Use_tools_jar) {
|
|
flags.bootClasspath = append(flags.bootClasspath,
|
|
android.PathForSource(ctx, java8Home, "lib/tools.jar"))
|
|
}
|
|
}
|
|
|
|
// systemModules
|
|
if deps.systemModules != nil {
|
|
flags.systemModules = append(flags.systemModules, deps.systemModules)
|
|
}
|
|
|
|
// aidl flags.
|
|
aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
|
|
if len(aidlFlags) > 0 {
|
|
// optimization.
|
|
ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
|
|
flags.aidlFlags = "$aidlFlags"
|
|
}
|
|
|
|
return flags
|
|
}
|
|
|
|
func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path) {
|
|
|
|
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
|
|
|
|
deps := j.collectDeps(ctx)
|
|
flags := j.collectBuilderFlags(ctx, deps)
|
|
|
|
if ctx.Config().TargetOpenJDK9() {
|
|
j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
|
|
}
|
|
srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
|
|
if hasSrcExt(srcFiles.Strings(), ".proto") {
|
|
flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
|
|
}
|
|
|
|
srcFiles = j.genSources(ctx, srcFiles, flags)
|
|
|
|
srcJars := srcFiles.FilterByExt(".srcjar")
|
|
srcJars = append(srcJars, deps.srcJars...)
|
|
srcJars = append(srcJars, extraSrcJars...)
|
|
|
|
var jars android.Paths
|
|
|
|
jarName := ctx.ModuleName() + ".jar"
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
var stripFiles []string
|
|
|
|
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"
|
|
|
|
if ctx.Device() {
|
|
flags.kotlincFlags += " -no-jdk"
|
|
}
|
|
|
|
var kotlinSrcFiles android.Paths
|
|
kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
|
|
kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
|
|
|
|
flags.kotlincClasspath = append(flags.kotlincClasspath, deps.bootClasspath...)
|
|
flags.kotlincClasspath = append(flags.kotlincClasspath, deps.kotlinStdlib...)
|
|
flags.kotlincClasspath = append(flags.kotlincClasspath, deps.classpath...)
|
|
|
|
kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
|
|
TransformKotlinToClasses(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags)
|
|
if ctx.Failed() {
|
|
return
|
|
}
|
|
|
|
// Make javac rule depend on the kotlinc rule
|
|
flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
|
|
flags.classpath = append(flags.classpath, kotlinJar)
|
|
|
|
// Jar kotlin classes into the final jar after javac
|
|
jars = append(jars, kotlinJar)
|
|
|
|
if Bool(j.properties.Renamed_kotlin_stdlib) {
|
|
// Remove any kotlin-reflect related files
|
|
// TODO(pszczepaniak): Support kotlin-reflect
|
|
stripFiles = append(stripFiles,
|
|
"**/*.kotlin_module",
|
|
"**/*.kotlin_builtins")
|
|
} else {
|
|
// Only add kotlin-stdlib if not using (on-device) renamed stdlib
|
|
// (it's expected to be on device bootclasspath)
|
|
jars = append(jars, deps.kotlinStdlib...)
|
|
}
|
|
}
|
|
|
|
// Store the list of .java files that was passed to javac
|
|
j.compiledJavaSrcs = uniqueSrcFiles
|
|
j.compiledSrcJars = srcJars
|
|
|
|
enable_sharding := false
|
|
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") {
|
|
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)
|
|
}
|
|
}
|
|
j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName)
|
|
if ctx.Failed() {
|
|
return
|
|
}
|
|
}
|
|
if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
|
|
var extraJarDeps android.Paths
|
|
if ctx.Config().RunErrorProne() {
|
|
// 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
|
|
// a rebuild when error-prone is turned off).
|
|
// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
|
|
// enable error-prone without affecting the output class files.
|
|
errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
|
|
RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags)
|
|
extraJarDeps = append(extraJarDeps, errorprone)
|
|
}
|
|
|
|
if enable_sharding {
|
|
flags.classpath = append(flags.classpath, j.headerJarFile)
|
|
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)
|
|
}
|
|
if ctx.Failed() {
|
|
return
|
|
}
|
|
}
|
|
|
|
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 Bool(j.properties.Include_srcs) {
|
|
srcArgs, srcDeps := SourceFilesToJarArgs(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
|
|
resArgs = append(resArgs, srcArgs...)
|
|
resDeps = append(resDeps, srcDeps...)
|
|
}
|
|
|
|
if len(resArgs) > 0 {
|
|
resourceJar := android.PathForModuleOut(ctx, "res", jarName)
|
|
TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
|
|
if ctx.Failed() {
|
|
return
|
|
}
|
|
|
|
jars = append(jars, resourceJar)
|
|
}
|
|
|
|
// static classpath jars have the resources in them, so the resource jars aren't necessary here
|
|
jars = append(jars, deps.staticJars...)
|
|
jars = append(jars, deps.staticJarResources...)
|
|
|
|
var manifest android.OptionalPath
|
|
if j.properties.Manifest != nil {
|
|
manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "manifest"))
|
|
}
|
|
|
|
// Combine the classes built from sources, any manifests, and any static libraries into
|
|
// classes.jar. If there is only one input jar this step will be skipped.
|
|
var outputFile android.Path
|
|
|
|
if len(jars) == 1 && !manifest.Valid() {
|
|
// 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 = jars[0]
|
|
} else {
|
|
combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
|
|
TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
|
|
false, stripFiles, nil)
|
|
outputFile = combinedJar
|
|
}
|
|
|
|
// Use renamed kotlin standard library?
|
|
if srcFiles.HasExt(".kt") && 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
|
|
}
|
|
}
|
|
|
|
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, "jarjar", jarName)
|
|
TransformJarJar(ctx, jarjarFile, outputFile, jarjar_rules)
|
|
outputFile = jarjarFile
|
|
if ctx.Failed() {
|
|
return
|
|
}
|
|
}
|
|
j.implementationJarFile = outputFile
|
|
if j.headerJarFile == nil {
|
|
j.headerJarFile = j.implementationJarFile
|
|
}
|
|
|
|
if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
|
|
if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
|
|
j.properties.Instrument = true
|
|
}
|
|
}
|
|
|
|
if j.shouldInstrument(ctx) {
|
|
outputFile = j.instrument(ctx, flags, outputFile, jarName)
|
|
}
|
|
|
|
if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
|
|
var dexOutputFile android.Path
|
|
dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
|
|
if ctx.Failed() {
|
|
return
|
|
}
|
|
if Bool(j.properties.Installable) {
|
|
outputFile = dexOutputFile
|
|
}
|
|
}
|
|
ctx.CheckbuildFile(outputFile)
|
|
j.outputFile = outputFile
|
|
}
|
|
|
|
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
|
|
deps deps, flags javaBuilderFlags, jarName string) android.Path {
|
|
|
|
var jars android.Paths
|
|
if len(srcFiles) > 0 || len(srcJars) > 0 {
|
|
// Compile java sources into turbine.jar.
|
|
turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
|
|
TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
|
|
if ctx.Failed() {
|
|
return nil
|
|
}
|
|
jars = append(jars, turbineJar)
|
|
}
|
|
|
|
// 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...)
|
|
|
|
// 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, nil, []string{"META-INF"})
|
|
headerJar = combinedJar
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
return headerJar
|
|
}
|
|
|
|
func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
|
|
classesJar android.Path, jarName string) android.Path {
|
|
|
|
specs := j.jacocoModuleToZipCommand(ctx)
|
|
|
|
jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName)
|
|
instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName)
|
|
|
|
jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)
|
|
|
|
j.jacocoReportClassesFile = jacocoReportClassesFile
|
|
|
|
return instrumentedJar
|
|
}
|
|
|
|
var _ Dependency = (*Library)(nil)
|
|
|
|
func (j *Module) HeaderJars() android.Paths {
|
|
return android.Paths{j.headerJarFile}
|
|
}
|
|
|
|
func (j *Module) ImplementationJars() android.Paths {
|
|
return android.Paths{j.implementationJarFile}
|
|
}
|
|
|
|
func (j *Module) AidlIncludeDirs() android.Paths {
|
|
return j.exportAidlIncludeDirs
|
|
}
|
|
|
|
func (j *Module) ExportedSdkLibs() []string {
|
|
return j.exportedSdkLibs
|
|
}
|
|
|
|
var _ logtagsProducer = (*Module)(nil)
|
|
|
|
func (j *Module) logtags() android.Paths {
|
|
return j.logtagsSrcs
|
|
}
|
|
|
|
//
|
|
// Java libraries (.jar file)
|
|
//
|
|
|
|
type Library struct {
|
|
Module
|
|
}
|
|
|
|
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
j.compile(ctx)
|
|
|
|
if Bool(j.properties.Installable) || ctx.Host() {
|
|
j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
|
|
ctx.ModuleName()+".jar", j.outputFile)
|
|
}
|
|
}
|
|
|
|
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
j.deps(ctx)
|
|
}
|
|
|
|
func LibraryFactory() android.Module {
|
|
module := &Library{}
|
|
|
|
module.AddProperties(
|
|
&module.Module.properties,
|
|
&module.Module.deviceProperties,
|
|
&module.Module.protoProperties)
|
|
|
|
InitJavaModule(module, android.HostAndDeviceSupported)
|
|
return module
|
|
}
|
|
|
|
func LibraryHostFactory() android.Module {
|
|
module := &Library{}
|
|
|
|
module.AddProperties(
|
|
&module.Module.properties,
|
|
&module.Module.protoProperties)
|
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
|
|
|
InitJavaModule(module, android.HostSupported)
|
|
return module
|
|
}
|
|
|
|
//
|
|
// Java Junit Tests
|
|
//
|
|
|
|
type testProperties struct {
|
|
// If true, add a static dependency on the platform junit library. Defaults to true.
|
|
Junit *bool
|
|
|
|
// list of compatibility suites (for example "cts", "vts") that the module should be
|
|
// installed into.
|
|
Test_suites []string `android:"arch_variant"`
|
|
}
|
|
|
|
type Test struct {
|
|
Library
|
|
|
|
testProperties testProperties
|
|
}
|
|
|
|
func (j *Test) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
j.deps(ctx)
|
|
if BoolDefault(j.testProperties.Junit, true) {
|
|
ctx.AddDependency(ctx.Module(), staticLibTag, "junit")
|
|
}
|
|
}
|
|
|
|
func TestFactory() android.Module {
|
|
module := &Test{}
|
|
|
|
module.AddProperties(
|
|
&module.Module.properties,
|
|
&module.Module.deviceProperties,
|
|
&module.Module.protoProperties,
|
|
&module.testProperties)
|
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
|
|
|
InitJavaModule(module, android.HostAndDeviceSupported)
|
|
android.InitDefaultableModule(module)
|
|
return module
|
|
}
|
|
|
|
func TestHostFactory() android.Module {
|
|
module := &Test{}
|
|
|
|
module.AddProperties(
|
|
&module.Module.properties,
|
|
&module.Module.protoProperties,
|
|
&module.testProperties)
|
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
|
|
|
InitJavaModule(module, android.HostSupported)
|
|
android.InitDefaultableModule(module)
|
|
return module
|
|
}
|
|
|
|
//
|
|
// Java Binaries (.jar file plus wrapper script)
|
|
//
|
|
|
|
type binaryProperties struct {
|
|
// installable script to execute the resulting jar
|
|
Wrapper *string
|
|
}
|
|
|
|
type Binary struct {
|
|
Library
|
|
|
|
binaryProperties binaryProperties
|
|
|
|
isWrapperVariant bool
|
|
|
|
wrapperFile android.Path
|
|
binaryFile android.OutputPath
|
|
}
|
|
|
|
func (j *Binary) HostToolPath() android.OptionalPath {
|
|
return android.OptionalPathForPath(j.binaryFile)
|
|
}
|
|
|
|
func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
if ctx.Arch().ArchType == android.Common {
|
|
// Compile the jar
|
|
j.Library.GenerateAndroidBuildActions(ctx)
|
|
} else {
|
|
// Handle the binary wrapper
|
|
j.isWrapperVariant = true
|
|
|
|
if j.binaryProperties.Wrapper != nil {
|
|
j.wrapperFile = ctx.ExpandSource(*j.binaryProperties.Wrapper, "wrapper")
|
|
} 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)
|
|
}
|
|
}
|
|
|
|
func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
if ctx.Arch().ArchType == android.Common {
|
|
j.deps(ctx)
|
|
} else {
|
|
android.ExtractSourceDeps(ctx, j.binaryProperties.Wrapper)
|
|
}
|
|
}
|
|
|
|
func BinaryFactory() android.Module {
|
|
module := &Binary{}
|
|
|
|
module.AddProperties(
|
|
&module.Module.properties,
|
|
&module.Module.deviceProperties,
|
|
&module.Module.protoProperties,
|
|
&module.binaryProperties)
|
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
|
|
|
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
|
|
android.InitDefaultableModule(module)
|
|
return module
|
|
}
|
|
|
|
func BinaryHostFactory() android.Module {
|
|
module := &Binary{}
|
|
|
|
module.AddProperties(
|
|
&module.Module.properties,
|
|
&module.Module.protoProperties,
|
|
&module.binaryProperties)
|
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
|
|
|
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
|
|
android.InitDefaultableModule(module)
|
|
return module
|
|
}
|
|
|
|
//
|
|
// Java prebuilts
|
|
//
|
|
|
|
type ImportProperties struct {
|
|
Jars []string
|
|
|
|
Sdk_version *string
|
|
|
|
Installable *bool
|
|
|
|
// List of shared java libs that this module has dependencies to
|
|
Libs []string
|
|
|
|
// 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
|
|
}
|
|
|
|
type Import struct {
|
|
android.ModuleBase
|
|
prebuilt android.Prebuilt
|
|
|
|
properties ImportProperties
|
|
|
|
combinedClasspathFile android.Path
|
|
exportedSdkLibs []string
|
|
}
|
|
|
|
func (j *Import) sdkVersion() string {
|
|
return String(j.properties.Sdk_version)
|
|
}
|
|
|
|
func (j *Import) minSdkVersion() string {
|
|
return j.sdkVersion()
|
|
}
|
|
|
|
func (j *Import) Prebuilt() *android.Prebuilt {
|
|
return &j.prebuilt
|
|
}
|
|
|
|
func (j *Import) PrebuiltSrcs() []string {
|
|
return j.properties.Jars
|
|
}
|
|
|
|
func (j *Import) Name() string {
|
|
return j.prebuilt.Name(j.ModuleBase.Name())
|
|
}
|
|
|
|
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
android.ExtractSourcesDeps(ctx, j.properties.Jars)
|
|
ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
|
|
}
|
|
|
|
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
jars := ctx.ExpandSources(j.properties.Jars, nil)
|
|
|
|
outputFile := android.PathForModuleOut(ctx, "classes.jar")
|
|
TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
|
|
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
|
|
j.combinedClasspathFile = outputFile
|
|
|
|
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)
|
|
}
|
|
|
|
var _ Dependency = (*Import)(nil)
|
|
|
|
func (j *Import) HeaderJars() android.Paths {
|
|
return android.Paths{j.combinedClasspathFile}
|
|
}
|
|
|
|
func (j *Import) ImplementationJars() android.Paths {
|
|
return android.Paths{j.combinedClasspathFile}
|
|
}
|
|
|
|
func (j *Import) AidlIncludeDirs() android.Paths {
|
|
return nil
|
|
}
|
|
|
|
func (j *Import) ExportedSdkLibs() []string {
|
|
return j.exportedSdkLibs
|
|
}
|
|
|
|
var _ android.PrebuiltInterface = (*Import)(nil)
|
|
|
|
func ImportFactory() android.Module {
|
|
module := &Import{}
|
|
|
|
module.AddProperties(&module.properties)
|
|
|
|
android.InitPrebuiltModule(module, &module.properties.Jars)
|
|
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
|
|
return module
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
//
|
|
// 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{},
|
|
&android.ProtoProperties{},
|
|
)
|
|
|
|
android.InitDefaultsModule(module)
|
|
|
|
return module
|
|
}
|
|
|
|
var Bool = proptools.Bool
|
|
var BoolDefault = proptools.BoolDefault
|
|
var String = proptools.String
|
|
var inList = android.InList
|