blob: 50fda5f7080c1cb408cb25ccf952a04872f919e4 [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
Clément Bérac8b2c152022-06-22 08:23:47 +02007import desugaredlibrary.CustomConversionAsmRewriterTask
Ian Zerny5fffb0a2019-02-11 13:54:22 +01008import net.ltgt.gradle.errorprone.CheckSeverity
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02009import org.gradle.internal.os.OperatingSystem
Jake Wharton2d7aab82019-09-13 10:24:26 -040010import smali.SmaliTask
Ian Zernyb2d27c42019-02-20 09:09:41 +010011import tasks.DownloadDependency
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +000012import tasks.GetJarsFromConfiguration
Stephan Herhut417a72a2017-07-18 10:38:30 +020013import utils.Utils
Mads Ager418d1ca2017-05-22 09:35:49 +020014
Ian Zerny5fffb0a2019-02-11 13:54:22 +010015buildscript {
16 repositories {
Rico Wind23a05112019-03-27 08:00:44 +010017 maven {
Rico Wind70d614f2020-01-31 08:45:21 +010018 url 'https://storage.googleapis.com/r8-deps/maven_mirror/'
Rico Wind23a05112019-03-27 08:00:44 +010019 }
Ian Zerny5fffb0a2019-02-11 13:54:22 +010020 mavenCentral()
Jake Wharton5e5b5232019-09-17 16:13:32 -040021 gradlePluginPortal()
Morten Krogh-Jespersen68cc4b62019-03-21 10:32:17 +010022 jcenter()
Ian Zerny5fffb0a2019-02-11 13:54:22 +010023 }
Ian Zerny5fffb0a2019-02-11 13:54:22 +010024}
25
26plugins {
27 id "net.ltgt.errorprone" version "0.7"
28}
29
30apply plugin: 'java'
31apply plugin: 'idea'
32
Sebastien Hertz143ed112018-02-13 14:26:41 +010033ext {
34 androidSupportVersion = '25.4.0'
Clément Bérac8b2c152022-06-22 08:23:47 +020035 asmVersion = '9.3' // When updating update tools/asmifier.py, build.src and Toolhelper as well.
Sebastien Hertz143ed112018-02-13 14:26:41 +010036 espressoVersion = '3.0.0'
37 fastutilVersion = '7.2.0'
Søren Gjessea93b4262021-12-08 14:40:10 +010038 guavaVersion = '30.1.1-jre'
Sebastien Hertz143ed112018-02-13 14:26:41 +010039 joptSimpleVersion = '4.6'
Mads Ager48dd79e2018-05-15 09:13:55 +020040 gsonVersion = '2.7'
Morten Krogh-Jespersen94ff6762019-03-20 14:45:23 +010041 junitVersion = '4.13-beta-2'
Jinseong Jeone11145f2018-12-13 10:57:29 -080042 mockitoVersion = '2.10.0'
Morten Krogh-Jespersen358c8a72021-02-24 11:07:57 +010043 // The kotlin version is only here to specify the kotlin language level,
44 // all kotlin compilations are done in tests.
Morten Krogh-Jespersenc9e17cb2021-11-30 08:22:54 +010045 kotlinVersion = '1.6.0'
Morten Krogh-Jespersen8fac8cf2021-12-02 09:58:01 +010046 kotlinExtMetadataJVMVersion = '0.4.1'
Sebastien Hertz143ed112018-02-13 14:26:41 +010047 smaliVersion = '2.2b4'
Ian Zerny5fffb0a2019-02-11 13:54:22 +010048 errorproneVersion = '2.3.2'
clementbera4f9c2a92019-07-09 08:50:37 +020049 testngVersion = '6.10'
Sebastien Hertz143ed112018-02-13 14:26:41 +010050}
51
Mads Ager418d1ca2017-05-22 09:35:49 +020052repositories {
Rico Wind23a05112019-03-27 08:00:44 +010053 maven {
Rico Wind70d614f2020-01-31 08:45:21 +010054 url 'https://storage.googleapis.com/r8-deps/maven_mirror/'
Rico Wind23a05112019-03-27 08:00:44 +010055 }
Jake Wharton5e5b5232019-09-17 16:13:32 -040056 google()
Mads Ager418d1ca2017-05-22 09:35:49 +020057 mavenCentral()
58}
59
Jinseong Jeon05064e12018-07-03 00:21:12 -070060if (project.hasProperty('with_code_coverage')) {
61 apply plugin: 'jacoco'
62}
63
Mads Ager418d1ca2017-05-22 09:35:49 +020064// Custom source set for example tests and generated tests.
65sourceSets {
Morten Krogh-Jespersen4e10d682022-05-05 15:57:47 +020066 main {
67 java {
68 srcDirs = ['src/main/java']
69 }
70 resources {
71 srcDirs "third_party/api_database/api_database"
72 }
73 }
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +020074 main11 {
75 java {
76 srcDirs = ['src/main/java']
77 }
Morten Krogh-Jespersen798aac02021-10-06 15:32:20 +020078 resources {
Morten Krogh-Jespersen4e10d682022-05-05 15:57:47 +020079 srcDirs "third_party/api_database/api_database"
Morten Krogh-Jespersen798aac02021-10-06 15:32:20 +020080 }
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +020081 }
Mads Ager418d1ca2017-05-22 09:35:49 +020082 test {
83 java {
84 srcDirs = [
clementbera0fe940d2019-04-23 12:45:18 +020085 'src/test/java',
86 'build/generated/test/java',
87 ]
88 }
89 }
Yohann Rousselbb571622017-11-09 10:47:36 +010090 apiUsageSample {
91 java {
Mathias Rave3f3c522018-05-30 08:22:17 +020092 srcDirs = ['src/test/apiUsageSample', 'src/main/java']
93 include 'com/android/tools/apiusagesample/*.java'
94 include 'com/android/tools/r8/BaseCompilerCommandParser.java'
95 include 'com/android/tools/r8/D8CommandParser.java'
96 include 'com/android/tools/r8/R8CommandParser.java'
97 include 'com/android/tools/r8/utils/FlagFile.java'
Yohann Rousselbb571622017-11-09 10:47:36 +010098 }
Yohann Rousselbb571622017-11-09 10:47:36 +010099 }
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +0100100 cfSegments {
101 java {
102 srcDirs = ['third_party/classlib/java', 'src/cf_segments/java']
103 }
104 output.resourcesDir = 'build/classes/cfSegments'
105 }
Søren Gjesse17fc67d2019-12-04 14:50:17 +0100106 libraryDesugarConversions {
107 java {
108 srcDirs = ['src/library_desugar/java']
109 }
110 output.resourcesDir = 'build/classes/library_desugar_conversions'
111 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200112 debugTestResources {
113 java {
114 srcDirs = ['src/test/debugTestResources']
115 }
116 output.resourcesDir = 'build/classes/debugTestResources'
117 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +0200118 debugTestResourcesJava8 {
119 java {
120 srcDirs = ['src/test/debugTestResourcesJava8']
121 }
122 output.resourcesDir = 'build/classes/debugTestResourcesJava8'
123 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200124 examples {
125 java {
Ivan Gavrilovic664f34d2018-11-09 10:02:40 -0800126 srcDirs = ['src/test/examples']
Mads Ager418d1ca2017-05-22 09:35:49 +0200127 }
128 output.resourcesDir = 'build/classes/examples'
129 }
Ian Zernyd3020482019-04-25 07:05:04 +0200130 examplesJava9 {
131 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200132 srcDirs = ['src/test/examplesJava9']
Ian Zernyd3020482019-04-25 07:05:04 +0200133 }
134 }
Jake Wharton2000b2f2019-12-11 20:37:49 -0500135 examplesJava10 {
136 java {
137 srcDirs = ['src/test/examplesJava10']
138 }
139 }
Ian Zernyd3020482019-04-25 07:05:04 +0200140 examplesJava11 {
141 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200142 srcDirs = ['src/test/examplesJava11']
143 }
144 }
Søren Gjessee9966932021-09-15 17:08:37 +0200145 examplesJava17 {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100146 java {
Søren Gjessee9966932021-09-15 17:08:37 +0200147 srcDirs = ['src/test/examplesJava17']
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100148 }
149 }
Søren Gjessed1e08992022-02-07 16:46:31 +0100150 examplesJava18 {
151 java {
152 srcDirs = ['src/test/examplesJava18']
153 }
154 }
clementberaefa10522019-07-11 11:20:46 +0200155 examplesTestNGRunner {
clementbera4f9c2a92019-07-09 08:50:37 +0200156 java {
157 srcDirs = ['src/test/testngrunner']
158 }
159 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200160 examplesAndroidN {
161 java {
162 srcDirs = ['src/test/examplesAndroidN']
163 }
164 output.resourcesDir = 'build/classes/examplesAndroidN'
165 }
166 examplesAndroidO {
167 java {
168 srcDirs = ['src/test/examplesAndroidO']
169 }
170 output.resourcesDir = 'build/classes/examplesAndroidO'
171 }
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +0200172 examplesAndroidP {
173 java {
174 srcDirs = ['src/test/examplesAndroidP']
175 }
176 output.resourcesDir = 'build/classes/examplesAndroidP'
177 }
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200178 examplesProto {
179 java {
180 srcDirs = ['src/test/examplesProto']
181 }
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +0200182 compileClasspath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
183 compileClasspath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200184 output.resourcesDir = 'build/classes/examplesProto'
185 }
Sebastien Hertzd3313772018-01-16 14:12:37 +0100186 kotlinR8TestResources {
187 java {
188 srcDirs = ['src/test/kotlinR8TestResources']
189 }
190 output.resourcesDir = 'build/classes/kotlinR8TestResources'
191 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200192}
193
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800194// Ensure importing into IntelliJ IDEA use the same output directories as Gradle. In tests we
195// use the output path for tests (ultimately through ToolHelper.getClassPathForTests()) and
196// therefore these paths need to be the same. See https://youtrack.jetbrains.com/issue/IDEA-175172
197// for context.
198idea {
199 sourceSets.all { SourceSet sources ->
200 module {
201 if (sources.name == "main") {
202 sourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100203 outputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800204 } else {
205 testSourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100206 testOutputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800207 }
208 }
209 }
210}
211
Yohann Roussel126f6872017-08-03 16:25:32 +0200212configurations {
213 supportLibs
214}
215
Mads Ager418d1ca2017-05-22 09:35:49 +0200216dependencies {
Mads Agerd1d0da92018-12-10 13:56:50 +0100217 implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion"
218 implementation "com.google.code.gson:gson:$gsonVersion"
Mads Ager0aa48052017-09-15 12:39:15 +0200219 // Include all of guava when compiling the code, but exclude annotations that we don't
220 // need from the packaging.
Sebastien Hertz143ed112018-02-13 14:26:41 +0100221 compileOnly("com.google.guava:guava:$guavaVersion")
Mads Agerd1d0da92018-12-10 13:56:50 +0100222 implementation("com.google.guava:guava:$guavaVersion", {
Mads Ager0aa48052017-09-15 12:39:15 +0200223 exclude group: 'com.google.errorprone'
224 exclude group: 'com.google.code.findbugs'
225 exclude group: 'com.google.j2objc'
226 exclude group: 'org.codehaus.mojo'
227 })
Mads Agerd1d0da92018-12-10 13:56:50 +0100228 implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
229 implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
230 implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
231 implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
232 implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
233 implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
234 implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200235
236 main11Implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion"
237 main11Implementation "com.google.code.gson:gson:$gsonVersion"
238 // Include all of guava when compiling the code, but exclude annotations that we don't
239 // need from the packaging.
240 main11CompileOnly("com.google.guava:guava:$guavaVersion")
241 main11Implementation("com.google.guava:guava:$guavaVersion", {
242 exclude group: 'com.google.errorprone'
243 exclude group: 'com.google.code.findbugs'
244 exclude group: 'com.google.j2objc'
245 exclude group: 'org.codehaus.mojo'
246 })
247 main11Implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
248 main11Implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
249 main11Implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
250 main11Implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
251 main11Implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
252 main11Implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
253 main11Implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200254
clementberaefa10522019-07-11 11:20:46 +0200255 examplesTestNGRunnerCompile group: 'org.testng', name: 'testng', version: testngVersion
Ian Zerny161ff742022-01-20 12:39:40 +0100256
Mads Ager418d1ca2017-05-22 09:35:49 +0200257 testCompile sourceSets.examples.output
Sebastien Hertz143ed112018-02-13 14:26:41 +0100258 testCompile "junit:junit:$junitVersion"
Ian Zerny161ff742022-01-20 12:39:40 +0100259 testCompile "com.google.guava:guava:$guavaVersion"
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100260 testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
261 testCompile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100262 testCompile group: 'org.smali', name: 'smali', version: smaliVersion
Mads Ager418d1ca2017-05-22 09:35:49 +0200263 testCompile files('third_party/jasmin/jasmin-2.4.jar')
264 testCompile files('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
Jean-Marie Henaffce162f32017-10-04 10:39:27 +0200265 testCompile files('third_party/ddmlib/ddmlib.jar')
Ian Zerny161ff742022-01-20 12:39:40 +0100266 testCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
267 testCompile group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
268 testCompile group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
269 testCompile group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
270 testCompile group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
271 testCompile group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
272
Sebastien Hertz143ed112018-02-13 14:26:41 +0100273 examplesAndroidOCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
274 examplesAndroidPCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
Stephan Herhut52cb1022017-10-24 15:10:41 +0200275 // Import Guava for @Nullable annotation
Sebastien Hertz143ed112018-02-13 14:26:41 +0100276 examplesCompile "com.google.guava:guava:$guavaVersion"
Jinseong Jeone11145f2018-12-13 10:57:29 -0800277 examplesCompile "junit:junit:$junitVersion"
278 examplesCompile "org.mockito:mockito-core:$mockitoVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100279 supportLibs "com.android.support:support-v4:$androidSupportVersion"
280 supportLibs "junit:junit:$junitVersion"
281 supportLibs "com.android.support.test.espresso:espresso-core:$espressoVersion"
Yohann Rousselbb571622017-11-09 10:47:36 +0100282 apiUsageSampleCompile sourceSets.main.output
Tamas Kenezb865eee2018-12-03 16:50:45 +0100283 apiUsageSampleCompile "com.google.guava:guava:$guavaVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100284 kotlinR8TestResourcesCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100285 errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")
Stephan Herhut417a72a2017-07-18 10:38:30 +0200286}
287
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100288def r8LibPath = "$buildDir/libs/r8lib.jar"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +0100289def r8LibExludeDepsPath = "$buildDir/libs/r8lib-exclude-deps.jar"
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200290def r8DesugaredPath = "$buildDir/libs/r8desugared.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100291def r8LibGeneratedKeepRulesPath = "$buildDir/generated/keep.txt"
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +0100292def r8LibTestPath = "$buildDir/classes/r8libtest"
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +0200293def java11ClassFiles = "$buildDir/classes/java/mainJava11"
294def r8RetracePath = "$buildDir/libs/r8retrace.jar"
295def r8RetraceExludeDepsPath = "$buildDir/libs/r8retrace-exclude-deps.jar"
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100296
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200297def osString = OperatingSystem.current().isLinux() ? "linux" :
298 OperatingSystem.current().isMacOsX() ? "mac" : "windows"
Mads Ager418d1ca2017-05-22 09:35:49 +0200299
300def cloudDependencies = [
301 "tests" : [
mikaelpeltierc2aa6652017-10-06 12:53:37 +0200302 "2017-10-04/art",
Rico Wind132bfb42019-03-08 09:27:36 +0100303 "2016-12-19/art"
Mads Ager418d1ca2017-05-22 09:35:49 +0200304 ],
305 "third_party": [
Rico Windf72fa152018-10-22 15:41:03 +0200306 "android_cts_baseline",
Morten Krogh-Jespersena31c3442022-06-02 21:07:50 +0200307 "android_jar/libcore_latest",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200308 "android_jar/lib-v14",
Stephan Herhutb3aca8b2017-12-22 14:14:53 +0100309 "android_jar/lib-v15",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200310 "android_jar/lib-v19",
311 "android_jar/lib-v21",
Stephan Herhutd48be0d2018-01-04 15:33:10 +0100312 "android_jar/lib-v22",
313 "android_jar/lib-v23",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200314 "android_jar/lib-v24",
315 "android_jar/lib-v25",
316 "android_jar/lib-v26",
Søren Gjessec2ffae82018-12-21 12:20:18 +0100317 "android_jar/lib-v27",
318 "android_jar/lib-v28",
Søren Gjesse02f52852019-09-04 17:44:03 +0200319 "android_jar/lib-v29",
Søren Gjessefa3f8042020-04-20 12:56:11 +0200320 "android_jar/lib-v30",
Søren Gjesse8c15ecd2021-03-22 16:41:53 +0100321 "android_jar/lib-v31",
Søren Gjesse29c8c5b2021-11-01 10:30:57 +0100322 "android_jar/lib-v32",
Søren Gjessea1f2c512022-02-04 09:51:45 +0100323 "android_jar/lib-v33",
Morten Krogh-Jespersen4e10d682022-05-05 15:57:47 +0200324 "api_database/api_database",
Morten Krogh-Jespersen7a47b732021-05-11 17:32:34 +0200325 "api-outlining/simple-app-dump",
Ian Zerny0d806882021-09-30 15:17:40 +0200326 "binary_compatibility_tests/compiler_api_tests",
Rico Windf72fa152018-10-22 15:41:03 +0200327 "core-lambda-stubs",
Søren Gjesse7dee79d2022-03-17 13:50:48 +0100328 "dagger/2.41",
Rico Windf72fa152018-10-22 15:41:03 +0200329 "dart-sdk",
330 "ddmlib",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200331 "gradle/gradle",
Christoffer Quist Adamsene1821392022-02-15 14:58:03 +0100332 "google/google-java-format/1.14.0",
Ian Zerny33c1c582019-09-17 12:43:45 +0200333 "google-java-format",
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +0200334 "iosched_2019",
Søren Gjesse97679312020-10-06 13:44:59 +0200335 "jacoco/0.8.2",
336 "jacoco/0.8.6",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200337 "jasmin",
Morten Krogh-Jespersen4187e162019-03-25 13:19:17 +0100338 "junit",
Rico Windf72fa152018-10-22 15:41:03 +0200339 "jdwp-tests",
Søren Gjesse70f75b12019-08-22 12:32:02 +0200340 "jsr223-api-1.0",
Søren Gjesse8f0e0992019-09-06 09:28:14 +0200341 "rhino-1.7.10",
Søren Gjessef6c0a782019-08-22 12:48:46 +0200342 "rhino-android-1.1.1",
Morten Krogh-Jespersenb328dc62020-05-12 09:11:52 +0200343 "kotlin/kotlin-compiler-1.3.11",
344 "kotlin/kotlin-compiler-1.3.41",
Morten Krogh-Jespersend32c8f22020-05-12 10:56:16 +0200345 "kotlin/kotlin-compiler-1.3.72",
Morten Krogh-Jespersen1c801b02021-02-11 10:15:23 +0100346 "kotlin/kotlin-compiler-1.4.20",
Morten Krogh-Jespersena9705f52021-07-05 11:28:02 +0200347 "kotlin/kotlin-compiler-1.5.0",
Morten Krogh-Jespersen61683192021-11-25 11:14:47 +0100348 "kotlin/kotlin-compiler-1.6.0",
Morten Krogh-Jespersen14153472020-05-19 15:40:47 +0200349 "kotlinx-coroutines-1.3.6",
Mathias Rav5285faf2018-03-20 14:16:32 +0100350 "openjdk/openjdk-rt-1.8",
Søren Gjesse952e1d52019-05-28 12:51:30 +0200351 "openjdk/desugar_jdk_libs",
Clément Béracac269b2021-03-17 07:53:43 +0000352 "openjdk/desugar_jdk_libs_11",
Ian Zernyc4598882022-02-25 19:26:44 +0100353 "openjdk/desugar_jdk_libs_legacy",
Søren Gjesse09c3dd02021-06-17 08:21:51 +0200354 "openjdk/desugar_jdk_libs_releases/1.0.9",
355 "openjdk/desugar_jdk_libs_releases/1.0.10",
356 "openjdk/desugar_jdk_libs_releases/1.1.0",
357 "openjdk/desugar_jdk_libs_releases/1.1.1",
358 "openjdk/desugar_jdk_libs_releases/1.1.5",
clementbera8dbfeda2019-07-03 11:24:13 +0200359 "openjdk/jdk-11-test",
Ian Zernye5886582022-03-03 11:01:08 +0100360 "opensource-apps/tivi",
Rico Windf72fa152018-10-22 15:41:03 +0200361 "proguard/proguard5.2.1",
362 "proguard/proguard6.0.1",
Ian Zerny7c920ac2020-07-01 20:12:01 +0200363 "proguard/proguard-7.0.0",
Morten Krogh-Jespersen0cade312022-03-22 13:40:21 +0000364 "retrace_benchmark",
Morten Krogh-Jespersen7cbae972021-08-31 16:54:31 +0200365 "retrace/binary_compatibility",
Ian Zernyfad3a3c2022-03-30 19:55:42 +0200366 "r8",
Ian Zernye0fd0242020-06-23 13:46:14 +0200367 "r8-releases/2.0.74",
Ian Zerny20d576f2022-03-28 19:16:38 +0200368 "r8-releases/3.2.54",
Morten Krogh-Jespersen1ba55f52020-04-24 12:49:17 +0200369 "r8mappings",
370 "tachiyomi"
Mads Ager418d1ca2017-05-22 09:35:49 +0200371 ],
372 // All dex-vms have a fixed OS of Linux, as they are only supported on Linux, and will be run in a Docker
373 // container on other platforms where supported.
374 "tools" : [
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200375 "linux/art",
376 "linux/art-5.1.1",
377 "linux/art-6.0.1",
378 "linux/art-7.0.0",
Søren Gjesse1528c022018-11-23 15:14:05 +0100379 "linux/art-8.1.0",
Søren Gjessefe7c0112018-12-03 12:33:12 +0100380 "linux/art-9.0.0",
clementbera97d5cce2019-11-22 15:09:27 +0100381 "linux/art-10.0.0",
Søren Gjesse953f7c42021-08-18 16:42:06 +0200382 "linux/host/art-12.0.0-beta4",
Søren Gjesse2ba0f3a2022-04-20 13:55:15 +0200383 "linux/host/art-13-dev",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200384 "linux/dalvik",
Stephan Herhut02f0f9d2018-01-04 10:27:31 +0100385 "linux/dalvik-4.0.4",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200386 "${osString}/dx",
Mads Ager418d1ca2017-05-22 09:35:49 +0200387 ]
388]
389
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100390def cloudSystemDependencies = [
391 linux: [
clementbera81738ec2019-04-11 11:32:31 +0200392 "third_party": ["openjdk/openjdk-9.0.4/linux",
clementberab4fa18d2019-04-12 09:09:40 +0200393 "openjdk/jdk8/linux-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100394 "openjdk/jdk-11/linux",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100395 "openjdk/jdk-17/linux",
396 "openjdk/jdk-18/linux"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100397 ],
398 osx: [
clementbera81738ec2019-04-11 11:32:31 +0200399 "third_party": ["openjdk/openjdk-9.0.4/osx",
clementberab4fa18d2019-04-12 09:09:40 +0200400 "openjdk/jdk8/darwin-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100401 "openjdk/jdk-11/osx",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100402 "openjdk/jdk-17/osx",
403 "openjdk/jdk-18/osx"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100404 ],
405 windows: [
clementberab4fa18d2019-04-12 09:09:40 +0200406 "third_party": ["openjdk/openjdk-9.0.4/windows",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100407 "openjdk/jdk-11/windows",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100408 "openjdk/jdk-17/windows",
409 "openjdk/jdk-18/windows"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100410 ],
411]
412
413if (OperatingSystem.current().isWindows()) {
414 cloudSystemDependencies.windows.each { entry ->
415 cloudDependencies.get(entry.key).addAll(entry.value)
416 }
417} else if (OperatingSystem.current().isLinux()) {
418 cloudSystemDependencies.linux.each { entry ->
419 cloudDependencies.get(entry.key).addAll(entry.value)
420 }
421} else if (OperatingSystem.current().isMacOsX()) {
422 cloudSystemDependencies.osx.each { entry ->
423 cloudDependencies.get(entry.key).addAll(entry.value)
424 }
425} else {
426 println "WARNING: Unsupported system: " + OperatingSystem.current()
427}
428
429def getDownloadDepsTaskName(entryKey, entryFile) {
430 return "download_deps_${entryKey}_${entryFile.replace('/', '_').replace('\\', '_')}"
431}
432
Mads Ager418d1ca2017-05-22 09:35:49 +0200433cloudDependencies.each { entry ->
434 entry.value.each { entryFile ->
Morten Krogh-Jespersenc3e7ab92022-05-03 15:12:04 +0200435 task (getDownloadDepsTaskName(entry.key, entryFile), type: DownloadDependency) {
Ian Zernyb2d27c42019-02-20 09:09:41 +0100436 type DownloadDependency.Type.GOOGLE_STORAGE
437 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200438 }
439 }
440}
441
442def x20Dependencies = [
443 "third_party": [
Rico Windc346c4a2018-10-23 08:04:16 +0200444 "benchmarks/kotlin-benches",
Jinseong Jeonb0c2dc02019-07-18 11:41:11 -0700445 "chrome/chrome_180917_ffbaa8",
Christoffer Quist Adamsence640052020-04-30 11:47:41 +0200446 "chrome/chrome_200430",
Christoffer Quist Adamsen287c1862020-05-20 15:51:12 +0200447 "chrome/monochrome_public_minimal_apks/chrome_200520",
Clément Béra5da4e352021-01-27 18:16:27 +0000448 "chrome/clank_google3_prebuilt",
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +0100449 "classlib",
Morten Krogh-Jespersen480784d2019-02-05 08:10:46 +0100450 "cf_segments",
Rico Windf72fa152018-10-22 15:41:03 +0200451 "desugar/desugar_20180308",
Ian Zernybd2fdcc2019-03-22 13:57:21 +0100452 "internal/issue-127524985",
Rico Windf72fa152018-10-22 15:41:03 +0200453 "framework",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200454 "gmail/gmail_android_170604.16",
Søren Gjesseb552e842018-09-28 12:17:29 +0200455 "gmail/gmail_android_180826.15",
Rico Windf72fa152018-10-22 15:41:03 +0200456 "gmscore/gmscore_v10",
Rico Windf72fa152018-10-22 15:41:03 +0200457 "gmscore/latest",
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +0200458 "nest/nest_20180926_7c6cfb",
Rico Windf72fa152018-10-22 15:41:03 +0200459 "proguard/proguard_internal_159423826",
460 "proguardsettings",
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200461 "proto",
462 "protobuf-lite",
Morten Krogh-Jespersend87c0662020-06-22 10:45:43 +0200463 "retrace_internal",
Christoffer Quist Adamsen62fcc152022-06-03 14:01:35 +0200464 "youtube/youtube.android_16.20",
465 "youtube/youtube.android_17.19"
Mads Ager418d1ca2017-05-22 09:35:49 +0200466 ],
467]
468
469x20Dependencies.each { entry ->
470 entry.value.each { entryFile ->
Ian Zernyb2d27c42019-02-20 09:09:41 +0100471 task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) {
472 type DownloadDependency.Type.X20
473 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200474 }
475 }
476}
477
Rico Wind897bb712017-05-23 10:44:29 +0200478task downloadProguard {
479 cloudDependencies.each { entry ->
480 entry.value.each { entryFile ->
481 if (entryFile.contains("proguard")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100482 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Wind897bb712017-05-23 10:44:29 +0200483 }
484 }
485 }
486}
487
Rico Windf6c74ce2018-12-04 08:50:55 +0100488task downloadOpenJDKrt {
489 cloudDependencies.each { entry ->
490 entry.value.each { entryFile ->
491 if (entryFile.contains("openjdk-rt")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100492 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Windf6c74ce2018-12-04 08:50:55 +0100493 }
494 }
495 }
496}
497
Tamas Kenez427205b2017-06-29 15:57:09 +0200498task downloadDx {
499 cloudDependencies.each { entry ->
500 entry.value.each { entryFile ->
Tamas Kenezcea7c202017-10-13 10:53:32 +0200501 if (entryFile.endsWith("/dx")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100502 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez427205b2017-06-29 15:57:09 +0200503 }
504 }
505 }
506}
507
Tamas Kenez0e10c562017-06-08 10:00:34 +0200508task downloadAndroidCts {
509 cloudDependencies.each { entry ->
510 entry.value.each { entryFile ->
511 if (entryFile.contains("android_cts_baseline")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100512 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez0e10c562017-06-08 10:00:34 +0200513 }
514 }
515 }
516}
517
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200518task downloadCloudDeps() {
Mads Ager418d1ca2017-05-22 09:35:49 +0200519 cloudDependencies.each { entry ->
520 entry.value.each { entryFile ->
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100521 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200522 }
523 }
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200524}
525
526task downloadX20Deps() {
527 x20Dependencies.each { entry ->
528 entry.value.each { entryFile ->
529 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200530 }
531 }
532}
533
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200534task downloadDeps {
535 dependsOn downloadCloudDeps
536 if (!project.hasProperty('no_internal')) {
537 dependsOn downloadX20Deps
538 }
539}
540
Mads Ager418d1ca2017-05-22 09:35:49 +0200541allprojects {
542 sourceCompatibility = JavaVersion.VERSION_1_8
543 targetCompatibility = JavaVersion.VERSION_1_8
544}
545
Rico Wind266336c2019-02-25 10:11:38 +0100546// TODO(ricow): Remove debug prints
547println("NOTE: Current operating system: " + OperatingSystem.current())
548println("NOTE: Current operating system isWindows: " + OperatingSystem.current().isWindows())
549
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100550// Check if running with the JDK location from tools/jdk.py.
551if (OperatingSystem.current().isWindows()) {
552 println "NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome
Morten Krogh-Jespersend9a88452020-01-31 14:13:54 +0100553 compileJava.options.encoding = "UTF-8"
554 compileTestJava.options.encoding = "UTF-8"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100555} else {
556 def javaHomeOut = new StringBuilder()
557 def javaHomeErr = new StringBuilder()
Jake Wharton7c14ce72019-09-17 13:49:18 -0400558 def javaHomeProc = './tools/jdk.py'.execute([], projectDir)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100559 javaHomeProc.waitForProcessOutput(javaHomeOut, javaHomeErr)
560 def jdkHome = new File(javaHomeOut.toString().trim())
561 if (!jdkHome.exists()) {
562 println "WARNING: Failed to find the ./tools/jdk.py specified JDK: " + jdkHome
563 } else if (jdkHome != org.gradle.internal.jvm.Jvm.current().javaHome) {
564 println("WARNING: Gradle is running in a non-pinned Java"
565 + ". Gradle Java Home: " + org.gradle.internal.jvm.Jvm.current().javaHome
Christoffer Quist Adamsen79b126a2020-03-27 17:23:08 +0000566 + ". Expected: " + jdkHome)
Rico Wind266336c2019-02-25 10:11:38 +0100567 } else {
568 println("NOTE: Running with jdk from tools/jdk.py: " + jdkHome)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100569 }
Mads Agerc7d14d32018-09-27 11:09:46 +0200570}
571
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200572compileJava.dependsOn downloadCloudDeps
Morten Krogh-Jespersenc1bc4a02021-06-18 08:13:02 +0200573
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100574sourceSets.configureEach { sourceSet ->
575 tasks.named(sourceSet.compileJavaTaskName).configure {
576 // Default disable errorprone (enabled and setup below).
577 options.errorprone.enabled = false
578 options.compilerArgs << '-Xlint:unchecked'
Ian Zerny09135aa2019-02-12 16:03:34 +0100579 // Run all compilation tasks in a forked subprocess.
580 options.fork = true
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100581 // Javac often runs out of stack space when compiling the tests.
582 // Increase the stack size for the javac process.
Søren Gjesse1af374d2019-09-06 10:44:54 +0200583 options.forkOptions.jvmArgs << "-Xss256m"
Ian Zerny26307fb2019-03-06 15:18:17 +0100584 // Test compilation is sometimes hitting the default limit at 1g, increase it.
Ian Zerny293b8152019-09-20 10:40:53 +0200585 options.forkOptions.jvmArgs << "-Xmx3g"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100586 // Set the bootclass path so compilation is consistent with 1.8 target compatibility.
587 options.forkOptions.jvmArgs << "-Xbootclasspath/a:third_party/openjdk/openjdk-rt-1.8/rt.jar"
588 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200589}
590
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100591def setJdkCompilationWithCompatibility(String sourceSet, String javaHome, JavaVersion compatibility, boolean enablePreview) {
592 tasks.named(sourceSet).get().configure {
593 def jdkDir = "third_party/openjdk/${javaHome}/"
594 options.fork = true
595 options.forkOptions.jvmArgs = []
596 if (enablePreview) {
597 options.compilerArgs.add('--enable-preview')
598 }
599 if (OperatingSystem.current().isLinux()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200600 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/linux")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100601 options.forkOptions.javaHome = file(jdkDir + 'linux')
602 } else if (OperatingSystem.current().isMacOsX()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200603 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/osx")
Jake Whartonbd3196b2021-03-16 15:48:08 -0400604 options.forkOptions.javaHome = compatibility > JavaVersion.VERSION_1_9
605 ? file(jdkDir + 'osx/Contents/Home')
606 : file(jdkDir + 'osx')
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100607 } else {
Søren Gjesse96b37252021-08-09 16:08:05 +0200608 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/windows")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100609 options.forkOptions.javaHome = file(jdkDir + 'windows')
610 }
611 sourceCompatibility = compatibility
612 targetCompatibility = compatibility
Ian Zernyd3020482019-04-25 07:05:04 +0200613 }
Ian Zernyd3020482019-04-25 07:05:04 +0200614}
615
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100616setJdkCompilationWithCompatibility(
617 sourceSets.examplesJava9.compileJavaTaskName,
618 'openjdk-9.0.4',
619 JavaVersion.VERSION_1_9,
620 false)
621setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100622 sourceSets.examplesJava10.compileJavaTaskName,
623 'jdk-11',
624 JavaVersion.VERSION_1_10,
625 false)
626setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200627 sourceSets.main11.compileJavaTaskName,
628 'jdk-11',
629 JavaVersion.VERSION_11,
630 false)
631setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100632 sourceSets.examplesJava11.compileJavaTaskName,
633 'jdk-11',
634 JavaVersion.VERSION_11,
635 false)
636setJdkCompilationWithCompatibility(
637 sourceSets.examplesTestNGRunner.compileJavaTaskName,
638 'jdk-11',
639 JavaVersion.VERSION_11,
640 false)
641setJdkCompilationWithCompatibility(
Søren Gjessee9966932021-09-15 17:08:37 +0200642 sourceSets.examplesJava17.compileJavaTaskName,
643 'jdk-17',
644 JavaVersion.VERSION_17,
645 false)
Søren Gjessed1e08992022-02-07 16:46:31 +0100646setJdkCompilationWithCompatibility(
647 sourceSets.examplesJava18.compileJavaTaskName,
648 'jdk-18',
649 // TODO(b/218293990): Update Gradle to get JavaVersion.VERSION_18.
650 JavaVersion.VERSION_17,
651 false)
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100652
Clément Bérac94b6202021-09-28 11:16:58 +0000653task provideJdk11TestsDependencies(type: org.gradle.api.tasks.Copy) {
654 from sourceSets.examplesTestNGRunner.compileClasspath
655 include "**/**.jar"
656 into file("$buildDir/test/jdk11Tests")
657}
658
659task compileTestNGRunner (type: JavaCompile) {
660 dependsOn provideJdk11TestsDependencies
Clément Béra98d5b602021-09-29 06:27:21 +0000661 destinationDir = file("$buildDir/classes/java/examplesTestNGRunner")
Clément Bérac94b6202021-09-28 11:16:58 +0000662 source = sourceSets.examplesTestNGRunner.allSource
663 classpath = sourceSets.examplesTestNGRunner.compileClasspath
664}
665
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100666if (!project.hasProperty('without_error_prone') &&
667 // Don't enable error prone on Java 8 as the plugin setup does not support it.
668 !org.gradle.internal.jvm.Jvm.current().javaVersion.java8) {
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200669 compileJava {
670 // Enable error prone for D8/R8 sources.
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100671 options.errorprone.enabled = true
672 options.errorprone.disableAllChecks = true
673 options.errorprone.check('ClassCanBeStatic', CheckSeverity.ERROR)
Christoffer Quist Adamsen7bed1092020-05-04 11:08:00 +0200674 options.errorprone.check('CollectionIncompatibleType', CheckSeverity.ERROR)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100675 options.errorprone.check('OperatorPrecedence', CheckSeverity.ERROR)
676 options.errorprone.check('RemoveUnusedImports', CheckSeverity.ERROR)
677 options.errorprone.check('MissingOverride', CheckSeverity.ERROR)
678 options.errorprone.check('IntLongMath', CheckSeverity.ERROR)
679 options.errorprone.check('EqualsHashCode', CheckSeverity.ERROR)
680 options.errorprone.check('InconsistentOverloads', CheckSeverity.ERROR)
681 options.errorprone.check('ArrayHashCode', CheckSeverity.ERROR)
682 options.errorprone.check('EqualsIncompatibleType', CheckSeverity.ERROR)
683 options.errorprone.check('NonOverridingEquals', CheckSeverity.ERROR)
684 options.errorprone.check('FallThrough', CheckSeverity.ERROR)
685 options.errorprone.check('MissingCasesInEnumSwitch', CheckSeverity.ERROR)
686 options.errorprone.check('MissingDefault', CheckSeverity.ERROR)
687 options.errorprone.check('MultipleTopLevelClasses', CheckSeverity.ERROR)
688 options.errorprone.check('NarrowingCompoundAssignment', CheckSeverity.ERROR)
689 options.errorprone.check('BoxedPrimitiveConstructor', CheckSeverity.ERROR)
690 options.errorprone.check('LogicalAssignment', CheckSeverity.ERROR)
691 options.errorprone.check('FloatCast', CheckSeverity.ERROR)
692 options.errorprone.check('ReturnValueIgnored', CheckSeverity.ERROR)
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200693 }
694}
695
Yohann Roussel7f47c032017-09-14 12:19:06 +0200696task consolidatedLicense {
Yohann Roussel7f47c032017-09-14 12:19:06 +0200697 def license = new File(new File(buildDir, 'generatedLicense'), 'LICENSE')
Mads Agerd1d0da92018-12-10 13:56:50 +0100698
Yohann Roussel7f47c032017-09-14 12:19:06 +0200699 inputs.files files('LICENSE', 'LIBRARY-LICENSE') + fileTree(dir: 'library-licensing')
Mads Agerd1d0da92018-12-10 13:56:50 +0100700 def runtimeClasspath = configurations.findByName("runtimeClasspath")
701 inputs.files { runtimeClasspath.getResolvedConfiguration().files }
702
Yohann Roussel7f47c032017-09-14 12:19:06 +0200703 outputs.files license
Mads Agerd1d0da92018-12-10 13:56:50 +0100704
Yohann Roussel7f47c032017-09-14 12:19:06 +0200705 doLast {
Mads Agerd1d0da92018-12-10 13:56:50 +0100706 def dependencies = []
707 runtimeClasspath.resolvedConfiguration.resolvedArtifacts.each {
708 def identifier = (ModuleComponentIdentifier) it.id.componentIdentifier
709 dependencies.add("${identifier.group}:${identifier.module}")
710 }
711 def libraryLicenses = file('LIBRARY-LICENSE').text
712 dependencies.each {
713 if (!libraryLicenses.contains("- artifact: $it")) {
714 throw new GradleException("No license for $it in LIBRARY_LICENSE")
715 }
716 }
717
Yohann Roussel7f47c032017-09-14 12:19:06 +0200718 license.getParentFile().mkdirs()
719 license.createNewFile()
720 license.text = "This file lists all licenses for code distributed.\n"
721 license.text += "All non-library code has the following 3-Clause BSD license.\n"
722 license.text += "\n"
723 license.text += "\n"
724 license.text += file('LICENSE').text
725 license.text += "\n"
726 license.text += "\n"
727 license.text += "Summary of distributed libraries:\n"
728 license.text += "\n"
Mads Agerd1d0da92018-12-10 13:56:50 +0100729 license.text += libraryLicenses
Yohann Roussel7f47c032017-09-14 12:19:06 +0200730 license.text += "\n"
731 license.text += "\n"
732 license.text += "Licenses details:\n"
733 fileTree(dir: 'library-licensing').getFiles().stream().sorted().forEach { file ->
734 license.text += "\n"
735 license.text += "\n"
736 license.text += file.text
737 }
738 }
739}
740
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100741def repackageDepFile(file) {
742 if (file.getName().endsWith('.jar')) {
743 return zipTree(file).matching {
744 exclude '**/module-info.class'
745 exclude 'META-INF/maven/**'
746 exclude 'META-INF/LICENSE.txt'
747 exclude 'META-INF/MANIFEST.MF'
748 }
749 } else {
750 return fileTree(file)
Jinseong Jeon40ceab02018-07-09 14:25:31 -0700751 }
Morten Krogh-Jespersen00699af2018-10-09 10:54:42 +0200752}
753
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100754task repackageDeps(type: Jar) {
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200755 dependsOn downloadCloudDeps
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100756 dependsOn project.configurations.runtimeClasspath
757 project.configurations.runtimeClasspath.forEach {
758 from repackageDepFile(it)
759 }
760 archiveFileName = 'deps_all.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000761}
762
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100763task repackageTestDeps(type: Jar) {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200764 dependsOn downloadCloudDeps
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100765 dependsOn project.configurations.testCompile
766 project.configurations.testCompile.forEach {
767 from repackageDepFile(it)
768 }
769 archiveFileName = 'test_deps_all.jar'
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200770}
771
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100772task repackageSources(type: Jar) {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100773 // If this fails then remove all generated folders from
774 // build/classes/java/test that is not {com,dalvik}
Mads Ager418d1ca2017-05-22 09:35:49 +0200775 from sourceSets.main.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100776 archiveFileName = 'sources_main.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000777}
778
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100779task repackageSources11(type: Jar) {
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200780 from sourceSets.main11.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100781 archiveFileName = 'sources_main_11.jar'
clementbera0bca05e2019-05-29 14:11:18 +0200782}
783
Søren Gjesse145d9e82022-05-24 08:12:13 +0200784def r8CreateTask(name, baseName, sources, includeLibraryLicenses, includeSwissArmyKnife) {
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100785 return tasks.create("r8Create${name}", Jar) {
Morten Krogh-Jespersenb4b33eb2022-05-06 16:47:08 +0200786 entryCompression ZipEntryCompression.STORED
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100787 dependsOn sources
Søren Gjesse145d9e82022-05-24 08:12:13 +0200788 dependsOn files('LICENSE')
789 if (includeLibraryLicenses) {
790 from consolidatedLicense.outputs.files
791 } else {
792 from files('LICENSE')
793 }
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100794 from sources.collect { zipTree(it) }
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100795 exclude "$buildDir/classes/**"
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100796 archiveFileName = baseName
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200797 if (includeSwissArmyKnife) {
798 manifest {
799 attributes 'Main-Class': 'com.android.tools.r8.SwissArmyKnife'
800 }
801 }
802 exclude "META-INF/*.kotlin_module"
803 exclude "**/*.kotlin_metadata"
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200804 }
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200805}
806
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200807def r8RelocateTask(r8Task, output) {
808 return tasks.create("r8Relocate_${r8Task.name}", Exec) {
809 dependsOn r8WithDeps
810 dependsOn r8Task
811 outputs.file output
812 workingDir = projectDir
813 inputs.files r8Task.outputs.files + r8WithDeps.outputs.files
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200814 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200815 "relocator",
816 "--input",
817 r8Task.outputs.files[0],
818 "--output",
819 output,
820 "--map",
821 "com.google.common->com.android.tools.r8.com.google.common",
822 "--map",
823 "com.google.gson->com.android.tools.r8.com.google.gson",
824 "--map",
825 "com.google.thirdparty->com.android.tools.r8.com.google.thirdparty",
826 "--map",
827 "joptsimple->com.android.tools.r8.joptsimple",
828 "--map",
829 "org.objectweb.asm->com.android.tools.r8.org.objectweb.asm",
830 "--map",
831 "it.unimi.dsi.fastutil->com.android.tools.r8.it.unimi.dsi.fastutil",
832 "--map",
833 "kotlin->com.android.tools.r8.jetbrains.kotlin",
834 "--map",
835 "kotlinx->com.android.tools.r8.jetbrains.kotlinx",
836 "--map",
837 "org.jetbrains->com.android.tools.r8.org.jetbrains",
838 "--map",
Søren Gjessebeb5d872021-09-07 12:49:24 +0200839 "org.intellij->com.android.tools.r8.org.intellij",
840 "--map",
841 "org.checkerframework->com.android.tools.r8.org.checkerframework"
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200842 ])
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200843 }
844}
845
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200846task r8WithDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200847 dependsOn repackageSources
848 dependsOn repackageDeps
849 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200850 def r8Task = r8CreateTask(
851 'WithDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100852 'r8_with_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200853 repackageSources.outputs.files + repackageDeps.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200854 true,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200855 true)
856 dependsOn r8Task
857 outputs.files r8Task.outputs.files
clementbera0bca05e2019-05-29 14:11:18 +0200858}
859
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200860task r8WithDeps11 {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200861 dependsOn repackageSources11
862 dependsOn repackageDeps
863 inputs.files ([repackageSources11.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200864 def r8Task = r8CreateTask(
865 'WithDeps11',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100866 'r8_with_deps_11.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200867 repackageSources11.outputs.files + repackageDeps.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200868 true,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200869 true)
870 dependsOn r8Task
871 outputs.files r8Task.outputs.files
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100872}
873
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200874task r8WithRelocatedDeps {
875 def output = "${buildDir}/libs/r8_with_relocated_deps.jar"
876 dependsOn r8RelocateTask(r8WithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200877 inputs.files r8WithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200878 outputs.file output
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200879}
880
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200881task r8WithRelocatedDeps11 {
882 def output = "${buildDir}/libs/r8_with_relocated_deps_11.jar"
883 dependsOn r8RelocateTask(r8WithDeps11, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200884 inputs.files r8WithDeps11.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200885 outputs.file output
886}
887
888task r8WithoutDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200889 dependsOn repackageSources
890 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200891 def r8Task = r8CreateTask(
892 'WithoutDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100893 'r8_without_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200894 repackageSources.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200895 false,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200896 true)
897 dependsOn r8Task
898 outputs.files r8Task.outputs.files
899}
900
901task r8(type: Copy) {
902 def r8Task = project.hasProperty("exclude_deps")
903 ? r8WithoutDeps : r8WithRelocatedDeps
904 dependsOn r8Task
905 from r8Task.outputs.files[0]
906 into file("${buildDir}/libs")
907 rename { String fileName -> "r8.jar" }
908 outputs.file "${buildDir}/libs/r8.jar"
909}
910
911task r8NoManifestWithoutDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200912 dependsOn repackageSources
913 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200914 def r8Task = r8CreateTask(
915 'NoManifestWithoutDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100916 'r8_no_manifest_without_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200917 repackageSources.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200918 false,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200919 false)
920 dependsOn r8Task
921 outputs.files r8Task.outputs.files
922}
923
924task r8NoManifestWithDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200925 dependsOn repackageSources
926 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200927 def r8Task = r8CreateTask(
928 'NoManifestWithDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100929 'r8_no_manifest_with_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200930 repackageSources.outputs.files + repackageDeps.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200931 true,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200932 false)
933 dependsOn r8Task
934 outputs.files r8Task.outputs.files
935}
936
937task r8NoManifestWithRelocatedDeps {
938 def output = "${buildDir}/libs/r8_no_manifest_with_relocated_deps.jar"
939 dependsOn r8RelocateTask(r8NoManifestWithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200940 inputs.files r8NoManifestWithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200941 outputs.file output
942}
943
944task r8NoManifest(type: Copy) {
945 def r8Task = project.hasProperty("exclude_deps")
946 ? r8NoManifestWithoutDeps : r8NoManifestWithRelocatedDeps
947 dependsOn r8Task
948 from r8Task.outputs.files[0]
949 into file("${buildDir}/libs")
950 rename { String fileName -> "r8_no_manifest.jar" }
951 outputs.file "${buildDir}/libs/r8_no_manifest.jar"
Tamas Kenez8224fbc2018-12-10 09:57:56 +0100952}
953
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200954def baseCompilerCommandLine(compiler, args = []) {
955 // Execute r8 commands against a stable r8 with dependencies.
956 // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g).
957 return [org.gradle.internal.jvm.Jvm.current().getJavaExecutable(),
958 "-Xmx8g", "-ea", "-jar", r8WithDeps.outputs.files[0]] + compiler + args
959}
960
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100961def baseR8CommandLine(args = []) {
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200962 // Execute r8 commands against a stable r8 with dependencies.
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200963 return baseCompilerCommandLine("r8", args)
964}
965
966def baseD8CommandLine(args = []) {
967 // Execute r8 commands against a stable r8 with dependencies.
968 return baseCompilerCommandLine("d8", args)
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100969}
970
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200971def r8CfCommandLine(input, output, pgConfs = [], args = ["--release"], libs = []) {
972 def allArgs = [
973 "--classfile",
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100974 input,
975 "--output", output,
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100976 "--pg-map-output", output + ".map",
977 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200978 ] + args + libs.collectMany { ["--lib", it] } + pgConfs.collectMany { ["--pg-conf", it] }
979 return baseR8CommandLine(allArgs)
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100980}
981
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200982def d8CfCommandLine(input, output, args = ["--release"], libs = []) {
983 def allArgs = [
984 "--classfile",
985 input,
986 "--output", output,
987 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
988 ] + args + libs.collectMany { ["--lib", it] }
989 return baseD8CommandLine(allArgs)
990}
991
Ian Zernycf8ef512022-05-04 14:54:16 +0200992def r8LibCreateTask(name, pgConfs = [], r8Task, output, libs = [], classpath = [], excldeps=false) {
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100993 return tasks.create("r8Lib${name}", Exec) {
Ian Zernya0d27cf2021-10-14 13:55:34 +0200994 inputs.files ([pgConfs, r8WithRelocatedDeps.outputs, r8Task.outputs])
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100995 outputs.file output
996 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +0100997 dependsOn r8WithRelocatedDeps
998 dependsOn r8Task
Ian Zernya0d27cf2021-10-14 13:55:34 +0200999 commandLine ([
Ian Zerny99613a02022-02-23 11:50:13 +01001000 "python3", "tools/create_r8lib.py",
Ian Zernya0d27cf2021-10-14 13:55:34 +02001001 "--r8jar", r8Task.outputs.files[0],
1002 "--output", output]
Ian Zernycf8ef512022-05-04 14:54:16 +02001003 + (excldeps ? ['--excldeps-variant'] : [])
Ian Zernya0d27cf2021-10-14 13:55:34 +02001004 + (pgConfs.collectMany { ["--pg-conf", it] })
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001005 + (libs.collectMany { ["--lib", it] })
1006 + (classpath.collectMany { ["--classpath", it] }))
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +01001007 workingDir = projectDir
1008 }
1009}
1010
Clément Bérac8b2c152022-06-22 08:23:47 +02001011task rawBuildLibraryDesugarConversions(type: Zip, dependsOn: downloadDeps) {
Søren Gjesse17fc67d2019-12-04 14:50:17 +01001012 from sourceSets.libraryDesugarConversions.output
1013 include "java/**/*.class"
Clément Bérac8b2c152022-06-22 08:23:47 +02001014 baseName 'library_desugar_conversions_raw'
1015 destinationDir file('build/tmp/desugaredlibrary')
1016}
1017
1018task buildLibraryDesugarConversions(type: CustomConversionAsmRewriterTask, dependsOn: rawBuildLibraryDesugarConversions) {
1019 rawJar = file("tmp/library_desugar_conversions_raw.zip")
1020 outputDirectory = file("build/libs")
Søren Gjesse17fc67d2019-12-04 14:50:17 +01001021}
1022
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001023task testJarSources(type: Jar, dependsOn: [testClasses, buildLibraryDesugarConversions]) {
1024 archiveFileName = "r8testsbase.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001025 from sourceSets.test.output
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001026 // We only want to include tests that use R8 when generating keep rules for applymapping.
1027 include "com/android/tools/r8/**"
1028 include "dalvik/**"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001029}
1030
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001031task testJar(type: Exec) {
Morten Krogh-Jespersenac1a4d22020-05-04 01:42:13 +02001032 dependsOn r8WithDeps
1033 dependsOn testJarSources
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001034 def output = "$buildDir/libs/r8tests.jar"
1035 outputs.file output
1036 workingDir = projectDir
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001037 inputs.files (testJarSources.outputs.files + r8WithDeps.outputs.files)
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001038 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001039 "relocator",
1040 "--input",
1041 testJarSources.outputs.files[0],
1042 "--output",
1043 output,
1044 "--map",
1045 "kotlinx.metadata->com.android.tools.r8.jetbrains.kotlinx.metadata"
1046 ])
1047}
1048
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001049task generateR8LibKeepRules(type: Exec) {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001050 // Depend on r8WithRelocatedDeps to ensure that we do not have external
1051 // dependencies crossing the boundary.
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001052 dependsOn r8WithDeps
1053 dependsOn r8NoManifestWithRelocatedDeps
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001054 dependsOn testJar
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001055 dependsOn repackageTestDeps
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001056 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001057 inputs.files ([
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001058 r8WithDeps.outputs,
1059 r8NoManifestWithRelocatedDeps.outputs,
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001060 repackageDeps.outputs,
1061 repackageTestDeps.outputs,
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001062 testJar.outputs])
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001063 outputs.file r8LibGeneratedKeepRulesPath
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001064 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001065 "tracereferences",
1066 "--keep-rules",
1067 "--allowobfuscation",
1068 "--lib",
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001069 "third_party/openjdk/openjdk-rt-1.8/rt.jar",
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001070 "--lib",
1071 repackageDeps.outputs.files[0],
1072 "--lib",
1073 repackageTestDeps.outputs.files[0],
1074 "--target",
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001075 r8NoManifestWithRelocatedDeps.outputs.files[0],
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001076 "--source",
1077 testJar.outputs.files[0],
1078 "--output",
1079 r8LibGeneratedKeepRulesPath])
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001080 workingDir = projectDir
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001081}
1082
Morten Krogh-Jespersenb39fbe52018-12-17 14:58:48 +01001083task R8Lib {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001084 dependsOn r8LibCreateTask(
1085 "Main",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001086 ["src/main/keep.txt", generateR8LibKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001087 r8NoManifestWithRelocatedDeps,
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001088 r8LibPath,
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001089 ).dependsOn(generateR8LibKeepRules)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001090 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001091 outputs.file r8LibPath
Tamas Kenezf960e9c2018-12-03 16:13:29 +01001092}
1093
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001094task R8LibNoDeps {
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001095 dependsOn r8LibCreateTask(
Ian Zernya0d27cf2021-10-14 13:55:34 +02001096 "MainNoDeps",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001097 ["src/main/keep.txt"],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001098 r8NoManifestWithoutDeps,
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001099 r8LibExludeDepsPath,
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001100 [],
Ian Zernycf8ef512022-05-04 14:54:16 +02001101 repackageDeps.outputs.files,
1102 true,
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001103 ).dependsOn(repackageDeps)
1104 inputs.files ([r8NoManifestWithoutDeps.outputs, repackageDeps.outputs])
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001105 outputs.file r8LibExludeDepsPath
1106}
1107
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001108task R8Desugared(type: Exec) {
1109 dependsOn downloadOpenJDKrt
1110 dependsOn r8NoManifestWithRelocatedDeps
1111 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
1112 commandLine d8CfCommandLine(
1113 r8NoManifestWithRelocatedDeps.outputs.files[0],
1114 r8DesugaredPath,
1115 ["--release"])
1116 workingDir = projectDir
1117 outputs.file r8DesugaredPath
1118}
1119
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +02001120task R8Retrace {
1121 dependsOn R8Lib
1122 dependsOn r8LibCreateTask(
1123 "Retrace",
1124 ["src/main/keep_retrace.txt"],
1125 R8Lib,
1126 r8RetracePath,
1127 ).dependsOn(R8Lib)
1128 outputs.file r8RetracePath
1129}
1130
1131task R8RetraceNoDeps {
1132 dependsOn R8LibNoDeps
1133 dependsOn r8LibCreateTask(
1134 "RetraceNoDeps",
1135 ["src/main/keep_retrace.txt"],
1136 R8LibNoDeps,
1137 r8RetraceExludeDepsPath,
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001138 [],
Ian Zernycf8ef512022-05-04 14:54:16 +02001139 repackageDeps.outputs.files,
1140 true,
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +02001141 ).dependsOn(R8LibNoDeps)
1142 outputs.file r8RetraceExludeDepsPath
1143}
1144
Mads Ager418d1ca2017-05-22 09:35:49 +02001145task sourceJar(type: Jar, dependsOn: classes) {
1146 classifier = 'src'
1147 from sourceSets.main.allSource
1148}
1149
Mads Ager418d1ca2017-05-22 09:35:49 +02001150artifacts {
1151 archives sourceJar
1152}
1153
1154task createArtTests(type: Exec) {
1155 def outputDir = "build/generated/test/java/com/android/tools/r8/art"
Mads Ager7e5bd722017-05-24 07:17:27 +02001156 def createArtTestsScript = "tools/create_art_tests.py"
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001157 inputs.files files("tests/2017-10-04/art.tar.gz", createArtTestsScript)
Mads Ager418d1ca2017-05-22 09:35:49 +02001158 outputs.dir outputDir
1159 dependsOn downloadDeps
Ian Zerny99613a02022-02-23 11:50:13 +01001160 commandLine "python3", createArtTestsScript
Mads Ager418d1ca2017-05-22 09:35:49 +02001161 workingDir = projectDir
1162}
1163
Mads Ager418d1ca2017-05-22 09:35:49 +02001164compileTestJava {
1165 dependsOn createArtTests
Mads Ager418d1ca2017-05-22 09:35:49 +02001166}
1167
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001168task buildCfSegments(type: Jar, dependsOn: downloadDeps) {
1169 from sourceSets.cfSegments.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001170 archiveFileName = 'cf_segments.jar'
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001171 destinationDir file('build/libs')
1172}
1173
Ian Zerny923a0c12018-01-03 10:59:18 +01001174task buildR8ApiUsageSample(type: Jar) {
1175 from sourceSets.apiUsageSample.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001176 archiveFileName = 'r8_api_usage_sample.jar'
Ian Zerny923a0c12018-01-03 10:59:18 +01001177 destinationDir file('tests')
1178}
1179
Yohann Roussel548ae942018-01-05 11:13:28 +01001180task buildApiSampleJars {
Yohann Roussel548ae942018-01-05 11:13:28 +01001181 dependsOn buildR8ApiUsageSample
1182}
1183
Mads Ager418d1ca2017-05-22 09:35:49 +02001184task buildDebugTestResourcesJars {
Mads Ager418d1ca2017-05-22 09:35:49 +02001185 def resourcesDir = file("src/test/debugTestResources")
1186 def hostJar = "debug_test_resources.jar"
1187 task "compile_debugTestResources"(type: JavaCompile) {
1188 source = fileTree(dir: resourcesDir, include: '**/*.java')
1189 destinationDir = file("build/test/debugTestResources/classes")
1190 classpath = sourceSets.main.compileClasspath
1191 sourceCompatibility = JavaVersion.VERSION_1_7
1192 targetCompatibility = JavaVersion.VERSION_1_7
1193 options.compilerArgs += ["-g", "-Xlint:-options"]
1194 }
1195 task "jar_debugTestResources"(type: Jar, dependsOn: "compile_debugTestResources") {
1196 archiveName = hostJar
1197 destinationDir = file("build/test/")
1198 from "build/test/debugTestResources/classes"
1199 include "**/*.class"
1200 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001201 def java8ResourcesDir = file("src/test/debugTestResourcesJava8")
1202 def java8HostJar = "debug_test_resources_java8.jar"
1203 task "compile_debugTestResourcesJava8"(type: JavaCompile) {
1204 source = fileTree(dir: java8ResourcesDir, include: '**/*.java')
1205 destinationDir = file("build/test/debugTestResourcesJava8/classes")
1206 classpath = sourceSets.main.compileClasspath
1207 sourceCompatibility = JavaVersion.VERSION_1_8
1208 targetCompatibility = JavaVersion.VERSION_1_8
1209 options.compilerArgs += ["-g", "-Xlint:-options"]
1210 }
1211 task "jar_debugTestResourcesJava8"(type: Jar, dependsOn: "compile_debugTestResourcesJava8") {
1212 archiveName = java8HostJar
1213 destinationDir = file("build/test/")
1214 from "build/test/debugTestResourcesJava8/classes"
1215 include "**/*.class"
1216 }
1217 dependsOn downloadDeps
Mads Ager418d1ca2017-05-22 09:35:49 +02001218 dependsOn jar_debugTestResources
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001219 dependsOn jar_debugTestResourcesJava8
Mads Ager418d1ca2017-05-22 09:35:49 +02001220}
1221
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001222// Examples used by tests, where Android specific APIs are used.
1223task buildExampleAndroidApi(type: JavaCompile) {
1224 source = fileTree(dir: file("src/test/examplesAndroidApi"), include: "**/*.java")
1225 destinationDir = file("build/test/examplesAndroidApi/classes")
1226 classpath = files("third_party/android_jar/lib-v26/android.jar")
1227 sourceCompatibility = JavaVersion.VERSION_1_8
1228 targetCompatibility = JavaVersion.VERSION_1_8
1229}
1230
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001231task buildProtoGeneratedSources {
1232 def examplesProtoDir = file("src/test/examplesProto")
1233 examplesProtoDir.eachDir { dir ->
1234 def name = dir.getName()
1235 task "compile_proto_generated_source_${name}"(type: JavaCompile) {
1236 source = {
1237 file('third_party/proto').listFiles()
1238 .findAll { it.name.startsWith(name) && it.name.endsWith('-src.jar') }
1239 .collect { zipTree(it) }
1240 }
1241 destinationDir = file("build/generated/test/proto/${name}_classes")
1242 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1243 sourceCompatibility = JavaVersion.VERSION_1_8
1244 targetCompatibility = JavaVersion.VERSION_1_8
1245 }
1246 task "jar_proto_generated_source_${name}"(type: Jar, dependsOn: "compile_proto_generated_source_${name}") {
1247 archiveName = "${name}.jar"
1248 destinationDir = file("build/generated/test/proto")
1249 from "build/generated/test/proto/${name}_classes"
1250 include "/**/*.class"
1251 }
1252 dependsOn "jar_proto_generated_source_${name}"
1253 }
1254}
1255
1256task buildExamplesProto {
1257 def examplesProtoDir = file("src/test/examplesProto")
1258 def examplesProtoOutputDir = file("build/test/examplesProto");
1259 dependsOn buildProtoGeneratedSources
1260 task "compile_examples_proto"(type: JavaCompile) {
1261 source = fileTree(dir: examplesProtoDir, include: "**/*.java")
1262 destinationDir = file("build/test/examplesProto/classes")
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +02001263 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1264 classpath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001265 sourceCompatibility = JavaVersion.VERSION_1_8
1266 targetCompatibility = JavaVersion.VERSION_1_8
1267 }
1268 examplesProtoDir.eachDir { dir ->
1269 def name = dir.getName()
1270 task "jar_examples_proto_${name}"(type: Jar, dependsOn: "compile_examples_proto") {
1271 archiveName = "${name}.jar"
1272 destinationDir = examplesProtoOutputDir
1273 from "build/test/examplesProto/classes"
1274 include name + "/**/*.class"
1275 }
1276 dependsOn "jar_examples_proto_${name}"
1277 }
1278}
1279
Lars Bakc91e87e2017-08-18 08:53:10 +02001280// Proto lite generated code yields warnings when compiling with javac.
1281// We change the options passed to javac to ignore it.
1282compileExamplesJava.options.compilerArgs = ["-Xlint:none"]
1283
Søren Gjesse7320ce52018-05-07 15:45:22 +02001284
Mads Ager418d1ca2017-05-22 09:35:49 +02001285task buildExampleJars {
Rico Wind897bb712017-05-23 10:44:29 +02001286 dependsOn downloadProguard
Mads Ager418d1ca2017-05-22 09:35:49 +02001287 def examplesDir = file("src/test/examples")
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001288 def proguardScript
1289 if (OperatingSystem.current().isWindows()) {
1290 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.bat"
1291 } else {
1292 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.sh"
1293 }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001294 task extractExamplesRuntime(type: Sync) {
1295 dependsOn configurations.examplesRuntime
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001296 from { configurations.examplesRuntime.collect { zipTree(it) } }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001297 include "**/*.class"
1298 includeEmptyDirs false
1299 into "$buildDir/runtime/examples/"
1300 }
1301
Søren Gjesse7320ce52018-05-07 15:45:22 +02001302 task "copy_examples_resources"(type: org.gradle.api.tasks.Copy) {
1303 from examplesDir
1304 exclude "**/*.java"
1305 exclude "**/keep-rules*.txt"
1306 into file("build/test/examples/classes")
1307 }
1308
1309 task "compile_examples"(type: JavaCompile) {
Søren Gjesse7320ce52018-05-07 15:45:22 +02001310 dependsOn "copy_examples_resources"
Rico Wind40fd2c12018-09-12 12:14:44 +02001311 source examplesDir
Stephan Herhut417a72a2017-07-18 10:38:30 +02001312 include "**/*.java"
Mads Ager418d1ca2017-05-22 09:35:49 +02001313 destinationDir = file("build/test/examples/classes")
Stephan Herhut417a72a2017-07-18 10:38:30 +02001314 classpath = sourceSets.examples.compileClasspath
Mads Ager418d1ca2017-05-22 09:35:49 +02001315 sourceCompatibility = JavaVersion.VERSION_1_7
1316 targetCompatibility = JavaVersion.VERSION_1_7
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001317 options.compilerArgs = ["-g:source,lines", "-Xlint:none"]
1318 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001319 task "compile_examples_debuginfo_all"(type: JavaCompile) {
1320 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001321 include "**/*.java"
1322 destinationDir = file("build/test/examples/classes_debuginfo_all")
1323 classpath = sourceSets.examples.compileClasspath
1324 sourceCompatibility = JavaVersion.VERSION_1_7
1325 targetCompatibility = JavaVersion.VERSION_1_7
1326 options.compilerArgs = ["-g", "-Xlint:none"]
1327 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001328 task "compile_examples_debuginfo_none"(type: JavaCompile) {
1329 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001330 include "**/*.java"
1331 destinationDir = file("build/test/examples/classes_debuginfo_none")
1332 classpath = sourceSets.examples.compileClasspath
1333 sourceCompatibility = JavaVersion.VERSION_1_7
1334 targetCompatibility = JavaVersion.VERSION_1_7
1335 options.compilerArgs = ["-g:none", "-Xlint:none"]
Mads Ager418d1ca2017-05-22 09:35:49 +02001336 }
1337 examplesDir.eachDir { dir ->
1338 def name = dir.getName();
1339 def exampleOutputDir = file("build/test/examples");
1340 def jarName = "${name}.jar"
1341 dependsOn "jar_example_${name}"
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001342 dependsOn "jar_example_${name}_debuginfo_all"
1343 dependsOn "jar_example_${name}_debuginfo_none"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001344 dependsOn "extractExamplesRuntime"
1345 def runtimeDependencies = copySpec { }
Mads Ager418d1ca2017-05-22 09:35:49 +02001346 // The "throwing" test verifies debugging/stack info on the post-proguarded output.
1347 def proguardConfigPath = "${dir}/proguard.cfg"
1348 if (new File(proguardConfigPath).exists()) {
1349 task "pre_proguard_example_${name}"(type: Jar, dependsOn: "compile_examples") {
1350 archiveName = "${name}_pre_proguard.jar"
1351 destinationDir = exampleOutputDir
1352 from "build/test/examples/classes"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001353 include name + "/**/*.class"
1354 with runtimeDependencies
1355 includeEmptyDirs false
Mads Ager418d1ca2017-05-22 09:35:49 +02001356 }
1357 def jarPath = files(tasks.getByPath("pre_proguard_example_${name}")).files.first();
1358 def proguardJarPath = "${exampleOutputDir}/${jarName}"
1359 def proguardMapPath = "${exampleOutputDir}/${name}/${name}.map"
1360 task "jar_example_${name}"(type: Exec, dependsOn: "pre_proguard_example_${name}") {
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001361 inputs.files files(
1362 tasks.getByPath("pre_proguard_example_${name}"),
1363 proguardConfigPath)
Mads Ager418d1ca2017-05-22 09:35:49 +02001364 // Enable these to get stdout and stderr redirected to files...
1365 // standardOutput = new FileOutputStream('proguard.stdout')
1366 // errorOutput = new FileOutputStream('proguard.stderr')
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001367 def proguardArguments = "-verbose -dontwarn java.** -injars ${jarPath}" +
Mads Ager418d1ca2017-05-22 09:35:49 +02001368 " -outjars ${proguardJarPath}" +
1369 " -include ${proguardConfigPath}" +
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001370 " -printmapping ${proguardMapPath}"
1371 if (OperatingSystem.current().isWindows()) {
1372 executable "${proguardScript}"
1373 args "${proguardArguments}"
1374 } else {
1375 executable "bash"
1376 args "-c", "${proguardScript} '${proguardArguments}'"
1377 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001378 outputs.file proguardJarPath
1379 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001380 // TODO: Consider performing distinct proguard compilations.
1381 task "jar_example_${name}_debuginfo_all"(type: Copy, dependsOn: "jar_example_${name}") {
1382 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001383 into "${exampleOutputDir}"
1384 rename(".*", "${name}_debuginfo_all.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001385 }
1386 task "jar_example_${name}_debuginfo_none"(type: Copy, dependsOn: "jar_example_${name}") {
1387 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001388 into "${exampleOutputDir}"
1389 rename(".*", "${name}_debuginfo_none.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001390 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001391 } else {
1392 task "jar_example_${name}"(type: Jar, dependsOn: "compile_examples") {
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001393 archiveName = "${name}.jar"
Mads Ager418d1ca2017-05-22 09:35:49 +02001394 destinationDir = exampleOutputDir
1395 from "build/test/examples/classes"
Søren Gjesse7320ce52018-05-07 15:45:22 +02001396 include name + "/**/*"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001397 with runtimeDependencies
Søren Gjesse7320ce52018-05-07 15:45:22 +02001398 includeEmptyDirs true
Mads Ager418d1ca2017-05-22 09:35:49 +02001399 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001400 task "jar_example_${name}_debuginfo_all"(type: Jar, dependsOn: "compile_examples_debuginfo_all") {
1401 archiveName = "${name}_debuginfo_all.jar"
1402 destinationDir = exampleOutputDir
1403 from "build/test/examples/classes_debuginfo_all"
1404 include name + "/**/*.class"
1405 with runtimeDependencies
1406 includeEmptyDirs false
1407 }
1408 task "jar_example_${name}_debuginfo_none"(type: Jar, dependsOn: "compile_examples_debuginfo_none") {
1409 archiveName = "${name}_debuginfo_none.jar"
1410 destinationDir = exampleOutputDir
1411 from "build/test/examples/classes_debuginfo_none"
1412 include name + "/**/*.class"
1413 with runtimeDependencies
1414 includeEmptyDirs false
1415 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001416 }
1417 }
1418}
1419
1420task buildExampleAndroidNJars {
1421 dependsOn downloadDeps
1422 def examplesDir = file("src/test/examplesAndroidN")
1423 task "compile_examplesAndroidN"(type: JavaCompile) {
1424 source = fileTree(dir: examplesDir, include: '**/*.java')
1425 destinationDir = file("build/test/examplesAndroidN/classes")
1426 classpath = sourceSets.main.compileClasspath
1427 sourceCompatibility = JavaVersion.VERSION_1_8
1428 targetCompatibility = JavaVersion.VERSION_1_8
1429 options.compilerArgs += ["-Xlint:-options"]
1430 }
1431 examplesDir.eachDir { dir ->
1432 def name = dir.getName();
1433 def exampleOutputDir = file("build/test/examplesAndroidN");
1434 def jarName = "${name}.jar"
1435 dependsOn "jar_examplesAndroidN_${name}"
1436 task "jar_examplesAndroidN_${name}"(type: Jar, dependsOn: "compile_examplesAndroidN") {
1437 archiveName = jarName
1438 destinationDir = exampleOutputDir
1439 from "build/test/examplesAndroidN/classes"
1440 include "**/" + name + "/**/*.class"
1441 }
1442 }
1443}
1444
1445
1446task buildExampleAndroidOJars {
1447 dependsOn downloadDeps
1448 def examplesDir = file("src/test/examplesAndroidO")
1449 // NOTE: we want to enable a scenario when test needs to reference some
1450 // classes generated by legacy (1.6) Java compiler to test some specific
1451 // behaviour. To do so we compile all the java files located in sub-directory
1452 // called 'legacy' with Java 1.6, then compile the rest of the files with
1453 // Java 1.8 and a reference to previously generated 1.6 classes.
1454
1455 // Compiling all classes in dirs 'legacy' with old Java version.
1456 task "compile_examplesAndroidO_Legacy"(type: JavaCompile) {
1457 source = fileTree(dir: examplesDir, include: '**/legacy/**/*.java')
1458 destinationDir = file("build/test/examplesAndroidOLegacy/classes")
1459 classpath = sourceSets.main.compileClasspath
1460 sourceCompatibility = JavaVersion.VERSION_1_6
1461 targetCompatibility = JavaVersion.VERSION_1_6
1462 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1463 }
1464 // Compiling the rest of the files as Java 1.8 code.
1465 task "compile_examplesAndroidO"(type: JavaCompile) {
1466 dependsOn "compile_examplesAndroidO_Legacy"
1467 source = fileTree(dir: examplesDir, include: '**/*.java', exclude: '**/legacy/**/*.java')
1468 destinationDir = file("build/test/examplesAndroidO/classes")
1469 classpath = sourceSets.main.compileClasspath
1470 classpath += files("build/test/examplesAndroidOLegacy/classes")
1471 sourceCompatibility = JavaVersion.VERSION_1_8
1472 targetCompatibility = JavaVersion.VERSION_1_8
1473 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1474 }
1475 examplesDir.eachDir { dir ->
1476 def name = dir.getName();
1477 def destinationDir = file("build/test/examplesAndroidO/classes");
1478 if (file("src/test/examplesAndroidO/" + name + "/TestGenerator.java").isFile()) {
1479 task "generate_examplesAndroidO_${name}"(type: JavaExec,
1480 dependsOn: "compile_examplesAndroidO") {
1481 main = name + ".TestGenerator"
1482 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1483 args destinationDir
1484 }
1485 } else {
1486 task "generate_examplesAndroidO_${name}" () {}
1487 }
1488 }
1489 examplesDir.eachDir { dir ->
1490 def name = dir.getName();
1491 def exampleOutputDir = file("build/test/examplesAndroidO");
1492 def jarName = "${name}.jar"
1493 dependsOn "jar_examplesAndroidO_${name}"
1494 task "jar_examplesAndroidO_${name}"(type: Jar, dependsOn: ["compile_examplesAndroidO",
1495 "generate_examplesAndroidO_${name}"]) {
1496 archiveName = jarName
1497 destinationDir = exampleOutputDir
1498 from "build/test/examplesAndroidO/classes" // Java 1.8 classes
1499 from "build/test/examplesAndroidOLegacy/classes" // Java 1.6 classes
1500 include "**/" + name + "/**/*.class"
1501 // Do not include generator into the test runtime jar, it is not useful.
1502 // Otherwise, shrinking will need ASM jars.
1503 exclude "**/TestGenerator*"
1504 }
1505 }
1506}
1507
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001508task buildExampleAndroidPJars {
1509 dependsOn downloadDeps
1510 def examplesDir = file("src/test/examplesAndroidP")
1511
1512 task "compile_examplesAndroidP"(type: JavaCompile) {
1513 source = fileTree(dir: examplesDir, include: '**/*.java')
1514 destinationDir = file("build/test/examplesAndroidP/classes")
1515 classpath = sourceSets.main.compileClasspath
1516 sourceCompatibility = JavaVersion.VERSION_1_8
1517 targetCompatibility = JavaVersion.VERSION_1_8
1518 options.compilerArgs += ["-Xlint:-options"]
1519 }
1520 examplesDir.eachDir { dir ->
1521 def name = dir.getName();
1522 def destinationDir = file("build/test/examplesAndroidP/classes");
1523 if (file("src/test/examplesAndroidP/" + name + "/TestGenerator.java").isFile()) {
1524 task "generate_examplesAndroidP_${name}"(type: JavaExec,
1525 dependsOn: "compile_examplesAndroidP") {
1526 main = name + ".TestGenerator"
1527 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1528 args destinationDir
1529 }
1530 } else {
1531 task "generate_examplesAndroidP_${name}" () {}
1532 }
1533 }
1534 examplesDir.eachDir { dir ->
1535 def name = dir.getName();
1536 def exampleOutputDir = file("build/test/examplesAndroidP");
1537 def jarName = "${name}.jar"
1538 dependsOn "jar_examplesAndroidP_${name}"
1539 task "jar_examplesAndroidP_${name}"(type: Jar,
1540 dependsOn: ["compile_examplesAndroidP",
1541 "generate_examplesAndroidP_${name}"]) {
1542 archiveName = jarName
1543 destinationDir = exampleOutputDir
1544 from "build/test/examplesAndroidP/classes" // Java 1.8 classes
1545 include "**/" + name + "/**/*.class"
1546 // Do not include generator into the test runtime jar, it is not useful.
1547 // Otherwise, shrinking will need ASM jars.
1548 exclude "**/TestGenerator*"
1549 }
1550 }
1551}
1552
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001553def buildExampleJarsCreateTask(javaVersion, sourceSet) {
1554 return tasks.create("buildExample${javaVersion}Jars") {
1555 def examplesDir = file("src/test/examples${javaVersion}")
1556 examplesDir.eachDir { dir ->
1557 def name = dir.getName();
1558 def exampleOutputDir = file("build/test/examples${javaVersion}");
1559 def jarName = "${name}.jar"
1560 dependsOn "jar_examples${javaVersion}_${name}"
1561 task "jar_examples${javaVersion}_${name}"(type: Jar) {
1562 archiveName = jarName
1563 destinationDir = exampleOutputDir
1564 from sourceSet.output
1565 include "**/" + name + "/**/*.class"
1566 }
Mikaël Peltier61633d42017-10-13 16:51:06 +02001567 }
1568 }
1569}
1570
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001571buildExampleJarsCreateTask("Java9", sourceSets.examplesJava9)
1572buildExampleJarsCreateTask("Java10", sourceSets.examplesJava10)
1573buildExampleJarsCreateTask("Java11", sourceSets.examplesJava11)
Søren Gjessee9966932021-09-15 17:08:37 +02001574buildExampleJarsCreateTask("Java17", sourceSets.examplesJava17)
Søren Gjessed1e08992022-02-07 16:46:31 +01001575buildExampleJarsCreateTask("Java18", sourceSets.examplesJava18)
clementberad7ab1dd2019-04-16 16:05:00 +02001576
clementberaa92e3cd2019-07-12 14:13:22 +02001577task provideArtFrameworksDependencies {
1578 cloudDependencies.tools.forEach({ art ->
1579 if (art.contains("art")) {
1580 def taskName = art.replace('/','_')
1581 dependsOn "patch_${taskName}"
1582 task "patch_${taskName}"(type: org.gradle.api.tasks.Copy){
1583 from "tools/${art}/framework"
1584 include "**.jar"
1585 into file("tools/${art}/out/host/linux-x86/framework")
1586 }
1587 }
1588 })
1589}
1590
Sebastien Hertzd3313772018-01-16 14:12:37 +01001591task buildKotlinR8TestResources {
1592 def examplesDir = file("src/test/kotlinR8TestResources")
1593 examplesDir.eachDir { dir ->
Sebastien Hertzfe97a712018-02-13 12:08:59 +01001594 kotlin.Kotlinc.KotlinTargetVersion.values().each { kotlinTargetVersion ->
1595 def name = dir.getName()
1596 def taskName = "jar_kotlinR8TestResources_${name}_${kotlinTargetVersion}"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001597 def javaOutput = "build/test/kotlinR8TestResources/${kotlinTargetVersion}/${name}/java"
Denis Vnukovc22da842018-03-14 12:57:20 -07001598 def javaOutputJarName = "${name}.java.jar"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001599 def javaOutputJarDir = "build/test/kotlinR8TestResources/${kotlinTargetVersion}"
Denis Vnukovc22da842018-03-14 12:57:20 -07001600 task "${taskName}Java"(type: JavaCompile) {
1601 source = fileTree(dir: file("${examplesDir}/${name}"), include: '**/*.java')
1602 destinationDir = file(javaOutput)
1603 classpath = sourceSets.main.compileClasspath
1604 sourceCompatibility = JavaVersion.VERSION_1_6
1605 targetCompatibility = JavaVersion.VERSION_1_6
1606 options.compilerArgs += ["-g", "-Xlint:-options"]
1607 }
1608 task "${taskName}JavaJar"(type: Jar, dependsOn: "${taskName}Java") {
1609 archiveName = javaOutputJarName
1610 destinationDir = file(javaOutputJarDir)
1611 from javaOutput
1612 include "**/*.class"
1613 }
Morten Krogh-Jespersen358c8a72021-02-24 11:07:57 +01001614 dependsOn "${taskName}JavaJar"
Sebastien Hertzd3313772018-01-16 14:12:37 +01001615 }
Sebastien Hertzd3313772018-01-16 14:12:37 +01001616 }
1617}
1618
Mads Ager418d1ca2017-05-22 09:35:49 +02001619task buildExamples {
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001620 if (OperatingSystem.current().isMacOsX() || OperatingSystem.current().isWindows()) {
1621 logger.lifecycle("WARNING: Testing (including building examples) is only partially supported on your " +
1622 "platform (" + OperatingSystem.current().getName() + ").")
Mads Ager418d1ca2017-05-22 09:35:49 +02001623 } else if (!OperatingSystem.current().isLinux()) {
1624 logger.lifecycle("WARNING: Testing (including building examples) is not supported on your platform. " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001625 "It is fully supported on Linux and partially supported on Mac OS and Windows")
Mads Ager418d1ca2017-05-22 09:35:49 +02001626 return;
1627 }
1628 dependsOn buildDebugTestResourcesJars
1629 dependsOn buildExampleJars
1630 dependsOn buildExampleAndroidNJars
1631 dependsOn buildExampleAndroidOJars
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001632 dependsOn buildExampleAndroidPJars
Mikaël Peltier61633d42017-10-13 16:51:06 +02001633 dependsOn buildExampleJava9Jars
Jake Wharton2000b2f2019-12-11 20:37:49 -05001634 dependsOn buildExampleJava10Jars
clementberad7ab1dd2019-04-16 16:05:00 +02001635 dependsOn buildExampleJava11Jars
Søren Gjessee9966932021-09-15 17:08:37 +02001636 dependsOn buildExampleJava17Jars
Søren Gjessed1e08992022-02-07 16:46:31 +01001637 dependsOn buildExampleJava18Jars
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001638 dependsOn buildExampleAndroidApi
Mads Ager418d1ca2017-05-22 09:35:49 +02001639 def examplesDir = file("src/test/examples")
Yohann Rousself820a572017-05-31 20:25:51 +02001640 def noDexTests = [
1641 "multidex",
1642 "multidex002",
1643 "multidex004",
1644 ]
Mads Ager418d1ca2017-05-22 09:35:49 +02001645 examplesDir.eachDir { dir ->
1646 def name = dir.getName();
Yohann Rousself820a572017-05-31 20:25:51 +02001647 if (!(name in noDexTests)) {
1648 dependsOn "dex_example_${name}"
1649 def exampleOutputDir = file("build/test/examples/" + name);
1650 def dexPath = file("${exampleOutputDir}")
1651 def debug = (name == "throwing")
1652 if (!dexPath.exists()) {
1653 dexPath.mkdirs()
1654 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001655 task "dex_example_${name}"(type: DxTask, dependsOn: "jar_example_${name}") {
Yohann Rousself820a572017-05-31 20:25:51 +02001656 source = files(tasks.getByPath("jar_example_${name}")).asFileTree
1657 destination = dexPath
1658 debug = debug
1659 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001660 }
1661 }
1662}
1663
1664task buildSmali {
1665 def smaliDir = file("src/test/smali")
1666 smaliDir.eachDirRecurse() { dir ->
1667 def name = dir.getName();
1668 def relativeDir = smaliDir.toPath().relativize(dir.toPath());
1669 def smaliOutputDir = file("build/test/smali/" + relativeDir);
1670 smaliOutputDir.mkdirs()
1671 outputs.dir smaliOutputDir
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001672 def taskName = "smali_build_${relativeDir.toString().replace('/', '_').replace('\\', '_')}"
Mads Ager418d1ca2017-05-22 09:35:49 +02001673 def smaliFiles = fileTree(dir: dir, include: '*.smali')
1674 def javaFiles = fileTree(dir: dir, include: '*.java')
1675 def destDir = smaliOutputDir;
1676 def destFile = destDir.toPath().resolve("${name}.dex").toFile()
1677 def intermediateFileName = "${name}-intermediate.dex";
1678 def intermediateFile = destDir.toPath().resolve(intermediateFileName).toFile()
1679 if (javaFiles.empty) {
1680 if (!smaliFiles.empty) {
1681 dependsOn "${taskName}_smali"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001682 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001683 source = smaliFiles
1684 destination = destFile
1685 }
1686 }
1687 } else {
Rico Wind01c15c62021-04-22 17:30:41 +00001688 dependsOn "${taskName}_dexmerger"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001689 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001690 source = smaliFiles
1691 destination = intermediateFile
1692 }
1693 task "${taskName}_java"(type: JavaCompile) {
1694 source = javaFiles
1695 destinationDir destDir
1696 classpath = sourceSets.main.compileClasspath
1697 sourceCompatibility = JavaVersion.VERSION_1_7
1698 targetCompatibility = JavaVersion.VERSION_1_7
1699 options.compilerArgs += ["-Xlint:-options"]
1700 }
1701 task "${taskName}_jar"(type: Jar, dependsOn: "${taskName}_java") {
1702 archiveName = "Test.jar"
1703 destinationDir = destDir
1704 from fileTree(dir: destDir, include: 'Test.class')
1705 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001706 task "${taskName}_dx"(type: DxTask, dependsOn: "${taskName}_jar") {
Mads Ager418d1ca2017-05-22 09:35:49 +02001707 source = fileTree(dir: destDir, include: 'Test.jar')
1708 destination = destDir
1709 }
1710 task "${taskName}_dexmerger"(
Jake Wharton2d7aab82019-09-13 10:24:26 -04001711 type: DexMergerTask, dependsOn: ["${taskName}_dx", "${taskName}_smali"]) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001712 source = fileTree(dir: destDir, include: ["classes.dex", intermediateFileName])
1713 destination = destFile
1714 }
1715 }
1716 }
1717}
1718
1719tasks.withType(Test) {
Rico Windc56f21c2019-03-12 07:29:57 +01001720 println("NOTE: Number of processors " + Runtime.runtime.availableProcessors())
Mads Ager418d1ca2017-05-22 09:35:49 +02001721 def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK')
Rico Wind73da9f12019-09-19 09:27:07 +02001722 def processors = Runtime.runtime.availableProcessors()
Mads Ager418d1ca2017-05-22 09:35:49 +02001723 // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
Rico Wind73da9f12019-09-19 09:27:07 +02001724 if (userDefinedCoresPerFork) {
1725 maxParallelForks = processors.intdiv(userDefinedCoresPerFork.toInteger()) ?: 1
1726 } else {
1727 // On normal work machines this seems to give the best test execution time (without freezing)
Rico Wind3d4113e2021-09-30 07:50:43 +02001728 maxParallelForks = processors.intdiv(3) ?: 1
1729 // On low cpu count machines (bots) we under subscribe, so increase the count.
1730 if (processors == 8) {
Rico Wind59f7fb02021-10-25 09:01:39 +02001731 maxParallelForks = 3
Rico Wind3d4113e2021-09-30 07:50:43 +02001732 }
Rico Wind73da9f12019-09-19 09:27:07 +02001733 }
Rico Windc56f21c2019-03-12 07:29:57 +01001734 println("NOTE: Max parallel forks " + maxParallelForks)
Rico Wind73da9f12019-09-19 09:27:07 +02001735
Mads Ager418d1ca2017-05-22 09:35:49 +02001736 forkEvery = 0
Søren Gjesseaf1c5e22017-06-15 12:24:03 +02001737 if (project.hasProperty('disable_assertions')) {
1738 enableAssertions = false
1739 }
Ian Zerny16c2f2d2019-02-19 07:25:11 +01001740 // TODO(b/124091860): Increase the max heap size to avoid OOM when running tests.
Rico Wind97b0a992019-08-30 11:09:15 +02001741 if (project.hasProperty('test_xmx')) {
1742 maxHeapSize = project.property('test_xmx')
1743 } else {
1744 maxHeapSize = "4G"
1745 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001746}
1747
1748task buildPreNJdwpTestsJar(type: Jar) {
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001749 archiveFileName = 'jdwp-tests-preN.jar'
Mads Ager418d1ca2017-05-22 09:35:49 +02001750 from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
1751 // Exclude the classes containing java8
1752 exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
1753 exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
1754 includeEmptyDirs = false
1755}
1756
Ian Zerny74143162017-11-24 13:46:35 +01001757task buildPreNJdwpTestsDex(type: Exec, dependsOn: "buildPreNJdwpTestsJar") {
1758 def inFile = buildPreNJdwpTestsJar.archivePath
1759 def outFile = new File(buildPreNJdwpTestsJar.destinationDir, buildPreNJdwpTestsJar.baseName + '-dex.jar')
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001760 inputs.files files(inFile)
Ian Zerny74143162017-11-24 13:46:35 +01001761 outputs.file outFile
1762 if (OperatingSystem.current().isWindows()) {
1763 executable file("tools/windows/dx/bin/dx.bat")
1764 } else if (OperatingSystem.current().isMacOsX()) {
1765 executable file("tools/mac/dx/bin/dx");
1766 } else {
1767 executable file("tools/linux/dx/bin/dx");
1768 }
1769 args "--dex"
1770 args "--output=${outFile}"
1771 args inFile
1772}
1773
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001774task getJarsFromSupportLibs(type: GetJarsFromConfiguration) {
1775 setConfiguration(configurations.supportLibs)
Yohann Roussel126f6872017-08-03 16:25:32 +02001776}
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001777
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001778task generateR8TestKeepRules {
1779 def path = "build/generated/r8tests-keep.txt"
1780 outputs.file path
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001781 dependsOn R8Lib
1782 doLast {
1783 file(path).write """-keep class ** { *; }
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001784-dontshrink
1785-dontoptimize
1786-keepattributes *
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001787-applymapping ${R8Lib.outputs.files[0]}.map
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001788"""
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001789 }
1790}
1791
1792task buildR8LibCfTestDeps(type: Exec) {
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001793 def outputPath = "build/libs/r8libtestdeps-cf.jar"
1794 dependsOn downloadDeps
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001795 dependsOn r8NoManifest
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001796 dependsOn R8Lib
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001797 dependsOn generateR8TestKeepRules
1798 dependsOn testJar
1799 // Take all .jar files as libraries and append the generated test classes in classes/java/test.
1800 def addedLibraries = sourceSets.test.runtimeClasspath.findAll { pkg ->
1801 return pkg.toString().endsWith(".jar")
1802 } + ["${buildDir}/classes/java/test"]
1803 inputs.files testJar.outputs.files +
1804 generateR8TestKeepRules.outputs.files +
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001805 R8Lib.outputs
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001806 commandLine = r8CfCommandLine(
1807 testJar.outputs.files[0],
1808 outputPath,
1809 [generateR8TestKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001810 ["--debug", "--classpath", r8NoManifest.outputs.files[0]],
1811 r8NoManifest.outputs.files + addedLibraries)
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001812 workingDir = projectDir
1813 outputs.file outputPath
1814}
1815
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001816task configureTestForR8Lib(type: Copy) {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001817 dependsOn testJar
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001818 inputs.files buildR8LibCfTestDeps.outputs
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001819 dependsOn R8Lib
1820 delete r8LibTestPath
1821 from zipTree(buildR8LibCfTestDeps.outputs.files[0])
1822 def examplesDir = file("build/test")
1823 examplesDir.eachDir { dir ->
1824 from ("${buildDir}/test/${dir.getName()}/classes")
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001825 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001826 from ("${buildDir}/runtime/examples")
1827 into r8LibTestPath
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001828 outputs.dir r8LibTestPath
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +01001829}
1830
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001831def shouldRetrace() {
1832 return project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')
1833}
1834
1835def retrace(Throwable exception) {
1836 def out = new StringBuffer()
1837 def err = new StringBuffer()
Ian Zerny99613a02022-02-23 11:50:13 +01001838 def command = "python3 tools/retrace.py --quiet"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001839 def header = "RETRACED STACKTRACE";
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001840 out.append("\n--------------------------------------\n")
1841 out.append("${header}\n")
1842 out.append("--------------------------------------\n")
1843 Process process = command.execute()
1844 def processIn = new PrintStream(process.getOut())
1845 process.consumeProcessOutput(out, err)
1846 exception.printStackTrace(processIn)
1847 processIn.flush()
1848 processIn.close()
1849 def errorDuringRetracing = process.waitFor() != 0
1850 if (errorDuringRetracing) {
1851 out.append("ERROR DURING RETRACING\n")
1852 out.append(err.toString())
1853 }
1854 if (project.hasProperty('print_obfuscated_stacktraces') || errorDuringRetracing) {
1855 out.append("\n\n--------------------------------------\n")
1856 out.append("OBFUSCATED STACKTRACE\n")
1857 out.append("--------------------------------------\n")
1858 }
1859 return out.toString()
1860}
1861
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001862def printStackTrace(TestResult result) {
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001863 filterStackTraces(result)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001864 if (shouldRetrace()) {
1865 def exception = new Exception(retrace(result.exception))
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001866 exception.setStackTrace([] as StackTraceElement[])
1867 result.exceptions.add(0, exception)
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001868 }
1869}
1870
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001871def filterStackTraces(TestResult result) {
1872 for (Throwable throwable : result.getExceptions()) {
1873 filterStackTrace(throwable)
1874 }
1875}
1876
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001877// It would be nice to do this in a non-destructive way...
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001878def filterStackTrace(Throwable exception) {
1879 if (!project.hasProperty('print_full_stacktraces')) {
1880 def elements = []
1881 def skipped = []
1882 for (StackTraceElement element : exception.getStackTrace()) {
1883 if (element.toString().contains("com.android.tools.r8")) {
1884 elements.addAll(skipped)
1885 elements.add(element)
1886 skipped.clear()
1887 } else {
1888 skipped.add(element)
1889 }
1890 }
1891 exception.setStackTrace(elements as StackTraceElement[])
1892 }
1893}
1894
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001895def printAllStackTracesToFile(List<Throwable> exceptions, File out) {
1896 new PrintStream(new FileOutputStream(out)).withCloseable {printer ->
1897 exceptions.forEach { it.printStackTrace(printer) }
1898 }
1899}
1900
Ian Zerny89f16cf2021-04-29 21:10:09 +02001901static def escapeHtml(String string) {
1902 return string.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
1903}
1904
1905static def urlEncode(String string) {
1906 // Not sure why, but the + also needs to be converted to have working links.
1907 return URLEncoder.encode(string, "UTF-8").replace("+","%20")
1908}
1909
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001910def ensureDir(File dir) {
1911 dir.mkdirs()
1912 return dir
1913}
1914
Ian Zerny89f16cf2021-04-29 21:10:09 +02001915// Some of our test parameters have new lines :-( We really don't want test names to span lines.
1916static def sanitizedTestName(testDesc) {
1917 if (testDesc.getName().contains("\n")) {
1918 throw new RuntimeException("Unsupported use of newline in test name: '${testDesc.getName()}'")
1919 }
1920 return testDesc.getName()
1921}
1922
1923static def desanitizedTestName(testName) {
1924 return testName
1925}
1926
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001927def getTestReportEntryDir(reportDir, testDesc) {
1928 return ensureDir(reportDir.toPath()
1929 .resolve(testDesc.getClassName())
Ian Zerny89f16cf2021-04-29 21:10:09 +02001930 .resolve(sanitizedTestName(testDesc))
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001931 .toFile())
1932}
1933
Ian Zerny89f16cf2021-04-29 21:10:09 +02001934def getTestReportEntryURL(reportDir, testDesc) {
1935 def classDir = urlEncode(testDesc.getClassName())
1936 def testDir = urlEncode(sanitizedTestName(testDesc))
1937 return "file://${reportDir}/${classDir}/${testDir}"
1938}
1939
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001940def getTestResultEntryOutputFile(reportDir, testDesc, fileName) {
1941 def dir = getTestReportEntryDir(reportDir, testDesc).toPath()
1942 return dir.resolve(fileName).toFile()
1943}
1944
Ian Zerny89f16cf2021-04-29 21:10:09 +02001945def withTestResultEntryWriter(reportDir, testDesc, fileName, append, fn) {
1946 def file = getTestResultEntryOutputFile(reportDir, testDesc, fileName)
1947 new FileWriter(file, append).withCloseable fn
1948}
1949
Ian Zerny27ea4c72021-04-29 22:35:49 +02001950static def getGitBranchName() {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001951 def out = new StringBuilder()
1952 def err = new StringBuilder()
1953 def proc = "git rev-parse --abbrev-ref HEAD".execute()
1954 proc.waitForProcessOutput(out, err)
Ian Zerny27ea4c72021-04-29 22:35:49 +02001955 return out.toString().trim()
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001956}
1957
Ian Zerny27ea4c72021-04-29 22:35:49 +02001958static def getFreshTestReportIndex(File reportDir) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02001959 def number = 0
1960 while (true) {
1961 def freshIndex = reportDir.toPath().resolve("index.${number++}.html").toFile()
1962 if (!freshIndex.exists()) {
1963 return freshIndex
1964 }
1965 }
1966}
1967
1968def forEachTestReportAlreadyX(File reportDir, fileName, onTest) {
1969 def out = new StringBuilder()
1970 def err = new StringBuilder()
1971 def proc = "find . -name ${fileName}".execute([], reportDir)
1972 proc.waitForProcessOutput(out, err)
1973 def outString = out.toString()
1974 outString.eachLine {
1975 // Lines are of the form: ./<class>/<name>/FAILURE
1976 def clazz = null
1977 def name = null
1978 try {
1979 def trimmed = it.trim()
1980 def line = trimmed.substring(2)
1981 def sep = line.indexOf("/")
1982 clazz = line.substring(0, sep)
1983 name = line.substring(sep + 1, line.length() - fileName.length() - 1)
1984 } catch (Exception e) {
1985 logger.lifecycle("WARNING: failed attempt to read test description from: '${it}'")
1986 return
1987 }
1988 onTest(clazz, desanitizedTestName(name))
1989 }
1990 return !outString.trim().isEmpty()
1991}
1992
1993def forEachTestReportAlreadyFailing(File reportDir, onFailureTest) {
1994 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.FAILURE.name(), onFailureTest)
1995}
1996
1997def forEachTestReportAlreadyPassing(File reportDir, onSucceededTest) {
1998 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SUCCESS.name(), onSucceededTest)
1999}
2000
2001def forEachTestReportAlreadySkipped(File reportDir, onSucceededTest) {
2002 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SKIPPED.name(), onSucceededTest)
2003}
2004
Ian Zerny27ea4c72021-04-29 22:35:49 +02002005def setUpTestingState(Test task) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002006 // Hide all test events from the console, they are written to the report.
2007 task.testLogging { events = [] }
2008
Ian Zernycae764d2021-08-16 08:25:15 +02002009 def branch = project.hasProperty('testing-state-name')
2010 ? project.getProperty('testing-state-name')
2011 : getGitBranchName()
Ian Zerny27ea4c72021-04-29 22:35:49 +02002012 def reportDir = file("${buildDir}/test-state/${branch}")
Ian Zerny89f16cf2021-04-29 21:10:09 +02002013 def index = reportDir.toPath().resolve("index.html").toFile()
Ian Zerny27ea4c72021-04-29 22:35:49 +02002014 def resetState = project.hasProperty('reset-testing-state')
2015 def reportDirExists = reportDir.exists()
2016 def resuming = !resetState && reportDirExists
Ian Zerny89f16cf2021-04-29 21:10:09 +02002017
2018 def hasFailingTests = false;
2019 if (resuming) {
2020 // Test filtering happens before the test execution is initiated so compute it here.
2021 // If there are still failing tests in the report, include only those.
2022 hasFailingTests = forEachTestReportAlreadyFailing(reportDir, {
2023 clazz, name -> task.filter.includeTestsMatching("$clazz.$name")
2024 })
2025 // Otherwise exclude all of the test already marked as succeeding.
2026 if (!hasFailingTests) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002027 // Also allow the test to overall succeed if there are no remaining tests that match,
2028 // which is natural if the state already succeeded in full.
2029 task.filter.failOnNoMatchingTests = false
Ian Zerny89f16cf2021-04-29 21:10:09 +02002030 forEachTestReportAlreadyPassing(reportDir, {
2031 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2032 })
2033 forEachTestReportAlreadySkipped(reportDir, {
2034 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2035 })
2036 }
2037 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002038
2039 task.beforeSuite { desc ->
2040 if (!desc.parent) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002041 def parentReport = null
Ian Zerny27ea4c72021-04-29 22:35:49 +02002042 if (resetState && reportDirExists) {
2043 delete reportDir
2044 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002045 if (resuming) {
2046 if (index.exists()) {
2047 parentReport = getFreshTestReportIndex(reportDir)
2048 index.renameTo(parentReport)
2049 }
2050 } else {
2051 reportDir.mkdirs()
2052 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002053 def runPrefix = resuming ? "Resuming" : "Starting"
2054 def title = "${runPrefix} @ ${branch}"
2055 // Print a console link to the test report for easy access.
2056 println "${runPrefix} test, report written to:"
2057 println " file://${index}"
2058 // Print the new index content.
2059 index << "<html><head><title>${title}</title>"
2060 index << "<style> * { font-family: monospace; }</style>"
Morten Krogh-Jespersende7ddfa2021-09-03 12:37:32 +02002061 index << "<meta http-equiv='refresh' content='10' />"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002062 index << "</head><body><h1>${title}</h1>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002063 index << "<p>Run on: ${new Date()}</p>"
2064 index << "<p>Git branch: ${branch}</p>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002065 if (parentReport != null) {
2066 index << "<p><a href=\"file://${parentReport}\">Previous result index</a></p>"
2067 }
2068 index << "<p><a href=\"file://${index}\">Most recent result index</a></p>"
2069 index << "<p><a href=\"file://${reportDir}\">Test directories</a></p>"
Morten Krogh-Jespersende7ddfa2021-09-03 12:37:32 +02002070 index << "<h2>Failing tests (refreshing automatically every 10 seconds)</h2><ul>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002071 }
2072 }
2073
2074 task.afterSuite { desc, result ->
2075 if (!desc.parent) {
2076 // Update the final test results in the index.
2077 index << "</ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002078 if (result.resultType == TestResult.ResultType.SUCCESS) {
2079 if (hasFailingTests) {
2080 index << "<h2>Rerun of failed tests now pass!</h2>"
2081 index << "<h2>Rerun again to continue with outstanding tests!</h2>"
2082 } else {
2083 index << "<h2 style=\"background-color:#62D856\">GREEN BAR == YOU ROCK!</h2>"
2084 }
2085 } else if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002086 index << "<h2 style=\"background-color:#6D130A\">Some tests failed: ${result.resultType.name()}</h2><ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002087 } else {
2088 index << "<h2>Tests finished: ${result.resultType.name()}</h2><ul>"
2089 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002090 index << "<li>Number of tests: ${result.testCount}"
2091 index << "<li>Failing tests: ${result.failedTestCount}"
2092 index << "<li>Successful tests: ${result.successfulTestCount}"
2093 index << "<li>Skipped tests: ${result.skippedTestCount}"
2094 index << "</ul></body></html>"
2095 }
2096 }
2097
2098 // Events to stdout/err are appended to the files in the test directories.
2099 task.onOutput { desc, event ->
Ian Zerny89f16cf2021-04-29 21:10:09 +02002100 withTestResultEntryWriter(reportDir, desc, event.getDestination().name(), true, {
2101 it.append(event.getMessage())
2102 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002103 }
2104
Ian Zerny27ea4c72021-04-29 22:35:49 +02002105 task.beforeTest { desc ->
2106 // Remove any stale output files before running the test.
2107 for (def destType : TestOutputEvent.Destination.values()) {
2108 def destFile = getTestResultEntryOutputFile(reportDir, desc, destType.name())
2109 if (destFile.exists()) {
2110 delete destFile
2111 }
2112 }
2113 }
2114
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002115 task.afterTest { desc, result ->
2116 if (result.getTestCount() != 1) {
2117 throw new IllegalStateException("Unexpected test with more than one result: ${desc}")
2118 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002119 // Clear any previous result files.
2120 for (def resultType : TestResult.ResultType.values()) {
2121 delete getTestResultEntryOutputFile(reportDir, desc, resultType.name())
2122 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002123 // Emit the result type status in a file of the same name: SUCCESS, FAILURE or SKIPPED.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002124 withTestResultEntryWriter(reportDir, desc, result.getResultType().name(), false, {
2125 it.append(result.getResultType().name())
2126 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002127 // Emit the test time.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002128 withTestResultEntryWriter(reportDir, desc, "time", false, {
2129 it.append("${result.getEndTime() - result.getStartTime()}")
2130 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002131 // For failed tests, update the index and emit stack trace information.
2132 if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002133 def title = escapeHtml("${desc.className}.${desc.name}")
2134 def link = getTestReportEntryURL(reportDir, desc)
2135 index << "<li><a href=\"${link}\">${title}</a></li>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002136 if (!result.exceptions.isEmpty()) {
2137 printAllStackTracesToFile(
2138 result.exceptions,
2139 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002140 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002141 desc,
2142 "exceptions-raw.txt"))
2143 filterStackTraces(result)
2144 printAllStackTracesToFile(
2145 result.exceptions,
2146 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002147 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002148 desc,
2149 "exceptions-filtered.txt"))
2150 if (shouldRetrace()) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002151 withTestResultEntryWriter(reportDir, desc, "exceptions-retraced.txt", false, { writer ->
2152 result.exceptions.forEach { writer.append(retrace(it)) }
2153 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002154 }
2155 }
2156 }
2157 }
2158}
2159
Rico Windf2f4c292021-04-23 07:06:13 +02002160def testTimes = [:]
Ian Zerny475e4012021-04-29 14:01:49 +02002161def numberOfTestTimesToPrint = 100
Rico Windf2f4c292021-04-23 07:06:13 +02002162
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002163test { task ->
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002164
2165 dependsOn buildLibraryDesugarConversions
2166 dependsOn getJarsFromSupportLibs
2167 // R8.jar is required for running bootstrap tests.
2168 dependsOn r8
2169
Ian Zerny27ea4c72021-04-29 22:35:49 +02002170 def useTestingState = project.hasProperty('testing-state')
2171 if (useTestingState) {
2172 setUpTestingState(task)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002173 }
2174
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +02002175 if (project.hasProperty('generate_golden_files_to')) {
2176 systemProperty 'generate_golden_files_to', project.property('generate_golden_files_to')
2177 assert project.hasProperty('HEAD_sha1')
2178 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2179 }
2180
2181 if (project.hasProperty('use_golden_files_in')) {
2182 systemProperty 'use_golden_files_in', project.property('use_golden_files_in')
2183 assert project.hasProperty('HEAD_sha1')
2184 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2185 }
Ian Zerny4b0de282019-06-28 09:32:24 +02002186
Morten Krogh-Jespersendcb967e2021-12-02 11:18:39 +01002187 if (project.hasProperty('kotlin_compiler_dev')) {
2188 systemProperty 'com.android.tools.r8.kotlincompilerdev', '1';
2189 }
2190
2191 if (project.hasProperty('kotlin_compiler_old')) {
2192 systemProperty 'com.android.tools.r8.kotlincompilerold', '1';
2193 }
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002194
Ian Zerny27ea4c72021-04-29 22:35:49 +02002195 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002196 testLogging.exceptionFormat = 'full'
2197 if (project.hasProperty('print_test_stdout')) {
2198 testLogging.showStandardStreams = true
2199 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002200 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002201 if (project.hasProperty('dex_vm') && project.property('dex_vm') != 'default') {
Ian Zerny324d7612019-03-20 10:52:28 +01002202 println "NOTE: Running with non default vm: " + project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002203 systemProperty 'dex_vm', project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002204 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002205
Ian Zerny324d7612019-03-20 10:52:28 +01002206 // Forward runtime configurations for test parameters.
2207 if (project.hasProperty('runtimes')) {
2208 println "NOTE: Running with runtimes: " + project.property('runtimes')
2209 systemProperty 'runtimes', project.property('runtimes')
Ian Zerny4dfd5a52019-03-12 07:56:11 +01002210 }
2211
Christoffer Quist Adamsen748e4662019-08-23 14:53:49 +02002212 if (project.hasProperty('slow_tests')) {
2213 systemProperty 'slow_tests', project.property('slow_tests')
2214 }
2215
Søren Gjesseef195772021-03-11 16:04:42 +01002216
2217 if (project.hasProperty('desugar_jdk_json_dir')) {
2218 systemProperty 'desugar_jdk_json_dir', project.property('desugar_jdk_json_dir')
2219 }
Søren Gjesse4a45f9b2021-02-11 14:05:29 +01002220 if (project.hasProperty('desugar_jdk_libs')) {
2221 systemProperty 'desugar_jdk_libs', project.property('desugar_jdk_libs')
2222 }
2223
Ian Zerny27ea4c72021-04-29 22:35:49 +02002224 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002225 if (project.hasProperty('print_times') || project.hasProperty('one_line_per_test')) {
2226 afterTest { desc, result ->
2227 def executionTime = (result.endTime - result.startTime) / 1000
2228 testTimes["${desc.name} [${desc.className}]"] = executionTime
2229 }
2230 afterSuite { desc, result ->
2231 // parent is null if all tests are done.
2232 if (desc.parent == null) {
2233 def sortedTimes = testTimes.sort({ e1, e2 -> e2.value <=> e1.value })
2234 sortedTimes.eachWithIndex { key, value, i ->
2235 if (i < numberOfTestTimesToPrint) println "$key: $value"
2236 }
2237 }
2238 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002239 }
Rico Windf2f4c292021-04-23 07:06:13 +02002240
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002241 if (project.hasProperty('one_line_per_test')) {
2242 beforeTest { desc ->
2243 println "Start executing test ${desc.name} [${desc.className}]"
Rico Windf88b6be2018-12-11 15:14:05 +01002244 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002245
2246 afterTest { desc, result ->
2247 if (result.resultType == TestResult.ResultType.FAILURE) {
2248 printStackTrace(result)
2249 }
2250 if (project.hasProperty('update_test_timestamp')) {
2251 file(project.getProperty('update_test_timestamp')).text = new Date().getTime()
2252 }
2253 println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
Rico Windda6836e2018-12-07 12:32:03 +01002254 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002255 } else {
2256 afterTest { desc, result ->
2257 if (result.resultType == TestResult.ResultType.FAILURE) {
2258 printStackTrace(result)
2259 }
Rico Windf88b6be2018-12-11 15:14:05 +01002260 }
2261 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002262 }
2263 if (project.hasProperty('no_internal')) {
2264 exclude "com/android/tools/r8/internal/**"
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02002265 } else {
2266 dependsOn buildExamplesProto
Mads Ager418d1ca2017-05-22 09:35:49 +02002267 }
2268 if (project.hasProperty('only_internal')) {
2269 include "com/android/tools/r8/internal/**"
2270 }
Rico Wind4e218292019-03-07 12:44:49 +01002271
Rico Windba151112020-10-01 08:16:33 +02002272 if (project.hasProperty('test_namespace')) {
2273 include "com/android/tools/r8/" + project.getProperty('test_namespace') + "/**"
2274 }
2275
Ian Zerny3ced9262022-03-29 11:06:02 +02002276 if (project.hasProperty('tool') && project.property('tool') == 'd8') {
2277 // Don't run anything, deprecated
2278 println "Running with deprecated tool d8, not running any tests"
2279 include ""
Mads Ager418d1ca2017-05-22 09:35:49 +02002280 }
2281 if (!project.hasProperty('all_tests')) {
2282 exclude "com/android/tools/r8/art/dx/**"
Mads Ager418d1ca2017-05-22 09:35:49 +02002283 }
Rico Windbc820812022-05-31 09:19:56 +02002284 if (project.hasProperty('no_arttests')) {
2285 exclude "com/android/tools/r8/art/**"
2286 }
Rico Wind8e2f7e42019-02-21 10:13:21 +01002287 if (project.hasProperty('shard_count') ) {
2288 assert project.hasProperty('shard_number')
2289 int shard_count = project.getProperty('shard_count') as Integer
2290 int shard_number = project.getProperty('shard_number') as Integer
2291 assert shard_count < 65536
2292 assert shard_number < shard_count
2293 exclude {
2294 entry ->
2295 // Don't leave out directories. Leaving out a directory means all entries below.
2296 if (entry.file.isDirectory()) {
2297 return false
2298 }
2299 def first4 = entry.getRelativePath().toString().md5().substring(0, 4)
2300 int hash = Integer.parseInt(first4, 16)
2301 return hash % shard_count != shard_number
2302 }
2303 }
Tamas Kenezb77b7d82017-08-17 14:05:16 +02002304 if (project.hasProperty('test_dir')) {
2305 systemProperty 'test_dir', project.property('test_dir')
2306 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002307 if (project.hasProperty('r8lib')) {
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002308 dependsOn configureTestForR8Lib
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002309 // R8lib should be used instead of the main output and all the tests in
2310 // r8 should be mapped and exists in r8LibTestPath.
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02002311 classpath = sourceSets.test.runtimeClasspath.filter {
2312 !it.getAbsolutePath().contains("/build/")
2313 }
2314 classpath += files([r8LibPath, r8LibTestPath])
Ian Zerny5fffb0a2019-02-11 13:54:22 +01002315 testClassesDirs = files(r8LibTestPath)
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002316 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002317 if (OperatingSystem.current().isLinux()
2318 || OperatingSystem.current().isMacOsX()
2319 || OperatingSystem.current().isWindows()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002320 if (OperatingSystem.current().isMacOsX()) {
2321 logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " +
2322 "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " +
2323 "See tools/docker/README.md for details.")
2324 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002325 if (OperatingSystem.current().isWindows()) {
2326 logger.lifecycle("WARNING: Testing in only partially supported on Windows. " +
2327 "Art only runs on Linux and tests requiring Art will be skipped")
2328 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002329 dependsOn downloadDeps
2330 dependsOn buildExamples
Sebastien Hertzd3313772018-01-16 14:12:37 +01002331 dependsOn buildKotlinR8TestResources
Mads Ager418d1ca2017-05-22 09:35:49 +02002332 dependsOn buildSmali
Mads Ager418d1ca2017-05-22 09:35:49 +02002333 dependsOn buildPreNJdwpTestsJar
Mathias Ravcd795072018-03-22 12:47:32 +01002334 dependsOn buildPreNJdwpTestsDex
Clément Bérac94b6202021-09-28 11:16:58 +00002335 dependsOn compileTestNGRunner
clementberaa92e3cd2019-07-12 14:13:22 +02002336 dependsOn provideArtFrameworksDependencies
Mads Ager418d1ca2017-05-22 09:35:49 +02002337 } else {
2338 logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002339 "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.")
Mads Ager418d1ca2017-05-22 09:35:49 +02002340 }
2341}
2342
2343// The Art tests we use for R8 are pre-build and downloaded from Google Cloud Storage.
2344//
2345// To build and upload a new set of the Art tests for use with R8 follow these steps:
2346//
2347// First of all an Android checkout is required. Currently it must be located
2348// in $HOME/android/master.
2349//
2350// TODO(ricow): simplify this
2351//
2352// Before: update the checked in art, see scripts/update-host-art.sh
2353//
2354// 1. Get an android checkout in $HOME/android/master and apply the patch from
2355// https://android-review.googlesource.com/#/c/294187/
2356//
2357// 2. run the following commands in the Android checkout directory:
2358//
2359// source build/envsetup.sh
Søren Gjesse34b77732017-07-07 13:56:21 +02002360// lunch aosp_angler-userdebug # or lunch aosp_angler-eng
2361// m desugar
2362// m -j30 test-art-host
2363// DESUGAR=false ANDROID_COMPILE_WITH_JACK=false art/test.py --host -t 001-HelloWorld
2364//
2365// Without running the test.py command the classes.jar file used by desugar in
2366// $HOME/android/master/out/host/common/obj/JAVA_LIBRARIES/core-oj-hostdex_intermediates/
2367// seems to be missing - there is probably also a make target to build it more directly
Mads Ager418d1ca2017-05-22 09:35:49 +02002368//
2369// 3. In the R8 project root directory, make sure we have a clean state before starting:
2370// tools/gradle.py downloadDeps
2371// tools/gradle.py clean
2372// rm -rf tests/art
2373//
2374// 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 +02002375// Make sure you have smali on your path, please use the build binary in the
2376// out/host/linux-x86/bin directory of the android checkout. Currently this is version pre 2.2.1,
2377// if that is updated the call to smali in "task "${smaliToDexTask}"(type: Exec)" below might
2378// 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 +02002379// After Android O, Jack is no longer alive, do not forget to uncomment call to buildArtTest for
2380// Jack if you build an android version using Jack.
Mads Ager418d1ca2017-05-22 09:35:49 +02002381//
Søren Gjesse34b77732017-07-07 13:56:21 +02002382// PATH=$HOME/android/master/out/host/linux-x86/bin:$PATH tools/gradle.py -Pandroid_source buildArtTests
Mads Ager418d1ca2017-05-22 09:35:49 +02002383//
2384// 4a. If any failures are produced in step 4, figure out what went wrong and add an entry in
2385// skippedTests with an explanation. Rerun from step 3.
2386//
2387// 5. Run the tests:
2388// tools/gradle.py clean
2389// tools/test.py
2390//
Søren Gjesse34b77732017-07-07 13:56:21 +02002391// 5a. If any more tests fail, either fix the issue or add them to the failuresToTriage list (note
2392// that you need to change "_" to "-" from stdout). Rerun from step 5 if anything was added to
2393// failuresToTriage.
Mads Ager418d1ca2017-05-22 09:35:49 +02002394//
Søren Gjesse34b77732017-07-07 13:56:21 +02002395// 6. To upload a new version to Google Cloud Storage:
Mads Ager418d1ca2017-05-22 09:35:49 +02002396// cd tests
2397// upload_to_google_storage.py -a --bucket r8-deps art
Søren Gjesse34b77732017-07-07 13:56:21 +02002398//
2399// 7. Update the manifest file describing the Android repo used:
2400// repo manifest -o <r8-checkout-root>/tools/linux/aosp_master_manifest.xml -r
Mads Ager418d1ca2017-05-22 09:35:49 +02002401
Mads Ager418d1ca2017-05-22 09:35:49 +02002402def androidCheckoutDir = file("${System.env.HOME}/android/master")
Mads Ager418d1ca2017-05-22 09:35:49 +02002403
2404def artTestDir = file("${androidCheckoutDir}/art/test")
2405
2406if (project.hasProperty('android_source')) {
2407 task buildArtTests {
2408 outputs.upToDateWhen { false }
2409 def toBeTriaged = [
2410 "903-hello-tagging",
2411 "904-object-allocation",
2412 "905-object-free",
2413 "906-iterate-heap",
2414 "907-get-loaded-classes",
2415 "908-gc-start-finish",
2416 "954-invoke-polymorphic-verifier",
2417 "955-methodhandles-smali",
2418 "596-monitor-inflation",
2419 ]
2420 def skippedTests = toBeTriaged + [
2421 // This test produces no jar.
2422 "000-nop",
2423 // This does not build, as it tests the error when the application exceeds more
2424 // than 65536 methods
2425 "089-many-methods",
2426 // Requires some jack beta jar
2427 "956-methodhandles",
2428 ]
2429
2430 def skippedTestsDx = [
2431 // Tests with custom build scripts, where javac is not passed the options
2432 // -source 1.7 -target 1.7.
2433 "462-checker-inlining-across-dex-files",
2434 "556-invoke-super",
2435 "569-checker-pattern-replacement",
2436 // These tests use jack even when --build-with-javac-dx is specified.
2437 "004-JniTest",
2438 "048-reflect-v8",
2439 "146-bad-interface",
2440 "563-checker-invoke-super",
2441 "580-checker-string-fact-intrinsics", // java.lang.StringFactory
2442 "604-hot-static-interface",
2443 "957-methodhandle-transforms",
2444 "958-methodhandle-emulated-stackframe",
2445 "959-invoke-polymorphic-accessors",
2446 "961-default-iface-resolution-gen",
2447 "962-iface-static",
2448 "963-default-range-smali",
2449 "964-default-iface-init-gen",
2450 "965-default-verify",
2451 "966-default-conflict",
2452 "967-default-ame",
2453 "968-default-partial-compile-gen",
2454 "969-iface-super",
2455 "970-iface-super-resolution-gen",
2456 "971-iface-super",
2457 // These tests does not build with --build-with-javac-dx
2458 "004-NativeAllocations", // Javac error
2459 "031-class-attributes",
2460 "138-duplicate-classes-check",
2461 "157-void-class", // Javac error
2462 "580-checker-string-factory-intrinsics",
2463 "612-jit-dex-cache",
2464 "613-inlining-dex-cache",
2465 "900-hello-plugin", // --experimental agents
2466 "901-hello-ti-agent", // --experimental agents
2467 "902-hello-transformation", // --experimental agents
2468 "909-attach-agent", // --experimental agents
2469 "946-obsolete-throw", // -source 1.7 -target 1.7, but use lambda
2470 "950-redefine-intrinsic", // -source 1.7 -target 1.7, but use method references
2471 "951-threaded-obsolete", // -source 1.7 -target 1.7, but use lambda
2472 "960-default-smali", // --experimental default-methods
2473 // These tests force the build to use jack
2474 "953-invoke-polymorphic-compiler",
2475 "958-methodhandle-stackframe",
2476 ]
2477
2478 def artTestBuildDir = file("${projectDir}/tests/art")
2479
2480 if (androidCheckoutDir.exists()) {
2481 dependsOn downloadDeps
2482 artTestBuildDir.mkdirs()
Mads Ager418d1ca2017-05-22 09:35:49 +02002483 artTestDir.eachDir { dir ->
2484 def name = dir.getName();
2485 def markerFile = dir.toPath().resolve("info.txt").toFile();
2486 if (markerFile.exists() && !(name in skippedTests)) {
2487 if (!(name in skippedTestsDx)) {
Rico Windde2af6c2019-03-26 15:21:08 +01002488 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir);
Mads Ager418d1ca2017-05-22 09:35:49 +02002489 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002490 }
2491 }
2492 }
2493 doFirst {
2494 if (!androidCheckoutDir.exists()) {
2495 throw new InvalidUserDataException(
2496 "This task requires an Android checkout in ${androidCheckoutDir}");
Mads Ager418d1ca2017-05-22 09:35:49 +02002497 }
2498 }
2499 doLast {
2500 copy {
2501 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest64")
2502 into file("${artTestBuildDir}/lib64")
2503 include 'lib*.so'
2504 }
2505 copy {
2506 from file("${androidCheckoutDir}/out/host/linux-x86/lib64")
2507 into file("${artTestBuildDir}/lib64")
2508 include 'libart.so'
2509 include 'libbacktrace.so'
2510 include 'libbase.so'
2511 include 'libc++.so'
2512 include 'libcutils.so'
2513 include 'liblz4.so'
2514 include 'liblzma.so'
2515 include 'libnativebridge.so'
2516 include 'libnativeloader.so'
2517 include 'libsigchain.so'
2518 include 'libunwind.so'
2519 include 'libziparchive.so'
2520 }
2521 copy {
2522 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest")
2523 into file("${artTestBuildDir}/lib")
2524 include 'lib*.so'
2525 }
2526 copy {
2527 from file("${androidCheckoutDir}/out/host/linux-x86/lib")
2528 into file("${artTestBuildDir}/lib")
2529 include 'libart.so'
2530 include 'libbacktrace.so'
2531 include 'libbase.so'
2532 include 'libc++.so'
2533 include 'libcutils.so'
2534 include 'liblz4.so'
2535 include 'liblzma.so'
2536 include 'libnativebridge.so'
2537 include 'libnativeloader.so'
2538 include 'libsigchain.so'
2539 include 'libunwind.so'
2540 include 'libziparchive.so'
2541 }
2542 }
2543 }
2544}
2545
Rico Windde2af6c2019-03-26 15:21:08 +01002546def buildArtTest(androidCheckoutDir, artTestBuildDir, dir) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002547 def artTestDir = file("${androidCheckoutDir}/art/test")
2548 def artRunTestScript = file("${artTestDir}/run-test")
2549 def dxExecutable = new File("tools/linux/dx/bin/dx");
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02002550 def dexMergerExecutable = Utils.dexMergerExecutable()
Mads Ager418d1ca2017-05-22 09:35:49 +02002551
Søren Gjesse34b77732017-07-07 13:56:21 +02002552 def name = dir.getName()
Rico Windde2af6c2019-03-26 15:21:08 +01002553 def buildTask = "build_art_test_dx_${name}"
2554 def sanitizeTask = "sanitize_art_test_dx_${name}"
2555 def copyCheckTask = "copy_check_art_test_dx_${name}"
2556 def smaliToDexTask = "smali_to_dex_dx_${name}"
Mads Ager418d1ca2017-05-22 09:35:49 +02002557
2558 def buildInputs = fileTree(dir: dir, include: '**/*')
Rico Windde2af6c2019-03-26 15:21:08 +01002559 def testDir = file("${artTestBuildDir}/dx/${name}")
Mads Ager418d1ca2017-05-22 09:35:49 +02002560 def outputJar = testDir.toPath().resolve("${name}.jar").toFile()
2561 testDir.mkdirs()
Rico Windde2af6c2019-03-26 15:21:08 +01002562 task "$buildTask"(type: Exec) {
2563 outputs.upToDateWhen { false }
2564 inputs.file buildInputs
2565 executable "${artRunTestScript}"
2566 args "--host"
2567 args "--build-only"
2568 args "--build-with-javac-dx"
2569 args "--output-path", "${testDir}"
2570 args "${name}"
2571 environment DX: "${dxExecutable.absolutePath}"
2572 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
2573 environment ANDROID_BUILD_TOP: "${androidCheckoutDir}"
2574 outputs.file outputJar
Mads Ager418d1ca2017-05-22 09:35:49 +02002575 }
2576 task "${sanitizeTask}"(type: Exec, dependsOn: buildTask) {
2577 outputs.upToDateWhen { false }
2578 executable "/bin/bash"
2579 args "-c"
2580 args "rm -rf ${testDir}/smali_*.dex ${testDir}/*-ex.dex ${testDir}/*-ex.jar" +
2581 " ${testDir}/classes-ex ${testDir}/check"
2582 }
2583
2584 task "${smaliToDexTask}"(type: Exec) {
Mikaël Peltiere116cb62017-10-05 10:50:30 +02002585 // Directory that contains smali files is either smali, or smali/art
2586 def smali_dir = file("${dir}/smali/art")
2587 if (smali_dir.exists()) {
2588 workingDir "${testDir}/smali/art"
2589 } else {
2590 workingDir "${testDir}/smali"
2591 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002592 executable "/bin/bash"
Søren Gjesse34b77732017-07-07 13:56:21 +02002593 // This is the command line options for smali prior to 2.2.1, where smali got a new
2594 // command line interface.
2595 args "-c", "smali a *.smali"
2596 // This is the command line options for smali 2.2.1 and later.
2597 // args "-c", "smali -o out.dex *.smali"
Mads Ager418d1ca2017-05-22 09:35:49 +02002598 }
2599
2600 task "${copyCheckTask}"(type: Copy, dependsOn: sanitizeTask) {
2601 def smali_dir = file("${dir}/smali")
2602 outputs.upToDateWhen { false }
Rico Windde2af6c2019-03-26 15:21:08 +01002603 if (smali_dir.exists()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002604 dependsOn smaliToDexTask
2605 }
2606 from("${artTestDir}/${name}") {
2607 include 'check'
2608 }
2609 into testDir
2610 }
2611
2612 return copyCheckTask
2613}
2614
2615task javadocD8(type: Javadoc) {
Ian Zerny850f13d2018-01-04 11:25:38 +01002616 title "D8 API"
Mads Ager418d1ca2017-05-22 09:35:49 +02002617 classpath = sourceSets.main.compileClasspath
2618 source = sourceSets.main.allJava
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002619 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002620 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002621 include '**/com/android/tools/r8/BaseCommand.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002622 include '**/com/android/tools/r8/BaseCompilerCommand.java'
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002623 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002624 include '**/com/android/tools/r8/CompilationFailedException.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002625 include '**/com/android/tools/r8/CompilationMode.java'
2626 include '**/com/android/tools/r8/D8.java'
2627 include '**/com/android/tools/r8/D8Command.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002628 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2629 include '**/com/android/tools/r8/DexFilePerClassFileConsumer.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002630 include '**/com/android/tools/r8/Diagnostic.java'
2631 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002632 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2633 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002634 include '**/com/android/tools/r8/ProgramConsumer.java'
2635 include '**/com/android/tools/r8/ProgramResource.java'
2636 include '**/com/android/tools/r8/ProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002637 include '**/com/android/tools/r8/Resource.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002638 include '**/com/android/tools/r8/ResourceException.java'
2639 include '**/com/android/tools/r8/StringConsumer.java'
2640 include '**/com/android/tools/r8/StringResource.java'
2641 include '**/com/android/tools/r8/Version.java'
2642 include '**/com/android/tools/r8/origin/*.java'
2643}
2644
2645task javadocR8(type: Javadoc) {
2646 title "R8 API"
2647 classpath = sourceSets.main.compileClasspath
2648 source = sourceSets.main.allJava
2649 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
2650 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
2651 include '**/com/android/tools/r8/BaseCommand.java'
2652 include '**/com/android/tools/r8/BaseCompilerCommand.java'
2653 include '**/com/android/tools/r8/ClassFileConsumer.java'
2654 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
2655 include '**/com/android/tools/r8/CompilationFailedException.java'
2656 include '**/com/android/tools/r8/CompilationMode.java'
2657 include '**/com/android/tools/r8/R8.java'
2658 include '**/com/android/tools/r8/R8Command.java'
2659 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2660 include '**/com/android/tools/r8/Diagnostic.java'
2661 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002662 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2663 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002664 include '**/com/android/tools/r8/ProgramConsumer.java'
2665 include '**/com/android/tools/r8/ProgramResource.java'
2666 include '**/com/android/tools/r8/ProgramResourceProvider.java'
2667 include '**/com/android/tools/r8/Resource.java'
2668 include '**/com/android/tools/r8/ResourceException.java'
2669 include '**/com/android/tools/r8/StringConsumer.java'
2670 include '**/com/android/tools/r8/StringResource.java'
2671 include '**/com/android/tools/r8/Version.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002672 include '**/com/android/tools/r8/origin/*.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002673}
Søren Gjesse39a909a2017-10-12 09:49:20 +02002674
2675task copyMavenDeps(type: Copy) {
2676 from configurations.compile into "$buildDir/deps"
Morten Krogh-Jespersen75773302019-01-07 09:45:08 +01002677 from configurations.compileClasspath into "$buildDir/deps"
Søren Gjesse39a909a2017-10-12 09:49:20 +02002678 from configurations.testCompile into "$buildDir/deps"
2679}
Mikaël Peltier61633d42017-10-13 16:51:06 +02002680
Rico Wind23a05112019-03-27 08:00:44 +01002681task printMavenDeps {
2682 // Only actually print to stdout when we are updating.
2683 if (project.hasProperty('updatemavendeps')) {
2684 for (Configuration config : configurations) {
2685 if (!config.isCanBeResolved()) {
2686 continue
2687 }
2688 def componentIds = config.incoming.resolutionResult.allDependencies.collect {
2689 it.selected.id
2690 }
2691 def result = dependencies.createArtifactResolutionQuery()
2692 .forComponents(componentIds)
2693 .withArtifacts(MavenModule, MavenPomArtifact)
2694 .execute()
2695 for (component in result.resolvedComponents) {
2696 component.getArtifacts(MavenPomArtifact).each {
2697 println "POM: ${it.file} ${component.id}"
2698 }
2699 }
2700 config.each {
2701 println "JAR: ${it}"
2702 }
2703 }
2704 }
2705}
Ian Zerny9713c032020-01-23 11:41:58 +01002706
2707allprojects {
2708 tasks.withType(Exec) {
2709 doFirst {
Ian Zerny9794cfd2020-02-04 07:57:35 +01002710 println commandLine.join(' ')
Ian Zerny9713c032020-01-23 11:41:58 +01002711 }
2712 }
Søren Gjesse494609e2020-05-29 15:35:12 +02002713}