|  | // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar | 
|  | import dx.DexMergerTask | 
|  | import dx.DxTask | 
|  | import net.ltgt.gradle.errorprone.CheckSeverity | 
|  | import org.gradle.internal.os.OperatingSystem | 
|  | import smali.SmaliTask | 
|  | import tasks.DownloadDependency | 
|  | import tasks.GetJarsFromConfiguration | 
|  | import utils.Utils | 
|  |  | 
|  | buildscript { | 
|  | repositories { | 
|  | maven { | 
|  | url 'https://storage.googleapis.com/r8-deps/maven_mirror/' | 
|  | } | 
|  | mavenCentral() | 
|  | gradlePluginPortal() | 
|  | jcenter() | 
|  | } | 
|  | dependencies { | 
|  | classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0' | 
|  | } | 
|  | } | 
|  |  | 
|  | plugins { | 
|  | id "net.ltgt.errorprone" version "0.7" | 
|  | } | 
|  |  | 
|  | apply plugin: 'java' | 
|  | apply plugin: 'idea' | 
|  |  | 
|  | ext { | 
|  | androidSupportVersion = '25.4.0' | 
|  | asmVersion = '9.0'  // When updating update tools/asmifier.py and Toolhelper as well. | 
|  | espressoVersion = '3.0.0' | 
|  | fastutilVersion = '7.2.0' | 
|  | guavaVersion = '23.0' | 
|  | joptSimpleVersion = '4.6' | 
|  | gsonVersion = '2.7' | 
|  | junitVersion = '4.13-beta-2' | 
|  | mockitoVersion = '2.10.0' | 
|  | // The kotlin version is only here to specify the kotlin language level, | 
|  | // all kotlin compilations are done in tests. | 
|  | kotlinVersion = '1.3.72' | 
|  | kotlinExtMetadataJVMVersion = '0.1.0' | 
|  | smaliVersion = '2.2b4' | 
|  | errorproneVersion = '2.3.2' | 
|  | testngVersion = '6.10' | 
|  | } | 
|  |  | 
|  | apply from: 'copyAdditionalJctfCommonFiles.gradle' | 
|  |  | 
|  | repositories { | 
|  | maven { | 
|  | url 'https://storage.googleapis.com/r8-deps/maven_mirror/' | 
|  | } | 
|  | google() | 
|  | mavenCentral() | 
|  | } | 
|  |  | 
|  | if (project.hasProperty('with_code_coverage')) { | 
|  | apply plugin: 'jacoco' | 
|  | } | 
|  |  | 
|  | // Custom source set for example tests and generated tests. | 
|  | sourceSets { | 
|  | test { | 
|  | java { | 
|  | srcDirs = [ | 
|  | 'src/test/java', | 
|  | 'build/generated/test/java', | 
|  | ] | 
|  | } | 
|  | } | 
|  | apiUsageSample { | 
|  | java { | 
|  | srcDirs = ['src/test/apiUsageSample', 'src/main/java'] | 
|  | include 'com/android/tools/apiusagesample/*.java' | 
|  | include 'com/android/tools/r8/BaseCompilerCommandParser.java' | 
|  | include 'com/android/tools/r8/D8CommandParser.java' | 
|  | include 'com/android/tools/r8/R8CommandParser.java' | 
|  | include 'com/android/tools/r8/utils/FlagFile.java' | 
|  | } | 
|  | } | 
|  | cfSegments { | 
|  | java { | 
|  | srcDirs = ['third_party/classlib/java', 'src/cf_segments/java'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/cfSegments' | 
|  | } | 
|  | libraryDesugarConversions { | 
|  | java { | 
|  | srcDirs = ['src/library_desugar/java'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/library_desugar_conversions' | 
|  | } | 
|  | debugTestResources { | 
|  | java { | 
|  | srcDirs = ['src/test/debugTestResources'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/debugTestResources' | 
|  | } | 
|  | debugTestResourcesJava8 { | 
|  | java { | 
|  | srcDirs = ['src/test/debugTestResourcesJava8'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/debugTestResourcesJava8' | 
|  | } | 
|  | examples { | 
|  | java { | 
|  | srcDirs = ['src/test/examples'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/examples' | 
|  | } | 
|  | examplesJava9 { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesJava9'] | 
|  | } | 
|  | } | 
|  | examplesJava10 { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesJava10'] | 
|  | } | 
|  | } | 
|  | examplesJava11 { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesJava11'] | 
|  | } | 
|  | } | 
|  | examplesJava15 { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesJava15'] | 
|  | } | 
|  | } | 
|  | jdk11TimeTests { | 
|  | java { | 
|  | srcDirs = [ | 
|  | 'third_party/openjdk/jdk-11-test/java/time/tck', | 
|  | 'third_party/openjdk/jdk-11-test/java/time/test' | 
|  | ] | 
|  | exclude '**/TestZoneTextPrinterParser.java' | 
|  | } | 
|  | } | 
|  | examplesTestNGRunner { | 
|  | java { | 
|  | srcDirs = ['src/test/testngrunner'] | 
|  | } | 
|  | } | 
|  | examplesAndroidN { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesAndroidN'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/examplesAndroidN' | 
|  | } | 
|  | examplesAndroidO { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesAndroidO'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/examplesAndroidO' | 
|  | } | 
|  | examplesAndroidP { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesAndroidP'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/examplesAndroidP' | 
|  | } | 
|  | examplesProto { | 
|  | java { | 
|  | srcDirs = ['src/test/examplesProto'] | 
|  | } | 
|  | compileClasspath = files("third_party/protobuf-lite/libprotobuf_lite.jar") | 
|  | compileClasspath += fileTree(dir: "build/generated/test/proto", include: "*.jar") | 
|  | output.resourcesDir = 'build/classes/examplesProto' | 
|  | } | 
|  | jctfCommon { | 
|  | java { | 
|  | srcDirs = [ | 
|  | 'third_party/jctf/Harness/src', | 
|  | 'third_party/jctf/LibTests/src/com/google/jctf/test/categories', | 
|  | 'third_party/jctf/LibTests/src/com/google/jctf/test/helper', | 
|  | 'third_party/jctf/LibTests/src/com/google/jctf/testHelpers', | 
|  | 'third_party/jctf/LibTests/src/org', | 
|  | 'build/additionalJctfCommonFiles' | 
|  | ] | 
|  | } | 
|  | resources { | 
|  | srcDirs = ['third_party/jctf/LibTests/resources'] | 
|  | } | 
|  | } | 
|  | jctfTests { | 
|  | java { | 
|  | srcDirs = [ | 
|  | 'third_party/jctf/LibTests/src/com/google/jctf/test/lib', | 
|  | // 'third_party/jctf/VMTests/src', | 
|  | ] | 
|  | } | 
|  | } | 
|  | kotlinR8TestResources { | 
|  | java { | 
|  | srcDirs = ['src/test/kotlinR8TestResources'] | 
|  | } | 
|  | output.resourcesDir = 'build/classes/kotlinR8TestResources' | 
|  | } | 
|  | } | 
|  |  | 
|  | // Ensure importing into IntelliJ IDEA use the same output directories as Gradle. In tests we | 
|  | // use the output path for tests (ultimately through ToolHelper.getClassPathForTests()) and | 
|  | // therefore these paths need to be the same. See https://youtrack.jetbrains.com/issue/IDEA-175172 | 
|  | // for context. | 
|  | idea { | 
|  | sourceSets.all { SourceSet sources -> | 
|  | module { | 
|  | if (sources.name == "main") { | 
|  | sourceDirs += sources.java.srcDirs | 
|  | outputDir sources.output.classesDirs[0] | 
|  | } else { | 
|  | testSourceDirs += sources.java.srcDirs | 
|  | testOutputDir sources.output.classesDirs[0] | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | configurations { | 
|  | supportLibs | 
|  | } | 
|  |  | 
|  | dependencies { | 
|  | implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion" | 
|  | implementation "com.google.code.gson:gson:$gsonVersion" | 
|  | // Include all of guava when compiling the code, but exclude annotations that we don't | 
|  | // need from the packaging. | 
|  | compileOnly("com.google.guava:guava:$guavaVersion") | 
|  | implementation("com.google.guava:guava:$guavaVersion", { | 
|  | exclude group: 'com.google.errorprone' | 
|  | exclude group: 'com.google.code.findbugs' | 
|  | exclude group: 'com.google.j2objc' | 
|  | exclude group: 'org.codehaus.mojo' | 
|  | }) | 
|  | implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion | 
|  | implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion" | 
|  | implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion | 
|  | implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion | 
|  | implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion | 
|  | implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion | 
|  | implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion | 
|  | jdk11TimeTestsCompile group: 'org.testng', name: 'testng', version: testngVersion | 
|  | examplesTestNGRunnerCompile group: 'org.testng', name: 'testng', version: testngVersion | 
|  | testCompile sourceSets.examples.output | 
|  | testCompile "junit:junit:$junitVersion" | 
|  | testCompile group: 'org.smali', name: 'smali', version: smaliVersion | 
|  | testCompile files('third_party/jasmin/jasmin-2.4.jar') | 
|  | testCompile files('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar') | 
|  | testCompile files('third_party/ddmlib/ddmlib.jar') | 
|  | jctfCommonCompile "junit:junit:$junitVersion" | 
|  | jctfTestsCompile "junit:junit:$junitVersion" | 
|  | jctfTestsCompile sourceSets.jctfCommon.output | 
|  | examplesAndroidOCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion | 
|  | examplesAndroidPCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion | 
|  | // Import Guava for @Nullable annotation | 
|  | examplesCompile "com.google.guava:guava:$guavaVersion" | 
|  | examplesCompile "junit:junit:$junitVersion" | 
|  | examplesCompile "org.mockito:mockito-core:$mockitoVersion" | 
|  | supportLibs "com.android.support:support-v4:$androidSupportVersion" | 
|  | supportLibs "junit:junit:$junitVersion" | 
|  | supportLibs "com.android.support.test.espresso:espresso-core:$espressoVersion" | 
|  | apiUsageSampleCompile sourceSets.main.output | 
|  | apiUsageSampleCompile "com.google.guava:guava:$guavaVersion" | 
|  | kotlinR8TestResourcesCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" | 
|  | errorprone("com.google.errorprone:error_prone_core:$errorproneVersion") | 
|  | testImplementation "org.jetbrains.kotlin:kotlin-reflect:1.3.31" | 
|  | } | 
|  |  | 
|  | def r8LibPath = "$buildDir/libs/r8lib.jar" | 
|  | def r8LibExludeDepsPath = "$buildDir/libs/r8lib-exclude-deps.jar" | 
|  | def r8DesugaredPath = "$buildDir/libs/r8desugared.jar" | 
|  | def r8LibGeneratedKeepRulesPath = "$buildDir/generated/keep.txt" | 
|  | def r8LibTestPath = "$buildDir/classes/r8libtest" | 
|  | def java11ClassFiles = "$buildDir/classes/java/mainJava11" | 
|  | def r8RetracePath = "$buildDir/libs/r8retrace.jar" | 
|  | def r8RetraceExludeDepsPath = "$buildDir/libs/r8retrace-exclude-deps.jar" | 
|  |  | 
|  | def osString = OperatingSystem.current().isLinux() ? "linux" : | 
|  | OperatingSystem.current().isMacOsX() ? "mac" : "windows" | 
|  |  | 
|  | def cloudDependencies = [ | 
|  | "tests"      : [ | 
|  | "2017-10-04/art", | 
|  | "2016-12-19/art" | 
|  | ], | 
|  | "third_party": [ | 
|  | "android_cts_baseline", | 
|  | "android_jar/lib-v14", | 
|  | "android_jar/lib-v15", | 
|  | "android_jar/lib-v19", | 
|  | "android_jar/lib-v21", | 
|  | "android_jar/lib-v22", | 
|  | "android_jar/lib-v23", | 
|  | "android_jar/lib-v24", | 
|  | "android_jar/lib-v25", | 
|  | "android_jar/lib-v26", | 
|  | "android_jar/lib-v27", | 
|  | "android_jar/lib-v28", | 
|  | "android_jar/lib-v29", | 
|  | "android_jar/lib-v30", | 
|  | "core-lambda-stubs", | 
|  | "dart-sdk", | 
|  | "ddmlib", | 
|  | "gradle/gradle", | 
|  | "google-java-format", | 
|  | "iosched_2019", | 
|  | "jacoco/0.8.2", | 
|  | "jacoco/0.8.6", | 
|  | "jasmin", | 
|  | "jctf", | 
|  | "junit", | 
|  | "jdwp-tests", | 
|  | "jsr223-api-1.0", | 
|  | "rhino-1.7.10", | 
|  | "rhino-android-1.1.1", | 
|  | "kotlin/kotlin-compiler-1.3.11", | 
|  | "kotlin/kotlin-compiler-1.3.41", | 
|  | "kotlin/kotlin-compiler-1.3.72", | 
|  | "kotlin/kotlin-compiler-1.4.20", | 
|  | "kotlinx-coroutines-1.3.6", | 
|  | "openjdk/openjdk-rt-1.8", | 
|  | "openjdk/desugar_jdk_libs", | 
|  | "openjdk/jdk-11-test", | 
|  | "proguard/proguard5.2.1", | 
|  | "proguard/proguard6.0.1", | 
|  | "proguard/proguard-7.0.0", | 
|  | "r8", | 
|  | "r8-releases/2.0.74", | 
|  | "r8mappings", | 
|  | "tachiyomi" | 
|  | ], | 
|  | // All dex-vms have a fixed OS of Linux, as they are only supported on Linux, and will be run in a Docker | 
|  | // container on other platforms where supported. | 
|  | "tools"      : [ | 
|  | "linux/art", | 
|  | "linux/art-5.1.1", | 
|  | "linux/art-6.0.1", | 
|  | "linux/art-7.0.0", | 
|  | "linux/art-8.1.0", | 
|  | "linux/art-9.0.0", | 
|  | "linux/art-10.0.0", | 
|  | "linux/dalvik", | 
|  | "linux/dalvik-4.0.4", | 
|  | "${osString}/dx", | 
|  | ] | 
|  | ] | 
|  |  | 
|  | def cloudSystemDependencies = [ | 
|  | linux: [ | 
|  | "third_party": ["openjdk/openjdk-9.0.4/linux", | 
|  | "openjdk/jdk8/linux-x86", | 
|  | "openjdk/jdk-11/linux", | 
|  | "openjdk/jdk-15/linux"], | 
|  | ], | 
|  | osx: [ | 
|  | "third_party": ["openjdk/openjdk-9.0.4/osx", | 
|  | "openjdk/jdk8/darwin-x86", | 
|  | "openjdk/jdk-11/osx", | 
|  | "openjdk/jdk-15/osx"], | 
|  | ], | 
|  | windows: [ | 
|  | "third_party": ["openjdk/openjdk-9.0.4/windows", | 
|  | "openjdk/jdk-11/windows", | 
|  | "openjdk/jdk-15/windows"], | 
|  | ], | 
|  | ] | 
|  |  | 
|  | if (OperatingSystem.current().isWindows()) { | 
|  | cloudSystemDependencies.windows.each { entry -> | 
|  | cloudDependencies.get(entry.key).addAll(entry.value) | 
|  | } | 
|  | } else if (OperatingSystem.current().isLinux()) { | 
|  | cloudSystemDependencies.linux.each { entry -> | 
|  | cloudDependencies.get(entry.key).addAll(entry.value) | 
|  | } | 
|  | } else if (OperatingSystem.current().isMacOsX()) { | 
|  | cloudSystemDependencies.osx.each { entry -> | 
|  | cloudDependencies.get(entry.key).addAll(entry.value) | 
|  | } | 
|  | } else { | 
|  | println "WARNING: Unsupported system: " + OperatingSystem.current() | 
|  | } | 
|  |  | 
|  | def getDownloadDepsTaskName(entryKey, entryFile) { | 
|  | return "download_deps_${entryKey}_${entryFile.replace('/', '_').replace('\\', '_')}" | 
|  | } | 
|  |  | 
|  | cloudDependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) { | 
|  | type DownloadDependency.Type.GOOGLE_STORAGE | 
|  | dependency "${entry.key}/${entryFile}" | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | def x20Dependencies = [ | 
|  | "third_party": [ | 
|  | "benchmarks/kotlin-benches", | 
|  | "chrome/chrome_180917_ffbaa8", | 
|  | "chrome/chrome_200430", | 
|  | "chrome/monochrome_public_minimal_apks/chrome_200520", | 
|  | "chrome/clank_google3_prebuilt", | 
|  | "classlib", | 
|  | "cf_segments", | 
|  | "desugar/desugar_20180308", | 
|  | "internal/issue-127524985", | 
|  | "framework", | 
|  | "gmail/gmail_android_170604.16", | 
|  | "gmail/gmail_android_180826.15", | 
|  | "gmscore/gmscore_v10", | 
|  | "gmscore/gmscore_v9", | 
|  | "gmscore/latest", | 
|  | "gmscore/v4", | 
|  | "gmscore/v5", | 
|  | "gmscore/v6", | 
|  | "gmscore/v7", | 
|  | "gmscore/v8", | 
|  | "nest/nest_20180926_7c6cfb", | 
|  | "proguard/proguard_internal_159423826", | 
|  | "proguardsettings", | 
|  | "proto", | 
|  | "protobuf-lite", | 
|  | "retrace_internal", | 
|  | "youtube/youtube.android_12.10", | 
|  | "youtube/youtube.android_12.17", | 
|  | "youtube/youtube.android_12.22", | 
|  | "youtube/youtube.android_13.37", | 
|  | "youtube/youtube.android_14.19", | 
|  | "youtube/youtube.android_14.44", | 
|  | "youtube/youtube.android_15.08", | 
|  | "youtube/youtube.android_15.09", | 
|  | "youtube/youtube.android_15.33" | 
|  | ], | 
|  | ] | 
|  |  | 
|  | x20Dependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) { | 
|  | type DownloadDependency.Type.X20 | 
|  | dependency "${entry.key}/${entryFile}" | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task downloadProguard { | 
|  | cloudDependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | if (entryFile.contains("proguard")) { | 
|  | dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}" | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task downloadOpenJDKrt { | 
|  | cloudDependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | if (entryFile.contains("openjdk-rt")) { | 
|  | dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}" | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task downloadDx { | 
|  | cloudDependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | if (entryFile.endsWith("/dx")) { | 
|  | dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}" | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task downloadAndroidCts { | 
|  | cloudDependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | if (entryFile.contains("android_cts_baseline")) { | 
|  | dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}" | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task downloadDeps { | 
|  | cloudDependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}" | 
|  | } | 
|  | } | 
|  | if (!project.hasProperty('no_internal')) { | 
|  | x20Dependencies.each { entry -> | 
|  | entry.value.each { entryFile -> | 
|  | dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}" | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | allprojects { | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | } | 
|  |  | 
|  | // TODO(ricow): Remove debug prints | 
|  | println("NOTE: Current operating system: " + OperatingSystem.current()) | 
|  | println("NOTE: Current operating system isWindows: " + OperatingSystem.current().isWindows()) | 
|  |  | 
|  | // Check if running with the JDK location from tools/jdk.py. | 
|  | if (OperatingSystem.current().isWindows()) { | 
|  | println "NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome | 
|  | compileJava.options.encoding = "UTF-8" | 
|  | compileTestJava.options.encoding = "UTF-8" | 
|  | } else { | 
|  | def javaHomeOut = new StringBuilder() | 
|  | def javaHomeErr = new StringBuilder() | 
|  | def javaHomeProc = './tools/jdk.py'.execute([], projectDir) | 
|  | javaHomeProc.waitForProcessOutput(javaHomeOut, javaHomeErr) | 
|  | def jdkHome = new File(javaHomeOut.toString().trim()) | 
|  | if (!jdkHome.exists()) { | 
|  | println "WARNING: Failed to find the ./tools/jdk.py specified JDK: " + jdkHome | 
|  | } else if (jdkHome != org.gradle.internal.jvm.Jvm.current().javaHome) { | 
|  | println("WARNING: Gradle is running in a non-pinned Java" | 
|  | + ". Gradle Java Home: " + org.gradle.internal.jvm.Jvm.current().javaHome | 
|  | + ". Expected: " + jdkHome) | 
|  | } else { | 
|  | println("NOTE: Running with jdk from tools/jdk.py: " + jdkHome) | 
|  | } | 
|  | } | 
|  |  | 
|  | sourceSets.configureEach { sourceSet -> | 
|  | tasks.named(sourceSet.compileJavaTaskName).configure { | 
|  | // Default disable errorprone (enabled and setup below). | 
|  | options.errorprone.enabled = false | 
|  | options.compilerArgs << '-Xlint:unchecked' | 
|  | // Run all compilation tasks in a forked subprocess. | 
|  | options.fork = true | 
|  | // Javac often runs out of stack space when compiling the tests. | 
|  | // Increase the stack size for the javac process. | 
|  | options.forkOptions.jvmArgs << "-Xss256m" | 
|  | // Test compilation is sometimes hitting the default limit at 1g, increase it. | 
|  | options.forkOptions.jvmArgs << "-Xmx3g" | 
|  | // Set the bootclass path so compilation is consistent with 1.8 target compatibility. | 
|  | options.forkOptions.jvmArgs << "-Xbootclasspath/a:third_party/openjdk/openjdk-rt-1.8/rt.jar" | 
|  | } | 
|  | } | 
|  |  | 
|  | def setJdkCompilationWithCompatibility(String sourceSet, String javaHome, JavaVersion compatibility, boolean enablePreview) { | 
|  | tasks.named(sourceSet).get().configure { | 
|  | def jdkDir = "third_party/openjdk/${javaHome}/" | 
|  | options.fork = true | 
|  | options.forkOptions.jvmArgs = [] | 
|  | if (enablePreview) { | 
|  | options.compilerArgs.add('--enable-preview') | 
|  | } | 
|  | if (OperatingSystem.current().isLinux()) { | 
|  | options.forkOptions.javaHome = file(jdkDir + 'linux') | 
|  | } else if (OperatingSystem.current().isMacOsX()) { | 
|  | options.forkOptions.javaHome = file(jdkDir + 'osx') | 
|  | } else { | 
|  | options.forkOptions.javaHome = file(jdkDir + 'windows') | 
|  | } | 
|  | sourceCompatibility = compatibility | 
|  | targetCompatibility = compatibility | 
|  | } | 
|  | } | 
|  |  | 
|  | setJdkCompilationWithCompatibility( | 
|  | sourceSets.examplesJava9.compileJavaTaskName, | 
|  | 'openjdk-9.0.4', | 
|  | JavaVersion.VERSION_1_9, | 
|  | false) | 
|  | setJdkCompilationWithCompatibility( | 
|  | sourceSets.examplesJava11.compileJavaTaskName, | 
|  | 'jdk-11', | 
|  | JavaVersion.VERSION_11, | 
|  | false) | 
|  | setJdkCompilationWithCompatibility( | 
|  | sourceSets.examplesJava10.compileJavaTaskName, | 
|  | 'jdk-11', | 
|  | JavaVersion.VERSION_1_10, | 
|  | false) | 
|  | setJdkCompilationWithCompatibility( | 
|  | sourceSets.examplesJava11.compileJavaTaskName, | 
|  | 'jdk-11', | 
|  | JavaVersion.VERSION_11, | 
|  | false) | 
|  | setJdkCompilationWithCompatibility( | 
|  | sourceSets.examplesTestNGRunner.compileJavaTaskName, | 
|  | 'jdk-11', | 
|  | JavaVersion.VERSION_11, | 
|  | false) | 
|  | setJdkCompilationWithCompatibility( | 
|  | sourceSets.jdk11TimeTests.compileJavaTaskName, | 
|  | 'jdk-11', | 
|  | JavaVersion.VERSION_11, | 
|  | false) | 
|  | setJdkCompilationWithCompatibility( | 
|  | sourceSets.examplesJava15.compileJavaTaskName, | 
|  | 'jdk-15', | 
|  | JavaVersion.VERSION_15, | 
|  | true) | 
|  |  | 
|  | task compileMainWithJava11 (type: JavaCompile) { | 
|  | dependsOn downloadDeps | 
|  | def jdkDir = 'third_party/openjdk/jdk-11/' | 
|  | options.fork = true | 
|  | options.forkOptions.jvmArgs = [] | 
|  | if (OperatingSystem.current().isLinux()) { | 
|  | options.forkOptions.javaHome = file(jdkDir + 'linux') | 
|  | } else if (OperatingSystem.current().isMacOsX()) { | 
|  | options.forkOptions.javaHome = file(jdkDir + 'osx/Contents/Home') | 
|  | } else { | 
|  | options.forkOptions.javaHome = file(jdkDir + 'windows') | 
|  | } | 
|  | source = sourceSets.main.allSource | 
|  | destinationDir = file(java11ClassFiles) | 
|  | sourceCompatibility = JavaVersion.VERSION_11 | 
|  | targetCompatibility = JavaVersion.VERSION_11 | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | } | 
|  |  | 
|  | if (!project.hasProperty('without_error_prone') && | 
|  | // Don't enable error prone on Java 8 as the plugin setup does not support it. | 
|  | !org.gradle.internal.jvm.Jvm.current().javaVersion.java8) { | 
|  | compileJava { | 
|  | // Enable error prone for D8/R8 sources. | 
|  | options.errorprone.enabled = true | 
|  | options.errorprone.disableAllChecks = true | 
|  | options.errorprone.check('ClassCanBeStatic', CheckSeverity.ERROR) | 
|  | options.errorprone.check('CollectionIncompatibleType', CheckSeverity.ERROR) | 
|  | options.errorprone.check('OperatorPrecedence', CheckSeverity.ERROR) | 
|  | options.errorprone.check('RemoveUnusedImports', CheckSeverity.ERROR) | 
|  | options.errorprone.check('MissingOverride', CheckSeverity.ERROR) | 
|  | options.errorprone.check('IntLongMath', CheckSeverity.ERROR) | 
|  | options.errorprone.check('EqualsHashCode', CheckSeverity.ERROR) | 
|  | options.errorprone.check('InconsistentOverloads', CheckSeverity.ERROR) | 
|  | options.errorprone.check('ArrayHashCode', CheckSeverity.ERROR) | 
|  | options.errorprone.check('EqualsIncompatibleType', CheckSeverity.ERROR) | 
|  | options.errorprone.check('NonOverridingEquals', CheckSeverity.ERROR) | 
|  | options.errorprone.check('FallThrough', CheckSeverity.ERROR) | 
|  | options.errorprone.check('MissingCasesInEnumSwitch', CheckSeverity.ERROR) | 
|  | options.errorprone.check('MissingDefault', CheckSeverity.ERROR) | 
|  | options.errorprone.check('MultipleTopLevelClasses', CheckSeverity.ERROR) | 
|  | options.errorprone.check('NarrowingCompoundAssignment', CheckSeverity.ERROR) | 
|  | options.errorprone.check('BoxedPrimitiveConstructor', CheckSeverity.ERROR) | 
|  | options.errorprone.check('LogicalAssignment', CheckSeverity.ERROR) | 
|  | options.errorprone.check('FloatCast', CheckSeverity.ERROR) | 
|  | options.errorprone.check('ReturnValueIgnored', CheckSeverity.ERROR) | 
|  | } | 
|  | } | 
|  |  | 
|  | compileJctfCommonJava { | 
|  | dependsOn 'copyAdditionalJctfCommonFiles' | 
|  | options.compilerArgs = ['-Xlint:none'] | 
|  | } | 
|  |  | 
|  | compileJctfTestsJava { | 
|  | dependsOn 'jctfCommonClasses' | 
|  | options.compilerArgs = ['-Xlint:none'] | 
|  | } | 
|  |  | 
|  | task consolidatedLicense { | 
|  | def license = new File(new File(buildDir, 'generatedLicense'), 'LICENSE') | 
|  |  | 
|  | inputs.files files('LICENSE', 'LIBRARY-LICENSE') + fileTree(dir: 'library-licensing') | 
|  | def runtimeClasspath = configurations.findByName("runtimeClasspath") | 
|  | inputs.files { runtimeClasspath.getResolvedConfiguration().files } | 
|  |  | 
|  | outputs.files license | 
|  |  | 
|  | doLast { | 
|  | def dependencies = [] | 
|  | runtimeClasspath.resolvedConfiguration.resolvedArtifacts.each { | 
|  | def identifier = (ModuleComponentIdentifier) it.id.componentIdentifier | 
|  | dependencies.add("${identifier.group}:${identifier.module}") | 
|  | } | 
|  | def libraryLicenses = file('LIBRARY-LICENSE').text | 
|  | dependencies.each { | 
|  | if (!libraryLicenses.contains("- artifact: $it")) { | 
|  | throw new GradleException("No license for $it in LIBRARY_LICENSE") | 
|  | } | 
|  | } | 
|  |  | 
|  | license.getParentFile().mkdirs() | 
|  | license.createNewFile() | 
|  | license.text = "This file lists all licenses for code distributed.\n" | 
|  | license.text += "All non-library code has the following 3-Clause BSD license.\n" | 
|  | license.text += "\n" | 
|  | license.text += "\n" | 
|  | license.text += file('LICENSE').text | 
|  | license.text += "\n" | 
|  | license.text += "\n" | 
|  | license.text += "Summary of distributed libraries:\n" | 
|  | license.text += "\n" | 
|  | license.text += libraryLicenses | 
|  | license.text += "\n" | 
|  | license.text += "\n" | 
|  | license.text += "Licenses details:\n" | 
|  | fileTree(dir: 'library-licensing').getFiles().stream().sorted().forEach { file -> | 
|  | license.text += "\n" | 
|  | license.text += "\n" | 
|  | license.text += file.text | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | static mergeServiceFiles(ShadowJar task) { | 
|  | // Everything under META-INF is not included by default. | 
|  | // Should include before 'relocate' so that the service file path and its content | 
|  | // are properly relocated as well. | 
|  | task.mergeServiceFiles { | 
|  | include 'META-INF/services/*' | 
|  | } | 
|  | } | 
|  |  | 
|  | task repackageDepsNew(type: ShadowJar) { | 
|  | configurations = [project.configurations.runtimeClasspath] | 
|  | mergeServiceFiles(it) | 
|  | exclude { it.getRelativePath().getPathString() == "module-info.class" } | 
|  | exclude { it.getRelativePath().getPathString().startsWith("META-INF/maven/") } | 
|  | baseName 'deps_all' | 
|  | } | 
|  |  | 
|  | task repackageSourcesNew(type: ShadowJar) { | 
|  | // If this fails then remove all generated folders from | 
|  | // build/classes/java/test that is not {com,dalvik} | 
|  | from sourceSets.main.output | 
|  | mergeServiceFiles(it) | 
|  | baseName 'sources_main' | 
|  | } | 
|  |  | 
|  | task repackageSources11New(type: ShadowJar) { | 
|  | dependsOn compileMainWithJava11 | 
|  | from file(java11ClassFiles) | 
|  | mergeServiceFiles(it) | 
|  | baseName 'sources_main_11' | 
|  | } | 
|  |  | 
|  | def r8CreateTask(name, baseNameName, sources, includeSwissArmyKnife) { | 
|  | return tasks.create("r8Create${name}", ShadowJar) { | 
|  | from consolidatedLicense.outputs.files | 
|  | from sources | 
|  | exclude "$buildDir/classes/**" | 
|  | baseName baseNameName | 
|  | classifier = null | 
|  | version = null | 
|  | if (includeSwissArmyKnife) { | 
|  | manifest { | 
|  | attributes 'Main-Class': 'com.android.tools.r8.SwissArmyKnife' | 
|  | } | 
|  | } | 
|  | exclude "META-INF/*.kotlin_module" | 
|  | exclude "**/*.kotlin_metadata" | 
|  | } | 
|  | } | 
|  |  | 
|  | def r8RelocateTask(r8Task, output) { | 
|  | return tasks.create("r8Relocate_${r8Task.name}", Exec) { | 
|  | dependsOn r8WithDeps | 
|  | dependsOn r8Task | 
|  | outputs.file output | 
|  | workingDir = projectDir | 
|  | inputs.files r8Task.outputs.files + r8WithDeps.outputs.files | 
|  | commandLine baseCompilerCommandLine([ | 
|  | "relocator", | 
|  | "--input", | 
|  | r8Task.outputs.files[0], | 
|  | "--output", | 
|  | output, | 
|  | "--map", | 
|  | "com.google.common->com.android.tools.r8.com.google.common", | 
|  | "--map", | 
|  | "com.google.gson->com.android.tools.r8.com.google.gson", | 
|  | "--map", | 
|  | "com.google.thirdparty->com.android.tools.r8.com.google.thirdparty", | 
|  | "--map", | 
|  | "joptsimple->com.android.tools.r8.joptsimple", | 
|  | "--map", | 
|  | "org.objectweb.asm->com.android.tools.r8.org.objectweb.asm", | 
|  | "--map", | 
|  | "it.unimi.dsi.fastutil->com.android.tools.r8.it.unimi.dsi.fastutil", | 
|  | "--map", | 
|  | "kotlin->com.android.tools.r8.jetbrains.kotlin", | 
|  | "--map", | 
|  | "kotlinx->com.android.tools.r8.jetbrains.kotlinx", | 
|  | "--map", | 
|  | "org.jetbrains->com.android.tools.r8.org.jetbrains", | 
|  | "--map", | 
|  | "org.intellij->com.android.tools.r8.org.intellij" | 
|  | ]) | 
|  | } | 
|  | } | 
|  |  | 
|  | task r8WithDeps { | 
|  | dependsOn repackageSourcesNew | 
|  | dependsOn repackageDepsNew | 
|  | inputs.files ([repackageSourcesNew.outputs, repackageDepsNew.outputs]) | 
|  | def r8Task = r8CreateTask( | 
|  | 'WithDeps', | 
|  | 'r8_with_deps', | 
|  | repackageSourcesNew.outputs.files + repackageDepsNew.outputs.files, | 
|  | true) | 
|  | dependsOn r8Task | 
|  | outputs.files r8Task.outputs.files | 
|  | } | 
|  |  | 
|  | task r8WithDeps11 { | 
|  | dependsOn repackageSources11New | 
|  | dependsOn repackageDepsNew | 
|  | inputs.files ([repackageSources11New.outputs, repackageDepsNew.outputs]) | 
|  | def r8Task = r8CreateTask( | 
|  | 'WithDeps11', | 
|  | 'r8_with_deps_11', | 
|  | repackageSources11New.outputs.files + repackageDepsNew.outputs.files, | 
|  | true) | 
|  | dependsOn r8Task | 
|  | outputs.files r8Task.outputs.files | 
|  | } | 
|  |  | 
|  | task r8WithRelocatedDeps { | 
|  | def output = "${buildDir}/libs/r8_with_relocated_deps.jar" | 
|  | dependsOn r8RelocateTask(r8WithDeps, output) | 
|  | inputs.files r8WithDeps.outputs.files | 
|  | outputs.file output | 
|  | } | 
|  |  | 
|  | task r8WithRelocatedDeps11 { | 
|  | def output = "${buildDir}/libs/r8_with_relocated_deps_11.jar" | 
|  | dependsOn r8RelocateTask(r8WithDeps11, output) | 
|  | inputs.files r8WithDeps11.outputs.files | 
|  | outputs.file output | 
|  | } | 
|  |  | 
|  | task r8WithoutDeps { | 
|  | dependsOn repackageSourcesNew | 
|  | inputs.files repackageSourcesNew.outputs | 
|  | def r8Task = r8CreateTask( | 
|  | 'WithoutDeps', | 
|  | 'r8_without_deps', | 
|  | repackageSourcesNew.outputs.files, | 
|  | true) | 
|  | dependsOn r8Task | 
|  | outputs.files r8Task.outputs.files | 
|  | } | 
|  |  | 
|  | task r8(type: Copy) { | 
|  | def r8Task = project.hasProperty("exclude_deps") | 
|  | ? r8WithoutDeps : r8WithRelocatedDeps | 
|  | dependsOn r8Task | 
|  | from r8Task.outputs.files[0] | 
|  | into file("${buildDir}/libs") | 
|  | rename { String fileName -> "r8.jar" } | 
|  | outputs.file "${buildDir}/libs/r8.jar" | 
|  | } | 
|  |  | 
|  | task r8NoManifestWithoutDeps { | 
|  | dependsOn repackageSourcesNew | 
|  | inputs.files repackageSourcesNew.outputs | 
|  | def r8Task = r8CreateTask( | 
|  | 'NoManifestWithoutDeps', | 
|  | 'r8_no_manifest_without_deps', | 
|  | repackageSourcesNew.outputs.files, | 
|  | false) | 
|  | dependsOn r8Task | 
|  | outputs.files r8Task.outputs.files | 
|  | } | 
|  |  | 
|  | task r8NoManifestWithDeps { | 
|  | dependsOn repackageSourcesNew | 
|  | inputs.files ([repackageSourcesNew.outputs, repackageDepsNew.outputs]) | 
|  | def r8Task = r8CreateTask( | 
|  | 'NoManifestWithDeps', | 
|  | 'r8_no_manifest_with_deps', | 
|  | repackageSourcesNew.outputs.files + repackageDepsNew.outputs.files, | 
|  | false) | 
|  | dependsOn r8Task | 
|  | outputs.files r8Task.outputs.files | 
|  | } | 
|  |  | 
|  | task r8NoManifestWithRelocatedDeps { | 
|  | def output = "${buildDir}/libs/r8_no_manifest_with_relocated_deps.jar" | 
|  | dependsOn r8RelocateTask(r8NoManifestWithDeps, output) | 
|  | inputs.files r8NoManifestWithDeps.outputs.files | 
|  | outputs.file output | 
|  | } | 
|  |  | 
|  | task r8NoManifest(type: Copy) { | 
|  | def r8Task = project.hasProperty("exclude_deps") | 
|  | ? r8NoManifestWithoutDeps : r8NoManifestWithRelocatedDeps | 
|  | dependsOn r8Task | 
|  | from r8Task.outputs.files[0] | 
|  | into file("${buildDir}/libs") | 
|  | rename { String fileName -> "r8_no_manifest.jar" } | 
|  | outputs.file "${buildDir}/libs/r8_no_manifest.jar" | 
|  | } | 
|  |  | 
|  | task D8(type: ShadowJar) { | 
|  | dependsOn r8 | 
|  | from r8.outputs.files[0] | 
|  | baseName 'd8' | 
|  | manifest { | 
|  | attributes 'Main-Class': 'com.android.tools.r8.D8' | 
|  | } | 
|  | } | 
|  |  | 
|  | def baseCompilerCommandLine(compiler, args = []) { | 
|  | // Execute r8 commands against a stable r8 with dependencies. | 
|  | // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g). | 
|  | return [org.gradle.internal.jvm.Jvm.current().getJavaExecutable(), | 
|  | "-Xmx8g", "-ea", "-jar", r8WithDeps.outputs.files[0]] + compiler + args | 
|  | } | 
|  |  | 
|  | def baseR8CommandLine(args = []) { | 
|  | // Execute r8 commands against a stable r8 with dependencies. | 
|  | return baseCompilerCommandLine("r8", args) | 
|  | } | 
|  |  | 
|  | def baseD8CommandLine(args = []) { | 
|  | // Execute r8 commands against a stable r8 with dependencies. | 
|  | return baseCompilerCommandLine("d8", args) | 
|  | } | 
|  |  | 
|  | def r8CfCommandLine(input, output, pgConfs = [], args = ["--release"], libs = []) { | 
|  | def allArgs = [ | 
|  | "--classfile", | 
|  | input, | 
|  | "--output", output, | 
|  | "--pg-map-output", output + ".map", | 
|  | "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar" | 
|  | ] + args + libs.collectMany { ["--lib", it] } + pgConfs.collectMany { ["--pg-conf", it] } | 
|  | return baseR8CommandLine(allArgs) | 
|  | } | 
|  |  | 
|  | def d8CfCommandLine(input, output, args = ["--release"], libs = []) { | 
|  | def allArgs = [ | 
|  | "--classfile", | 
|  | input, | 
|  | "--output", output, | 
|  | "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar" | 
|  | ] + args + libs.collectMany { ["--lib", it] } | 
|  | return baseD8CommandLine(allArgs) | 
|  | } | 
|  |  | 
|  | def r8LibCreateTask(name, pgConfs = [], r8Task, output, args = ["--release"], libs = []) { | 
|  | return tasks.create("r8Lib${name}", Exec) { | 
|  | inputs.files ([pgConfs, r8WithRelocatedDeps.outputs, r8Task.outputs, libs]) | 
|  | outputs.file output | 
|  | dependsOn downloadOpenJDKrt | 
|  | dependsOn r8WithRelocatedDeps | 
|  | dependsOn r8Task | 
|  | commandLine r8CfCommandLine(r8Task.outputs.files[0], output, pgConfs, args, libs) | 
|  | workingDir = projectDir | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildLibraryDesugarConversions(type: Zip, dependsOn: downloadDeps) { | 
|  | from sourceSets.libraryDesugarConversions.output | 
|  | include "java/**/*.class" | 
|  | baseName 'library_desugar_conversions' | 
|  | destinationDir file('build/libs') | 
|  | } | 
|  |  | 
|  | task testJarSources(type: ShadowJar, dependsOn: [testClasses, buildLibraryDesugarConversions]) { | 
|  | baseName = "r8testsbase" | 
|  | from sourceSets.test.output | 
|  | // We only want to include tests that use R8 when generating keep rules for applymapping. | 
|  | include "com/android/tools/r8/**" | 
|  | include "dalvik/**" | 
|  | } | 
|  |  | 
|  | task testJar(type: Exec) { | 
|  | dependsOn r8WithDeps | 
|  | dependsOn testJarSources | 
|  | def output = "$buildDir/libs/r8tests.jar" | 
|  | outputs.file output | 
|  | workingDir = projectDir | 
|  | inputs.files (testJarSources.outputs.files + r8WithDeps.outputs.files) | 
|  | commandLine baseCompilerCommandLine([ | 
|  | "relocator", | 
|  | "--input", | 
|  | testJarSources.outputs.files[0], | 
|  | "--output", | 
|  | output, | 
|  | "--map", | 
|  | "kotlinx.metadata->com.android.tools.r8.jetbrains.kotlinx.metadata" | 
|  | ]) | 
|  | } | 
|  |  | 
|  | task generateR8LibKeepRules(type: Exec) { | 
|  | doFirst { | 
|  | // TODO(b/154785341): We should remove this. | 
|  | standardOutput new FileOutputStream(r8LibGeneratedKeepRulesPath) | 
|  | } | 
|  | // Depend on r8WithDeps for running baseCompilerCommandLine. | 
|  | dependsOn r8WithDeps | 
|  | dependsOn r8NoManifestWithRelocatedDeps | 
|  | dependsOn testJar | 
|  | dependsOn downloadOpenJDKrt | 
|  | inputs.files ([ | 
|  | r8WithDeps.outputs, | 
|  | r8NoManifestWithRelocatedDeps.outputs, | 
|  | testJar.outputs]) | 
|  | outputs.file r8LibGeneratedKeepRulesPath | 
|  | commandLine baseCompilerCommandLine([ | 
|  | "printuses", | 
|  | "--keeprules-allowobfuscation", | 
|  | "third_party/openjdk/openjdk-rt-1.8/rt.jar", | 
|  | r8NoManifestWithRelocatedDeps.outputs.files[0], | 
|  | testJar.outputs.files[0]]) | 
|  | workingDir = projectDir | 
|  | } | 
|  |  | 
|  | task R8LibApiOnly { | 
|  | dependsOn r8LibCreateTask("Api", ["src/main/keep.txt"], r8NoManifest, r8LibPath) | 
|  | outputs.file r8LibPath | 
|  | } | 
|  |  | 
|  | task R8Lib { | 
|  | dependsOn r8LibCreateTask( | 
|  | "Main", | 
|  | ["src/main/keep.txt", generateR8LibKeepRules.outputs.files[0]], | 
|  | r8NoManifestWithRelocatedDeps, | 
|  | r8LibPath, | 
|  | ).dependsOn(generateR8LibKeepRules) | 
|  | inputs.files r8NoManifestWithRelocatedDeps.outputs.files | 
|  | outputs.file r8LibPath | 
|  | } | 
|  |  | 
|  | task R8LibNoDeps { | 
|  | dependsOn r8LibCreateTask( | 
|  | "NoDeps", | 
|  | ["src/main/keep.txt"], | 
|  | r8NoManifestWithoutDeps, | 
|  | r8LibExludeDepsPath, | 
|  | "--release", | 
|  | repackageDepsNew.outputs.files | 
|  | ).dependsOn(repackageDepsNew) | 
|  | inputs.files ([r8NoManifestWithoutDeps.outputs, repackageDepsNew.outputs]) | 
|  | outputs.file r8LibExludeDepsPath | 
|  | } | 
|  |  | 
|  | task R8Desugared(type: Exec) { | 
|  | dependsOn downloadOpenJDKrt | 
|  | dependsOn r8NoManifestWithRelocatedDeps | 
|  | inputs.files r8NoManifestWithRelocatedDeps.outputs.files | 
|  | commandLine d8CfCommandLine( | 
|  | r8NoManifestWithRelocatedDeps.outputs.files[0], | 
|  | r8DesugaredPath, | 
|  | ["--release"]) | 
|  | workingDir = projectDir | 
|  | outputs.file r8DesugaredPath | 
|  | } | 
|  |  | 
|  | task R8Retrace { | 
|  | dependsOn R8Lib | 
|  | dependsOn r8LibCreateTask( | 
|  | "Retrace", | 
|  | ["src/main/keep_retrace.txt"], | 
|  | R8Lib, | 
|  | r8RetracePath, | 
|  | ).dependsOn(R8Lib) | 
|  | outputs.file r8RetracePath | 
|  | } | 
|  |  | 
|  | task R8RetraceNoDeps { | 
|  | dependsOn R8LibNoDeps | 
|  | dependsOn r8LibCreateTask( | 
|  | "RetraceNoDeps", | 
|  | ["src/main/keep_retrace.txt"], | 
|  | R8LibNoDeps, | 
|  | r8RetraceExludeDepsPath, | 
|  | "--release", | 
|  | repackageDepsNew.outputs.files | 
|  | ).dependsOn(R8LibNoDeps) | 
|  | outputs.file r8RetraceExludeDepsPath | 
|  | } | 
|  |  | 
|  | task sourceJar(type: Jar, dependsOn: classes) { | 
|  | classifier = 'src' | 
|  | from sourceSets.main.allSource | 
|  | } | 
|  |  | 
|  | task jctfCommonJar(type: Jar) { | 
|  | from sourceSets.jctfCommon.output | 
|  | baseName 'jctfCommon' | 
|  | } | 
|  |  | 
|  | artifacts { | 
|  | archives sourceJar | 
|  | } | 
|  |  | 
|  | task createArtTests(type: Exec) { | 
|  | def outputDir = "build/generated/test/java/com/android/tools/r8/art" | 
|  | def createArtTestsScript = "tools/create_art_tests.py" | 
|  | inputs.files files("tests/2017-10-04/art.tar.gz", createArtTestsScript) | 
|  | outputs.dir outputDir | 
|  | dependsOn downloadDeps | 
|  | commandLine "python", createArtTestsScript | 
|  | workingDir = projectDir | 
|  | } | 
|  |  | 
|  | task createJctfTests(type: Exec) { | 
|  | def outputDir = "build/generated/test/java/com/android/tools/r8/jctf" | 
|  | def script = "tools/create_jctf_tests.py" | 
|  | inputs.file script | 
|  | outputs.dir outputDir | 
|  | dependsOn downloadDeps | 
|  | commandLine "python", script | 
|  | workingDir = projectDir | 
|  | } | 
|  |  | 
|  | compileTestJava { | 
|  | dependsOn createArtTests | 
|  | dependsOn createJctfTests | 
|  | } | 
|  |  | 
|  | task buildCfSegments(type: Jar, dependsOn: downloadDeps) { | 
|  | from sourceSets.cfSegments.output | 
|  | baseName 'cf_segments' | 
|  | destinationDir file('build/libs') | 
|  | } | 
|  |  | 
|  | task buildR8ApiUsageSample(type: Jar) { | 
|  | from sourceSets.apiUsageSample.output | 
|  | baseName 'r8_api_usage_sample' | 
|  | destinationDir file('tests') | 
|  | } | 
|  |  | 
|  | task buildApiSampleJars { | 
|  | dependsOn buildR8ApiUsageSample | 
|  | } | 
|  |  | 
|  | task buildDebugInfoExamplesDex { | 
|  | def examplesDir = file("src/test/java") | 
|  | def hostJar = "debuginfo_examples.jar" | 
|  | def hostDexJar = "debuginfo_examples_dex.jar" | 
|  | task "compile_debuginfo_examples"(type: JavaCompile) { | 
|  | source = fileTree(dir: examplesDir, include: "com/android/tools/r8/debuginfo/*Test.java") | 
|  | destinationDir = file("build/test/debuginfo_examples/classes") | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_7 | 
|  | targetCompatibility = JavaVersion.VERSION_1_7 | 
|  | options.compilerArgs += ["-Xlint:-options"] | 
|  | } | 
|  | task "jar_debuginfo_examples"(type: Jar, dependsOn: "compile_debuginfo_examples") { | 
|  | archiveName = hostJar | 
|  | destinationDir = file("build/test/") | 
|  | from "build/test/debuginfo_examples/classes" | 
|  | include "**/*.class" | 
|  | } | 
|  | task "dex_debuginfo_examples"(type: Exec, | 
|  | dependsOn: ["jar_debuginfo_examples", "downloadDeps"]) { | 
|  | if (OperatingSystem.current().isWindows()) { | 
|  | executable file("tools/windows/dx/bin/dx.bat") | 
|  | } else if (OperatingSystem.current().isMacOsX()) { | 
|  | executable file("tools/mac/dx/bin/dx"); | 
|  | } else { | 
|  | executable file("tools/linux/dx/bin/dx"); | 
|  | } | 
|  | args "--dex" | 
|  | args "--output=build/test/${hostDexJar}" | 
|  | args "build/test/${hostJar}" | 
|  | inputs.files files("build/test/${hostJar}") | 
|  | outputs.file file("build/test/${hostDexJar}") | 
|  | } | 
|  | dependsOn dex_debuginfo_examples | 
|  | } | 
|  |  | 
|  | task buildDebugTestResourcesJars { | 
|  | def resourcesDir = file("src/test/debugTestResources") | 
|  | def hostJar = "debug_test_resources.jar" | 
|  | task "compile_debugTestResources"(type: JavaCompile) { | 
|  | source = fileTree(dir: resourcesDir, include: '**/*.java') | 
|  | destinationDir = file("build/test/debugTestResources/classes") | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_7 | 
|  | targetCompatibility = JavaVersion.VERSION_1_7 | 
|  | options.compilerArgs += ["-g", "-Xlint:-options"] | 
|  | } | 
|  | task "jar_debugTestResources"(type: Jar, dependsOn: "compile_debugTestResources") { | 
|  | archiveName = hostJar | 
|  | destinationDir = file("build/test/") | 
|  | from "build/test/debugTestResources/classes" | 
|  | include "**/*.class" | 
|  | } | 
|  | def java8ResourcesDir = file("src/test/debugTestResourcesJava8") | 
|  | def java8HostJar = "debug_test_resources_java8.jar" | 
|  | task "compile_debugTestResourcesJava8"(type: JavaCompile) { | 
|  | source = fileTree(dir: java8ResourcesDir, include: '**/*.java') | 
|  | destinationDir = file("build/test/debugTestResourcesJava8/classes") | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | options.compilerArgs += ["-g", "-Xlint:-options"] | 
|  | } | 
|  | task "jar_debugTestResourcesJava8"(type: Jar, dependsOn: "compile_debugTestResourcesJava8") { | 
|  | archiveName = java8HostJar | 
|  | destinationDir = file("build/test/") | 
|  | from "build/test/debugTestResourcesJava8/classes" | 
|  | include "**/*.class" | 
|  | } | 
|  | dependsOn downloadDeps | 
|  | dependsOn jar_debugTestResources | 
|  | dependsOn jar_debugTestResourcesJava8 | 
|  | } | 
|  |  | 
|  | // Examples used by tests, where Android specific APIs are used. | 
|  | task buildExampleAndroidApi(type: JavaCompile) { | 
|  | source = fileTree(dir: file("src/test/examplesAndroidApi"), include: "**/*.java") | 
|  | destinationDir = file("build/test/examplesAndroidApi/classes") | 
|  | classpath = files("third_party/android_jar/lib-v26/android.jar") | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | } | 
|  |  | 
|  | task buildProtoGeneratedSources { | 
|  | def examplesProtoDir = file("src/test/examplesProto") | 
|  | examplesProtoDir.eachDir { dir -> | 
|  | def name = dir.getName() | 
|  | task "compile_proto_generated_source_${name}"(type: JavaCompile) { | 
|  | source = { | 
|  | file('third_party/proto').listFiles() | 
|  | .findAll { it.name.startsWith(name) && it.name.endsWith('-src.jar') } | 
|  | .collect { zipTree(it) } | 
|  | } | 
|  | destinationDir = file("build/generated/test/proto/${name}_classes") | 
|  | classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar") | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | } | 
|  | task "jar_proto_generated_source_${name}"(type: Jar, dependsOn: "compile_proto_generated_source_${name}") { | 
|  | archiveName = "${name}.jar" | 
|  | destinationDir = file("build/generated/test/proto") | 
|  | from "build/generated/test/proto/${name}_classes" | 
|  | include "/**/*.class" | 
|  | } | 
|  | dependsOn "jar_proto_generated_source_${name}" | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildExamplesProto { | 
|  | def examplesProtoDir = file("src/test/examplesProto") | 
|  | def examplesProtoOutputDir = file("build/test/examplesProto"); | 
|  | dependsOn buildProtoGeneratedSources | 
|  | task "compile_examples_proto"(type: JavaCompile) { | 
|  | source = fileTree(dir: examplesProtoDir, include: "**/*.java") | 
|  | destinationDir = file("build/test/examplesProto/classes") | 
|  | classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar") | 
|  | classpath += fileTree(dir: "build/generated/test/proto", include: "*.jar") | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | } | 
|  | examplesProtoDir.eachDir { dir -> | 
|  | def name = dir.getName() | 
|  | task "jar_examples_proto_${name}"(type: Jar, dependsOn: "compile_examples_proto") { | 
|  | archiveName = "${name}.jar" | 
|  | destinationDir = examplesProtoOutputDir | 
|  | from "build/test/examplesProto/classes" | 
|  | include name + "/**/*.class" | 
|  | } | 
|  | dependsOn "jar_examples_proto_${name}" | 
|  | } | 
|  | } | 
|  |  | 
|  | // Proto lite generated code yields warnings when compiling with javac. | 
|  | // We change the options passed to javac to ignore it. | 
|  | compileExamplesJava.options.compilerArgs = ["-Xlint:none"] | 
|  |  | 
|  |  | 
|  | task buildExampleJars { | 
|  | dependsOn downloadProguard | 
|  | def examplesDir = file("src/test/examples") | 
|  | def proguardScript | 
|  | if (OperatingSystem.current().isWindows()) { | 
|  | proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.bat" | 
|  | } else { | 
|  | proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.sh" | 
|  | } | 
|  | task extractExamplesRuntime(type: Sync) { | 
|  | dependsOn configurations.examplesRuntime | 
|  | from { configurations.examplesRuntime.collect { zipTree(it) } } | 
|  | include "**/*.class" | 
|  | includeEmptyDirs false | 
|  | into "$buildDir/runtime/examples/" | 
|  | } | 
|  |  | 
|  | task "copy_examples_resources"(type: org.gradle.api.tasks.Copy) { | 
|  | from examplesDir | 
|  | exclude "**/*.java" | 
|  | exclude "**/keep-rules*.txt" | 
|  | into file("build/test/examples/classes") | 
|  | } | 
|  |  | 
|  | task "compile_examples"(type: JavaCompile) { | 
|  | dependsOn "copy_examples_resources" | 
|  | source examplesDir | 
|  | include "**/*.java" | 
|  | destinationDir = file("build/test/examples/classes") | 
|  | classpath = sourceSets.examples.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_7 | 
|  | targetCompatibility = JavaVersion.VERSION_1_7 | 
|  | options.compilerArgs = ["-g:source,lines", "-Xlint:none"] | 
|  | } | 
|  | task "compile_examples_debuginfo_all"(type: JavaCompile) { | 
|  | source examplesDir | 
|  | include "**/*.java" | 
|  | destinationDir = file("build/test/examples/classes_debuginfo_all") | 
|  | classpath = sourceSets.examples.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_7 | 
|  | targetCompatibility = JavaVersion.VERSION_1_7 | 
|  | options.compilerArgs = ["-g", "-Xlint:none"] | 
|  | } | 
|  | task "compile_examples_debuginfo_none"(type: JavaCompile) { | 
|  | source examplesDir | 
|  | include "**/*.java" | 
|  | destinationDir = file("build/test/examples/classes_debuginfo_none") | 
|  | classpath = sourceSets.examples.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_7 | 
|  | targetCompatibility = JavaVersion.VERSION_1_7 | 
|  | options.compilerArgs = ["-g:none", "-Xlint:none"] | 
|  | } | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def exampleOutputDir = file("build/test/examples"); | 
|  | def jarName = "${name}.jar" | 
|  | dependsOn "jar_example_${name}" | 
|  | dependsOn "jar_example_${name}_debuginfo_all" | 
|  | dependsOn "jar_example_${name}_debuginfo_none" | 
|  | dependsOn "extractExamplesRuntime" | 
|  | def runtimeDependencies = copySpec { } | 
|  | // The "throwing" test verifies debugging/stack info on the post-proguarded output. | 
|  | def proguardConfigPath = "${dir}/proguard.cfg" | 
|  | if (new File(proguardConfigPath).exists()) { | 
|  | task "pre_proguard_example_${name}"(type: Jar, dependsOn: "compile_examples") { | 
|  | archiveName = "${name}_pre_proguard.jar" | 
|  | destinationDir = exampleOutputDir | 
|  | from "build/test/examples/classes" | 
|  | include name + "/**/*.class" | 
|  | with runtimeDependencies | 
|  | includeEmptyDirs false | 
|  | } | 
|  | def jarPath = files(tasks.getByPath("pre_proguard_example_${name}")).files.first(); | 
|  | def proguardJarPath = "${exampleOutputDir}/${jarName}" | 
|  | def proguardMapPath = "${exampleOutputDir}/${name}/${name}.map" | 
|  | task "jar_example_${name}"(type: Exec, dependsOn: "pre_proguard_example_${name}") { | 
|  | inputs.files files( | 
|  | tasks.getByPath("pre_proguard_example_${name}"), | 
|  | proguardConfigPath) | 
|  | // Enable these to get stdout and stderr redirected to files... | 
|  | // standardOutput = new FileOutputStream('proguard.stdout') | 
|  | // errorOutput = new FileOutputStream('proguard.stderr') | 
|  | def proguardArguments = "-verbose -dontwarn java.** -injars ${jarPath}" + | 
|  | " -outjars ${proguardJarPath}" + | 
|  | " -include ${proguardConfigPath}" + | 
|  | " -printmapping ${proguardMapPath}" | 
|  | if (OperatingSystem.current().isWindows()) { | 
|  | executable "${proguardScript}" | 
|  | args "${proguardArguments}" | 
|  | } else { | 
|  | executable "bash" | 
|  | args "-c", "${proguardScript} '${proguardArguments}'" | 
|  | } | 
|  | outputs.file proguardJarPath | 
|  | } | 
|  | // TODO: Consider performing distinct proguard compilations. | 
|  | task "jar_example_${name}_debuginfo_all"(type: Copy, dependsOn: "jar_example_${name}") { | 
|  | from "${exampleOutputDir}/${name}.jar" | 
|  | into "${exampleOutputDir}" | 
|  | rename(".*", "${name}_debuginfo_all.jar") | 
|  | } | 
|  | task "jar_example_${name}_debuginfo_none"(type: Copy, dependsOn: "jar_example_${name}") { | 
|  | from "${exampleOutputDir}/${name}.jar" | 
|  | into "${exampleOutputDir}" | 
|  | rename(".*", "${name}_debuginfo_none.jar") | 
|  | } | 
|  | } else { | 
|  | task "jar_example_${name}"(type: Jar, dependsOn: "compile_examples") { | 
|  | archiveName = "${name}.jar" | 
|  | destinationDir = exampleOutputDir | 
|  | from "build/test/examples/classes" | 
|  | include name + "/**/*" | 
|  | with runtimeDependencies | 
|  | includeEmptyDirs true | 
|  | } | 
|  | task "jar_example_${name}_debuginfo_all"(type: Jar, dependsOn: "compile_examples_debuginfo_all") { | 
|  | archiveName = "${name}_debuginfo_all.jar" | 
|  | destinationDir = exampleOutputDir | 
|  | from "build/test/examples/classes_debuginfo_all" | 
|  | include name + "/**/*.class" | 
|  | with runtimeDependencies | 
|  | includeEmptyDirs false | 
|  | } | 
|  | task "jar_example_${name}_debuginfo_none"(type: Jar, dependsOn: "compile_examples_debuginfo_none") { | 
|  | archiveName = "${name}_debuginfo_none.jar" | 
|  | destinationDir = exampleOutputDir | 
|  | from "build/test/examples/classes_debuginfo_none" | 
|  | include name + "/**/*.class" | 
|  | with runtimeDependencies | 
|  | includeEmptyDirs false | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildExampleAndroidNJars { | 
|  | dependsOn downloadDeps | 
|  | def examplesDir = file("src/test/examplesAndroidN") | 
|  | task "compile_examplesAndroidN"(type: JavaCompile) { | 
|  | source = fileTree(dir: examplesDir, include: '**/*.java') | 
|  | destinationDir = file("build/test/examplesAndroidN/classes") | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | options.compilerArgs += ["-Xlint:-options"] | 
|  | } | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def exampleOutputDir = file("build/test/examplesAndroidN"); | 
|  | def jarName = "${name}.jar" | 
|  | dependsOn "jar_examplesAndroidN_${name}" | 
|  | task "jar_examplesAndroidN_${name}"(type: Jar, dependsOn: "compile_examplesAndroidN") { | 
|  | archiveName = jarName | 
|  | destinationDir = exampleOutputDir | 
|  | from "build/test/examplesAndroidN/classes" | 
|  | include "**/" + name + "/**/*.class" | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | task buildExampleAndroidOJars { | 
|  | dependsOn downloadDeps | 
|  | def examplesDir = file("src/test/examplesAndroidO") | 
|  | // NOTE: we want to enable a scenario when test needs to reference some | 
|  | // classes generated by legacy (1.6) Java compiler to test some specific | 
|  | // behaviour. To do so we compile all the java files located in sub-directory | 
|  | // called 'legacy' with Java 1.6, then compile the rest of the files with | 
|  | // Java 1.8 and a reference to previously generated 1.6 classes. | 
|  |  | 
|  | // Compiling all classes in dirs 'legacy' with old Java version. | 
|  | task "compile_examplesAndroidO_Legacy"(type: JavaCompile) { | 
|  | source = fileTree(dir: examplesDir, include: '**/legacy/**/*.java') | 
|  | destinationDir = file("build/test/examplesAndroidOLegacy/classes") | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_6 | 
|  | targetCompatibility = JavaVersion.VERSION_1_6 | 
|  | options.compilerArgs += ["-Xlint:-options", "-parameters"] | 
|  | } | 
|  | // Compiling the rest of the files as Java 1.8 code. | 
|  | task "compile_examplesAndroidO"(type: JavaCompile) { | 
|  | dependsOn "compile_examplesAndroidO_Legacy" | 
|  | source = fileTree(dir: examplesDir, include: '**/*.java', exclude: '**/legacy/**/*.java') | 
|  | destinationDir = file("build/test/examplesAndroidO/classes") | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | classpath += files("build/test/examplesAndroidOLegacy/classes") | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | options.compilerArgs += ["-Xlint:-options", "-parameters"] | 
|  | } | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def destinationDir = file("build/test/examplesAndroidO/classes"); | 
|  | if (file("src/test/examplesAndroidO/" + name + "/TestGenerator.java").isFile()) { | 
|  | task "generate_examplesAndroidO_${name}"(type: JavaExec, | 
|  | dependsOn: "compile_examplesAndroidO") { | 
|  | main = name + ".TestGenerator" | 
|  | classpath = files(destinationDir, sourceSets.main.compileClasspath) | 
|  | args destinationDir | 
|  | } | 
|  | } else { | 
|  | task "generate_examplesAndroidO_${name}" () {} | 
|  | } | 
|  | } | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def exampleOutputDir = file("build/test/examplesAndroidO"); | 
|  | def jarName = "${name}.jar" | 
|  | dependsOn "jar_examplesAndroidO_${name}" | 
|  | task "jar_examplesAndroidO_${name}"(type: Jar, dependsOn: ["compile_examplesAndroidO", | 
|  | "generate_examplesAndroidO_${name}"]) { | 
|  | archiveName = jarName | 
|  | destinationDir = exampleOutputDir | 
|  | from "build/test/examplesAndroidO/classes"        // Java 1.8 classes | 
|  | from "build/test/examplesAndroidOLegacy/classes"  // Java 1.6 classes | 
|  | include "**/" + name + "/**/*.class" | 
|  | // Do not include generator into the test runtime jar, it is not useful. | 
|  | // Otherwise, shrinking will need ASM jars. | 
|  | exclude "**/TestGenerator*" | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildExampleAndroidPJars { | 
|  | dependsOn downloadDeps | 
|  | def examplesDir = file("src/test/examplesAndroidP") | 
|  |  | 
|  | task "compile_examplesAndroidP"(type: JavaCompile) { | 
|  | source = fileTree(dir: examplesDir, include: '**/*.java') | 
|  | destinationDir = file("build/test/examplesAndroidP/classes") | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_8 | 
|  | targetCompatibility = JavaVersion.VERSION_1_8 | 
|  | options.compilerArgs += ["-Xlint:-options"] | 
|  | } | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def destinationDir = file("build/test/examplesAndroidP/classes"); | 
|  | if (file("src/test/examplesAndroidP/" + name + "/TestGenerator.java").isFile()) { | 
|  | task "generate_examplesAndroidP_${name}"(type: JavaExec, | 
|  | dependsOn: "compile_examplesAndroidP") { | 
|  | main = name + ".TestGenerator" | 
|  | classpath = files(destinationDir, sourceSets.main.compileClasspath) | 
|  | args destinationDir | 
|  | } | 
|  | } else { | 
|  | task "generate_examplesAndroidP_${name}" () {} | 
|  | } | 
|  | } | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def exampleOutputDir = file("build/test/examplesAndroidP"); | 
|  | def jarName = "${name}.jar" | 
|  | dependsOn "jar_examplesAndroidP_${name}" | 
|  | task "jar_examplesAndroidP_${name}"(type: Jar, | 
|  | dependsOn: ["compile_examplesAndroidP", | 
|  | "generate_examplesAndroidP_${name}"]) { | 
|  | archiveName = jarName | 
|  | destinationDir = exampleOutputDir | 
|  | from "build/test/examplesAndroidP/classes"  // Java 1.8 classes | 
|  | include "**/" + name + "/**/*.class" | 
|  | // Do not include generator into the test runtime jar, it is not useful. | 
|  | // Otherwise, shrinking will need ASM jars. | 
|  | exclude "**/TestGenerator*" | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | def buildExampleJarsCreateTask(javaVersion, sourceSet) { | 
|  | return tasks.create("buildExample${javaVersion}Jars") { | 
|  | def examplesDir = file("src/test/examples${javaVersion}") | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def exampleOutputDir = file("build/test/examples${javaVersion}"); | 
|  | def jarName = "${name}.jar" | 
|  | dependsOn "jar_examples${javaVersion}_${name}" | 
|  | task "jar_examples${javaVersion}_${name}"(type: Jar) { | 
|  | archiveName = jarName | 
|  | destinationDir = exampleOutputDir | 
|  | from sourceSet.output | 
|  | include "**/" + name + "/**/*.class" | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | buildExampleJarsCreateTask("Java9", sourceSets.examplesJava9) | 
|  | buildExampleJarsCreateTask("Java10", sourceSets.examplesJava10) | 
|  | buildExampleJarsCreateTask("Java11", sourceSets.examplesJava11) | 
|  | buildExampleJarsCreateTask("Java15", sourceSets.examplesJava15) | 
|  |  | 
|  | task provideArtFrameworksDependencies { | 
|  | cloudDependencies.tools.forEach({ art -> | 
|  | if (art.contains("art")) { | 
|  | def taskName = art.replace('/','_') | 
|  | dependsOn "patch_${taskName}" | 
|  | task "patch_${taskName}"(type: org.gradle.api.tasks.Copy){ | 
|  | from "tools/${art}/framework" | 
|  | include "**.jar" | 
|  | into file("tools/${art}/out/host/linux-x86/framework") | 
|  | } | 
|  | } | 
|  | }) | 
|  | } | 
|  |  | 
|  | task provideJdk11TestsDependencies(type: org.gradle.api.tasks.Copy) { | 
|  | from sourceSets.jdk11TimeTests.compileClasspath | 
|  | include "**/**.jar" | 
|  | into file("build/test/jdk11Tests") | 
|  | } | 
|  |  | 
|  | task buildJdk11TimeTestsJar { | 
|  | def exampleOutputDir = file("build/test/jdk11Tests"); | 
|  | def jarName = "jdk11TimeTests.jar" | 
|  | dependsOn "jar_jdk11TimeTests" | 
|  | dependsOn provideJdk11TestsDependencies | 
|  | task "jar_jdk11TimeTests"(type: Jar) { | 
|  | archiveName = jarName | 
|  | destinationDir = exampleOutputDir | 
|  | from sourceSets.examplesTestNGRunner.output | 
|  | include "**.class" | 
|  | from sourceSets.jdk11TimeTests.output | 
|  | include "**.class" | 
|  | include "**/**.class" | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildKotlinR8TestResources { | 
|  | def examplesDir = file("src/test/kotlinR8TestResources") | 
|  | examplesDir.eachDir { dir -> | 
|  | kotlin.Kotlinc.KotlinTargetVersion.values().each { kotlinTargetVersion -> | 
|  | def name = dir.getName() | 
|  | def taskName = "jar_kotlinR8TestResources_${name}_${kotlinTargetVersion}" | 
|  | def javaOutput = "build/test/kotlinR8TestResources/${kotlinTargetVersion}/${name}/java" | 
|  | def javaOutputJarName = "${name}.java.jar" | 
|  | def javaOutputJarDir = "build/test/kotlinR8TestResources/${kotlinTargetVersion}" | 
|  | task "${taskName}Java"(type: JavaCompile) { | 
|  | source = fileTree(dir: file("${examplesDir}/${name}"), include: '**/*.java') | 
|  | destinationDir = file(javaOutput) | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_6 | 
|  | targetCompatibility = JavaVersion.VERSION_1_6 | 
|  | options.compilerArgs += ["-g", "-Xlint:-options"] | 
|  | } | 
|  | task "${taskName}JavaJar"(type: Jar, dependsOn: "${taskName}Java") { | 
|  | archiveName = javaOutputJarName | 
|  | destinationDir = file(javaOutputJarDir) | 
|  | from javaOutput | 
|  | include "**/*.class" | 
|  | } | 
|  | dependsOn "${taskName}JavaJar" | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildExamples { | 
|  | if (OperatingSystem.current().isMacOsX() || OperatingSystem.current().isWindows()) { | 
|  | logger.lifecycle("WARNING: Testing (including building examples) is only partially supported on your " + | 
|  | "platform (" + OperatingSystem.current().getName() + ").") | 
|  | } else if (!OperatingSystem.current().isLinux()) { | 
|  | logger.lifecycle("WARNING: Testing (including building examples) is not supported on your platform. " + | 
|  | "It is fully supported on Linux and partially supported on Mac OS and Windows") | 
|  | return; | 
|  | } | 
|  | dependsOn buildDebugTestResourcesJars | 
|  | dependsOn buildExampleJars | 
|  | dependsOn buildExampleAndroidNJars | 
|  | dependsOn buildExampleAndroidOJars | 
|  | dependsOn buildExampleAndroidPJars | 
|  | dependsOn buildExampleJava9Jars | 
|  | dependsOn buildExampleJava10Jars | 
|  | dependsOn buildExampleJava11Jars | 
|  | dependsOn buildExampleJava15Jars | 
|  | dependsOn buildExampleAndroidApi | 
|  | def examplesDir = file("src/test/examples") | 
|  | def noDexTests = [ | 
|  | "multidex", | 
|  | "multidex002", | 
|  | "multidex004", | 
|  | ] | 
|  | examplesDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | if (!(name in noDexTests)) { | 
|  | dependsOn "dex_example_${name}" | 
|  | def exampleOutputDir = file("build/test/examples/" + name); | 
|  | def dexPath = file("${exampleOutputDir}") | 
|  | def debug = (name == "throwing") | 
|  | if (!dexPath.exists()) { | 
|  | dexPath.mkdirs() | 
|  | } | 
|  | task "dex_example_${name}"(type: DxTask, dependsOn: "jar_example_${name}") { | 
|  | source = files(tasks.getByPath("jar_example_${name}")).asFileTree | 
|  | destination = dexPath | 
|  | debug = debug | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildSmali { | 
|  | def smaliDir = file("src/test/smali") | 
|  | smaliDir.eachDirRecurse() { dir -> | 
|  | def name = dir.getName(); | 
|  | def relativeDir = smaliDir.toPath().relativize(dir.toPath()); | 
|  | def smaliOutputDir = file("build/test/smali/" + relativeDir); | 
|  | smaliOutputDir.mkdirs() | 
|  | outputs.dir smaliOutputDir | 
|  | def taskName = "smali_build_${relativeDir.toString().replace('/', '_').replace('\\', '_')}" | 
|  | def smaliFiles = fileTree(dir: dir, include: '*.smali') | 
|  | def javaFiles = fileTree(dir: dir, include: '*.java') | 
|  | def destDir = smaliOutputDir; | 
|  | def destFile = destDir.toPath().resolve("${name}.dex").toFile() | 
|  | def intermediateFileName = "${name}-intermediate.dex"; | 
|  | def intermediateFile = destDir.toPath().resolve(intermediateFileName).toFile() | 
|  | if (javaFiles.empty) { | 
|  | if (!smaliFiles.empty) { | 
|  | dependsOn "${taskName}_smali" | 
|  | task "${taskName}_smali"(type: SmaliTask) { | 
|  | source = smaliFiles | 
|  | destination = destFile | 
|  | } | 
|  | } | 
|  | } else { | 
|  | dependsOn "${taskName}_dexmerger" | 
|  | task "${taskName}_smali"(type: SmaliTask) { | 
|  | source = smaliFiles | 
|  | destination = intermediateFile | 
|  | } | 
|  | task "${taskName}_java"(type: JavaCompile) { | 
|  | source = javaFiles | 
|  | destinationDir destDir | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | sourceCompatibility = JavaVersion.VERSION_1_7 | 
|  | targetCompatibility = JavaVersion.VERSION_1_7 | 
|  | options.compilerArgs += ["-Xlint:-options"] | 
|  | } | 
|  | task "${taskName}_jar"(type: Jar, dependsOn: "${taskName}_java") { | 
|  | archiveName = "Test.jar" | 
|  | destinationDir = destDir | 
|  | from fileTree(dir: destDir, include: 'Test.class') | 
|  | } | 
|  | task "${taskName}_dx"(type: DxTask, dependsOn: "${taskName}_jar") { | 
|  | source = fileTree(dir: destDir, include: 'Test.jar') | 
|  | destination = destDir | 
|  | } | 
|  | task "${taskName}_dexmerger"( | 
|  | type: DexMergerTask, dependsOn: ["${taskName}_dx", "${taskName}_smali"]) { | 
|  | source = fileTree(dir: destDir, include: ["classes.dex", intermediateFileName]) | 
|  | destination = destFile | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | tasks.withType(Test) { | 
|  | println("NOTE: Number of processors " + Runtime.runtime.availableProcessors()) | 
|  | def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK') | 
|  | def processors = Runtime.runtime.availableProcessors() | 
|  | // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html. | 
|  | if (userDefinedCoresPerFork) { | 
|  | maxParallelForks = processors.intdiv(userDefinedCoresPerFork.toInteger()) ?: 1 | 
|  | } else { | 
|  | // On normal work machines this seems to give the best test execution time (without freezing) | 
|  | maxParallelForks = processors.intdiv(3) ?: 1 | 
|  | } | 
|  | println("NOTE: Max parallel forks " + maxParallelForks) | 
|  |  | 
|  | forkEvery = 0 | 
|  | if (project.hasProperty('disable_assertions')) { | 
|  | enableAssertions = false | 
|  | } | 
|  | // TODO(b/124091860): Increase the max heap size to avoid OOM when running tests. | 
|  | if (project.hasProperty('test_xmx')) { | 
|  | maxHeapSize = project.property('test_xmx') | 
|  | } else { | 
|  | maxHeapSize = "4G" | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildPreNJdwpTestsJar(type: Jar) { | 
|  | baseName = 'jdwp-tests-preN' | 
|  | from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar') | 
|  | // Exclude the classes containing java8 | 
|  | exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class' | 
|  | exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class' | 
|  | includeEmptyDirs = false | 
|  | } | 
|  |  | 
|  | task buildPreNJdwpTestsDex(type: Exec, dependsOn: "buildPreNJdwpTestsJar") { | 
|  | def inFile = buildPreNJdwpTestsJar.archivePath | 
|  | def outFile = new File(buildPreNJdwpTestsJar.destinationDir, buildPreNJdwpTestsJar.baseName + '-dex.jar') | 
|  | inputs.files files(inFile) | 
|  | outputs.file outFile | 
|  | if (OperatingSystem.current().isWindows()) { | 
|  | executable file("tools/windows/dx/bin/dx.bat") | 
|  | } else if (OperatingSystem.current().isMacOsX()) { | 
|  | executable file("tools/mac/dx/bin/dx"); | 
|  | } else { | 
|  | executable file("tools/linux/dx/bin/dx"); | 
|  | } | 
|  | args "--dex" | 
|  | args "--output=${outFile}" | 
|  | args inFile | 
|  | } | 
|  |  | 
|  | task getJarsFromSupportLibs(type: GetJarsFromConfiguration) { | 
|  | setConfiguration(configurations.supportLibs) | 
|  | } | 
|  |  | 
|  | task generateR8TestKeepRules { | 
|  | def path = "build/generated/r8tests-keep.txt" | 
|  | outputs.file path | 
|  | dependsOn R8Lib | 
|  | doLast { | 
|  | file(path).write """-keep class ** { *; } | 
|  | -dontshrink | 
|  | -dontoptimize | 
|  | -keepattributes * | 
|  | -applymapping ${R8Lib.outputs.files[0]}.map | 
|  | """ | 
|  | } | 
|  | } | 
|  |  | 
|  | task buildR8LibCfTestDeps(type: Exec) { | 
|  | def outputPath = "build/libs/r8libtestdeps-cf.jar" | 
|  | dependsOn downloadDeps | 
|  | dependsOn r8NoManifest | 
|  | dependsOn R8Lib | 
|  | dependsOn generateR8TestKeepRules | 
|  | dependsOn testJar | 
|  | // Take all .jar files as libraries and append the generated test classes in classes/java/test. | 
|  | def addedLibraries = sourceSets.test.runtimeClasspath.findAll { pkg -> | 
|  | return pkg.toString().endsWith(".jar") | 
|  | } + ["${buildDir}/classes/java/test"] | 
|  | inputs.files testJar.outputs.files + | 
|  | generateR8TestKeepRules.outputs.files + | 
|  | R8Lib.outputs | 
|  | commandLine = r8CfCommandLine( | 
|  | testJar.outputs.files[0], | 
|  | outputPath, | 
|  | [generateR8TestKeepRules.outputs.files[0]], | 
|  | ["--debug", "--classpath", r8NoManifest.outputs.files[0]], | 
|  | r8NoManifest.outputs.files + addedLibraries) | 
|  | workingDir = projectDir | 
|  | outputs.file outputPath | 
|  | } | 
|  |  | 
|  | task configureTestForR8Lib(type: Copy) { | 
|  | dependsOn testJar | 
|  | inputs.files buildR8LibCfTestDeps.outputs | 
|  | dependsOn R8Lib | 
|  | delete r8LibTestPath | 
|  | from zipTree(buildR8LibCfTestDeps.outputs.files[0]) | 
|  | def examplesDir = file("build/test") | 
|  | examplesDir.eachDir { dir -> | 
|  | from ("${buildDir}/test/${dir.getName()}/classes") | 
|  | } | 
|  | from ("${buildDir}/runtime/examples") | 
|  | into r8LibTestPath | 
|  | outputs.dir r8LibTestPath | 
|  | } | 
|  |  | 
|  | def printStackTrace(TestResult result) { | 
|  | filterStackTraces(result) | 
|  | if (project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')) { | 
|  | def out = new StringBuffer() | 
|  | def err = new StringBuffer() | 
|  | def command = "python tools/retrace.py --quiet" | 
|  | def header = "RETRACED STACKTRACE"; | 
|  | if (System.getenv('BUILDBOT_BUILDERNAME') != null | 
|  | && !System.getenv('BUILDBOT_BUILDERNAME').endsWith("_release")) { | 
|  | header += ": (${command} --commit_hash ${System.getenv('BUILDBOT_REVISION')})"; | 
|  | } | 
|  | out.append("\n--------------------------------------\n") | 
|  | out.append("${header}\n") | 
|  | out.append("--------------------------------------\n") | 
|  | Process process = command.execute() | 
|  | def processIn = new PrintStream(process.getOut()) | 
|  | process.consumeProcessOutput(out, err) | 
|  | result.exception.printStackTrace(processIn) | 
|  | processIn.flush() | 
|  | processIn.close() | 
|  | def errorDuringRetracing = process.waitFor() != 0 | 
|  | if (errorDuringRetracing) { | 
|  | out.append("ERROR DURING RETRACING\n") | 
|  | out.append(err.toString()) | 
|  | } | 
|  | if (project.hasProperty('print_obfuscated_stacktraces') || errorDuringRetracing) { | 
|  | out.append("\n\n--------------------------------------\n") | 
|  | out.append("OBFUSCATED STACKTRACE\n") | 
|  | out.append("--------------------------------------\n") | 
|  | } else { | 
|  | result.exceptions.clear() | 
|  | } | 
|  | def exception = new Exception(out.toString()) | 
|  | exception.setStackTrace([] as StackTraceElement[]) | 
|  | result.exceptions.add(0, exception) | 
|  | } else { | 
|  | result.exception.printStackTrace() | 
|  | } | 
|  | } | 
|  |  | 
|  | def filterStackTraces(TestResult result) { | 
|  | for (Throwable throwable : result.getExceptions()) { | 
|  | filterStackTrace(throwable) | 
|  | } | 
|  | } | 
|  |  | 
|  | def filterStackTrace(Throwable exception) { | 
|  | if (!project.hasProperty('print_full_stacktraces')) { | 
|  | def elements = [] | 
|  | def skipped = [] | 
|  | for (StackTraceElement element : exception.getStackTrace()) { | 
|  | if (element.toString().contains("com.android.tools.r8")) { | 
|  | elements.addAll(skipped) | 
|  | elements.add(element) | 
|  | skipped.clear() | 
|  | } else { | 
|  | skipped.add(element) | 
|  | } | 
|  | } | 
|  | exception.setStackTrace(elements as StackTraceElement[]) | 
|  | } | 
|  | } | 
|  |  | 
|  | test { | 
|  | if (project.hasProperty('generate_golden_files_to')) { | 
|  | systemProperty 'generate_golden_files_to', project.property('generate_golden_files_to') | 
|  | assert project.hasProperty('HEAD_sha1') | 
|  | systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1') | 
|  | } | 
|  |  | 
|  | if (project.hasProperty('use_golden_files_in')) { | 
|  | systemProperty 'use_golden_files_in', project.property('use_golden_files_in') | 
|  | assert project.hasProperty('HEAD_sha1') | 
|  | systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1') | 
|  | } | 
|  |  | 
|  | dependsOn buildLibraryDesugarConversions | 
|  | dependsOn getJarsFromSupportLibs | 
|  | // R8.jar is required for running bootstrap tests. | 
|  | dependsOn r8 | 
|  | testLogging.exceptionFormat = 'full' | 
|  | if (project.hasProperty('print_test_stdout')) { | 
|  | testLogging.showStandardStreams = true | 
|  | } | 
|  | if (project.hasProperty('dex_vm') && project.property('dex_vm') != 'default') { | 
|  | println "NOTE: Running with non default vm: " + project.property('dex_vm') | 
|  | systemProperty 'dex_vm', project.property('dex_vm') | 
|  | } | 
|  |  | 
|  | // Forward runtime configurations for test parameters. | 
|  | if (project.hasProperty('runtimes')) { | 
|  | println "NOTE: Running with runtimes: " + project.property('runtimes') | 
|  | systemProperty 'runtimes', project.property('runtimes') | 
|  | } | 
|  |  | 
|  | if (project.hasProperty('slow_tests')) { | 
|  | systemProperty 'slow_tests', project.property('slow_tests') | 
|  | } | 
|  |  | 
|  | if (project.hasProperty('desugar_jdk_libs')) { | 
|  | systemProperty 'desugar_jdk_libs', project.property('desugar_jdk_libs') | 
|  | } | 
|  |  | 
|  | if (project.hasProperty('one_line_per_test')) { | 
|  | beforeTest { desc -> | 
|  | println "Start executing test ${desc.name} [${desc.className}]" | 
|  | } | 
|  | afterTest { desc, result -> | 
|  | if (result.resultType == TestResult.ResultType.FAILURE) { | 
|  | printStackTrace(result) | 
|  | } | 
|  | if (project.hasProperty('update_test_timestamp')) { | 
|  | file(project.getProperty('update_test_timestamp')).text = new Date().getTime() | 
|  | } | 
|  | println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}" | 
|  | } | 
|  | } else { | 
|  | afterTest { desc, result -> | 
|  | if (result.resultType == TestResult.ResultType.FAILURE) { | 
|  | printStackTrace(result) | 
|  | } | 
|  | } | 
|  | } | 
|  | if (project.hasProperty('no_internal')) { | 
|  | exclude "com/android/tools/r8/internal/**" | 
|  | } else { | 
|  | dependsOn buildExamplesProto | 
|  | } | 
|  | if (project.hasProperty('only_internal')) { | 
|  | include "com/android/tools/r8/internal/**" | 
|  | } | 
|  |  | 
|  | if (project.hasProperty('test_namespace')) { | 
|  | include "com/android/tools/r8/" + project.getProperty('test_namespace') + "/**" | 
|  | } | 
|  |  | 
|  | if (project.hasProperty('tool')) { | 
|  | if (project.property('tool') == 'r8') { | 
|  | exclude "com/android/tools/r8/jctf/**" | 
|  | } else if (project.property('tool') == 'd8') { | 
|  | if (project.hasProperty('only_jctf')) { | 
|  | include "com/android/tools/r8/jctf/d8/**" | 
|  | } else { | 
|  | // Don't run anything, deprecated | 
|  | println "Running with deprecated tool d8, not running any tests" | 
|  | include "" | 
|  | } | 
|  | } else { | 
|  | assert(project.property('tool') == 'r8cf') | 
|  | assert(project.hasProperty('only_jctf')) | 
|  | include "com/android/tools/r8/jctf/r8cf/**" | 
|  | } | 
|  | } | 
|  | if (!project.hasProperty('all_tests')) { | 
|  | exclude "com/android/tools/r8/art/dx/**" | 
|  | } | 
|  | if (!project.hasProperty('jctf') && !project.hasProperty('only_jctf')) { | 
|  | exclude "com/android/tools/r8/jctf/**" | 
|  | } | 
|  | if (project.hasProperty('shard_count') ) { | 
|  | assert project.hasProperty('shard_number') | 
|  | int shard_count = project.getProperty('shard_count') as Integer | 
|  | int shard_number = project.getProperty('shard_number') as Integer | 
|  | assert shard_count < 65536 | 
|  | assert shard_number < shard_count | 
|  | exclude { | 
|  | entry -> | 
|  | // Don't leave out directories. Leaving out a directory means all entries below. | 
|  | if (entry.file.isDirectory()) { | 
|  | return false | 
|  | } | 
|  | def first4 = entry.getRelativePath().toString().md5().substring(0, 4) | 
|  | int hash = Integer.parseInt(first4, 16) | 
|  | return hash % shard_count != shard_number | 
|  | } | 
|  | } | 
|  | if (project.hasProperty('jctf_compile_only')) { | 
|  | println "JCTF: compiling only" | 
|  | systemProperty 'jctf_compile_only', '1' | 
|  | } | 
|  | if (project.hasProperty('test_dir')) { | 
|  | systemProperty 'test_dir', project.property('test_dir') | 
|  | } | 
|  | if (project.hasProperty('r8lib')) { | 
|  | dependsOn configureTestForR8Lib | 
|  | // R8lib should be used instead of the main output and all the tests in | 
|  | // r8 should be mapped and exists in r8LibTestPath. | 
|  | classpath = sourceSets.test.runtimeClasspath.filter { | 
|  | !it.getAbsolutePath().contains("/build/") | 
|  | } | 
|  | classpath += files([r8LibPath, r8LibTestPath]) | 
|  | testClassesDirs = files(r8LibTestPath) | 
|  | } | 
|  | if (OperatingSystem.current().isLinux() | 
|  | || OperatingSystem.current().isMacOsX() | 
|  | || OperatingSystem.current().isWindows()) { | 
|  | if (OperatingSystem.current().isMacOsX()) { | 
|  | logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " + | 
|  | "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " + | 
|  | "See tools/docker/README.md for details.") | 
|  | } | 
|  | if (OperatingSystem.current().isWindows()) { | 
|  | logger.lifecycle("WARNING: Testing in only partially supported on Windows. " + | 
|  | "Art only runs on Linux and tests requiring Art will be skipped") | 
|  | } | 
|  | dependsOn downloadDeps | 
|  | dependsOn buildExamples | 
|  | dependsOn buildKotlinR8TestResources | 
|  | dependsOn buildSmali | 
|  | dependsOn jctfCommonJar | 
|  | dependsOn jctfTestsClasses | 
|  | dependsOn buildDebugInfoExamplesDex | 
|  | dependsOn buildPreNJdwpTestsJar | 
|  | dependsOn buildPreNJdwpTestsDex | 
|  | dependsOn buildJdk11TimeTestsJar | 
|  | dependsOn provideArtFrameworksDependencies | 
|  | } else { | 
|  | logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " + | 
|  | "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.") | 
|  | } | 
|  | } | 
|  |  | 
|  | // The Art tests we use for R8 are pre-build and downloaded from Google Cloud Storage. | 
|  | // | 
|  | // To build and upload a new set of the Art tests for use with R8 follow these steps: | 
|  | // | 
|  | // First of all an Android checkout is required. Currently it must be located | 
|  | // in $HOME/android/master. | 
|  | // | 
|  | // TODO(ricow): simplify this | 
|  | // | 
|  | // Before: update the checked in art, see scripts/update-host-art.sh | 
|  | // | 
|  | // 1. Get an android checkout in $HOME/android/master and apply the patch from | 
|  | //    https://android-review.googlesource.com/#/c/294187/ | 
|  | // | 
|  | // 2. run the following commands in the Android checkout directory: | 
|  | // | 
|  | //    source build/envsetup.sh | 
|  | //    lunch aosp_angler-userdebug # or lunch aosp_angler-eng | 
|  | //    m desugar | 
|  | //    m -j30 test-art-host | 
|  | //    DESUGAR=false ANDROID_COMPILE_WITH_JACK=false art/test.py --host -t 001-HelloWorld | 
|  | // | 
|  | //    Without running the test.py command the classes.jar file used by desugar in | 
|  | //    $HOME/android/master/out/host/common/obj/JAVA_LIBRARIES/core-oj-hostdex_intermediates/ | 
|  | //    seems to be missing - there is probably also a make target to build it more directly | 
|  | // | 
|  | // 3. In the R8 project root directory, make sure we have a clean state before starting: | 
|  | //    tools/gradle.py downloadDeps | 
|  | //    tools/gradle.py clean | 
|  | //    rm -rf tests/art | 
|  | // | 
|  | // 4. Now build in the R8 checkout (-P hack to not generate dirs when not running this target) | 
|  | //    Make sure you have smali on your path, please use the build binary in the | 
|  | //    out/host/linux-x86/bin directory of the android checkout. Currently this is version pre 2.2.1, | 
|  | //    if that is updated the call to smali in "task "${smaliToDexTask}"(type: Exec)" below might | 
|  | //    need to change as smali got a completely new command line interface in version 2.2.1. | 
|  | //    After Android O, Jack is no longer alive, do not forget to uncomment call to buildArtTest for | 
|  | //    Jack if you build an android version using Jack. | 
|  | // | 
|  | //    PATH=$HOME/android/master/out/host/linux-x86/bin:$PATH tools/gradle.py -Pandroid_source buildArtTests | 
|  | // | 
|  | // 4a. If any failures are produced in step 4, figure out what went wrong and add an entry in | 
|  | //     skippedTests with an explanation. Rerun from step 3. | 
|  | // | 
|  | // 5. Run the tests: | 
|  | //    tools/gradle.py clean | 
|  | //    tools/test.py | 
|  | // | 
|  | // 5a. If any more tests fail, either fix the issue or add them to the failuresToTriage list (note | 
|  | //     that you need to change "_" to "-" from stdout). Rerun from step 5 if anything was added to | 
|  | //     failuresToTriage. | 
|  | // | 
|  | // 6. To upload a new version to Google Cloud Storage: | 
|  | //    cd tests | 
|  | //    upload_to_google_storage.py -a --bucket r8-deps art | 
|  | // | 
|  | // 7. Update the manifest file describing the Android repo used: | 
|  | //    repo manifest -o <r8-checkout-root>/tools/linux/aosp_master_manifest.xml -r | 
|  |  | 
|  | def androidCheckoutDir = file("${System.env.HOME}/android/master") | 
|  |  | 
|  | def artTestDir = file("${androidCheckoutDir}/art/test") | 
|  |  | 
|  | if (project.hasProperty('android_source')) { | 
|  | task buildArtTests { | 
|  | outputs.upToDateWhen { false } | 
|  | def toBeTriaged = [ | 
|  | "903-hello-tagging", | 
|  | "904-object-allocation", | 
|  | "905-object-free", | 
|  | "906-iterate-heap", | 
|  | "907-get-loaded-classes", | 
|  | "908-gc-start-finish", | 
|  | "954-invoke-polymorphic-verifier", | 
|  | "955-methodhandles-smali", | 
|  | "596-monitor-inflation", | 
|  | ] | 
|  | def skippedTests = toBeTriaged + [ | 
|  | // This test produces no jar. | 
|  | "000-nop", | 
|  | // This does not build, as it tests the error when the application exceeds more | 
|  | // than 65536 methods | 
|  | "089-many-methods", | 
|  | // Requires some jack beta jar | 
|  | "956-methodhandles", | 
|  | ] | 
|  |  | 
|  | def skippedTestsDx = [ | 
|  | // Tests with custom build scripts, where javac is not passed the options | 
|  | // -source 1.7 -target 1.7. | 
|  | "462-checker-inlining-across-dex-files", | 
|  | "556-invoke-super", | 
|  | "569-checker-pattern-replacement", | 
|  | // These tests use jack even when --build-with-javac-dx is specified. | 
|  | "004-JniTest", | 
|  | "048-reflect-v8", | 
|  | "146-bad-interface", | 
|  | "563-checker-invoke-super", | 
|  | "580-checker-string-fact-intrinsics",  // java.lang.StringFactory | 
|  | "604-hot-static-interface", | 
|  | "957-methodhandle-transforms", | 
|  | "958-methodhandle-emulated-stackframe", | 
|  | "959-invoke-polymorphic-accessors", | 
|  | "961-default-iface-resolution-gen", | 
|  | "962-iface-static", | 
|  | "963-default-range-smali", | 
|  | "964-default-iface-init-gen", | 
|  | "965-default-verify", | 
|  | "966-default-conflict", | 
|  | "967-default-ame", | 
|  | "968-default-partial-compile-gen", | 
|  | "969-iface-super", | 
|  | "970-iface-super-resolution-gen", | 
|  | "971-iface-super", | 
|  | // These tests does not build with --build-with-javac-dx | 
|  | "004-NativeAllocations", // Javac error | 
|  | "031-class-attributes", | 
|  | "138-duplicate-classes-check", | 
|  | "157-void-class", // Javac error | 
|  | "580-checker-string-factory-intrinsics", | 
|  | "612-jit-dex-cache", | 
|  | "613-inlining-dex-cache", | 
|  | "900-hello-plugin",  // --experimental agents | 
|  | "901-hello-ti-agent",  // --experimental agents | 
|  | "902-hello-transformation",  // --experimental agents | 
|  | "909-attach-agent",  // --experimental agents | 
|  | "946-obsolete-throw", // -source 1.7 -target 1.7, but use lambda | 
|  | "950-redefine-intrinsic", // -source 1.7 -target 1.7, but use method references | 
|  | "951-threaded-obsolete", // -source 1.7 -target 1.7, but use lambda | 
|  | "960-default-smali",  // --experimental default-methods | 
|  | // These tests force the build to use jack | 
|  | "953-invoke-polymorphic-compiler", | 
|  | "958-methodhandle-stackframe", | 
|  | ] | 
|  |  | 
|  | def artTestBuildDir = file("${projectDir}/tests/art") | 
|  |  | 
|  | if (androidCheckoutDir.exists()) { | 
|  | dependsOn downloadDeps | 
|  | artTestBuildDir.mkdirs() | 
|  | artTestDir.eachDir { dir -> | 
|  | def name = dir.getName(); | 
|  | def markerFile = dir.toPath().resolve("info.txt").toFile(); | 
|  | if (markerFile.exists() && !(name in skippedTests)) { | 
|  | if (!(name in skippedTestsDx)) { | 
|  | dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | doFirst { | 
|  | if (!androidCheckoutDir.exists()) { | 
|  | throw new InvalidUserDataException( | 
|  | "This task requires an Android checkout in ${androidCheckoutDir}"); | 
|  | } | 
|  | } | 
|  | doLast { | 
|  | copy { | 
|  | from file("${androidCheckoutDir}/out/host/linux-x86/nativetest64") | 
|  | into file("${artTestBuildDir}/lib64") | 
|  | include 'lib*.so' | 
|  | } | 
|  | copy { | 
|  | from file("${androidCheckoutDir}/out/host/linux-x86/lib64") | 
|  | into file("${artTestBuildDir}/lib64") | 
|  | include 'libart.so' | 
|  | include 'libbacktrace.so' | 
|  | include 'libbase.so' | 
|  | include 'libc++.so' | 
|  | include 'libcutils.so' | 
|  | include 'liblz4.so' | 
|  | include 'liblzma.so' | 
|  | include 'libnativebridge.so' | 
|  | include 'libnativeloader.so' | 
|  | include 'libsigchain.so' | 
|  | include 'libunwind.so' | 
|  | include 'libziparchive.so' | 
|  | } | 
|  | copy { | 
|  | from file("${androidCheckoutDir}/out/host/linux-x86/nativetest") | 
|  | into file("${artTestBuildDir}/lib") | 
|  | include 'lib*.so' | 
|  | } | 
|  | copy { | 
|  | from file("${androidCheckoutDir}/out/host/linux-x86/lib") | 
|  | into file("${artTestBuildDir}/lib") | 
|  | include 'libart.so' | 
|  | include 'libbacktrace.so' | 
|  | include 'libbase.so' | 
|  | include 'libc++.so' | 
|  | include 'libcutils.so' | 
|  | include 'liblz4.so' | 
|  | include 'liblzma.so' | 
|  | include 'libnativebridge.so' | 
|  | include 'libnativeloader.so' | 
|  | include 'libsigchain.so' | 
|  | include 'libunwind.so' | 
|  | include 'libziparchive.so' | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | def buildArtTest(androidCheckoutDir, artTestBuildDir, dir) { | 
|  | def artTestDir = file("${androidCheckoutDir}/art/test") | 
|  | def artRunTestScript = file("${artTestDir}/run-test") | 
|  | def dxExecutable = new File("tools/linux/dx/bin/dx"); | 
|  | def dexMergerExecutable = Utils.dexMergerExecutable() | 
|  |  | 
|  | def name = dir.getName() | 
|  | def buildTask = "build_art_test_dx_${name}" | 
|  | def sanitizeTask = "sanitize_art_test_dx_${name}" | 
|  | def copyCheckTask = "copy_check_art_test_dx_${name}" | 
|  | def smaliToDexTask = "smali_to_dex_dx_${name}" | 
|  |  | 
|  | def buildInputs = fileTree(dir: dir, include: '**/*') | 
|  | def testDir = file("${artTestBuildDir}/dx/${name}") | 
|  | def outputJar = testDir.toPath().resolve("${name}.jar").toFile() | 
|  | testDir.mkdirs() | 
|  | task "$buildTask"(type: Exec) { | 
|  | outputs.upToDateWhen { false } | 
|  | inputs.file buildInputs | 
|  | executable "${artRunTestScript}" | 
|  | args "--host" | 
|  | args "--build-only" | 
|  | args "--build-with-javac-dx" | 
|  | args "--output-path", "${testDir}" | 
|  | args "${name}" | 
|  | environment DX: "${dxExecutable.absolutePath}" | 
|  | environment DXMERGER: "${dexMergerExecutable.absolutePath}" | 
|  | environment ANDROID_BUILD_TOP: "${androidCheckoutDir}" | 
|  | outputs.file outputJar | 
|  | } | 
|  | task "${sanitizeTask}"(type: Exec, dependsOn: buildTask) { | 
|  | outputs.upToDateWhen { false } | 
|  | executable "/bin/bash" | 
|  | args "-c" | 
|  | args "rm -rf ${testDir}/smali_*.dex ${testDir}/*-ex.dex ${testDir}/*-ex.jar" + | 
|  | " ${testDir}/classes-ex ${testDir}/check" | 
|  | } | 
|  |  | 
|  | task "${smaliToDexTask}"(type: Exec) { | 
|  | // Directory that contains smali files is either smali, or smali/art | 
|  | def smali_dir = file("${dir}/smali/art") | 
|  | if (smali_dir.exists()) { | 
|  | workingDir "${testDir}/smali/art" | 
|  | } else  { | 
|  | workingDir "${testDir}/smali" | 
|  | } | 
|  | executable "/bin/bash" | 
|  | // This is the command line options for smali prior to 2.2.1, where smali got a new | 
|  | // command line interface. | 
|  | args "-c", "smali a *.smali" | 
|  | // This is the command line options for smali 2.2.1 and later. | 
|  | // args "-c", "smali -o out.dex *.smali" | 
|  | } | 
|  |  | 
|  | task "${copyCheckTask}"(type: Copy, dependsOn: sanitizeTask) { | 
|  | def smali_dir = file("${dir}/smali") | 
|  | outputs.upToDateWhen { false } | 
|  | if (smali_dir.exists()) { | 
|  | dependsOn smaliToDexTask | 
|  | } | 
|  | from("${artTestDir}/${name}") { | 
|  | include 'check' | 
|  | } | 
|  | into testDir | 
|  | } | 
|  |  | 
|  | return copyCheckTask | 
|  | } | 
|  |  | 
|  | task javadocD8(type: Javadoc) { | 
|  | title "D8 API" | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | source = sourceSets.main.allJava | 
|  | include '**/com/android/tools/r8/ArchiveClassFileProvider.java' | 
|  | include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java' | 
|  | include '**/com/android/tools/r8/BaseCommand.java' | 
|  | include '**/com/android/tools/r8/BaseCompilerCommand.java' | 
|  | include '**/com/android/tools/r8/ClassFileResourceProvider.java' | 
|  | include '**/com/android/tools/r8/CompilationFailedException.java' | 
|  | include '**/com/android/tools/r8/CompilationMode.java' | 
|  | include '**/com/android/tools/r8/D8.java' | 
|  | include '**/com/android/tools/r8/D8Command.java' | 
|  | include '**/com/android/tools/r8/DexIndexedConsumer.java' | 
|  | include '**/com/android/tools/r8/DexFilePerClassFileConsumer.java' | 
|  | include '**/com/android/tools/r8/Diagnostic.java' | 
|  | include '**/com/android/tools/r8/DiagnosticsHandler.java' | 
|  | include '**/com/android/tools/r8/DirectoryClassFileProvider.java' | 
|  | include '**/com/android/tools/r8/OutputMode.java' | 
|  | include '**/com/android/tools/r8/ProgramConsumer.java' | 
|  | include '**/com/android/tools/r8/ProgramResource.java' | 
|  | include '**/com/android/tools/r8/ProgramResourceProvider.java' | 
|  | include '**/com/android/tools/r8/Resource.java' | 
|  | include '**/com/android/tools/r8/ResourceException.java' | 
|  | include '**/com/android/tools/r8/StringConsumer.java' | 
|  | include '**/com/android/tools/r8/StringResource.java' | 
|  | include '**/com/android/tools/r8/Version.java' | 
|  | include '**/com/android/tools/r8/origin/*.java' | 
|  | } | 
|  |  | 
|  | task javadocR8(type: Javadoc) { | 
|  | title "R8 API" | 
|  | classpath = sourceSets.main.compileClasspath | 
|  | source = sourceSets.main.allJava | 
|  | include '**/com/android/tools/r8/ArchiveClassFileProvider.java' | 
|  | include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java' | 
|  | include '**/com/android/tools/r8/BaseCommand.java' | 
|  | include '**/com/android/tools/r8/BaseCompilerCommand.java' | 
|  | include '**/com/android/tools/r8/ClassFileConsumer.java' | 
|  | include '**/com/android/tools/r8/ClassFileResourceProvider.java' | 
|  | include '**/com/android/tools/r8/CompilationFailedException.java' | 
|  | include '**/com/android/tools/r8/CompilationMode.java' | 
|  | include '**/com/android/tools/r8/R8.java' | 
|  | include '**/com/android/tools/r8/R8Command.java' | 
|  | include '**/com/android/tools/r8/DexIndexedConsumer.java' | 
|  | include '**/com/android/tools/r8/Diagnostic.java' | 
|  | include '**/com/android/tools/r8/DiagnosticsHandler.java' | 
|  | include '**/com/android/tools/r8/DirectoryClassFileProvider.java' | 
|  | include '**/com/android/tools/r8/OutputMode.java' | 
|  | include '**/com/android/tools/r8/ProgramConsumer.java' | 
|  | include '**/com/android/tools/r8/ProgramResource.java' | 
|  | include '**/com/android/tools/r8/ProgramResourceProvider.java' | 
|  | include '**/com/android/tools/r8/Resource.java' | 
|  | include '**/com/android/tools/r8/ResourceException.java' | 
|  | include '**/com/android/tools/r8/StringConsumer.java' | 
|  | include '**/com/android/tools/r8/StringResource.java' | 
|  | include '**/com/android/tools/r8/Version.java' | 
|  | include '**/com/android/tools/r8/origin/*.java' | 
|  | } | 
|  |  | 
|  | task copyMavenDeps(type: Copy) { | 
|  | from configurations.compile into "$buildDir/deps" | 
|  | from configurations.compileClasspath into "$buildDir/deps" | 
|  | from configurations.testCompile into "$buildDir/deps" | 
|  | } | 
|  |  | 
|  | task printMavenDeps { | 
|  | // Only actually print to stdout when we are updating. | 
|  | if (project.hasProperty('updatemavendeps')) { | 
|  | for (Configuration config : configurations) { | 
|  | if (!config.isCanBeResolved()) { | 
|  | continue | 
|  | } | 
|  | def componentIds = config.incoming.resolutionResult.allDependencies.collect { | 
|  | it.selected.id | 
|  | } | 
|  | def result = dependencies.createArtifactResolutionQuery() | 
|  | .forComponents(componentIds) | 
|  | .withArtifacts(MavenModule, MavenPomArtifact) | 
|  | .execute() | 
|  | for (component in result.resolvedComponents) { | 
|  | component.getArtifacts(MavenPomArtifact).each { | 
|  | println "POM: ${it.file} ${component.id}" | 
|  | } | 
|  | } | 
|  | config.each { | 
|  | println "JAR: ${it}" | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | allprojects { | 
|  | tasks.withType(Exec) { | 
|  | doFirst { | 
|  | println commandLine.join(' ') | 
|  | } | 
|  | } | 
|  | } |