blob: 8be67ce0c63c0bf98bdaa30495ae4d00d1b01611 [file] [log] [blame]
Mads Ager418d1ca2017-05-22 09:35:49 +02001// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
Ian Zerny5fffb0a2019-02-11 13:54:22 +01004
Jake Wharton2d7aab82019-09-13 10:24:26 -04005import dx.DexMergerTask
6import dx.DxTask
Ian Zerny5fffb0a2019-02-11 13:54:22 +01007import net.ltgt.gradle.errorprone.CheckSeverity
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02008import org.gradle.internal.os.OperatingSystem
Jake Wharton2d7aab82019-09-13 10:24:26 -04009import smali.SmaliTask
Ian Zernyb2d27c42019-02-20 09:09:41 +010010import tasks.DownloadDependency
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +000011import tasks.GetJarsFromConfiguration
Stephan Herhut417a72a2017-07-18 10:38:30 +020012import utils.Utils
Mads Ager418d1ca2017-05-22 09:35:49 +020013
Ian Zerny5fffb0a2019-02-11 13:54:22 +010014buildscript {
15 repositories {
Rico Wind23a05112019-03-27 08:00:44 +010016 maven {
Rico Wind70d614f2020-01-31 08:45:21 +010017 url 'https://storage.googleapis.com/r8-deps/maven_mirror/'
Rico Wind23a05112019-03-27 08:00:44 +010018 }
Ian Zerny5fffb0a2019-02-11 13:54:22 +010019 mavenCentral()
Jake Wharton5e5b5232019-09-17 16:13:32 -040020 gradlePluginPortal()
Morten Krogh-Jespersen68cc4b62019-03-21 10:32:17 +010021 jcenter()
Ian Zerny5fffb0a2019-02-11 13:54:22 +010022 }
Ian Zerny5fffb0a2019-02-11 13:54:22 +010023}
24
25plugins {
26 id "net.ltgt.errorprone" version "0.7"
27}
28
29apply plugin: 'java'
30apply plugin: 'idea'
31
Sebastien Hertz143ed112018-02-13 14:26:41 +010032ext {
33 androidSupportVersion = '25.4.0'
Søren Gjesse4832e8b2021-06-30 09:25:25 +020034 asmVersion = '9.2' // When updating update tools/asmifier.py and Toolhelper as well.
Sebastien Hertz143ed112018-02-13 14:26:41 +010035 espressoVersion = '3.0.0'
36 fastutilVersion = '7.2.0'
37 guavaVersion = '23.0'
38 joptSimpleVersion = '4.6'
Mads Ager48dd79e2018-05-15 09:13:55 +020039 gsonVersion = '2.7'
Morten Krogh-Jespersen94ff6762019-03-20 14:45:23 +010040 junitVersion = '4.13-beta-2'
Jinseong Jeone11145f2018-12-13 10:57:29 -080041 mockitoVersion = '2.10.0'
Morten Krogh-Jespersen358c8a72021-02-24 11:07:57 +010042 // The kotlin version is only here to specify the kotlin language level,
43 // all kotlin compilations are done in tests.
Morten Krogh-Jespersenb0b39092021-07-05 14:20:44 +020044 kotlinVersion = '1.5.0'
Morten Krogh-Jespersen742d18e2021-12-10 13:52:05 +010045 kotlinExtMetadataJVMVersion = '0.4.1'
Sebastien Hertz143ed112018-02-13 14:26:41 +010046 smaliVersion = '2.2b4'
Ian Zerny5fffb0a2019-02-11 13:54:22 +010047 errorproneVersion = '2.3.2'
clementbera4f9c2a92019-07-09 08:50:37 +020048 testngVersion = '6.10'
Sebastien Hertz143ed112018-02-13 14:26:41 +010049}
50
Mads Ager418d1ca2017-05-22 09:35:49 +020051apply from: 'copyAdditionalJctfCommonFiles.gradle'
52
53repositories {
Rico Wind23a05112019-03-27 08:00:44 +010054 maven {
Rico Wind70d614f2020-01-31 08:45:21 +010055 url 'https://storage.googleapis.com/r8-deps/maven_mirror/'
Rico Wind23a05112019-03-27 08:00:44 +010056 }
Jake Wharton5e5b5232019-09-17 16:13:32 -040057 google()
Mads Ager418d1ca2017-05-22 09:35:49 +020058 mavenCentral()
59}
60
Jinseong Jeon05064e12018-07-03 00:21:12 -070061if (project.hasProperty('with_code_coverage')) {
62 apply plugin: 'jacoco'
63}
64
Mads Ager418d1ca2017-05-22 09:35:49 +020065// Custom source set for example tests and generated tests.
66sourceSets {
67 test {
68 java {
69 srcDirs = [
clementbera0fe940d2019-04-23 12:45:18 +020070 'src/test/java',
71 'build/generated/test/java',
72 ]
73 }
74 }
Yohann Rousselbb571622017-11-09 10:47:36 +010075 apiUsageSample {
76 java {
Mathias Rave3f3c522018-05-30 08:22:17 +020077 srcDirs = ['src/test/apiUsageSample', 'src/main/java']
78 include 'com/android/tools/apiusagesample/*.java'
79 include 'com/android/tools/r8/BaseCompilerCommandParser.java'
80 include 'com/android/tools/r8/D8CommandParser.java'
81 include 'com/android/tools/r8/R8CommandParser.java'
82 include 'com/android/tools/r8/utils/FlagFile.java'
Yohann Rousselbb571622017-11-09 10:47:36 +010083 }
Yohann Rousselbb571622017-11-09 10:47:36 +010084 }
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +010085 cfSegments {
86 java {
87 srcDirs = ['third_party/classlib/java', 'src/cf_segments/java']
88 }
89 output.resourcesDir = 'build/classes/cfSegments'
90 }
Søren Gjesse17fc67d2019-12-04 14:50:17 +010091 libraryDesugarConversions {
92 java {
93 srcDirs = ['src/library_desugar/java']
94 }
95 output.resourcesDir = 'build/classes/library_desugar_conversions'
96 }
Mads Ager418d1ca2017-05-22 09:35:49 +020097 debugTestResources {
98 java {
99 srcDirs = ['src/test/debugTestResources']
100 }
101 output.resourcesDir = 'build/classes/debugTestResources'
102 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +0200103 debugTestResourcesJava8 {
104 java {
105 srcDirs = ['src/test/debugTestResourcesJava8']
106 }
107 output.resourcesDir = 'build/classes/debugTestResourcesJava8'
108 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200109 examples {
110 java {
Ivan Gavrilovic664f34d2018-11-09 10:02:40 -0800111 srcDirs = ['src/test/examples']
Mads Ager418d1ca2017-05-22 09:35:49 +0200112 }
113 output.resourcesDir = 'build/classes/examples'
114 }
Ian Zernyd3020482019-04-25 07:05:04 +0200115 examplesJava9 {
116 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200117 srcDirs = ['src/test/examplesJava9']
Ian Zernyd3020482019-04-25 07:05:04 +0200118 }
119 }
Jake Wharton2000b2f2019-12-11 20:37:49 -0500120 examplesJava10 {
121 java {
122 srcDirs = ['src/test/examplesJava10']
123 }
124 }
Ian Zernyd3020482019-04-25 07:05:04 +0200125 examplesJava11 {
126 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200127 srcDirs = ['src/test/examplesJava11']
128 }
129 }
Søren Gjesse2b19a032021-11-12 10:45:04 +0100130 examplesJava17 {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100131 java {
Søren Gjesse2b19a032021-11-12 10:45:04 +0100132 srcDirs = ['src/test/examplesJava17']
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100133 }
134 }
clementbera4f9c2a92019-07-09 08:50:37 +0200135 jdk11TimeTests {
136 java {
137 srcDirs = [
138 'third_party/openjdk/jdk-11-test/java/time/tck',
139 'third_party/openjdk/jdk-11-test/java/time/test'
140 ]
141 exclude '**/TestZoneTextPrinterParser.java'
142 }
143 }
clementberaefa10522019-07-11 11:20:46 +0200144 examplesTestNGRunner {
clementbera4f9c2a92019-07-09 08:50:37 +0200145 java {
146 srcDirs = ['src/test/testngrunner']
147 }
148 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200149 examplesAndroidN {
150 java {
151 srcDirs = ['src/test/examplesAndroidN']
152 }
153 output.resourcesDir = 'build/classes/examplesAndroidN'
154 }
155 examplesAndroidO {
156 java {
157 srcDirs = ['src/test/examplesAndroidO']
158 }
159 output.resourcesDir = 'build/classes/examplesAndroidO'
160 }
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +0200161 examplesAndroidP {
162 java {
163 srcDirs = ['src/test/examplesAndroidP']
164 }
165 output.resourcesDir = 'build/classes/examplesAndroidP'
166 }
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200167 examplesProto {
168 java {
169 srcDirs = ['src/test/examplesProto']
170 }
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +0200171 compileClasspath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
172 compileClasspath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200173 output.resourcesDir = 'build/classes/examplesProto'
174 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200175 jctfCommon {
176 java {
177 srcDirs = [
178 'third_party/jctf/Harness/src',
179 'third_party/jctf/LibTests/src/com/google/jctf/test/categories',
180 'third_party/jctf/LibTests/src/com/google/jctf/test/helper',
181 'third_party/jctf/LibTests/src/com/google/jctf/testHelpers',
182 'third_party/jctf/LibTests/src/org',
183 'build/additionalJctfCommonFiles'
184 ]
185 }
186 resources {
187 srcDirs = ['third_party/jctf/LibTests/resources']
188 }
189 }
190 jctfTests {
191 java {
192 srcDirs = [
193 'third_party/jctf/LibTests/src/com/google/jctf/test/lib',
194 // 'third_party/jctf/VMTests/src',
195 ]
196 }
197 }
Sebastien Hertzd3313772018-01-16 14:12:37 +0100198 kotlinR8TestResources {
199 java {
200 srcDirs = ['src/test/kotlinR8TestResources']
201 }
202 output.resourcesDir = 'build/classes/kotlinR8TestResources'
203 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200204}
205
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800206// Ensure importing into IntelliJ IDEA use the same output directories as Gradle. In tests we
207// use the output path for tests (ultimately through ToolHelper.getClassPathForTests()) and
208// therefore these paths need to be the same. See https://youtrack.jetbrains.com/issue/IDEA-175172
209// for context.
210idea {
211 sourceSets.all { SourceSet sources ->
212 module {
213 if (sources.name == "main") {
214 sourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100215 outputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800216 } else {
217 testSourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100218 testOutputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800219 }
220 }
221 }
222}
223
Yohann Roussel126f6872017-08-03 16:25:32 +0200224configurations {
225 supportLibs
226}
227
Mads Ager418d1ca2017-05-22 09:35:49 +0200228dependencies {
Mads Agerd1d0da92018-12-10 13:56:50 +0100229 implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion"
230 implementation "com.google.code.gson:gson:$gsonVersion"
Mads Ager0aa48052017-09-15 12:39:15 +0200231 // Include all of guava when compiling the code, but exclude annotations that we don't
232 // need from the packaging.
Sebastien Hertz143ed112018-02-13 14:26:41 +0100233 compileOnly("com.google.guava:guava:$guavaVersion")
Mads Agerd1d0da92018-12-10 13:56:50 +0100234 implementation("com.google.guava:guava:$guavaVersion", {
Mads Ager0aa48052017-09-15 12:39:15 +0200235 exclude group: 'com.google.errorprone'
236 exclude group: 'com.google.code.findbugs'
237 exclude group: 'com.google.j2objc'
238 exclude group: 'org.codehaus.mojo'
239 })
Mads Agerd1d0da92018-12-10 13:56:50 +0100240 implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
241 implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
242 implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
243 implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
244 implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
245 implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
246 implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
Morten Krogh-Jespersenc5a346e2021-06-14 17:50:07 +0200247 implementation files('third_party/android_jar/api-database/api-database.jar')
clementbera4f9c2a92019-07-09 08:50:37 +0200248 jdk11TimeTestsCompile group: 'org.testng', name: 'testng', version: testngVersion
clementberaefa10522019-07-11 11:20:46 +0200249 examplesTestNGRunnerCompile group: 'org.testng', name: 'testng', version: testngVersion
Mads Ager418d1ca2017-05-22 09:35:49 +0200250 testCompile sourceSets.examples.output
Sebastien Hertz143ed112018-02-13 14:26:41 +0100251 testCompile "junit:junit:$junitVersion"
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100252 testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
253 testCompile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100254 testCompile group: 'org.smali', name: 'smali', version: smaliVersion
Mads Ager418d1ca2017-05-22 09:35:49 +0200255 testCompile files('third_party/jasmin/jasmin-2.4.jar')
256 testCompile files('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
Jean-Marie Henaffce162f32017-10-04 10:39:27 +0200257 testCompile files('third_party/ddmlib/ddmlib.jar')
Sebastien Hertz143ed112018-02-13 14:26:41 +0100258 jctfCommonCompile "junit:junit:$junitVersion"
259 jctfTestsCompile "junit:junit:$junitVersion"
Mads Ager418d1ca2017-05-22 09:35:49 +0200260 jctfTestsCompile sourceSets.jctfCommon.output
Sebastien Hertz143ed112018-02-13 14:26:41 +0100261 examplesAndroidOCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
262 examplesAndroidPCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
Stephan Herhut52cb1022017-10-24 15:10:41 +0200263 // Import Guava for @Nullable annotation
Sebastien Hertz143ed112018-02-13 14:26:41 +0100264 examplesCompile "com.google.guava:guava:$guavaVersion"
Jinseong Jeone11145f2018-12-13 10:57:29 -0800265 examplesCompile "junit:junit:$junitVersion"
266 examplesCompile "org.mockito:mockito-core:$mockitoVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100267 supportLibs "com.android.support:support-v4:$androidSupportVersion"
268 supportLibs "junit:junit:$junitVersion"
269 supportLibs "com.android.support.test.espresso:espresso-core:$espressoVersion"
Yohann Rousselbb571622017-11-09 10:47:36 +0100270 apiUsageSampleCompile sourceSets.main.output
Tamas Kenezb865eee2018-12-03 16:50:45 +0100271 apiUsageSampleCompile "com.google.guava:guava:$guavaVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100272 kotlinR8TestResourcesCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100273 errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")
Stephan Herhut417a72a2017-07-18 10:38:30 +0200274}
275
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100276def r8LibPath = "$buildDir/libs/r8lib.jar"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +0100277def r8LibExludeDepsPath = "$buildDir/libs/r8lib-exclude-deps.jar"
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200278def r8DesugaredPath = "$buildDir/libs/r8desugared.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100279def r8LibGeneratedKeepRulesPath = "$buildDir/generated/keep.txt"
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +0100280def r8LibTestPath = "$buildDir/classes/r8libtest"
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100281def java11ClassFiles = "$buildDir/classes/java/mainJava11"
Morten Krogh-Jespersen0d7a96f2021-01-11 17:48:12 +0100282def r8RetracePath = "$buildDir/libs/r8retrace.jar"
Morten Krogh-Jesperseneebdeb32021-01-14 16:23:53 +0100283def r8RetraceExludeDepsPath = "$buildDir/libs/r8retrace-exclude-deps.jar"
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100284
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200285def osString = OperatingSystem.current().isLinux() ? "linux" :
286 OperatingSystem.current().isMacOsX() ? "mac" : "windows"
Mads Ager418d1ca2017-05-22 09:35:49 +0200287
288def cloudDependencies = [
289 "tests" : [
mikaelpeltierc2aa6652017-10-06 12:53:37 +0200290 "2017-10-04/art",
Rico Wind132bfb42019-03-08 09:27:36 +0100291 "2016-12-19/art"
Mads Ager418d1ca2017-05-22 09:35:49 +0200292 ],
293 "third_party": [
Rico Windf72fa152018-10-22 15:41:03 +0200294 "android_cts_baseline",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200295 "android_jar/lib-v14",
Stephan Herhutb3aca8b2017-12-22 14:14:53 +0100296 "android_jar/lib-v15",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200297 "android_jar/lib-v19",
298 "android_jar/lib-v21",
Stephan Herhutd48be0d2018-01-04 15:33:10 +0100299 "android_jar/lib-v22",
300 "android_jar/lib-v23",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200301 "android_jar/lib-v24",
302 "android_jar/lib-v25",
303 "android_jar/lib-v26",
Søren Gjessec2ffae82018-12-21 12:20:18 +0100304 "android_jar/lib-v27",
305 "android_jar/lib-v28",
Søren Gjesse02f52852019-09-04 17:44:03 +0200306 "android_jar/lib-v29",
Søren Gjessefa3f8042020-04-20 12:56:11 +0200307 "android_jar/lib-v30",
Søren Gjesse8c15ecd2021-03-22 16:41:53 +0100308 "android_jar/lib-v31",
Søren Gjessed5b058e2021-11-04 15:00:19 +0100309 "android_jar/lib-v32",
Morten Krogh-Jespersenbc7009a2021-06-11 15:18:55 +0200310 "android_jar/api-versions",
Morten Krogh-Jespersena4e813e2021-06-14 17:45:48 +0200311 "android_jar/api-database",
Morten Krogh-Jespersen7a47b732021-05-11 17:32:34 +0200312 "api-outlining/simple-app-dump",
Rico Windf72fa152018-10-22 15:41:03 +0200313 "core-lambda-stubs",
314 "dart-sdk",
315 "ddmlib",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200316 "gradle/gradle",
Ian Zerny33c1c582019-09-17 12:43:45 +0200317 "google-java-format",
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +0200318 "iosched_2019",
Søren Gjesse97679312020-10-06 13:44:59 +0200319 "jacoco/0.8.2",
320 "jacoco/0.8.6",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200321 "jasmin",
322 "jctf",
Morten Krogh-Jespersen4187e162019-03-25 13:19:17 +0100323 "junit",
Rico Windf72fa152018-10-22 15:41:03 +0200324 "jdwp-tests",
Søren Gjesse70f75b12019-08-22 12:32:02 +0200325 "jsr223-api-1.0",
Søren Gjesse8f0e0992019-09-06 09:28:14 +0200326 "rhino-1.7.10",
Søren Gjessef6c0a782019-08-22 12:48:46 +0200327 "rhino-android-1.1.1",
Morten Krogh-Jespersenb328dc62020-05-12 09:11:52 +0200328 "kotlin/kotlin-compiler-1.3.11",
329 "kotlin/kotlin-compiler-1.3.41",
Morten Krogh-Jespersend32c8f22020-05-12 10:56:16 +0200330 "kotlin/kotlin-compiler-1.3.72",
Morten Krogh-Jespersen1c801b02021-02-11 10:15:23 +0100331 "kotlin/kotlin-compiler-1.4.20",
Morten Krogh-Jespersena9705f52021-07-05 11:28:02 +0200332 "kotlin/kotlin-compiler-1.5.0",
Morten Krogh-Jespersen14153472020-05-19 15:40:47 +0200333 "kotlinx-coroutines-1.3.6",
Mathias Rav5285faf2018-03-20 14:16:32 +0100334 "openjdk/openjdk-rt-1.8",
Søren Gjesse952e1d52019-05-28 12:51:30 +0200335 "openjdk/desugar_jdk_libs",
Clément Béracac269b2021-03-17 07:53:43 +0000336 "openjdk/desugar_jdk_libs_11",
Søren Gjesse09c3dd02021-06-17 08:21:51 +0200337 "openjdk/desugar_jdk_libs_releases/1.0.9",
338 "openjdk/desugar_jdk_libs_releases/1.0.10",
339 "openjdk/desugar_jdk_libs_releases/1.1.0",
340 "openjdk/desugar_jdk_libs_releases/1.1.1",
341 "openjdk/desugar_jdk_libs_releases/1.1.5",
clementbera8dbfeda2019-07-03 11:24:13 +0200342 "openjdk/jdk-11-test",
Rico Windf72fa152018-10-22 15:41:03 +0200343 "proguard/proguard5.2.1",
344 "proguard/proguard6.0.1",
Ian Zerny7c920ac2020-07-01 20:12:01 +0200345 "proguard/proguard-7.0.0",
Morten Krogh-Jespersen7cbae972021-08-31 16:54:31 +0200346 "retrace/binary_compatibility",
Mathias Rav891831f2018-04-26 14:51:18 +0200347 "r8",
Ian Zernye0fd0242020-06-23 13:46:14 +0200348 "r8-releases/2.0.74",
Morten Krogh-Jespersen1ba55f52020-04-24 12:49:17 +0200349 "r8mappings",
350 "tachiyomi"
Mads Ager418d1ca2017-05-22 09:35:49 +0200351 ],
352 // All dex-vms have a fixed OS of Linux, as they are only supported on Linux, and will be run in a Docker
353 // container on other platforms where supported.
354 "tools" : [
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200355 "linux/art",
356 "linux/art-5.1.1",
357 "linux/art-6.0.1",
358 "linux/art-7.0.0",
Søren Gjesse1528c022018-11-23 15:14:05 +0100359 "linux/art-8.1.0",
Søren Gjessefe7c0112018-12-03 12:33:12 +0100360 "linux/art-9.0.0",
clementbera97d5cce2019-11-22 15:09:27 +0100361 "linux/art-10.0.0",
Søren Gjesse953f7c42021-08-18 16:42:06 +0200362 "linux/host/art-12.0.0-beta4",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200363 "linux/dalvik",
Stephan Herhut02f0f9d2018-01-04 10:27:31 +0100364 "linux/dalvik-4.0.4",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200365 "${osString}/dx",
Mads Ager418d1ca2017-05-22 09:35:49 +0200366 ]
367]
368
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100369def cloudSystemDependencies = [
370 linux: [
clementbera81738ec2019-04-11 11:32:31 +0200371 "third_party": ["openjdk/openjdk-9.0.4/linux",
clementberab4fa18d2019-04-12 09:09:40 +0200372 "openjdk/jdk8/linux-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100373 "openjdk/jdk-11/linux",
Søren Gjesse2b19a032021-11-12 10:45:04 +0100374 "openjdk/jdk-17/linux"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100375 ],
376 osx: [
clementbera81738ec2019-04-11 11:32:31 +0200377 "third_party": ["openjdk/openjdk-9.0.4/osx",
clementberab4fa18d2019-04-12 09:09:40 +0200378 "openjdk/jdk8/darwin-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100379 "openjdk/jdk-11/osx",
Søren Gjesse2b19a032021-11-12 10:45:04 +0100380 "openjdk/jdk-17/osx"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100381 ],
382 windows: [
clementberab4fa18d2019-04-12 09:09:40 +0200383 "third_party": ["openjdk/openjdk-9.0.4/windows",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100384 "openjdk/jdk-11/windows",
Søren Gjesse2b19a032021-11-12 10:45:04 +0100385 "openjdk/jdk-17/windows"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100386 ],
387]
388
389if (OperatingSystem.current().isWindows()) {
390 cloudSystemDependencies.windows.each { entry ->
391 cloudDependencies.get(entry.key).addAll(entry.value)
392 }
393} else if (OperatingSystem.current().isLinux()) {
394 cloudSystemDependencies.linux.each { entry ->
395 cloudDependencies.get(entry.key).addAll(entry.value)
396 }
397} else if (OperatingSystem.current().isMacOsX()) {
398 cloudSystemDependencies.osx.each { entry ->
399 cloudDependencies.get(entry.key).addAll(entry.value)
400 }
401} else {
402 println "WARNING: Unsupported system: " + OperatingSystem.current()
403}
404
405def getDownloadDepsTaskName(entryKey, entryFile) {
406 return "download_deps_${entryKey}_${entryFile.replace('/', '_').replace('\\', '_')}"
407}
408
Mads Ager418d1ca2017-05-22 09:35:49 +0200409cloudDependencies.each { entry ->
410 entry.value.each { entryFile ->
Ian Zernyb2d27c42019-02-20 09:09:41 +0100411 task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) {
412 type DownloadDependency.Type.GOOGLE_STORAGE
413 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200414 }
415 }
416}
417
418def x20Dependencies = [
419 "third_party": [
Rico Windc346c4a2018-10-23 08:04:16 +0200420 "benchmarks/kotlin-benches",
Jinseong Jeonb0c2dc02019-07-18 11:41:11 -0700421 "chrome/chrome_180917_ffbaa8",
Christoffer Quist Adamsence640052020-04-30 11:47:41 +0200422 "chrome/chrome_200430",
Christoffer Quist Adamsen287c1862020-05-20 15:51:12 +0200423 "chrome/monochrome_public_minimal_apks/chrome_200520",
Clément Béra5da4e352021-01-27 18:16:27 +0000424 "chrome/clank_google3_prebuilt",
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +0100425 "classlib",
Morten Krogh-Jespersen480784d2019-02-05 08:10:46 +0100426 "cf_segments",
Rico Windf72fa152018-10-22 15:41:03 +0200427 "desugar/desugar_20180308",
Ian Zernybd2fdcc2019-03-22 13:57:21 +0100428 "internal/issue-127524985",
Rico Windf72fa152018-10-22 15:41:03 +0200429 "framework",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200430 "gmail/gmail_android_170604.16",
Søren Gjesseb552e842018-09-28 12:17:29 +0200431 "gmail/gmail_android_180826.15",
Rico Windf72fa152018-10-22 15:41:03 +0200432 "gmscore/gmscore_v10",
Rico Windf72fa152018-10-22 15:41:03 +0200433 "gmscore/latest",
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +0200434 "nest/nest_20180926_7c6cfb",
Rico Windf72fa152018-10-22 15:41:03 +0200435 "proguard/proguard_internal_159423826",
436 "proguardsettings",
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200437 "proto",
438 "protobuf-lite",
Morten Krogh-Jespersend87c0662020-06-22 10:45:43 +0200439 "retrace_internal",
Christoffer Quist Adamsene44d6532021-04-14 16:07:06 +0200440 "youtube/youtube.android_15.33",
Christoffer Quist Adamsene18f9202021-05-31 13:14:20 +0200441 "youtube/youtube.android_16.12",
442 "youtube/youtube.android_16.20"
Mads Ager418d1ca2017-05-22 09:35:49 +0200443 ],
444]
445
446x20Dependencies.each { entry ->
447 entry.value.each { entryFile ->
Ian Zernyb2d27c42019-02-20 09:09:41 +0100448 task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) {
449 type DownloadDependency.Type.X20
450 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200451 }
452 }
453}
454
Rico Wind897bb712017-05-23 10:44:29 +0200455task downloadProguard {
456 cloudDependencies.each { entry ->
457 entry.value.each { entryFile ->
458 if (entryFile.contains("proguard")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100459 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Wind897bb712017-05-23 10:44:29 +0200460 }
461 }
462 }
463}
464
Rico Windf6c74ce2018-12-04 08:50:55 +0100465task downloadOpenJDKrt {
466 cloudDependencies.each { entry ->
467 entry.value.each { entryFile ->
468 if (entryFile.contains("openjdk-rt")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100469 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Windf6c74ce2018-12-04 08:50:55 +0100470 }
471 }
472 }
473}
474
Tamas Kenez427205b2017-06-29 15:57:09 +0200475task downloadDx {
476 cloudDependencies.each { entry ->
477 entry.value.each { entryFile ->
Tamas Kenezcea7c202017-10-13 10:53:32 +0200478 if (entryFile.endsWith("/dx")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100479 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez427205b2017-06-29 15:57:09 +0200480 }
481 }
482 }
483}
484
Tamas Kenez0e10c562017-06-08 10:00:34 +0200485task downloadAndroidCts {
486 cloudDependencies.each { entry ->
487 entry.value.each { entryFile ->
488 if (entryFile.contains("android_cts_baseline")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100489 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez0e10c562017-06-08 10:00:34 +0200490 }
491 }
492 }
493}
494
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200495task downloadCloudDeps() {
Mads Ager418d1ca2017-05-22 09:35:49 +0200496 cloudDependencies.each { entry ->
497 entry.value.each { entryFile ->
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100498 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200499 }
500 }
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200501}
502
503task downloadX20Deps() {
504 x20Dependencies.each { entry ->
505 entry.value.each { entryFile ->
506 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200507 }
508 }
509}
510
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200511task downloadDeps {
512 dependsOn downloadCloudDeps
513 if (!project.hasProperty('no_internal')) {
514 dependsOn downloadX20Deps
515 }
516}
517
Mads Ager418d1ca2017-05-22 09:35:49 +0200518allprojects {
519 sourceCompatibility = JavaVersion.VERSION_1_8
520 targetCompatibility = JavaVersion.VERSION_1_8
521}
522
Rico Wind266336c2019-02-25 10:11:38 +0100523// TODO(ricow): Remove debug prints
524println("NOTE: Current operating system: " + OperatingSystem.current())
525println("NOTE: Current operating system isWindows: " + OperatingSystem.current().isWindows())
526
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100527// Check if running with the JDK location from tools/jdk.py.
528if (OperatingSystem.current().isWindows()) {
529 println "NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome
Morten Krogh-Jespersend9a88452020-01-31 14:13:54 +0100530 compileJava.options.encoding = "UTF-8"
531 compileTestJava.options.encoding = "UTF-8"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100532} else {
533 def javaHomeOut = new StringBuilder()
534 def javaHomeErr = new StringBuilder()
Jake Wharton7c14ce72019-09-17 13:49:18 -0400535 def javaHomeProc = './tools/jdk.py'.execute([], projectDir)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100536 javaHomeProc.waitForProcessOutput(javaHomeOut, javaHomeErr)
537 def jdkHome = new File(javaHomeOut.toString().trim())
538 if (!jdkHome.exists()) {
539 println "WARNING: Failed to find the ./tools/jdk.py specified JDK: " + jdkHome
540 } else if (jdkHome != org.gradle.internal.jvm.Jvm.current().javaHome) {
541 println("WARNING: Gradle is running in a non-pinned Java"
542 + ". Gradle Java Home: " + org.gradle.internal.jvm.Jvm.current().javaHome
Christoffer Quist Adamsen79b126a2020-03-27 17:23:08 +0000543 + ". Expected: " + jdkHome)
Rico Wind266336c2019-02-25 10:11:38 +0100544 } else {
545 println("NOTE: Running with jdk from tools/jdk.py: " + jdkHome)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100546 }
Mads Agerc7d14d32018-09-27 11:09:46 +0200547}
548
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200549compileJava.dependsOn downloadCloudDeps
Morten Krogh-Jespersenc1bc4a02021-06-18 08:13:02 +0200550
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100551sourceSets.configureEach { sourceSet ->
552 tasks.named(sourceSet.compileJavaTaskName).configure {
553 // Default disable errorprone (enabled and setup below).
554 options.errorprone.enabled = false
555 options.compilerArgs << '-Xlint:unchecked'
Ian Zerny09135aa2019-02-12 16:03:34 +0100556 // Run all compilation tasks in a forked subprocess.
557 options.fork = true
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100558 // Javac often runs out of stack space when compiling the tests.
559 // Increase the stack size for the javac process.
Søren Gjesse1af374d2019-09-06 10:44:54 +0200560 options.forkOptions.jvmArgs << "-Xss256m"
Ian Zerny26307fb2019-03-06 15:18:17 +0100561 // Test compilation is sometimes hitting the default limit at 1g, increase it.
Ian Zerny293b8152019-09-20 10:40:53 +0200562 options.forkOptions.jvmArgs << "-Xmx3g"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100563 // Set the bootclass path so compilation is consistent with 1.8 target compatibility.
564 options.forkOptions.jvmArgs << "-Xbootclasspath/a:third_party/openjdk/openjdk-rt-1.8/rt.jar"
565 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200566}
567
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100568def setJdkCompilationWithCompatibility(String sourceSet, String javaHome, JavaVersion compatibility, boolean enablePreview) {
569 tasks.named(sourceSet).get().configure {
570 def jdkDir = "third_party/openjdk/${javaHome}/"
571 options.fork = true
572 options.forkOptions.jvmArgs = []
573 if (enablePreview) {
574 options.compilerArgs.add('--enable-preview')
575 }
576 if (OperatingSystem.current().isLinux()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200577 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/linux")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100578 options.forkOptions.javaHome = file(jdkDir + 'linux')
579 } else if (OperatingSystem.current().isMacOsX()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200580 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/osx")
Jake Whartonbd3196b2021-03-16 15:48:08 -0400581 options.forkOptions.javaHome = compatibility > JavaVersion.VERSION_1_9
582 ? file(jdkDir + 'osx/Contents/Home')
583 : file(jdkDir + 'osx')
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100584 } else {
Søren Gjesse96b37252021-08-09 16:08:05 +0200585 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/windows")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100586 options.forkOptions.javaHome = file(jdkDir + 'windows')
587 }
588 sourceCompatibility = compatibility
589 targetCompatibility = compatibility
Ian Zernyd3020482019-04-25 07:05:04 +0200590 }
Ian Zernyd3020482019-04-25 07:05:04 +0200591}
592
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100593setJdkCompilationWithCompatibility(
594 sourceSets.examplesJava9.compileJavaTaskName,
595 'openjdk-9.0.4',
596 JavaVersion.VERSION_1_9,
597 false)
598setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100599 sourceSets.examplesJava11.compileJavaTaskName,
600 'jdk-11',
601 JavaVersion.VERSION_11,
602 false)
603setJdkCompilationWithCompatibility(
604 sourceSets.examplesJava10.compileJavaTaskName,
605 'jdk-11',
606 JavaVersion.VERSION_1_10,
607 false)
608setJdkCompilationWithCompatibility(
609 sourceSets.examplesJava11.compileJavaTaskName,
610 'jdk-11',
611 JavaVersion.VERSION_11,
612 false)
613setJdkCompilationWithCompatibility(
614 sourceSets.examplesTestNGRunner.compileJavaTaskName,
615 'jdk-11',
616 JavaVersion.VERSION_11,
617 false)
618setJdkCompilationWithCompatibility(
619 sourceSets.jdk11TimeTests.compileJavaTaskName,
620 'jdk-11',
621 JavaVersion.VERSION_11,
622 false)
623setJdkCompilationWithCompatibility(
Søren Gjesse2b19a032021-11-12 10:45:04 +0100624 sourceSets.examplesJava17.compileJavaTaskName,
625 'jdk-17',
626 JavaVersion.VERSION_17,
627 false)
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100628
clementbera0bca05e2019-05-29 14:11:18 +0200629task compileMainWithJava11 (type: JavaCompile) {
Ian Zernye0dd4c42019-12-02 10:12:15 +0100630 dependsOn downloadDeps
clementbera0bca05e2019-05-29 14:11:18 +0200631 def jdkDir = 'third_party/openjdk/jdk-11/'
632 options.fork = true
633 options.forkOptions.jvmArgs = []
634 if (OperatingSystem.current().isLinux()) {
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100635 options.forkOptions.javaHome = file(jdkDir + 'linux')
clementbera0bca05e2019-05-29 14:11:18 +0200636 } else if (OperatingSystem.current().isMacOsX()) {
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100637 options.forkOptions.javaHome = file(jdkDir + 'osx/Contents/Home')
clementbera0bca05e2019-05-29 14:11:18 +0200638 } else {
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100639 options.forkOptions.javaHome = file(jdkDir + 'windows')
clementbera0bca05e2019-05-29 14:11:18 +0200640 }
641 source = sourceSets.main.allSource
642 destinationDir = file(java11ClassFiles)
643 sourceCompatibility = JavaVersion.VERSION_11
644 targetCompatibility = JavaVersion.VERSION_11
645 classpath = sourceSets.main.compileClasspath
646}
clementbera0fe940d2019-04-23 12:45:18 +0200647
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100648if (!project.hasProperty('without_error_prone') &&
649 // Don't enable error prone on Java 8 as the plugin setup does not support it.
650 !org.gradle.internal.jvm.Jvm.current().javaVersion.java8) {
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200651 compileJava {
652 // Enable error prone for D8/R8 sources.
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100653 options.errorprone.enabled = true
654 options.errorprone.disableAllChecks = true
655 options.errorprone.check('ClassCanBeStatic', CheckSeverity.ERROR)
Christoffer Quist Adamsen7bed1092020-05-04 11:08:00 +0200656 options.errorprone.check('CollectionIncompatibleType', CheckSeverity.ERROR)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100657 options.errorprone.check('OperatorPrecedence', CheckSeverity.ERROR)
658 options.errorprone.check('RemoveUnusedImports', CheckSeverity.ERROR)
659 options.errorprone.check('MissingOverride', CheckSeverity.ERROR)
660 options.errorprone.check('IntLongMath', CheckSeverity.ERROR)
661 options.errorprone.check('EqualsHashCode', CheckSeverity.ERROR)
662 options.errorprone.check('InconsistentOverloads', CheckSeverity.ERROR)
663 options.errorprone.check('ArrayHashCode', CheckSeverity.ERROR)
664 options.errorprone.check('EqualsIncompatibleType', CheckSeverity.ERROR)
665 options.errorprone.check('NonOverridingEquals', CheckSeverity.ERROR)
666 options.errorprone.check('FallThrough', CheckSeverity.ERROR)
667 options.errorprone.check('MissingCasesInEnumSwitch', CheckSeverity.ERROR)
668 options.errorprone.check('MissingDefault', CheckSeverity.ERROR)
669 options.errorprone.check('MultipleTopLevelClasses', CheckSeverity.ERROR)
670 options.errorprone.check('NarrowingCompoundAssignment', CheckSeverity.ERROR)
671 options.errorprone.check('BoxedPrimitiveConstructor', CheckSeverity.ERROR)
672 options.errorprone.check('LogicalAssignment', CheckSeverity.ERROR)
673 options.errorprone.check('FloatCast', CheckSeverity.ERROR)
674 options.errorprone.check('ReturnValueIgnored', CheckSeverity.ERROR)
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200675 }
676}
677
Mads Ager418d1ca2017-05-22 09:35:49 +0200678compileJctfCommonJava {
679 dependsOn 'copyAdditionalJctfCommonFiles'
680 options.compilerArgs = ['-Xlint:none']
681}
682
683compileJctfTestsJava {
684 dependsOn 'jctfCommonClasses'
685 options.compilerArgs = ['-Xlint:none']
686}
687
Yohann Roussel7f47c032017-09-14 12:19:06 +0200688task consolidatedLicense {
Yohann Roussel7f47c032017-09-14 12:19:06 +0200689 def license = new File(new File(buildDir, 'generatedLicense'), 'LICENSE')
Mads Agerd1d0da92018-12-10 13:56:50 +0100690
Yohann Roussel7f47c032017-09-14 12:19:06 +0200691 inputs.files files('LICENSE', 'LIBRARY-LICENSE') + fileTree(dir: 'library-licensing')
Mads Agerd1d0da92018-12-10 13:56:50 +0100692 def runtimeClasspath = configurations.findByName("runtimeClasspath")
693 inputs.files { runtimeClasspath.getResolvedConfiguration().files }
694
Yohann Roussel7f47c032017-09-14 12:19:06 +0200695 outputs.files license
Mads Agerd1d0da92018-12-10 13:56:50 +0100696
Yohann Roussel7f47c032017-09-14 12:19:06 +0200697 doLast {
Mads Agerd1d0da92018-12-10 13:56:50 +0100698 def dependencies = []
699 runtimeClasspath.resolvedConfiguration.resolvedArtifacts.each {
700 def identifier = (ModuleComponentIdentifier) it.id.componentIdentifier
701 dependencies.add("${identifier.group}:${identifier.module}")
702 }
703 def libraryLicenses = file('LIBRARY-LICENSE').text
704 dependencies.each {
705 if (!libraryLicenses.contains("- artifact: $it")) {
706 throw new GradleException("No license for $it in LIBRARY_LICENSE")
707 }
708 }
709
Yohann Roussel7f47c032017-09-14 12:19:06 +0200710 license.getParentFile().mkdirs()
711 license.createNewFile()
712 license.text = "This file lists all licenses for code distributed.\n"
713 license.text += "All non-library code has the following 3-Clause BSD license.\n"
714 license.text += "\n"
715 license.text += "\n"
716 license.text += file('LICENSE').text
717 license.text += "\n"
718 license.text += "\n"
719 license.text += "Summary of distributed libraries:\n"
720 license.text += "\n"
Mads Agerd1d0da92018-12-10 13:56:50 +0100721 license.text += libraryLicenses
Yohann Roussel7f47c032017-09-14 12:19:06 +0200722 license.text += "\n"
723 license.text += "\n"
724 license.text += "Licenses details:\n"
725 fileTree(dir: 'library-licensing').getFiles().stream().sorted().forEach { file ->
726 license.text += "\n"
727 license.text += "\n"
728 license.text += file.text
729 }
730 }
731}
732
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100733def repackageDepFile(file) {
734 if (file.getName().endsWith('.jar')) {
735 return zipTree(file).matching {
736 exclude '**/module-info.class'
737 exclude 'META-INF/maven/**'
738 exclude 'META-INF/LICENSE.txt'
739 exclude 'META-INF/MANIFEST.MF'
740 }
741 } else {
742 return fileTree(file)
Jinseong Jeon40ceab02018-07-09 14:25:31 -0700743 }
Morten Krogh-Jespersen00699af2018-10-09 10:54:42 +0200744}
745
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100746task repackageDeps(type: Jar) {
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200747 dependsOn downloadCloudDeps
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100748 dependsOn project.configurations.runtimeClasspath
749 project.configurations.runtimeClasspath.forEach {
750 from repackageDepFile(it)
751 }
752 archiveFileName = 'deps_all.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000753}
754
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100755task repackageTestDeps(type: Jar) {
756 dependsOn downloadCloudDeps
757 dependsOn project.configurations.testCompile
758 project.configurations.testCompile.forEach {
759 from repackageDepFile(it)
760 }
761 archiveFileName = 'test_deps_all.jar'
762}
763
764task repackageSources(type: Jar) {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100765 // If this fails then remove all generated folders from
766 // build/classes/java/test that is not {com,dalvik}
Mads Ager418d1ca2017-05-22 09:35:49 +0200767 from sourceSets.main.output
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100768 archiveFileName = 'sources_main.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000769}
770
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100771task repackageSources11(type: Jar) {
clementbera0bca05e2019-05-29 14:11:18 +0200772 dependsOn compileMainWithJava11
773 from file(java11ClassFiles)
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100774 archiveFileName = 'sources_main_11.jar'
clementbera0bca05e2019-05-29 14:11:18 +0200775}
776
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100777def r8CreateTask(name, baseName, sources, includeSwissArmyKnife) {
778 return tasks.create("r8Create${name}", Jar) {
779 dependsOn sources
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200780 from consolidatedLicense.outputs.files
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100781 from sources.collect { zipTree(it) }
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100782 exclude "$buildDir/classes/**"
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100783 archiveFileName = baseName
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200784 if (includeSwissArmyKnife) {
785 manifest {
786 attributes 'Main-Class': 'com.android.tools.r8.SwissArmyKnife'
787 }
788 }
789 exclude "META-INF/*.kotlin_module"
790 exclude "**/*.kotlin_metadata"
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200791 }
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200792}
793
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200794def r8RelocateTask(r8Task, output) {
795 return tasks.create("r8Relocate_${r8Task.name}", Exec) {
796 dependsOn r8WithDeps
797 dependsOn r8Task
798 outputs.file output
799 workingDir = projectDir
800 inputs.files r8Task.outputs.files + r8WithDeps.outputs.files
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200801 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200802 "relocator",
803 "--input",
804 r8Task.outputs.files[0],
805 "--output",
806 output,
807 "--map",
808 "com.google.common->com.android.tools.r8.com.google.common",
809 "--map",
810 "com.google.gson->com.android.tools.r8.com.google.gson",
811 "--map",
812 "com.google.thirdparty->com.android.tools.r8.com.google.thirdparty",
813 "--map",
814 "joptsimple->com.android.tools.r8.joptsimple",
815 "--map",
816 "org.objectweb.asm->com.android.tools.r8.org.objectweb.asm",
817 "--map",
818 "it.unimi.dsi.fastutil->com.android.tools.r8.it.unimi.dsi.fastutil",
819 "--map",
820 "kotlin->com.android.tools.r8.jetbrains.kotlin",
821 "--map",
822 "kotlinx->com.android.tools.r8.jetbrains.kotlinx",
823 "--map",
824 "org.jetbrains->com.android.tools.r8.org.jetbrains",
825 "--map",
826 "org.intellij->com.android.tools.r8.org.intellij"
827 ])
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200828 }
829}
830
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200831task r8WithDeps {
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100832 dependsOn repackageSources
833 dependsOn repackageDeps
834 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200835 def r8Task = r8CreateTask(
836 'WithDeps',
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100837 'r8_with_deps.jar',
838 repackageSources.outputs.files + repackageDeps.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200839 true)
840 dependsOn r8Task
841 outputs.files r8Task.outputs.files
clementbera0bca05e2019-05-29 14:11:18 +0200842}
843
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200844task r8WithDeps11 {
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100845 dependsOn repackageSources11
846 dependsOn repackageDeps
847 inputs.files ([repackageSources11.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200848 def r8Task = r8CreateTask(
849 'WithDeps11',
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100850 'r8_with_deps_11.jar',
851 repackageSources11.outputs.files + repackageDeps.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200852 true)
853 dependsOn r8Task
854 outputs.files r8Task.outputs.files
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100855}
856
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200857task r8WithRelocatedDeps {
858 def output = "${buildDir}/libs/r8_with_relocated_deps.jar"
859 dependsOn r8RelocateTask(r8WithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200860 inputs.files r8WithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200861 outputs.file output
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200862}
863
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200864task r8WithRelocatedDeps11 {
865 def output = "${buildDir}/libs/r8_with_relocated_deps_11.jar"
866 dependsOn r8RelocateTask(r8WithDeps11, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200867 inputs.files r8WithDeps11.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200868 outputs.file output
869}
870
871task r8WithoutDeps {
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100872 dependsOn repackageSources
873 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200874 def r8Task = r8CreateTask(
875 'WithoutDeps',
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100876 'r8_without_deps.jar',
877 repackageSources.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200878 true)
879 dependsOn r8Task
880 outputs.files r8Task.outputs.files
881}
882
883task r8(type: Copy) {
884 def r8Task = project.hasProperty("exclude_deps")
885 ? r8WithoutDeps : r8WithRelocatedDeps
886 dependsOn r8Task
887 from r8Task.outputs.files[0]
888 into file("${buildDir}/libs")
889 rename { String fileName -> "r8.jar" }
890 outputs.file "${buildDir}/libs/r8.jar"
891}
892
893task r8NoManifestWithoutDeps {
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100894 dependsOn repackageSources
895 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200896 def r8Task = r8CreateTask(
897 'NoManifestWithoutDeps',
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100898 'r8_no_manifest_without_deps.jar',
899 repackageSources.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200900 false)
901 dependsOn r8Task
902 outputs.files r8Task.outputs.files
903}
904
905task r8NoManifestWithDeps {
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100906 dependsOn repackageSources
907 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200908 def r8Task = r8CreateTask(
909 'NoManifestWithDeps',
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100910 'r8_no_manifest_with_deps.jar',
911 repackageSources.outputs.files + repackageDeps.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200912 false)
913 dependsOn r8Task
914 outputs.files r8Task.outputs.files
915}
916
917task r8NoManifestWithRelocatedDeps {
918 def output = "${buildDir}/libs/r8_no_manifest_with_relocated_deps.jar"
919 dependsOn r8RelocateTask(r8NoManifestWithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200920 inputs.files r8NoManifestWithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200921 outputs.file output
922}
923
924task r8NoManifest(type: Copy) {
925 def r8Task = project.hasProperty("exclude_deps")
926 ? r8NoManifestWithoutDeps : r8NoManifestWithRelocatedDeps
927 dependsOn r8Task
928 from r8Task.outputs.files[0]
929 into file("${buildDir}/libs")
930 rename { String fileName -> "r8_no_manifest.jar" }
931 outputs.file "${buildDir}/libs/r8_no_manifest.jar"
Tamas Kenez8224fbc2018-12-10 09:57:56 +0100932}
933
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100934task D8(type: Jar) {
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200935 dependsOn r8
Morten Krogh-Jespersen344a86e2021-12-21 09:31:12 +0100936 from zipTree(r8.outputs.files[0])
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +0100937 archiveFileName = 'd8.jar'
Mads Ager418d1ca2017-05-22 09:35:49 +0200938 manifest {
mikaelpeltier80939312017-08-17 15:00:09 +0200939 attributes 'Main-Class': 'com.android.tools.r8.D8'
Mads Ager418d1ca2017-05-22 09:35:49 +0200940 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200941}
942
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200943def baseCompilerCommandLine(compiler, args = []) {
944 // Execute r8 commands against a stable r8 with dependencies.
945 // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g).
946 return [org.gradle.internal.jvm.Jvm.current().getJavaExecutable(),
947 "-Xmx8g", "-ea", "-jar", r8WithDeps.outputs.files[0]] + compiler + args
948}
949
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100950def baseR8CommandLine(args = []) {
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200951 // Execute r8 commands against a stable r8 with dependencies.
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200952 return baseCompilerCommandLine("r8", args)
953}
954
955def baseD8CommandLine(args = []) {
956 // Execute r8 commands against a stable r8 with dependencies.
957 return baseCompilerCommandLine("d8", args)
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100958}
959
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200960def r8CfCommandLine(input, output, pgConfs = [], args = ["--release"], libs = []) {
961 def allArgs = [
962 "--classfile",
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100963 input,
964 "--output", output,
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100965 "--pg-map-output", output + ".map",
966 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200967 ] + args + libs.collectMany { ["--lib", it] } + pgConfs.collectMany { ["--pg-conf", it] }
968 return baseR8CommandLine(allArgs)
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100969}
970
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200971def d8CfCommandLine(input, output, args = ["--release"], libs = []) {
972 def allArgs = [
973 "--classfile",
974 input,
975 "--output", output,
976 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
977 ] + args + libs.collectMany { ["--lib", it] }
978 return baseD8CommandLine(allArgs)
979}
980
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200981def r8LibCreateTask(name, pgConfs = [], r8Task, output, args = ["--release"], libs = []) {
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100982 return tasks.create("r8Lib${name}", Exec) {
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200983 inputs.files ([pgConfs, r8WithRelocatedDeps.outputs, r8Task.outputs, libs])
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100984 outputs.file output
985 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +0100986 dependsOn r8WithRelocatedDeps
987 dependsOn r8Task
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200988 commandLine r8CfCommandLine(r8Task.outputs.files[0], output, pgConfs, args, libs)
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100989 workingDir = projectDir
990 }
991}
992
Søren Gjesse17fc67d2019-12-04 14:50:17 +0100993task buildLibraryDesugarConversions(type: Zip, dependsOn: downloadDeps) {
994 from sourceSets.libraryDesugarConversions.output
995 include "java/**/*.class"
996 baseName 'library_desugar_conversions'
997 destinationDir file('build/libs')
998}
999
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +01001000task testJarSources(type: Jar, dependsOn: [testClasses, buildLibraryDesugarConversions]) {
1001 archiveFileName = "r8testsbase.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001002 from sourceSets.test.output
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001003 // We only want to include tests that use R8 when generating keep rules for applymapping.
1004 include "com/android/tools/r8/**"
1005 include "dalvik/**"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001006}
1007
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001008task testJar(type: Exec) {
Morten Krogh-Jespersenac1a4d22020-05-04 01:42:13 +02001009 dependsOn r8WithDeps
1010 dependsOn testJarSources
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001011 def output = "$buildDir/libs/r8tests.jar"
1012 outputs.file output
1013 workingDir = projectDir
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001014 inputs.files (testJarSources.outputs.files + r8WithDeps.outputs.files)
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001015 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001016 "relocator",
1017 "--input",
1018 testJarSources.outputs.files[0],
1019 "--output",
1020 output,
1021 "--map",
1022 "kotlinx.metadata->com.android.tools.r8.jetbrains.kotlinx.metadata"
1023 ])
1024}
1025
Clément Béracac269b2021-03-17 07:53:43 +00001026task buildDesugaredLibrary(type: Exec) {
1027 def outputDir = "build/libs"
1028 def script = "tools/create_jctf_tests.py"
1029 inputs.file script
1030 outputs.dir outputDir
1031 dependsOn downloadDeps
1032 commandLine "python", script
1033 workingDir = projectDir
1034}
1035
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001036task generateR8LibKeepRules(type: Exec) {
1037 doFirst {
1038 // TODO(b/154785341): We should remove this.
1039 standardOutput new FileOutputStream(r8LibGeneratedKeepRulesPath)
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001040 }
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001041 // Depend on r8WithDeps for running baseCompilerCommandLine.
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001042 dependsOn r8WithDeps
1043 dependsOn r8NoManifestWithRelocatedDeps
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001044 dependsOn testJar
1045 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001046 inputs.files ([
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001047 r8WithDeps.outputs,
1048 r8NoManifestWithRelocatedDeps.outputs,
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001049 testJar.outputs])
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001050 outputs.file r8LibGeneratedKeepRulesPath
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001051 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001052 "printuses",
1053 "--keeprules-allowobfuscation",
1054 "third_party/openjdk/openjdk-rt-1.8/rt.jar",
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001055 r8NoManifestWithRelocatedDeps.outputs.files[0],
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001056 testJar.outputs.files[0]])
1057 workingDir = projectDir
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001058}
1059
Morten Krogh-Jespersencc5c7d02019-01-10 19:57:15 +01001060task R8LibApiOnly {
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001061 dependsOn r8LibCreateTask("Api", ["src/main/keep.txt"], r8NoManifest, r8LibPath)
Morten Krogh-Jespersencc5c7d02019-01-10 19:57:15 +01001062 outputs.file r8LibPath
1063}
1064
Morten Krogh-Jespersenb39fbe52018-12-17 14:58:48 +01001065task R8Lib {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001066 dependsOn r8LibCreateTask(
1067 "Main",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001068 ["src/main/keep.txt", generateR8LibKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001069 r8NoManifestWithRelocatedDeps,
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001070 r8LibPath,
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001071 ).dependsOn(generateR8LibKeepRules)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001072 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001073 outputs.file r8LibPath
Tamas Kenezf960e9c2018-12-03 16:13:29 +01001074}
1075
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001076task R8LibNoDeps {
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001077 dependsOn r8LibCreateTask(
1078 "NoDeps",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001079 ["src/main/keep.txt"],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001080 r8NoManifestWithoutDeps,
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001081 r8LibExludeDepsPath,
Søren Gjesse92992fe2019-08-30 14:04:22 +02001082 "--release",
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +01001083 repackageDeps.outputs.files
1084 ).dependsOn(repackageDeps)
1085 inputs.files ([r8NoManifestWithoutDeps.outputs, repackageDeps.outputs])
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001086 outputs.file r8LibExludeDepsPath
1087}
1088
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001089task R8Desugared(type: Exec) {
1090 dependsOn downloadOpenJDKrt
1091 dependsOn r8NoManifestWithRelocatedDeps
1092 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
1093 commandLine d8CfCommandLine(
1094 r8NoManifestWithRelocatedDeps.outputs.files[0],
1095 r8DesugaredPath,
1096 ["--release"])
1097 workingDir = projectDir
1098 outputs.file r8DesugaredPath
1099}
1100
Morten Krogh-Jespersen0d7a96f2021-01-11 17:48:12 +01001101task R8Retrace {
1102 dependsOn R8Lib
1103 dependsOn r8LibCreateTask(
1104 "Retrace",
1105 ["src/main/keep_retrace.txt"],
1106 R8Lib,
1107 r8RetracePath,
1108 ).dependsOn(R8Lib)
1109 outputs.file r8RetracePath
1110}
1111
Morten Krogh-Jesperseneebdeb32021-01-14 16:23:53 +01001112task R8RetraceNoDeps {
1113 dependsOn R8LibNoDeps
1114 dependsOn r8LibCreateTask(
1115 "RetraceNoDeps",
1116 ["src/main/keep_retrace.txt"],
1117 R8LibNoDeps,
1118 r8RetraceExludeDepsPath,
1119 "--release",
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +01001120 repackageDeps.outputs.files
Morten Krogh-Jesperseneebdeb32021-01-14 16:23:53 +01001121 ).dependsOn(R8LibNoDeps)
1122 outputs.file r8RetraceExludeDepsPath
1123}
1124
Mads Ager418d1ca2017-05-22 09:35:49 +02001125task sourceJar(type: Jar, dependsOn: classes) {
1126 classifier = 'src'
1127 from sourceSets.main.allSource
1128}
1129
1130task jctfCommonJar(type: Jar) {
1131 from sourceSets.jctfCommon.output
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +01001132 archiveFileName = 'jctfCommon.jar'
Mads Ager418d1ca2017-05-22 09:35:49 +02001133}
1134
1135artifacts {
1136 archives sourceJar
1137}
1138
1139task createArtTests(type: Exec) {
1140 def outputDir = "build/generated/test/java/com/android/tools/r8/art"
Mads Ager7e5bd722017-05-24 07:17:27 +02001141 def createArtTestsScript = "tools/create_art_tests.py"
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001142 inputs.files files("tests/2017-10-04/art.tar.gz", createArtTestsScript)
Mads Ager418d1ca2017-05-22 09:35:49 +02001143 outputs.dir outputDir
1144 dependsOn downloadDeps
Mads Ager677e3002017-05-24 07:54:51 +02001145 commandLine "python", createArtTestsScript
Mads Ager418d1ca2017-05-22 09:35:49 +02001146 workingDir = projectDir
1147}
1148
1149task createJctfTests(type: Exec) {
Stephan Herhutea6ee582017-05-23 13:14:34 +02001150 def outputDir = "build/generated/test/java/com/android/tools/r8/jctf"
Tamas Kenez25a99e92017-05-29 10:15:30 +02001151 def script = "tools/create_jctf_tests.py"
Mads Ager418d1ca2017-05-22 09:35:49 +02001152 inputs.file script
1153 outputs.dir outputDir
1154 dependsOn downloadDeps
Tamas Kenez25a99e92017-05-29 10:15:30 +02001155 commandLine "python", script
Mads Ager418d1ca2017-05-22 09:35:49 +02001156 workingDir = projectDir
1157}
1158
1159compileTestJava {
1160 dependsOn createArtTests
1161 dependsOn createJctfTests
1162}
1163
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001164task buildCfSegments(type: Jar, dependsOn: downloadDeps) {
1165 from sourceSets.cfSegments.output
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +01001166 archiveFileName = 'cf_segments.jar'
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001167 destinationDir file('build/libs')
1168}
1169
Ian Zerny923a0c12018-01-03 10:59:18 +01001170task buildR8ApiUsageSample(type: Jar) {
1171 from sourceSets.apiUsageSample.output
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +01001172 archiveFileName = 'r8_api_usage_sample.jar'
Ian Zerny923a0c12018-01-03 10:59:18 +01001173 destinationDir file('tests')
1174}
1175
Yohann Roussel548ae942018-01-05 11:13:28 +01001176task buildApiSampleJars {
Yohann Roussel548ae942018-01-05 11:13:28 +01001177 dependsOn buildR8ApiUsageSample
1178}
1179
Mads Ager418d1ca2017-05-22 09:35:49 +02001180task buildDebugInfoExamplesDex {
1181 def examplesDir = file("src/test/java")
1182 def hostJar = "debuginfo_examples.jar"
1183 def hostDexJar = "debuginfo_examples_dex.jar"
1184 task "compile_debuginfo_examples"(type: JavaCompile) {
1185 source = fileTree(dir: examplesDir, include: "com/android/tools/r8/debuginfo/*Test.java")
1186 destinationDir = file("build/test/debuginfo_examples/classes")
1187 classpath = sourceSets.main.compileClasspath
1188 sourceCompatibility = JavaVersion.VERSION_1_7
1189 targetCompatibility = JavaVersion.VERSION_1_7
1190 options.compilerArgs += ["-Xlint:-options"]
1191 }
1192 task "jar_debuginfo_examples"(type: Jar, dependsOn: "compile_debuginfo_examples") {
1193 archiveName = hostJar
1194 destinationDir = file("build/test/")
1195 from "build/test/debuginfo_examples/classes"
1196 include "**/*.class"
1197 }
1198 task "dex_debuginfo_examples"(type: Exec,
1199 dependsOn: ["jar_debuginfo_examples", "downloadDeps"]) {
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001200 if (OperatingSystem.current().isWindows()) {
1201 executable file("tools/windows/dx/bin/dx.bat")
Jinseong Jeon35a1eff2017-09-24 23:28:08 -07001202 } else if (OperatingSystem.current().isMacOsX()) {
1203 executable file("tools/mac/dx/bin/dx");
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001204 } else {
1205 executable file("tools/linux/dx/bin/dx");
1206 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001207 args "--dex"
1208 args "--output=build/test/${hostDexJar}"
1209 args "build/test/${hostJar}"
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001210 inputs.files files("build/test/${hostJar}")
Mads Ager418d1ca2017-05-22 09:35:49 +02001211 outputs.file file("build/test/${hostDexJar}")
1212 }
1213 dependsOn dex_debuginfo_examples
1214}
1215
1216task buildDebugTestResourcesJars {
Mads Ager418d1ca2017-05-22 09:35:49 +02001217 def resourcesDir = file("src/test/debugTestResources")
1218 def hostJar = "debug_test_resources.jar"
1219 task "compile_debugTestResources"(type: JavaCompile) {
1220 source = fileTree(dir: resourcesDir, include: '**/*.java')
1221 destinationDir = file("build/test/debugTestResources/classes")
1222 classpath = sourceSets.main.compileClasspath
1223 sourceCompatibility = JavaVersion.VERSION_1_7
1224 targetCompatibility = JavaVersion.VERSION_1_7
1225 options.compilerArgs += ["-g", "-Xlint:-options"]
1226 }
1227 task "jar_debugTestResources"(type: Jar, dependsOn: "compile_debugTestResources") {
1228 archiveName = hostJar
1229 destinationDir = file("build/test/")
1230 from "build/test/debugTestResources/classes"
1231 include "**/*.class"
1232 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001233 def java8ResourcesDir = file("src/test/debugTestResourcesJava8")
1234 def java8HostJar = "debug_test_resources_java8.jar"
1235 task "compile_debugTestResourcesJava8"(type: JavaCompile) {
1236 source = fileTree(dir: java8ResourcesDir, include: '**/*.java')
1237 destinationDir = file("build/test/debugTestResourcesJava8/classes")
1238 classpath = sourceSets.main.compileClasspath
1239 sourceCompatibility = JavaVersion.VERSION_1_8
1240 targetCompatibility = JavaVersion.VERSION_1_8
1241 options.compilerArgs += ["-g", "-Xlint:-options"]
1242 }
1243 task "jar_debugTestResourcesJava8"(type: Jar, dependsOn: "compile_debugTestResourcesJava8") {
1244 archiveName = java8HostJar
1245 destinationDir = file("build/test/")
1246 from "build/test/debugTestResourcesJava8/classes"
1247 include "**/*.class"
1248 }
1249 dependsOn downloadDeps
Mads Ager418d1ca2017-05-22 09:35:49 +02001250 dependsOn jar_debugTestResources
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001251 dependsOn jar_debugTestResourcesJava8
Mads Ager418d1ca2017-05-22 09:35:49 +02001252}
1253
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001254// Examples used by tests, where Android specific APIs are used.
1255task buildExampleAndroidApi(type: JavaCompile) {
1256 source = fileTree(dir: file("src/test/examplesAndroidApi"), include: "**/*.java")
1257 destinationDir = file("build/test/examplesAndroidApi/classes")
1258 classpath = files("third_party/android_jar/lib-v26/android.jar")
1259 sourceCompatibility = JavaVersion.VERSION_1_8
1260 targetCompatibility = JavaVersion.VERSION_1_8
1261}
1262
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001263task buildProtoGeneratedSources {
1264 def examplesProtoDir = file("src/test/examplesProto")
1265 examplesProtoDir.eachDir { dir ->
1266 def name = dir.getName()
1267 task "compile_proto_generated_source_${name}"(type: JavaCompile) {
1268 source = {
1269 file('third_party/proto').listFiles()
1270 .findAll { it.name.startsWith(name) && it.name.endsWith('-src.jar') }
1271 .collect { zipTree(it) }
1272 }
1273 destinationDir = file("build/generated/test/proto/${name}_classes")
1274 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1275 sourceCompatibility = JavaVersion.VERSION_1_8
1276 targetCompatibility = JavaVersion.VERSION_1_8
1277 }
1278 task "jar_proto_generated_source_${name}"(type: Jar, dependsOn: "compile_proto_generated_source_${name}") {
1279 archiveName = "${name}.jar"
1280 destinationDir = file("build/generated/test/proto")
1281 from "build/generated/test/proto/${name}_classes"
1282 include "/**/*.class"
1283 }
1284 dependsOn "jar_proto_generated_source_${name}"
1285 }
1286}
1287
1288task buildExamplesProto {
1289 def examplesProtoDir = file("src/test/examplesProto")
1290 def examplesProtoOutputDir = file("build/test/examplesProto");
1291 dependsOn buildProtoGeneratedSources
1292 task "compile_examples_proto"(type: JavaCompile) {
1293 source = fileTree(dir: examplesProtoDir, include: "**/*.java")
1294 destinationDir = file("build/test/examplesProto/classes")
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +02001295 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1296 classpath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001297 sourceCompatibility = JavaVersion.VERSION_1_8
1298 targetCompatibility = JavaVersion.VERSION_1_8
1299 }
1300 examplesProtoDir.eachDir { dir ->
1301 def name = dir.getName()
1302 task "jar_examples_proto_${name}"(type: Jar, dependsOn: "compile_examples_proto") {
1303 archiveName = "${name}.jar"
1304 destinationDir = examplesProtoOutputDir
1305 from "build/test/examplesProto/classes"
1306 include name + "/**/*.class"
1307 }
1308 dependsOn "jar_examples_proto_${name}"
1309 }
1310}
1311
Lars Bakc91e87e2017-08-18 08:53:10 +02001312// Proto lite generated code yields warnings when compiling with javac.
1313// We change the options passed to javac to ignore it.
1314compileExamplesJava.options.compilerArgs = ["-Xlint:none"]
1315
Søren Gjesse7320ce52018-05-07 15:45:22 +02001316
Mads Ager418d1ca2017-05-22 09:35:49 +02001317task buildExampleJars {
Rico Wind897bb712017-05-23 10:44:29 +02001318 dependsOn downloadProguard
Mads Ager418d1ca2017-05-22 09:35:49 +02001319 def examplesDir = file("src/test/examples")
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001320 def proguardScript
1321 if (OperatingSystem.current().isWindows()) {
1322 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.bat"
1323 } else {
1324 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.sh"
1325 }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001326 task extractExamplesRuntime(type: Sync) {
1327 dependsOn configurations.examplesRuntime
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001328 from { configurations.examplesRuntime.collect { zipTree(it) } }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001329 include "**/*.class"
1330 includeEmptyDirs false
1331 into "$buildDir/runtime/examples/"
1332 }
1333
Søren Gjesse7320ce52018-05-07 15:45:22 +02001334 task "copy_examples_resources"(type: org.gradle.api.tasks.Copy) {
1335 from examplesDir
1336 exclude "**/*.java"
1337 exclude "**/keep-rules*.txt"
1338 into file("build/test/examples/classes")
1339 }
1340
1341 task "compile_examples"(type: JavaCompile) {
Søren Gjesse7320ce52018-05-07 15:45:22 +02001342 dependsOn "copy_examples_resources"
Rico Wind40fd2c12018-09-12 12:14:44 +02001343 source examplesDir
Stephan Herhut417a72a2017-07-18 10:38:30 +02001344 include "**/*.java"
Mads Ager418d1ca2017-05-22 09:35:49 +02001345 destinationDir = file("build/test/examples/classes")
Stephan Herhut417a72a2017-07-18 10:38:30 +02001346 classpath = sourceSets.examples.compileClasspath
Mads Ager418d1ca2017-05-22 09:35:49 +02001347 sourceCompatibility = JavaVersion.VERSION_1_7
1348 targetCompatibility = JavaVersion.VERSION_1_7
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001349 options.compilerArgs = ["-g:source,lines", "-Xlint:none"]
1350 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001351 task "compile_examples_debuginfo_all"(type: JavaCompile) {
1352 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001353 include "**/*.java"
1354 destinationDir = file("build/test/examples/classes_debuginfo_all")
1355 classpath = sourceSets.examples.compileClasspath
1356 sourceCompatibility = JavaVersion.VERSION_1_7
1357 targetCompatibility = JavaVersion.VERSION_1_7
1358 options.compilerArgs = ["-g", "-Xlint:none"]
1359 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001360 task "compile_examples_debuginfo_none"(type: JavaCompile) {
1361 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001362 include "**/*.java"
1363 destinationDir = file("build/test/examples/classes_debuginfo_none")
1364 classpath = sourceSets.examples.compileClasspath
1365 sourceCompatibility = JavaVersion.VERSION_1_7
1366 targetCompatibility = JavaVersion.VERSION_1_7
1367 options.compilerArgs = ["-g:none", "-Xlint:none"]
Mads Ager418d1ca2017-05-22 09:35:49 +02001368 }
1369 examplesDir.eachDir { dir ->
1370 def name = dir.getName();
1371 def exampleOutputDir = file("build/test/examples");
1372 def jarName = "${name}.jar"
1373 dependsOn "jar_example_${name}"
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001374 dependsOn "jar_example_${name}_debuginfo_all"
1375 dependsOn "jar_example_${name}_debuginfo_none"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001376 dependsOn "extractExamplesRuntime"
1377 def runtimeDependencies = copySpec { }
Mads Ager418d1ca2017-05-22 09:35:49 +02001378 // The "throwing" test verifies debugging/stack info on the post-proguarded output.
1379 def proguardConfigPath = "${dir}/proguard.cfg"
1380 if (new File(proguardConfigPath).exists()) {
1381 task "pre_proguard_example_${name}"(type: Jar, dependsOn: "compile_examples") {
1382 archiveName = "${name}_pre_proguard.jar"
1383 destinationDir = exampleOutputDir
1384 from "build/test/examples/classes"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001385 include name + "/**/*.class"
1386 with runtimeDependencies
1387 includeEmptyDirs false
Mads Ager418d1ca2017-05-22 09:35:49 +02001388 }
1389 def jarPath = files(tasks.getByPath("pre_proguard_example_${name}")).files.first();
1390 def proguardJarPath = "${exampleOutputDir}/${jarName}"
1391 def proguardMapPath = "${exampleOutputDir}/${name}/${name}.map"
1392 task "jar_example_${name}"(type: Exec, dependsOn: "pre_proguard_example_${name}") {
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001393 inputs.files files(
1394 tasks.getByPath("pre_proguard_example_${name}"),
1395 proguardConfigPath)
Mads Ager418d1ca2017-05-22 09:35:49 +02001396 // Enable these to get stdout and stderr redirected to files...
1397 // standardOutput = new FileOutputStream('proguard.stdout')
1398 // errorOutput = new FileOutputStream('proguard.stderr')
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001399 def proguardArguments = "-verbose -dontwarn java.** -injars ${jarPath}" +
Mads Ager418d1ca2017-05-22 09:35:49 +02001400 " -outjars ${proguardJarPath}" +
1401 " -include ${proguardConfigPath}" +
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001402 " -printmapping ${proguardMapPath}"
1403 if (OperatingSystem.current().isWindows()) {
1404 executable "${proguardScript}"
1405 args "${proguardArguments}"
1406 } else {
1407 executable "bash"
1408 args "-c", "${proguardScript} '${proguardArguments}'"
1409 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001410 outputs.file proguardJarPath
1411 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001412 // TODO: Consider performing distinct proguard compilations.
1413 task "jar_example_${name}_debuginfo_all"(type: Copy, dependsOn: "jar_example_${name}") {
1414 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001415 into "${exampleOutputDir}"
1416 rename(".*", "${name}_debuginfo_all.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001417 }
1418 task "jar_example_${name}_debuginfo_none"(type: Copy, dependsOn: "jar_example_${name}") {
1419 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001420 into "${exampleOutputDir}"
1421 rename(".*", "${name}_debuginfo_none.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001422 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001423 } else {
1424 task "jar_example_${name}"(type: Jar, dependsOn: "compile_examples") {
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001425 archiveName = "${name}.jar"
Mads Ager418d1ca2017-05-22 09:35:49 +02001426 destinationDir = exampleOutputDir
1427 from "build/test/examples/classes"
Søren Gjesse7320ce52018-05-07 15:45:22 +02001428 include name + "/**/*"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001429 with runtimeDependencies
Søren Gjesse7320ce52018-05-07 15:45:22 +02001430 includeEmptyDirs true
Mads Ager418d1ca2017-05-22 09:35:49 +02001431 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001432 task "jar_example_${name}_debuginfo_all"(type: Jar, dependsOn: "compile_examples_debuginfo_all") {
1433 archiveName = "${name}_debuginfo_all.jar"
1434 destinationDir = exampleOutputDir
1435 from "build/test/examples/classes_debuginfo_all"
1436 include name + "/**/*.class"
1437 with runtimeDependencies
1438 includeEmptyDirs false
1439 }
1440 task "jar_example_${name}_debuginfo_none"(type: Jar, dependsOn: "compile_examples_debuginfo_none") {
1441 archiveName = "${name}_debuginfo_none.jar"
1442 destinationDir = exampleOutputDir
1443 from "build/test/examples/classes_debuginfo_none"
1444 include name + "/**/*.class"
1445 with runtimeDependencies
1446 includeEmptyDirs false
1447 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001448 }
1449 }
1450}
1451
1452task buildExampleAndroidNJars {
1453 dependsOn downloadDeps
1454 def examplesDir = file("src/test/examplesAndroidN")
1455 task "compile_examplesAndroidN"(type: JavaCompile) {
1456 source = fileTree(dir: examplesDir, include: '**/*.java')
1457 destinationDir = file("build/test/examplesAndroidN/classes")
1458 classpath = sourceSets.main.compileClasspath
1459 sourceCompatibility = JavaVersion.VERSION_1_8
1460 targetCompatibility = JavaVersion.VERSION_1_8
1461 options.compilerArgs += ["-Xlint:-options"]
1462 }
1463 examplesDir.eachDir { dir ->
1464 def name = dir.getName();
1465 def exampleOutputDir = file("build/test/examplesAndroidN");
1466 def jarName = "${name}.jar"
1467 dependsOn "jar_examplesAndroidN_${name}"
1468 task "jar_examplesAndroidN_${name}"(type: Jar, dependsOn: "compile_examplesAndroidN") {
1469 archiveName = jarName
1470 destinationDir = exampleOutputDir
1471 from "build/test/examplesAndroidN/classes"
1472 include "**/" + name + "/**/*.class"
1473 }
1474 }
1475}
1476
1477
1478task buildExampleAndroidOJars {
1479 dependsOn downloadDeps
1480 def examplesDir = file("src/test/examplesAndroidO")
1481 // NOTE: we want to enable a scenario when test needs to reference some
1482 // classes generated by legacy (1.6) Java compiler to test some specific
1483 // behaviour. To do so we compile all the java files located in sub-directory
1484 // called 'legacy' with Java 1.6, then compile the rest of the files with
1485 // Java 1.8 and a reference to previously generated 1.6 classes.
1486
1487 // Compiling all classes in dirs 'legacy' with old Java version.
1488 task "compile_examplesAndroidO_Legacy"(type: JavaCompile) {
1489 source = fileTree(dir: examplesDir, include: '**/legacy/**/*.java')
1490 destinationDir = file("build/test/examplesAndroidOLegacy/classes")
1491 classpath = sourceSets.main.compileClasspath
1492 sourceCompatibility = JavaVersion.VERSION_1_6
1493 targetCompatibility = JavaVersion.VERSION_1_6
1494 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1495 }
1496 // Compiling the rest of the files as Java 1.8 code.
1497 task "compile_examplesAndroidO"(type: JavaCompile) {
1498 dependsOn "compile_examplesAndroidO_Legacy"
1499 source = fileTree(dir: examplesDir, include: '**/*.java', exclude: '**/legacy/**/*.java')
1500 destinationDir = file("build/test/examplesAndroidO/classes")
1501 classpath = sourceSets.main.compileClasspath
1502 classpath += files("build/test/examplesAndroidOLegacy/classes")
1503 sourceCompatibility = JavaVersion.VERSION_1_8
1504 targetCompatibility = JavaVersion.VERSION_1_8
1505 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1506 }
1507 examplesDir.eachDir { dir ->
1508 def name = dir.getName();
1509 def destinationDir = file("build/test/examplesAndroidO/classes");
1510 if (file("src/test/examplesAndroidO/" + name + "/TestGenerator.java").isFile()) {
1511 task "generate_examplesAndroidO_${name}"(type: JavaExec,
1512 dependsOn: "compile_examplesAndroidO") {
1513 main = name + ".TestGenerator"
1514 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1515 args destinationDir
1516 }
1517 } else {
1518 task "generate_examplesAndroidO_${name}" () {}
1519 }
1520 }
1521 examplesDir.eachDir { dir ->
1522 def name = dir.getName();
1523 def exampleOutputDir = file("build/test/examplesAndroidO");
1524 def jarName = "${name}.jar"
1525 dependsOn "jar_examplesAndroidO_${name}"
1526 task "jar_examplesAndroidO_${name}"(type: Jar, dependsOn: ["compile_examplesAndroidO",
1527 "generate_examplesAndroidO_${name}"]) {
1528 archiveName = jarName
1529 destinationDir = exampleOutputDir
1530 from "build/test/examplesAndroidO/classes" // Java 1.8 classes
1531 from "build/test/examplesAndroidOLegacy/classes" // Java 1.6 classes
1532 include "**/" + name + "/**/*.class"
1533 // Do not include generator into the test runtime jar, it is not useful.
1534 // Otherwise, shrinking will need ASM jars.
1535 exclude "**/TestGenerator*"
1536 }
1537 }
1538}
1539
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001540task buildExampleAndroidPJars {
1541 dependsOn downloadDeps
1542 def examplesDir = file("src/test/examplesAndroidP")
1543
1544 task "compile_examplesAndroidP"(type: JavaCompile) {
1545 source = fileTree(dir: examplesDir, include: '**/*.java')
1546 destinationDir = file("build/test/examplesAndroidP/classes")
1547 classpath = sourceSets.main.compileClasspath
1548 sourceCompatibility = JavaVersion.VERSION_1_8
1549 targetCompatibility = JavaVersion.VERSION_1_8
1550 options.compilerArgs += ["-Xlint:-options"]
1551 }
1552 examplesDir.eachDir { dir ->
1553 def name = dir.getName();
1554 def destinationDir = file("build/test/examplesAndroidP/classes");
1555 if (file("src/test/examplesAndroidP/" + name + "/TestGenerator.java").isFile()) {
1556 task "generate_examplesAndroidP_${name}"(type: JavaExec,
1557 dependsOn: "compile_examplesAndroidP") {
1558 main = name + ".TestGenerator"
1559 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1560 args destinationDir
1561 }
1562 } else {
1563 task "generate_examplesAndroidP_${name}" () {}
1564 }
1565 }
1566 examplesDir.eachDir { dir ->
1567 def name = dir.getName();
1568 def exampleOutputDir = file("build/test/examplesAndroidP");
1569 def jarName = "${name}.jar"
1570 dependsOn "jar_examplesAndroidP_${name}"
1571 task "jar_examplesAndroidP_${name}"(type: Jar,
1572 dependsOn: ["compile_examplesAndroidP",
1573 "generate_examplesAndroidP_${name}"]) {
1574 archiveName = jarName
1575 destinationDir = exampleOutputDir
1576 from "build/test/examplesAndroidP/classes" // Java 1.8 classes
1577 include "**/" + name + "/**/*.class"
1578 // Do not include generator into the test runtime jar, it is not useful.
1579 // Otherwise, shrinking will need ASM jars.
1580 exclude "**/TestGenerator*"
1581 }
1582 }
1583}
1584
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001585def buildExampleJarsCreateTask(javaVersion, sourceSet) {
1586 return tasks.create("buildExample${javaVersion}Jars") {
1587 def examplesDir = file("src/test/examples${javaVersion}")
1588 examplesDir.eachDir { dir ->
1589 def name = dir.getName();
1590 def exampleOutputDir = file("build/test/examples${javaVersion}");
1591 def jarName = "${name}.jar"
1592 dependsOn "jar_examples${javaVersion}_${name}"
1593 task "jar_examples${javaVersion}_${name}"(type: Jar) {
1594 archiveName = jarName
1595 destinationDir = exampleOutputDir
1596 from sourceSet.output
1597 include "**/" + name + "/**/*.class"
1598 }
Mikaël Peltier61633d42017-10-13 16:51:06 +02001599 }
1600 }
1601}
1602
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001603buildExampleJarsCreateTask("Java9", sourceSets.examplesJava9)
1604buildExampleJarsCreateTask("Java10", sourceSets.examplesJava10)
1605buildExampleJarsCreateTask("Java11", sourceSets.examplesJava11)
Søren Gjesse2b19a032021-11-12 10:45:04 +01001606buildExampleJarsCreateTask("Java17", sourceSets.examplesJava17)
clementberad7ab1dd2019-04-16 16:05:00 +02001607
clementberaa92e3cd2019-07-12 14:13:22 +02001608task provideArtFrameworksDependencies {
1609 cloudDependencies.tools.forEach({ art ->
1610 if (art.contains("art")) {
1611 def taskName = art.replace('/','_')
1612 dependsOn "patch_${taskName}"
1613 task "patch_${taskName}"(type: org.gradle.api.tasks.Copy){
1614 from "tools/${art}/framework"
1615 include "**.jar"
1616 into file("tools/${art}/out/host/linux-x86/framework")
1617 }
1618 }
1619 })
1620}
1621
clementbera4f9c2a92019-07-09 08:50:37 +02001622task provideJdk11TestsDependencies(type: org.gradle.api.tasks.Copy) {
1623 from sourceSets.jdk11TimeTests.compileClasspath
1624 include "**/**.jar"
1625 into file("build/test/jdk11Tests")
1626}
1627
1628task buildJdk11TimeTestsJar {
1629 def exampleOutputDir = file("build/test/jdk11Tests");
1630 def jarName = "jdk11TimeTests.jar"
1631 dependsOn "jar_jdk11TimeTests"
1632 dependsOn provideJdk11TestsDependencies
1633 task "jar_jdk11TimeTests"(type: Jar) {
1634 archiveName = jarName
1635 destinationDir = exampleOutputDir
clementberaefa10522019-07-11 11:20:46 +02001636 from sourceSets.examplesTestNGRunner.output
clementbera4f9c2a92019-07-09 08:50:37 +02001637 include "**.class"
1638 from sourceSets.jdk11TimeTests.output
1639 include "**.class"
1640 include "**/**.class"
1641 }
1642}
1643
Sebastien Hertzd3313772018-01-16 14:12:37 +01001644task buildKotlinR8TestResources {
1645 def examplesDir = file("src/test/kotlinR8TestResources")
1646 examplesDir.eachDir { dir ->
Sebastien Hertzfe97a712018-02-13 12:08:59 +01001647 kotlin.Kotlinc.KotlinTargetVersion.values().each { kotlinTargetVersion ->
1648 def name = dir.getName()
1649 def taskName = "jar_kotlinR8TestResources_${name}_${kotlinTargetVersion}"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001650 def javaOutput = "build/test/kotlinR8TestResources/${kotlinTargetVersion}/${name}/java"
Denis Vnukovc22da842018-03-14 12:57:20 -07001651 def javaOutputJarName = "${name}.java.jar"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001652 def javaOutputJarDir = "build/test/kotlinR8TestResources/${kotlinTargetVersion}"
Denis Vnukovc22da842018-03-14 12:57:20 -07001653 task "${taskName}Java"(type: JavaCompile) {
1654 source = fileTree(dir: file("${examplesDir}/${name}"), include: '**/*.java')
1655 destinationDir = file(javaOutput)
1656 classpath = sourceSets.main.compileClasspath
1657 sourceCompatibility = JavaVersion.VERSION_1_6
1658 targetCompatibility = JavaVersion.VERSION_1_6
1659 options.compilerArgs += ["-g", "-Xlint:-options"]
1660 }
1661 task "${taskName}JavaJar"(type: Jar, dependsOn: "${taskName}Java") {
1662 archiveName = javaOutputJarName
1663 destinationDir = file(javaOutputJarDir)
1664 from javaOutput
1665 include "**/*.class"
1666 }
Morten Krogh-Jespersen358c8a72021-02-24 11:07:57 +01001667 dependsOn "${taskName}JavaJar"
Sebastien Hertzd3313772018-01-16 14:12:37 +01001668 }
Sebastien Hertzd3313772018-01-16 14:12:37 +01001669 }
1670}
1671
Mads Ager418d1ca2017-05-22 09:35:49 +02001672task buildExamples {
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001673 if (OperatingSystem.current().isMacOsX() || OperatingSystem.current().isWindows()) {
1674 logger.lifecycle("WARNING: Testing (including building examples) is only partially supported on your " +
1675 "platform (" + OperatingSystem.current().getName() + ").")
Mads Ager418d1ca2017-05-22 09:35:49 +02001676 } else if (!OperatingSystem.current().isLinux()) {
1677 logger.lifecycle("WARNING: Testing (including building examples) is not supported on your platform. " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001678 "It is fully supported on Linux and partially supported on Mac OS and Windows")
Mads Ager418d1ca2017-05-22 09:35:49 +02001679 return;
1680 }
1681 dependsOn buildDebugTestResourcesJars
1682 dependsOn buildExampleJars
1683 dependsOn buildExampleAndroidNJars
1684 dependsOn buildExampleAndroidOJars
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001685 dependsOn buildExampleAndroidPJars
Mikaël Peltier61633d42017-10-13 16:51:06 +02001686 dependsOn buildExampleJava9Jars
Jake Wharton2000b2f2019-12-11 20:37:49 -05001687 dependsOn buildExampleJava10Jars
clementberad7ab1dd2019-04-16 16:05:00 +02001688 dependsOn buildExampleJava11Jars
Søren Gjesse2b19a032021-11-12 10:45:04 +01001689 dependsOn buildExampleJava17Jars
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001690 dependsOn buildExampleAndroidApi
Mads Ager418d1ca2017-05-22 09:35:49 +02001691 def examplesDir = file("src/test/examples")
Yohann Rousself820a572017-05-31 20:25:51 +02001692 def noDexTests = [
1693 "multidex",
1694 "multidex002",
1695 "multidex004",
1696 ]
Mads Ager418d1ca2017-05-22 09:35:49 +02001697 examplesDir.eachDir { dir ->
1698 def name = dir.getName();
Yohann Rousself820a572017-05-31 20:25:51 +02001699 if (!(name in noDexTests)) {
1700 dependsOn "dex_example_${name}"
1701 def exampleOutputDir = file("build/test/examples/" + name);
1702 def dexPath = file("${exampleOutputDir}")
1703 def debug = (name == "throwing")
1704 if (!dexPath.exists()) {
1705 dexPath.mkdirs()
1706 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001707 task "dex_example_${name}"(type: DxTask, dependsOn: "jar_example_${name}") {
Yohann Rousself820a572017-05-31 20:25:51 +02001708 source = files(tasks.getByPath("jar_example_${name}")).asFileTree
1709 destination = dexPath
1710 debug = debug
1711 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001712 }
1713 }
1714}
1715
1716task buildSmali {
1717 def smaliDir = file("src/test/smali")
1718 smaliDir.eachDirRecurse() { dir ->
1719 def name = dir.getName();
1720 def relativeDir = smaliDir.toPath().relativize(dir.toPath());
1721 def smaliOutputDir = file("build/test/smali/" + relativeDir);
1722 smaliOutputDir.mkdirs()
1723 outputs.dir smaliOutputDir
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001724 def taskName = "smali_build_${relativeDir.toString().replace('/', '_').replace('\\', '_')}"
Mads Ager418d1ca2017-05-22 09:35:49 +02001725 def smaliFiles = fileTree(dir: dir, include: '*.smali')
1726 def javaFiles = fileTree(dir: dir, include: '*.java')
1727 def destDir = smaliOutputDir;
1728 def destFile = destDir.toPath().resolve("${name}.dex").toFile()
1729 def intermediateFileName = "${name}-intermediate.dex";
1730 def intermediateFile = destDir.toPath().resolve(intermediateFileName).toFile()
1731 if (javaFiles.empty) {
1732 if (!smaliFiles.empty) {
1733 dependsOn "${taskName}_smali"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001734 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001735 source = smaliFiles
1736 destination = destFile
1737 }
1738 }
1739 } else {
Rico Wind01c15c62021-04-22 17:30:41 +00001740 dependsOn "${taskName}_dexmerger"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001741 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001742 source = smaliFiles
1743 destination = intermediateFile
1744 }
1745 task "${taskName}_java"(type: JavaCompile) {
1746 source = javaFiles
1747 destinationDir destDir
1748 classpath = sourceSets.main.compileClasspath
1749 sourceCompatibility = JavaVersion.VERSION_1_7
1750 targetCompatibility = JavaVersion.VERSION_1_7
1751 options.compilerArgs += ["-Xlint:-options"]
1752 }
1753 task "${taskName}_jar"(type: Jar, dependsOn: "${taskName}_java") {
1754 archiveName = "Test.jar"
1755 destinationDir = destDir
1756 from fileTree(dir: destDir, include: 'Test.class')
1757 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001758 task "${taskName}_dx"(type: DxTask, dependsOn: "${taskName}_jar") {
Mads Ager418d1ca2017-05-22 09:35:49 +02001759 source = fileTree(dir: destDir, include: 'Test.jar')
1760 destination = destDir
1761 }
1762 task "${taskName}_dexmerger"(
Jake Wharton2d7aab82019-09-13 10:24:26 -04001763 type: DexMergerTask, dependsOn: ["${taskName}_dx", "${taskName}_smali"]) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001764 source = fileTree(dir: destDir, include: ["classes.dex", intermediateFileName])
1765 destination = destFile
1766 }
1767 }
1768 }
1769}
1770
1771tasks.withType(Test) {
Rico Windc56f21c2019-03-12 07:29:57 +01001772 println("NOTE: Number of processors " + Runtime.runtime.availableProcessors())
Mads Ager418d1ca2017-05-22 09:35:49 +02001773 def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK')
Rico Wind73da9f12019-09-19 09:27:07 +02001774 def processors = Runtime.runtime.availableProcessors()
Mads Ager418d1ca2017-05-22 09:35:49 +02001775 // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
Rico Wind73da9f12019-09-19 09:27:07 +02001776 if (userDefinedCoresPerFork) {
1777 maxParallelForks = processors.intdiv(userDefinedCoresPerFork.toInteger()) ?: 1
1778 } else {
1779 // On normal work machines this seems to give the best test execution time (without freezing)
1780 maxParallelForks = processors.intdiv(3) ?: 1
1781 }
Rico Windc56f21c2019-03-12 07:29:57 +01001782 println("NOTE: Max parallel forks " + maxParallelForks)
Rico Wind73da9f12019-09-19 09:27:07 +02001783
Mads Ager418d1ca2017-05-22 09:35:49 +02001784 forkEvery = 0
Søren Gjesseaf1c5e22017-06-15 12:24:03 +02001785 if (project.hasProperty('disable_assertions')) {
1786 enableAssertions = false
1787 }
Ian Zerny16c2f2d2019-02-19 07:25:11 +01001788 // TODO(b/124091860): Increase the max heap size to avoid OOM when running tests.
Rico Wind97b0a992019-08-30 11:09:15 +02001789 if (project.hasProperty('test_xmx')) {
1790 maxHeapSize = project.property('test_xmx')
1791 } else {
1792 maxHeapSize = "4G"
1793 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001794}
1795
1796task buildPreNJdwpTestsJar(type: Jar) {
Morten Krogh-Jespersen3de109f2021-12-21 09:45:46 +01001797 archiveFileName = 'jdwp-tests-preN.jar'
Mads Ager418d1ca2017-05-22 09:35:49 +02001798 from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
1799 // Exclude the classes containing java8
1800 exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
1801 exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
1802 includeEmptyDirs = false
1803}
1804
Ian Zerny74143162017-11-24 13:46:35 +01001805task buildPreNJdwpTestsDex(type: Exec, dependsOn: "buildPreNJdwpTestsJar") {
1806 def inFile = buildPreNJdwpTestsJar.archivePath
1807 def outFile = new File(buildPreNJdwpTestsJar.destinationDir, buildPreNJdwpTestsJar.baseName + '-dex.jar')
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001808 inputs.files files(inFile)
Ian Zerny74143162017-11-24 13:46:35 +01001809 outputs.file outFile
1810 if (OperatingSystem.current().isWindows()) {
1811 executable file("tools/windows/dx/bin/dx.bat")
1812 } else if (OperatingSystem.current().isMacOsX()) {
1813 executable file("tools/mac/dx/bin/dx");
1814 } else {
1815 executable file("tools/linux/dx/bin/dx");
1816 }
1817 args "--dex"
1818 args "--output=${outFile}"
1819 args inFile
1820}
1821
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001822task getJarsFromSupportLibs(type: GetJarsFromConfiguration) {
1823 setConfiguration(configurations.supportLibs)
Yohann Roussel126f6872017-08-03 16:25:32 +02001824}
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001825
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001826task generateR8TestKeepRules {
1827 def path = "build/generated/r8tests-keep.txt"
1828 outputs.file path
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001829 dependsOn R8Lib
1830 doLast {
1831 file(path).write """-keep class ** { *; }
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001832-dontshrink
1833-dontoptimize
1834-keepattributes *
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001835-applymapping ${R8Lib.outputs.files[0]}.map
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001836"""
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001837 }
1838}
1839
1840task buildR8LibCfTestDeps(type: Exec) {
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001841 def outputPath = "build/libs/r8libtestdeps-cf.jar"
1842 dependsOn downloadDeps
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001843 dependsOn r8NoManifest
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001844 dependsOn R8Lib
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001845 dependsOn generateR8TestKeepRules
1846 dependsOn testJar
1847 // Take all .jar files as libraries and append the generated test classes in classes/java/test.
1848 def addedLibraries = sourceSets.test.runtimeClasspath.findAll { pkg ->
1849 return pkg.toString().endsWith(".jar")
1850 } + ["${buildDir}/classes/java/test"]
1851 inputs.files testJar.outputs.files +
1852 generateR8TestKeepRules.outputs.files +
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001853 R8Lib.outputs
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001854 commandLine = r8CfCommandLine(
1855 testJar.outputs.files[0],
1856 outputPath,
1857 [generateR8TestKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001858 ["--debug", "--classpath", r8NoManifest.outputs.files[0]],
1859 r8NoManifest.outputs.files + addedLibraries)
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001860 workingDir = projectDir
1861 outputs.file outputPath
1862}
1863
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001864task configureTestForR8Lib(type: Copy) {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001865 dependsOn testJar
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001866 inputs.files buildR8LibCfTestDeps.outputs
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001867 dependsOn R8Lib
1868 delete r8LibTestPath
1869 from zipTree(buildR8LibCfTestDeps.outputs.files[0])
1870 def examplesDir = file("build/test")
1871 examplesDir.eachDir { dir ->
1872 from ("${buildDir}/test/${dir.getName()}/classes")
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001873 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001874 from ("${buildDir}/runtime/examples")
1875 into r8LibTestPath
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001876 outputs.dir r8LibTestPath
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +01001877}
1878
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001879def shouldRetrace() {
1880 return project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')
1881}
1882
1883def retrace(Throwable exception) {
1884 def out = new StringBuffer()
1885 def err = new StringBuffer()
1886 def command = "python tools/retrace.py --quiet"
1887 def header = "RETRACED STACKTRACE";
1888 if (System.getenv('BUILDBOT_BUILDERNAME') != null
1889 && !System.getenv('BUILDBOT_BUILDERNAME').endsWith("_release")) {
1890 header += ": (${command} --commit_hash ${System.getenv('BUILDBOT_REVISION')})";
1891 }
1892 out.append("\n--------------------------------------\n")
1893 out.append("${header}\n")
1894 out.append("--------------------------------------\n")
1895 Process process = command.execute()
1896 def processIn = new PrintStream(process.getOut())
1897 process.consumeProcessOutput(out, err)
1898 exception.printStackTrace(processIn)
1899 processIn.flush()
1900 processIn.close()
1901 def errorDuringRetracing = process.waitFor() != 0
1902 if (errorDuringRetracing) {
1903 out.append("ERROR DURING RETRACING\n")
1904 out.append(err.toString())
1905 }
1906 if (project.hasProperty('print_obfuscated_stacktraces') || errorDuringRetracing) {
1907 out.append("\n\n--------------------------------------\n")
1908 out.append("OBFUSCATED STACKTRACE\n")
1909 out.append("--------------------------------------\n")
1910 }
1911 return out.toString()
1912}
1913
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001914def printStackTrace(TestResult result) {
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001915 filterStackTraces(result)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001916 if (shouldRetrace()) {
1917 def exception = new Exception(retrace(result.exception))
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001918 exception.setStackTrace([] as StackTraceElement[])
1919 result.exceptions.add(0, exception)
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001920 }
1921}
1922
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001923def filterStackTraces(TestResult result) {
1924 for (Throwable throwable : result.getExceptions()) {
1925 filterStackTrace(throwable)
1926 }
1927}
1928
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001929// It would be nice to do this in a non-destructive way...
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001930def filterStackTrace(Throwable exception) {
1931 if (!project.hasProperty('print_full_stacktraces')) {
1932 def elements = []
1933 def skipped = []
1934 for (StackTraceElement element : exception.getStackTrace()) {
1935 if (element.toString().contains("com.android.tools.r8")) {
1936 elements.addAll(skipped)
1937 elements.add(element)
1938 skipped.clear()
1939 } else {
1940 skipped.add(element)
1941 }
1942 }
1943 exception.setStackTrace(elements as StackTraceElement[])
1944 }
1945}
1946
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001947def printAllStackTracesToFile(List<Throwable> exceptions, File out) {
1948 new PrintStream(new FileOutputStream(out)).withCloseable {printer ->
1949 exceptions.forEach { it.printStackTrace(printer) }
1950 }
1951}
1952
Ian Zerny89f16cf2021-04-29 21:10:09 +02001953static def escapeHtml(String string) {
1954 return string.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
1955}
1956
1957static def urlEncode(String string) {
1958 // Not sure why, but the + also needs to be converted to have working links.
1959 return URLEncoder.encode(string, "UTF-8").replace("+","%20")
1960}
1961
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001962def ensureDir(File dir) {
1963 dir.mkdirs()
1964 return dir
1965}
1966
Ian Zerny89f16cf2021-04-29 21:10:09 +02001967// Some of our test parameters have new lines :-( We really don't want test names to span lines.
1968static def sanitizedTestName(testDesc) {
1969 if (testDesc.getName().contains("\n")) {
1970 throw new RuntimeException("Unsupported use of newline in test name: '${testDesc.getName()}'")
1971 }
1972 return testDesc.getName()
1973}
1974
1975static def desanitizedTestName(testName) {
1976 return testName
1977}
1978
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001979def getTestReportEntryDir(reportDir, testDesc) {
1980 return ensureDir(reportDir.toPath()
1981 .resolve(testDesc.getClassName())
Ian Zerny89f16cf2021-04-29 21:10:09 +02001982 .resolve(sanitizedTestName(testDesc))
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001983 .toFile())
1984}
1985
Ian Zerny89f16cf2021-04-29 21:10:09 +02001986def getTestReportEntryURL(reportDir, testDesc) {
1987 def classDir = urlEncode(testDesc.getClassName())
1988 def testDir = urlEncode(sanitizedTestName(testDesc))
1989 return "file://${reportDir}/${classDir}/${testDir}"
1990}
1991
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001992def getTestResultEntryOutputFile(reportDir, testDesc, fileName) {
1993 def dir = getTestReportEntryDir(reportDir, testDesc).toPath()
1994 return dir.resolve(fileName).toFile()
1995}
1996
Ian Zerny89f16cf2021-04-29 21:10:09 +02001997def withTestResultEntryWriter(reportDir, testDesc, fileName, append, fn) {
1998 def file = getTestResultEntryOutputFile(reportDir, testDesc, fileName)
1999 new FileWriter(file, append).withCloseable fn
2000}
2001
Ian Zerny27ea4c72021-04-29 22:35:49 +02002002static def getGitBranchName() {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002003 def out = new StringBuilder()
2004 def err = new StringBuilder()
2005 def proc = "git rev-parse --abbrev-ref HEAD".execute()
2006 proc.waitForProcessOutput(out, err)
Ian Zerny27ea4c72021-04-29 22:35:49 +02002007 return out.toString().trim()
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002008}
2009
Ian Zerny27ea4c72021-04-29 22:35:49 +02002010static def getFreshTestReportIndex(File reportDir) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002011 def number = 0
2012 while (true) {
2013 def freshIndex = reportDir.toPath().resolve("index.${number++}.html").toFile()
2014 if (!freshIndex.exists()) {
2015 return freshIndex
2016 }
2017 }
2018}
2019
2020def forEachTestReportAlreadyX(File reportDir, fileName, onTest) {
2021 def out = new StringBuilder()
2022 def err = new StringBuilder()
2023 def proc = "find . -name ${fileName}".execute([], reportDir)
2024 proc.waitForProcessOutput(out, err)
2025 def outString = out.toString()
2026 outString.eachLine {
2027 // Lines are of the form: ./<class>/<name>/FAILURE
2028 def clazz = null
2029 def name = null
2030 try {
2031 def trimmed = it.trim()
2032 def line = trimmed.substring(2)
2033 def sep = line.indexOf("/")
2034 clazz = line.substring(0, sep)
2035 name = line.substring(sep + 1, line.length() - fileName.length() - 1)
2036 } catch (Exception e) {
2037 logger.lifecycle("WARNING: failed attempt to read test description from: '${it}'")
2038 return
2039 }
2040 onTest(clazz, desanitizedTestName(name))
2041 }
2042 return !outString.trim().isEmpty()
2043}
2044
2045def forEachTestReportAlreadyFailing(File reportDir, onFailureTest) {
2046 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.FAILURE.name(), onFailureTest)
2047}
2048
2049def forEachTestReportAlreadyPassing(File reportDir, onSucceededTest) {
2050 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SUCCESS.name(), onSucceededTest)
2051}
2052
2053def forEachTestReportAlreadySkipped(File reportDir, onSucceededTest) {
2054 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SKIPPED.name(), onSucceededTest)
2055}
2056
Ian Zerny27ea4c72021-04-29 22:35:49 +02002057def setUpTestingState(Test task) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002058 // Hide all test events from the console, they are written to the report.
2059 task.testLogging { events = [] }
2060
Ian Zernycae764d2021-08-16 08:25:15 +02002061 def branch = project.hasProperty('testing-state-name')
2062 ? project.getProperty('testing-state-name')
2063 : getGitBranchName()
Ian Zerny27ea4c72021-04-29 22:35:49 +02002064 def reportDir = file("${buildDir}/test-state/${branch}")
Ian Zerny89f16cf2021-04-29 21:10:09 +02002065 def index = reportDir.toPath().resolve("index.html").toFile()
Ian Zerny27ea4c72021-04-29 22:35:49 +02002066 def resetState = project.hasProperty('reset-testing-state')
2067 def reportDirExists = reportDir.exists()
2068 def resuming = !resetState && reportDirExists
Ian Zerny89f16cf2021-04-29 21:10:09 +02002069
2070 def hasFailingTests = false;
2071 if (resuming) {
2072 // Test filtering happens before the test execution is initiated so compute it here.
2073 // If there are still failing tests in the report, include only those.
2074 hasFailingTests = forEachTestReportAlreadyFailing(reportDir, {
2075 clazz, name -> task.filter.includeTestsMatching("$clazz.$name")
2076 })
2077 // Otherwise exclude all of the test already marked as succeeding.
2078 if (!hasFailingTests) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002079 // Also allow the test to overall succeed if there are no remaining tests that match,
2080 // which is natural if the state already succeeded in full.
2081 task.filter.failOnNoMatchingTests = false
Ian Zerny89f16cf2021-04-29 21:10:09 +02002082 forEachTestReportAlreadyPassing(reportDir, {
2083 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2084 })
2085 forEachTestReportAlreadySkipped(reportDir, {
2086 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2087 })
2088 }
2089 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002090
2091 task.beforeSuite { desc ->
2092 if (!desc.parent) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002093 def parentReport = null
Ian Zerny27ea4c72021-04-29 22:35:49 +02002094 if (resetState && reportDirExists) {
2095 delete reportDir
2096 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002097 if (resuming) {
2098 if (index.exists()) {
2099 parentReport = getFreshTestReportIndex(reportDir)
2100 index.renameTo(parentReport)
2101 }
2102 } else {
2103 reportDir.mkdirs()
2104 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002105 def runPrefix = resuming ? "Resuming" : "Starting"
2106 def title = "${runPrefix} @ ${branch}"
2107 // Print a console link to the test report for easy access.
2108 println "${runPrefix} test, report written to:"
2109 println " file://${index}"
2110 // Print the new index content.
2111 index << "<html><head><title>${title}</title>"
2112 index << "<style> * { font-family: monospace; }</style>"
2113 index << "</head><body><h1>${title}</h1>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002114 index << "<p>Run on: ${new Date()}</p>"
2115 index << "<p>Git branch: ${branch}</p>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002116 if (parentReport != null) {
2117 index << "<p><a href=\"file://${parentReport}\">Previous result index</a></p>"
2118 }
2119 index << "<p><a href=\"file://${index}\">Most recent result index</a></p>"
2120 index << "<p><a href=\"file://${reportDir}\">Test directories</a></p>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002121 index << "<h2>Failing tests (reload to refresh)</h2><ul>"
2122 }
2123 }
2124
2125 task.afterSuite { desc, result ->
2126 if (!desc.parent) {
2127 // Update the final test results in the index.
2128 index << "</ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002129 if (result.resultType == TestResult.ResultType.SUCCESS) {
2130 if (hasFailingTests) {
2131 index << "<h2>Rerun of failed tests now pass!</h2>"
2132 index << "<h2>Rerun again to continue with outstanding tests!</h2>"
2133 } else {
2134 index << "<h2 style=\"background-color:#62D856\">GREEN BAR == YOU ROCK!</h2>"
2135 }
2136 } else if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002137 index << "<h2 style=\"background-color:#6D130A\">Some tests failed: ${result.resultType.name()}</h2><ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002138 } else {
2139 index << "<h2>Tests finished: ${result.resultType.name()}</h2><ul>"
2140 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002141 index << "<li>Number of tests: ${result.testCount}"
2142 index << "<li>Failing tests: ${result.failedTestCount}"
2143 index << "<li>Successful tests: ${result.successfulTestCount}"
2144 index << "<li>Skipped tests: ${result.skippedTestCount}"
2145 index << "</ul></body></html>"
2146 }
2147 }
2148
2149 // Events to stdout/err are appended to the files in the test directories.
2150 task.onOutput { desc, event ->
Ian Zerny89f16cf2021-04-29 21:10:09 +02002151 withTestResultEntryWriter(reportDir, desc, event.getDestination().name(), true, {
2152 it.append(event.getMessage())
2153 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002154 }
2155
Ian Zerny27ea4c72021-04-29 22:35:49 +02002156 task.beforeTest { desc ->
2157 // Remove any stale output files before running the test.
2158 for (def destType : TestOutputEvent.Destination.values()) {
2159 def destFile = getTestResultEntryOutputFile(reportDir, desc, destType.name())
2160 if (destFile.exists()) {
2161 delete destFile
2162 }
2163 }
2164 }
2165
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002166 task.afterTest { desc, result ->
2167 if (result.getTestCount() != 1) {
2168 throw new IllegalStateException("Unexpected test with more than one result: ${desc}")
2169 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002170 // Clear any previous result files.
2171 for (def resultType : TestResult.ResultType.values()) {
2172 delete getTestResultEntryOutputFile(reportDir, desc, resultType.name())
2173 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002174 // Emit the result type status in a file of the same name: SUCCESS, FAILURE or SKIPPED.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002175 withTestResultEntryWriter(reportDir, desc, result.getResultType().name(), false, {
2176 it.append(result.getResultType().name())
2177 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002178 // Emit the test time.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002179 withTestResultEntryWriter(reportDir, desc, "time", false, {
2180 it.append("${result.getEndTime() - result.getStartTime()}")
2181 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002182 // For failed tests, update the index and emit stack trace information.
2183 if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002184 def title = escapeHtml("${desc.className}.${desc.name}")
2185 def link = getTestReportEntryURL(reportDir, desc)
2186 index << "<li><a href=\"${link}\">${title}</a></li>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002187 if (!result.exceptions.isEmpty()) {
2188 printAllStackTracesToFile(
2189 result.exceptions,
2190 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002191 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002192 desc,
2193 "exceptions-raw.txt"))
2194 filterStackTraces(result)
2195 printAllStackTracesToFile(
2196 result.exceptions,
2197 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002198 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002199 desc,
2200 "exceptions-filtered.txt"))
2201 if (shouldRetrace()) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002202 withTestResultEntryWriter(reportDir, desc, "exceptions-retraced.txt", false, { writer ->
2203 result.exceptions.forEach { writer.append(retrace(it)) }
2204 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002205 }
2206 }
2207 }
2208 }
2209}
2210
Rico Windf2f4c292021-04-23 07:06:13 +02002211def testTimes = [:]
Ian Zerny475e4012021-04-29 14:01:49 +02002212def numberOfTestTimesToPrint = 100
Rico Windf2f4c292021-04-23 07:06:13 +02002213
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002214test { task ->
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002215
2216 dependsOn buildLibraryDesugarConversions
2217 dependsOn getJarsFromSupportLibs
2218 // R8.jar is required for running bootstrap tests.
2219 dependsOn r8
2220
Ian Zerny27ea4c72021-04-29 22:35:49 +02002221 def useTestingState = project.hasProperty('testing-state')
2222 if (useTestingState) {
2223 setUpTestingState(task)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002224 }
2225
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +02002226 if (project.hasProperty('generate_golden_files_to')) {
2227 systemProperty 'generate_golden_files_to', project.property('generate_golden_files_to')
2228 assert project.hasProperty('HEAD_sha1')
2229 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2230 }
2231
2232 if (project.hasProperty('use_golden_files_in')) {
2233 systemProperty 'use_golden_files_in', project.property('use_golden_files_in')
2234 assert project.hasProperty('HEAD_sha1')
2235 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2236 }
Ian Zerny4b0de282019-06-28 09:32:24 +02002237
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002238
Ian Zerny27ea4c72021-04-29 22:35:49 +02002239 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002240 testLogging.exceptionFormat = 'full'
2241 if (project.hasProperty('print_test_stdout')) {
2242 testLogging.showStandardStreams = true
2243 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002244 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002245 if (project.hasProperty('dex_vm') && project.property('dex_vm') != 'default') {
Ian Zerny324d7612019-03-20 10:52:28 +01002246 println "NOTE: Running with non default vm: " + project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002247 systemProperty 'dex_vm', project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002248 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002249
Ian Zerny324d7612019-03-20 10:52:28 +01002250 // Forward runtime configurations for test parameters.
2251 if (project.hasProperty('runtimes')) {
2252 println "NOTE: Running with runtimes: " + project.property('runtimes')
2253 systemProperty 'runtimes', project.property('runtimes')
Ian Zerny4dfd5a52019-03-12 07:56:11 +01002254 }
2255
Christoffer Quist Adamsen748e4662019-08-23 14:53:49 +02002256 if (project.hasProperty('slow_tests')) {
2257 systemProperty 'slow_tests', project.property('slow_tests')
2258 }
2259
Søren Gjesseef195772021-03-11 16:04:42 +01002260
2261 if (project.hasProperty('desugar_jdk_json_dir')) {
2262 systemProperty 'desugar_jdk_json_dir', project.property('desugar_jdk_json_dir')
2263 }
Søren Gjesse4a45f9b2021-02-11 14:05:29 +01002264 if (project.hasProperty('desugar_jdk_libs')) {
2265 systemProperty 'desugar_jdk_libs', project.property('desugar_jdk_libs')
2266 }
2267
Ian Zerny27ea4c72021-04-29 22:35:49 +02002268 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002269 if (project.hasProperty('print_times') || project.hasProperty('one_line_per_test')) {
2270 afterTest { desc, result ->
2271 def executionTime = (result.endTime - result.startTime) / 1000
2272 testTimes["${desc.name} [${desc.className}]"] = executionTime
2273 }
2274 afterSuite { desc, result ->
2275 // parent is null if all tests are done.
2276 if (desc.parent == null) {
2277 def sortedTimes = testTimes.sort({ e1, e2 -> e2.value <=> e1.value })
2278 sortedTimes.eachWithIndex { key, value, i ->
2279 if (i < numberOfTestTimesToPrint) println "$key: $value"
2280 }
2281 }
2282 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002283 }
Rico Windf2f4c292021-04-23 07:06:13 +02002284
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002285 if (project.hasProperty('one_line_per_test')) {
2286 beforeTest { desc ->
2287 println "Start executing test ${desc.name} [${desc.className}]"
Rico Windf88b6be2018-12-11 15:14:05 +01002288 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002289
2290 afterTest { desc, result ->
2291 if (result.resultType == TestResult.ResultType.FAILURE) {
2292 printStackTrace(result)
2293 }
2294 if (project.hasProperty('update_test_timestamp')) {
2295 file(project.getProperty('update_test_timestamp')).text = new Date().getTime()
2296 }
2297 println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
Rico Windda6836e2018-12-07 12:32:03 +01002298 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002299 } else {
2300 afterTest { desc, result ->
2301 if (result.resultType == TestResult.ResultType.FAILURE) {
2302 printStackTrace(result)
2303 }
Rico Windf88b6be2018-12-11 15:14:05 +01002304 }
2305 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002306 }
2307 if (project.hasProperty('no_internal')) {
2308 exclude "com/android/tools/r8/internal/**"
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02002309 } else {
2310 dependsOn buildExamplesProto
Mads Ager418d1ca2017-05-22 09:35:49 +02002311 }
2312 if (project.hasProperty('only_internal')) {
2313 include "com/android/tools/r8/internal/**"
2314 }
Rico Wind4e218292019-03-07 12:44:49 +01002315
Rico Windba151112020-10-01 08:16:33 +02002316 if (project.hasProperty('test_namespace')) {
2317 include "com/android/tools/r8/" + project.getProperty('test_namespace') + "/**"
2318 }
2319
Mads Ager418d1ca2017-05-22 09:35:49 +02002320 if (project.hasProperty('tool')) {
2321 if (project.property('tool') == 'r8') {
Rico Windf02167a2019-03-15 12:27:03 +01002322 exclude "com/android/tools/r8/jctf/**"
Tamas Kenezcfb2c052018-10-12 11:03:57 +02002323 } else if (project.property('tool') == 'd8') {
Rico Windf02167a2019-03-15 12:27:03 +01002324 if (project.hasProperty('only_jctf')) {
2325 include "com/android/tools/r8/jctf/d8/**"
2326 } else {
Rico Wind819f7c52019-03-20 09:44:27 +01002327 // Don't run anything, deprecated
2328 println "Running with deprecated tool d8, not running any tests"
2329 include ""
Rico Windf02167a2019-03-15 12:27:03 +01002330 }
Tamas Kenezcfb2c052018-10-12 11:03:57 +02002331 } else {
2332 assert(project.property('tool') == 'r8cf')
Rico Windf02167a2019-03-15 12:27:03 +01002333 assert(project.hasProperty('only_jctf'))
2334 include "com/android/tools/r8/jctf/r8cf/**"
Mads Ager418d1ca2017-05-22 09:35:49 +02002335 }
2336 }
2337 if (!project.hasProperty('all_tests')) {
2338 exclude "com/android/tools/r8/art/dx/**"
Mads Ager418d1ca2017-05-22 09:35:49 +02002339 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002340 if (!project.hasProperty('jctf') && !project.hasProperty('only_jctf')) {
Stephan Herhutea6ee582017-05-23 13:14:34 +02002341 exclude "com/android/tools/r8/jctf/**"
Mads Ager418d1ca2017-05-22 09:35:49 +02002342 }
Rico Wind8e2f7e42019-02-21 10:13:21 +01002343 if (project.hasProperty('shard_count') ) {
2344 assert project.hasProperty('shard_number')
2345 int shard_count = project.getProperty('shard_count') as Integer
2346 int shard_number = project.getProperty('shard_number') as Integer
2347 assert shard_count < 65536
2348 assert shard_number < shard_count
2349 exclude {
2350 entry ->
2351 // Don't leave out directories. Leaving out a directory means all entries below.
2352 if (entry.file.isDirectory()) {
2353 return false
2354 }
2355 def first4 = entry.getRelativePath().toString().md5().substring(0, 4)
2356 int hash = Integer.parseInt(first4, 16)
2357 return hash % shard_count != shard_number
2358 }
2359 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002360 if (project.hasProperty('jctf_compile_only')) {
2361 println "JCTF: compiling only"
2362 systemProperty 'jctf_compile_only', '1'
2363 }
Tamas Kenezb77b7d82017-08-17 14:05:16 +02002364 if (project.hasProperty('test_dir')) {
2365 systemProperty 'test_dir', project.property('test_dir')
2366 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002367 if (project.hasProperty('r8lib')) {
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002368 dependsOn configureTestForR8Lib
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002369 // R8lib should be used instead of the main output and all the tests in
2370 // r8 should be mapped and exists in r8LibTestPath.
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02002371 classpath = sourceSets.test.runtimeClasspath.filter {
2372 !it.getAbsolutePath().contains("/build/")
2373 }
2374 classpath += files([r8LibPath, r8LibTestPath])
Ian Zerny5fffb0a2019-02-11 13:54:22 +01002375 testClassesDirs = files(r8LibTestPath)
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002376 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002377 if (OperatingSystem.current().isLinux()
2378 || OperatingSystem.current().isMacOsX()
2379 || OperatingSystem.current().isWindows()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002380 if (OperatingSystem.current().isMacOsX()) {
2381 logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " +
2382 "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " +
2383 "See tools/docker/README.md for details.")
2384 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002385 if (OperatingSystem.current().isWindows()) {
2386 logger.lifecycle("WARNING: Testing in only partially supported on Windows. " +
2387 "Art only runs on Linux and tests requiring Art will be skipped")
2388 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002389 dependsOn downloadDeps
2390 dependsOn buildExamples
Sebastien Hertzd3313772018-01-16 14:12:37 +01002391 dependsOn buildKotlinR8TestResources
Mads Ager418d1ca2017-05-22 09:35:49 +02002392 dependsOn buildSmali
2393 dependsOn jctfCommonJar
2394 dependsOn jctfTestsClasses
2395 dependsOn buildDebugInfoExamplesDex
2396 dependsOn buildPreNJdwpTestsJar
Mathias Ravcd795072018-03-22 12:47:32 +01002397 dependsOn buildPreNJdwpTestsDex
clementbera4f9c2a92019-07-09 08:50:37 +02002398 dependsOn buildJdk11TimeTestsJar
clementberaa92e3cd2019-07-12 14:13:22 +02002399 dependsOn provideArtFrameworksDependencies
Mads Ager418d1ca2017-05-22 09:35:49 +02002400 } else {
2401 logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002402 "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.")
Mads Ager418d1ca2017-05-22 09:35:49 +02002403 }
2404}
2405
2406// The Art tests we use for R8 are pre-build and downloaded from Google Cloud Storage.
2407//
2408// To build and upload a new set of the Art tests for use with R8 follow these steps:
2409//
2410// First of all an Android checkout is required. Currently it must be located
2411// in $HOME/android/master.
2412//
2413// TODO(ricow): simplify this
2414//
2415// Before: update the checked in art, see scripts/update-host-art.sh
2416//
2417// 1. Get an android checkout in $HOME/android/master and apply the patch from
2418// https://android-review.googlesource.com/#/c/294187/
2419//
2420// 2. run the following commands in the Android checkout directory:
2421//
2422// source build/envsetup.sh
Søren Gjesse34b77732017-07-07 13:56:21 +02002423// lunch aosp_angler-userdebug # or lunch aosp_angler-eng
2424// m desugar
2425// m -j30 test-art-host
2426// DESUGAR=false ANDROID_COMPILE_WITH_JACK=false art/test.py --host -t 001-HelloWorld
2427//
2428// Without running the test.py command the classes.jar file used by desugar in
2429// $HOME/android/master/out/host/common/obj/JAVA_LIBRARIES/core-oj-hostdex_intermediates/
2430// seems to be missing - there is probably also a make target to build it more directly
Mads Ager418d1ca2017-05-22 09:35:49 +02002431//
2432// 3. In the R8 project root directory, make sure we have a clean state before starting:
2433// tools/gradle.py downloadDeps
2434// tools/gradle.py clean
2435// rm -rf tests/art
2436//
2437// 4. Now build in the R8 checkout (-P hack to not generate dirs when not running this target)
Søren Gjesse34b77732017-07-07 13:56:21 +02002438// Make sure you have smali on your path, please use the build binary in the
2439// out/host/linux-x86/bin directory of the android checkout. Currently this is version pre 2.2.1,
2440// if that is updated the call to smali in "task "${smaliToDexTask}"(type: Exec)" below might
2441// need to change as smali got a completely new command line interface in version 2.2.1.
Mikaël Peltiere116cb62017-10-05 10:50:30 +02002442// After Android O, Jack is no longer alive, do not forget to uncomment call to buildArtTest for
2443// Jack if you build an android version using Jack.
Mads Ager418d1ca2017-05-22 09:35:49 +02002444//
Søren Gjesse34b77732017-07-07 13:56:21 +02002445// PATH=$HOME/android/master/out/host/linux-x86/bin:$PATH tools/gradle.py -Pandroid_source buildArtTests
Mads Ager418d1ca2017-05-22 09:35:49 +02002446//
2447// 4a. If any failures are produced in step 4, figure out what went wrong and add an entry in
2448// skippedTests with an explanation. Rerun from step 3.
2449//
2450// 5. Run the tests:
2451// tools/gradle.py clean
2452// tools/test.py
2453//
Søren Gjesse34b77732017-07-07 13:56:21 +02002454// 5a. If any more tests fail, either fix the issue or add them to the failuresToTriage list (note
2455// that you need to change "_" to "-" from stdout). Rerun from step 5 if anything was added to
2456// failuresToTriage.
Mads Ager418d1ca2017-05-22 09:35:49 +02002457//
Søren Gjesse34b77732017-07-07 13:56:21 +02002458// 6. To upload a new version to Google Cloud Storage:
Mads Ager418d1ca2017-05-22 09:35:49 +02002459// cd tests
2460// upload_to_google_storage.py -a --bucket r8-deps art
Søren Gjesse34b77732017-07-07 13:56:21 +02002461//
2462// 7. Update the manifest file describing the Android repo used:
2463// repo manifest -o <r8-checkout-root>/tools/linux/aosp_master_manifest.xml -r
Mads Ager418d1ca2017-05-22 09:35:49 +02002464
Mads Ager418d1ca2017-05-22 09:35:49 +02002465def androidCheckoutDir = file("${System.env.HOME}/android/master")
Mads Ager418d1ca2017-05-22 09:35:49 +02002466
2467def artTestDir = file("${androidCheckoutDir}/art/test")
2468
2469if (project.hasProperty('android_source')) {
2470 task buildArtTests {
2471 outputs.upToDateWhen { false }
2472 def toBeTriaged = [
2473 "903-hello-tagging",
2474 "904-object-allocation",
2475 "905-object-free",
2476 "906-iterate-heap",
2477 "907-get-loaded-classes",
2478 "908-gc-start-finish",
2479 "954-invoke-polymorphic-verifier",
2480 "955-methodhandles-smali",
2481 "596-monitor-inflation",
2482 ]
2483 def skippedTests = toBeTriaged + [
2484 // This test produces no jar.
2485 "000-nop",
2486 // This does not build, as it tests the error when the application exceeds more
2487 // than 65536 methods
2488 "089-many-methods",
2489 // Requires some jack beta jar
2490 "956-methodhandles",
2491 ]
2492
2493 def skippedTestsDx = [
2494 // Tests with custom build scripts, where javac is not passed the options
2495 // -source 1.7 -target 1.7.
2496 "462-checker-inlining-across-dex-files",
2497 "556-invoke-super",
2498 "569-checker-pattern-replacement",
2499 // These tests use jack even when --build-with-javac-dx is specified.
2500 "004-JniTest",
2501 "048-reflect-v8",
2502 "146-bad-interface",
2503 "563-checker-invoke-super",
2504 "580-checker-string-fact-intrinsics", // java.lang.StringFactory
2505 "604-hot-static-interface",
2506 "957-methodhandle-transforms",
2507 "958-methodhandle-emulated-stackframe",
2508 "959-invoke-polymorphic-accessors",
2509 "961-default-iface-resolution-gen",
2510 "962-iface-static",
2511 "963-default-range-smali",
2512 "964-default-iface-init-gen",
2513 "965-default-verify",
2514 "966-default-conflict",
2515 "967-default-ame",
2516 "968-default-partial-compile-gen",
2517 "969-iface-super",
2518 "970-iface-super-resolution-gen",
2519 "971-iface-super",
2520 // These tests does not build with --build-with-javac-dx
2521 "004-NativeAllocations", // Javac error
2522 "031-class-attributes",
2523 "138-duplicate-classes-check",
2524 "157-void-class", // Javac error
2525 "580-checker-string-factory-intrinsics",
2526 "612-jit-dex-cache",
2527 "613-inlining-dex-cache",
2528 "900-hello-plugin", // --experimental agents
2529 "901-hello-ti-agent", // --experimental agents
2530 "902-hello-transformation", // --experimental agents
2531 "909-attach-agent", // --experimental agents
2532 "946-obsolete-throw", // -source 1.7 -target 1.7, but use lambda
2533 "950-redefine-intrinsic", // -source 1.7 -target 1.7, but use method references
2534 "951-threaded-obsolete", // -source 1.7 -target 1.7, but use lambda
2535 "960-default-smali", // --experimental default-methods
2536 // These tests force the build to use jack
2537 "953-invoke-polymorphic-compiler",
2538 "958-methodhandle-stackframe",
2539 ]
2540
2541 def artTestBuildDir = file("${projectDir}/tests/art")
2542
2543 if (androidCheckoutDir.exists()) {
2544 dependsOn downloadDeps
2545 artTestBuildDir.mkdirs()
Mads Ager418d1ca2017-05-22 09:35:49 +02002546 artTestDir.eachDir { dir ->
2547 def name = dir.getName();
2548 def markerFile = dir.toPath().resolve("info.txt").toFile();
2549 if (markerFile.exists() && !(name in skippedTests)) {
2550 if (!(name in skippedTestsDx)) {
Rico Windde2af6c2019-03-26 15:21:08 +01002551 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir);
Mads Ager418d1ca2017-05-22 09:35:49 +02002552 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002553 }
2554 }
2555 }
2556 doFirst {
2557 if (!androidCheckoutDir.exists()) {
2558 throw new InvalidUserDataException(
2559 "This task requires an Android checkout in ${androidCheckoutDir}");
Mads Ager418d1ca2017-05-22 09:35:49 +02002560 }
2561 }
2562 doLast {
2563 copy {
2564 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest64")
2565 into file("${artTestBuildDir}/lib64")
2566 include 'lib*.so'
2567 }
2568 copy {
2569 from file("${androidCheckoutDir}/out/host/linux-x86/lib64")
2570 into file("${artTestBuildDir}/lib64")
2571 include 'libart.so'
2572 include 'libbacktrace.so'
2573 include 'libbase.so'
2574 include 'libc++.so'
2575 include 'libcutils.so'
2576 include 'liblz4.so'
2577 include 'liblzma.so'
2578 include 'libnativebridge.so'
2579 include 'libnativeloader.so'
2580 include 'libsigchain.so'
2581 include 'libunwind.so'
2582 include 'libziparchive.so'
2583 }
2584 copy {
2585 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest")
2586 into file("${artTestBuildDir}/lib")
2587 include 'lib*.so'
2588 }
2589 copy {
2590 from file("${androidCheckoutDir}/out/host/linux-x86/lib")
2591 into file("${artTestBuildDir}/lib")
2592 include 'libart.so'
2593 include 'libbacktrace.so'
2594 include 'libbase.so'
2595 include 'libc++.so'
2596 include 'libcutils.so'
2597 include 'liblz4.so'
2598 include 'liblzma.so'
2599 include 'libnativebridge.so'
2600 include 'libnativeloader.so'
2601 include 'libsigchain.so'
2602 include 'libunwind.so'
2603 include 'libziparchive.so'
2604 }
2605 }
2606 }
2607}
2608
Rico Windde2af6c2019-03-26 15:21:08 +01002609def buildArtTest(androidCheckoutDir, artTestBuildDir, dir) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002610 def artTestDir = file("${androidCheckoutDir}/art/test")
2611 def artRunTestScript = file("${artTestDir}/run-test")
2612 def dxExecutable = new File("tools/linux/dx/bin/dx");
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02002613 def dexMergerExecutable = Utils.dexMergerExecutable()
Mads Ager418d1ca2017-05-22 09:35:49 +02002614
Søren Gjesse34b77732017-07-07 13:56:21 +02002615 def name = dir.getName()
Rico Windde2af6c2019-03-26 15:21:08 +01002616 def buildTask = "build_art_test_dx_${name}"
2617 def sanitizeTask = "sanitize_art_test_dx_${name}"
2618 def copyCheckTask = "copy_check_art_test_dx_${name}"
2619 def smaliToDexTask = "smali_to_dex_dx_${name}"
Mads Ager418d1ca2017-05-22 09:35:49 +02002620
2621 def buildInputs = fileTree(dir: dir, include: '**/*')
Rico Windde2af6c2019-03-26 15:21:08 +01002622 def testDir = file("${artTestBuildDir}/dx/${name}")
Mads Ager418d1ca2017-05-22 09:35:49 +02002623 def outputJar = testDir.toPath().resolve("${name}.jar").toFile()
2624 testDir.mkdirs()
Rico Windde2af6c2019-03-26 15:21:08 +01002625 task "$buildTask"(type: Exec) {
2626 outputs.upToDateWhen { false }
2627 inputs.file buildInputs
2628 executable "${artRunTestScript}"
2629 args "--host"
2630 args "--build-only"
2631 args "--build-with-javac-dx"
2632 args "--output-path", "${testDir}"
2633 args "${name}"
2634 environment DX: "${dxExecutable.absolutePath}"
2635 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
2636 environment ANDROID_BUILD_TOP: "${androidCheckoutDir}"
2637 outputs.file outputJar
Mads Ager418d1ca2017-05-22 09:35:49 +02002638 }
2639 task "${sanitizeTask}"(type: Exec, dependsOn: buildTask) {
2640 outputs.upToDateWhen { false }
2641 executable "/bin/bash"
2642 args "-c"
2643 args "rm -rf ${testDir}/smali_*.dex ${testDir}/*-ex.dex ${testDir}/*-ex.jar" +
2644 " ${testDir}/classes-ex ${testDir}/check"
2645 }
2646
2647 task "${smaliToDexTask}"(type: Exec) {
Mikaël Peltiere116cb62017-10-05 10:50:30 +02002648 // Directory that contains smali files is either smali, or smali/art
2649 def smali_dir = file("${dir}/smali/art")
2650 if (smali_dir.exists()) {
2651 workingDir "${testDir}/smali/art"
2652 } else {
2653 workingDir "${testDir}/smali"
2654 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002655 executable "/bin/bash"
Søren Gjesse34b77732017-07-07 13:56:21 +02002656 // This is the command line options for smali prior to 2.2.1, where smali got a new
2657 // command line interface.
2658 args "-c", "smali a *.smali"
2659 // This is the command line options for smali 2.2.1 and later.
2660 // args "-c", "smali -o out.dex *.smali"
Mads Ager418d1ca2017-05-22 09:35:49 +02002661 }
2662
2663 task "${copyCheckTask}"(type: Copy, dependsOn: sanitizeTask) {
2664 def smali_dir = file("${dir}/smali")
2665 outputs.upToDateWhen { false }
Rico Windde2af6c2019-03-26 15:21:08 +01002666 if (smali_dir.exists()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002667 dependsOn smaliToDexTask
2668 }
2669 from("${artTestDir}/${name}") {
2670 include 'check'
2671 }
2672 into testDir
2673 }
2674
2675 return copyCheckTask
2676}
2677
2678task javadocD8(type: Javadoc) {
Ian Zerny850f13d2018-01-04 11:25:38 +01002679 title "D8 API"
Mads Ager418d1ca2017-05-22 09:35:49 +02002680 classpath = sourceSets.main.compileClasspath
2681 source = sourceSets.main.allJava
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002682 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002683 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002684 include '**/com/android/tools/r8/BaseCommand.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002685 include '**/com/android/tools/r8/BaseCompilerCommand.java'
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002686 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002687 include '**/com/android/tools/r8/CompilationFailedException.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002688 include '**/com/android/tools/r8/CompilationMode.java'
2689 include '**/com/android/tools/r8/D8.java'
2690 include '**/com/android/tools/r8/D8Command.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002691 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2692 include '**/com/android/tools/r8/DexFilePerClassFileConsumer.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002693 include '**/com/android/tools/r8/Diagnostic.java'
2694 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002695 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2696 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002697 include '**/com/android/tools/r8/ProgramConsumer.java'
2698 include '**/com/android/tools/r8/ProgramResource.java'
2699 include '**/com/android/tools/r8/ProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002700 include '**/com/android/tools/r8/Resource.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002701 include '**/com/android/tools/r8/ResourceException.java'
2702 include '**/com/android/tools/r8/StringConsumer.java'
2703 include '**/com/android/tools/r8/StringResource.java'
2704 include '**/com/android/tools/r8/Version.java'
2705 include '**/com/android/tools/r8/origin/*.java'
2706}
2707
2708task javadocR8(type: Javadoc) {
2709 title "R8 API"
2710 classpath = sourceSets.main.compileClasspath
2711 source = sourceSets.main.allJava
2712 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
2713 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
2714 include '**/com/android/tools/r8/BaseCommand.java'
2715 include '**/com/android/tools/r8/BaseCompilerCommand.java'
2716 include '**/com/android/tools/r8/ClassFileConsumer.java'
2717 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
2718 include '**/com/android/tools/r8/CompilationFailedException.java'
2719 include '**/com/android/tools/r8/CompilationMode.java'
2720 include '**/com/android/tools/r8/R8.java'
2721 include '**/com/android/tools/r8/R8Command.java'
2722 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2723 include '**/com/android/tools/r8/Diagnostic.java'
2724 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002725 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2726 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002727 include '**/com/android/tools/r8/ProgramConsumer.java'
2728 include '**/com/android/tools/r8/ProgramResource.java'
2729 include '**/com/android/tools/r8/ProgramResourceProvider.java'
2730 include '**/com/android/tools/r8/Resource.java'
2731 include '**/com/android/tools/r8/ResourceException.java'
2732 include '**/com/android/tools/r8/StringConsumer.java'
2733 include '**/com/android/tools/r8/StringResource.java'
2734 include '**/com/android/tools/r8/Version.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002735 include '**/com/android/tools/r8/origin/*.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002736}
Søren Gjesse39a909a2017-10-12 09:49:20 +02002737
2738task copyMavenDeps(type: Copy) {
2739 from configurations.compile into "$buildDir/deps"
Morten Krogh-Jespersen75773302019-01-07 09:45:08 +01002740 from configurations.compileClasspath into "$buildDir/deps"
Søren Gjesse39a909a2017-10-12 09:49:20 +02002741 from configurations.testCompile into "$buildDir/deps"
2742}
Mikaël Peltier61633d42017-10-13 16:51:06 +02002743
Rico Wind23a05112019-03-27 08:00:44 +01002744task printMavenDeps {
2745 // Only actually print to stdout when we are updating.
2746 if (project.hasProperty('updatemavendeps')) {
2747 for (Configuration config : configurations) {
2748 if (!config.isCanBeResolved()) {
2749 continue
2750 }
2751 def componentIds = config.incoming.resolutionResult.allDependencies.collect {
2752 it.selected.id
2753 }
2754 def result = dependencies.createArtifactResolutionQuery()
2755 .forComponents(componentIds)
2756 .withArtifacts(MavenModule, MavenPomArtifact)
2757 .execute()
2758 for (component in result.resolvedComponents) {
2759 component.getArtifacts(MavenPomArtifact).each {
2760 println "POM: ${it.file} ${component.id}"
2761 }
2762 }
2763 config.each {
2764 println "JAR: ${it}"
2765 }
2766 }
2767 }
2768}
Ian Zerny9713c032020-01-23 11:41:58 +01002769
2770allprojects {
2771 tasks.withType(Exec) {
2772 doFirst {
Ian Zerny9794cfd2020-02-04 07:57:35 +01002773 println commandLine.join(' ')
Ian Zerny9713c032020-01-23 11:41:58 +01002774 }
2775 }
Søren Gjesse494609e2020-05-29 15:35:12 +02002776}