f19b9bb981
Now that the SDK stubs are built in Soong, undo the hack that uses the prebuilt stubs. Fix the linktype checks to treat the various stubs libraries as the correct type, since they can't be annotated with sdk_version. Bug: 70351683 Bug: 77285514 Test: m checkbuild Change-Id: I5e870c34dd0ebc8ae3f888ec627da590c846a76f
1409 lines
43 KiB
Go
1409 lines
43 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(true))
|
|
android.RegisterModuleType("java_library_static", LibraryFactory(false))
|
|
android.RegisterModuleType("java_library_host", LibraryHostFactory)
|
|
android.RegisterModuleType("java_binary", BinaryFactory)
|
|
android.RegisterModuleType("java_binary_host", BinaryHostFactory)
|
|
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 false, don't allow this module to be installed. Defaults to true.
|
|
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
|
|
Sdk_version *string
|
|
|
|
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
|
|
}
|
|
|
|
// If true, export a copy of the module as a -hostdex module for host testing.
|
|
Hostdex *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 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
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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"}
|
|
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
|
|
|
|
module string
|
|
systemModules string
|
|
|
|
jar android.Path
|
|
aidl android.Path
|
|
}
|
|
|
|
func sdkStringToNumber(ctx android.BaseContext, v string) int {
|
|
switch v {
|
|
case "", "current", "system_current", "test_current", "core_current":
|
|
return android.FutureApiLevel
|
|
default:
|
|
if i, err := strconv.Atoi(android.GetNumericSdkVersion(v)); err != nil {
|
|
ctx.PropertyErrorf("sdk_version", "invalid sdk version")
|
|
return -1
|
|
} else {
|
|
return i
|
|
}
|
|
}
|
|
}
|
|
|
|
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 decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
|
|
i := sdkStringToNumber(ctx, v)
|
|
if i == -1 {
|
|
// Invalid sdk version, error handled by sdkStringToNumber.
|
|
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)
|
|
}
|
|
}
|
|
|
|
toFile := func(v string) sdkDep {
|
|
isCore := strings.HasPrefix(v, "core_")
|
|
if isCore {
|
|
v = strings.TrimPrefix(v, "core_")
|
|
}
|
|
dir := filepath.Join("prebuilts/sdk", v)
|
|
jar := filepath.Join(dir, "android.jar")
|
|
if isCore {
|
|
jar = filepath.Join(dir, "core.jar")
|
|
}
|
|
aidl := filepath.Join(dir, "framework.aidl")
|
|
jarPath := android.ExistentPathForSource(ctx, jar)
|
|
aidlPath := android.ExistentPathForSource(ctx, aidl)
|
|
|
|
if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
|
|
return sdkDep{
|
|
invalidVersion: true,
|
|
module: "sdk_v" + 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,
|
|
jar: jarPath.Path(),
|
|
aidl: aidlPath.Path(),
|
|
}
|
|
}
|
|
|
|
toModule := func(m string) sdkDep {
|
|
ret := sdkDep{
|
|
useModule: true,
|
|
module: m,
|
|
systemModules: m + "_system_modules",
|
|
}
|
|
if m == "core.current.stubs" {
|
|
ret.systemModules = "core-system-modules"
|
|
}
|
|
return ret
|
|
}
|
|
|
|
if ctx.Config().UnbundledBuild() && v != "" {
|
|
return toFile(v)
|
|
}
|
|
|
|
switch v {
|
|
case "":
|
|
return sdkDep{
|
|
useDefaultLibs: true,
|
|
}
|
|
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")
|
|
case "core_current":
|
|
return toModule("core.current.stubs")
|
|
default:
|
|
return toFile(v)
|
|
}
|
|
}
|
|
|
|
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
|
|
if ctx.Device() {
|
|
if !proptools.Bool(j.properties.No_standard_libs) {
|
|
sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version))
|
|
if sdkDep.useDefaultLibs {
|
|
ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
|
|
if ctx.Config().TargetOpenJDK9() {
|
|
ctx.AddDependency(ctx.Module(), systemModulesTag, config.DefaultSystemModules)
|
|
}
|
|
if !proptools.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.module)
|
|
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.AddDependency(ctx.Module(), frameworkApkTag, "framework-res")
|
|
}
|
|
}
|
|
|
|
ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
|
|
ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
|
|
ctx.AddDependency(ctx.Module(), libTag, 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)...)
|
|
|
|
var flags []string
|
|
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")
|
|
}
|
|
|
|
return flags
|
|
}
|
|
|
|
type deps struct {
|
|
classpath classpath
|
|
bootClasspath 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 := String(m.deviceProperties.Sdk_version)
|
|
switch {
|
|
case name == "core.current.stubs" || ver == "core_current":
|
|
return javaCore
|
|
case name == "android_system_stubs_current" || strings.HasPrefix(ver, "system_"):
|
|
return javaSystem
|
|
case name == "android_test_stubs_current" || strings.HasPrefix(ver, "test_"):
|
|
return javaPlatform
|
|
case name == "android_stubs_current" || ver == "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, 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)
|
|
}
|
|
}
|
|
|
|
ctx.VisitDirectDeps(func(module android.Module) {
|
|
otherName := ctx.OtherModuleName(module)
|
|
tag := ctx.OtherModuleDependencyTag(module)
|
|
|
|
if to, ok := module.(*Library); ok {
|
|
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()...)
|
|
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)
|
|
}
|
|
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)
|
|
}
|
|
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:
|
|
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)
|
|
}
|
|
}
|
|
})
|
|
|
|
return deps
|
|
}
|
|
|
|
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 len(j.properties.Errorprone.Javacflags) > 0 {
|
|
flags.errorProneExtraJavacFlags = strings.Join(j.properties.Errorprone.Javacflags, " ")
|
|
}
|
|
|
|
// javaVersion flag.
|
|
sdk := sdkStringToNumber(ctx, String(j.deviceProperties.Sdk_version))
|
|
if j.properties.Java_version != nil {
|
|
flags.javaVersion = *j.properties.Java_version
|
|
} else if ctx.Device() && sdk <= 23 {
|
|
flags.javaVersion = "1.7"
|
|
} else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() {
|
|
flags.javaVersion = "1.8"
|
|
} else if ctx.Device() && String(j.deviceProperties.Sdk_version) != "" && sdk == android.FutureApiLevel {
|
|
// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
|
|
flags.javaVersion = "1.8"
|
|
} else {
|
|
flags.javaVersion = "1.9"
|
|
}
|
|
|
|
// classpath
|
|
flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
|
|
flags.classpath = append(flags.classpath, deps.classpath...)
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
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, kotlinJar)
|
|
|
|
// Jar kotlin classes into the final jar after javac
|
|
jars = append(jars, kotlinJar)
|
|
|
|
// 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...)
|
|
}
|
|
}
|
|
|
|
// 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().IsEnvTrue("RUN_ERROR_PRONE") {
|
|
// 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 proptools.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, nil)
|
|
outputFile = combinedJar
|
|
}
|
|
|
|
// 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
|
|
}
|
|
}
|
|
|
|
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() && j.installable() {
|
|
outputFile = j.compileDex(ctx, flags, outputFile, jarName)
|
|
if ctx.Failed() {
|
|
return
|
|
}
|
|
}
|
|
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, []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
|
|
}
|
|
|
|
// 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) {
|
|
case "", "current", "test_current", "system_current", "core_current":
|
|
return strconv.Itoa(ctx.Config().DefaultAppTargetSdkInt())
|
|
default:
|
|
return android.GetNumericSdkVersion(String(j.deviceProperties.Sdk_version))
|
|
}
|
|
}
|
|
|
|
func (j *Module) installable() bool {
|
|
return j.properties.Installable == nil || *j.properties.Installable
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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 j.installable() {
|
|
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(installable bool) func() android.Module {
|
|
return func() android.Module {
|
|
module := &Library{}
|
|
|
|
if !installable {
|
|
module.properties.Installable = proptools.BoolPtr(false)
|
|
}
|
|
|
|
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)
|
|
|
|
InitJavaModule(module, android.HostSupported)
|
|
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)
|
|
|
|
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)
|
|
|
|
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
|
|
android.InitDefaultableModule(module)
|
|
return module
|
|
}
|
|
|
|
//
|
|
// Java prebuilts
|
|
//
|
|
|
|
type ImportProperties struct {
|
|
Jars []string
|
|
|
|
Sdk_version *string
|
|
|
|
Installable *bool
|
|
}
|
|
|
|
type Import struct {
|
|
android.ModuleBase
|
|
prebuilt android.Prebuilt
|
|
|
|
properties ImportProperties
|
|
|
|
classpathFiles android.Paths
|
|
combinedClasspathFile android.Path
|
|
}
|
|
|
|
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) {
|
|
}
|
|
|
|
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars)
|
|
|
|
outputFile := android.PathForModuleOut(ctx, "classes.jar")
|
|
TransformJarsToJar(ctx, outputFile, "for prebuilts", j.classpathFiles, android.OptionalPath{}, false, nil)
|
|
j.combinedClasspathFile = outputFile
|
|
}
|
|
|
|
var _ Dependency = (*Import)(nil)
|
|
|
|
func (j *Import) HeaderJars() android.Paths {
|
|
return j.classpathFiles
|
|
}
|
|
|
|
func (j *Import) ImplementationJars() android.Paths {
|
|
return j.classpathFiles
|
|
}
|
|
|
|
func (j *Import) AidlIncludeDirs() android.Paths {
|
|
return nil
|
|
}
|
|
|
|
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 String = proptools.String
|
|
var inList = android.InList
|