blob: 5d4868a7f91431fff0d8475dbc7f518ed54586f7 [file] [log] [blame]
Mads Ager418d1ca2017-05-22 09:35:49 +02001// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
Ian Zerny5fffb0a2019-02-11 13:54:22 +01004
Jake Wharton2d7aab82019-09-13 10:24:26 -04005import dx.DexMergerTask
6import dx.DxTask
Ian Zerny5fffb0a2019-02-11 13:54:22 +01007import net.ltgt.gradle.errorprone.CheckSeverity
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02008import org.gradle.internal.os.OperatingSystem
Jake Wharton2d7aab82019-09-13 10:24:26 -04009import smali.SmaliTask
Ian Zernyb2d27c42019-02-20 09:09:41 +010010import tasks.DownloadDependency
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +000011import tasks.GetJarsFromConfiguration
Stephan Herhut417a72a2017-07-18 10:38:30 +020012import utils.Utils
Mads Ager418d1ca2017-05-22 09:35:49 +020013
Ian Zerny5fffb0a2019-02-11 13:54:22 +010014buildscript {
15 repositories {
Rico Wind23a05112019-03-27 08:00:44 +010016 maven {
Rico Wind70d614f2020-01-31 08:45:21 +010017 url 'https://storage.googleapis.com/r8-deps/maven_mirror/'
Rico Wind23a05112019-03-27 08:00:44 +010018 }
Ian Zerny5fffb0a2019-02-11 13:54:22 +010019 mavenCentral()
Jake Wharton5e5b5232019-09-17 16:13:32 -040020 gradlePluginPortal()
Morten Krogh-Jespersen68cc4b62019-03-21 10:32:17 +010021 jcenter()
Ian Zerny5fffb0a2019-02-11 13:54:22 +010022 }
Ian Zerny5fffb0a2019-02-11 13:54:22 +010023}
24
25plugins {
26 id "net.ltgt.errorprone" version "0.7"
27}
28
29apply plugin: 'java'
30apply plugin: 'idea'
31
Sebastien Hertz143ed112018-02-13 14:26:41 +010032ext {
33 androidSupportVersion = '25.4.0'
Søren Gjesse4832e8b2021-06-30 09:25:25 +020034 asmVersion = '9.2' // When updating update tools/asmifier.py and Toolhelper as well.
Sebastien Hertz143ed112018-02-13 14:26:41 +010035 espressoVersion = '3.0.0'
36 fastutilVersion = '7.2.0'
Søren Gjessea93b4262021-12-08 14:40:10 +010037 guavaVersion = '30.1.1-jre'
Sebastien Hertz143ed112018-02-13 14:26:41 +010038 joptSimpleVersion = '4.6'
Mads Ager48dd79e2018-05-15 09:13:55 +020039 gsonVersion = '2.7'
Morten Krogh-Jespersen94ff6762019-03-20 14:45:23 +010040 junitVersion = '4.13-beta-2'
Jinseong Jeone11145f2018-12-13 10:57:29 -080041 mockitoVersion = '2.10.0'
Morten Krogh-Jespersen358c8a72021-02-24 11:07:57 +010042 // The kotlin version is only here to specify the kotlin language level,
43 // all kotlin compilations are done in tests.
Morten Krogh-Jespersenc9e17cb2021-11-30 08:22:54 +010044 kotlinVersion = '1.6.0'
Morten Krogh-Jespersen8fac8cf2021-12-02 09:58:01 +010045 kotlinExtMetadataJVMVersion = '0.4.1'
Sebastien Hertz143ed112018-02-13 14:26:41 +010046 smaliVersion = '2.2b4'
Ian Zerny5fffb0a2019-02-11 13:54:22 +010047 errorproneVersion = '2.3.2'
clementbera4f9c2a92019-07-09 08:50:37 +020048 testngVersion = '6.10'
Sebastien Hertz143ed112018-02-13 14:26:41 +010049}
50
Mads Ager418d1ca2017-05-22 09:35:49 +020051repositories {
Rico Wind23a05112019-03-27 08:00:44 +010052 maven {
Rico Wind70d614f2020-01-31 08:45:21 +010053 url 'https://storage.googleapis.com/r8-deps/maven_mirror/'
Rico Wind23a05112019-03-27 08:00:44 +010054 }
Jake Wharton5e5b5232019-09-17 16:13:32 -040055 google()
Mads Ager418d1ca2017-05-22 09:35:49 +020056 mavenCentral()
57}
58
Jinseong Jeon05064e12018-07-03 00:21:12 -070059if (project.hasProperty('with_code_coverage')) {
60 apply plugin: 'jacoco'
61}
62
Mads Ager418d1ca2017-05-22 09:35:49 +020063// Custom source set for example tests and generated tests.
64sourceSets {
Morten Krogh-Jespersen4e10d682022-05-05 15:57:47 +020065 main {
66 java {
67 srcDirs = ['src/main/java']
68 }
69 resources {
70 srcDirs "third_party/api_database/api_database"
71 }
72 }
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +020073 main11 {
74 java {
75 srcDirs = ['src/main/java']
76 }
Morten Krogh-Jespersen798aac02021-10-06 15:32:20 +020077 resources {
Morten Krogh-Jespersen4e10d682022-05-05 15:57:47 +020078 srcDirs "third_party/api_database/api_database"
Morten Krogh-Jespersen798aac02021-10-06 15:32:20 +020079 }
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +020080 }
Mads Ager418d1ca2017-05-22 09:35:49 +020081 test {
82 java {
83 srcDirs = [
clementbera0fe940d2019-04-23 12:45:18 +020084 'src/test/java',
85 'build/generated/test/java',
86 ]
87 }
88 }
Yohann Rousselbb571622017-11-09 10:47:36 +010089 apiUsageSample {
90 java {
Mathias Rave3f3c522018-05-30 08:22:17 +020091 srcDirs = ['src/test/apiUsageSample', 'src/main/java']
92 include 'com/android/tools/apiusagesample/*.java'
93 include 'com/android/tools/r8/BaseCompilerCommandParser.java'
94 include 'com/android/tools/r8/D8CommandParser.java'
95 include 'com/android/tools/r8/R8CommandParser.java'
96 include 'com/android/tools/r8/utils/FlagFile.java'
Yohann Rousselbb571622017-11-09 10:47:36 +010097 }
Yohann Rousselbb571622017-11-09 10:47:36 +010098 }
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +010099 cfSegments {
100 java {
101 srcDirs = ['third_party/classlib/java', 'src/cf_segments/java']
102 }
103 output.resourcesDir = 'build/classes/cfSegments'
104 }
Søren Gjesse17fc67d2019-12-04 14:50:17 +0100105 libraryDesugarConversions {
106 java {
107 srcDirs = ['src/library_desugar/java']
108 }
109 output.resourcesDir = 'build/classes/library_desugar_conversions'
110 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200111 debugTestResources {
112 java {
113 srcDirs = ['src/test/debugTestResources']
114 }
115 output.resourcesDir = 'build/classes/debugTestResources'
116 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +0200117 debugTestResourcesJava8 {
118 java {
119 srcDirs = ['src/test/debugTestResourcesJava8']
120 }
121 output.resourcesDir = 'build/classes/debugTestResourcesJava8'
122 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200123 examples {
124 java {
Ivan Gavrilovic664f34d2018-11-09 10:02:40 -0800125 srcDirs = ['src/test/examples']
Mads Ager418d1ca2017-05-22 09:35:49 +0200126 }
127 output.resourcesDir = 'build/classes/examples'
128 }
Ian Zernyd3020482019-04-25 07:05:04 +0200129 examplesJava9 {
130 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200131 srcDirs = ['src/test/examplesJava9']
Ian Zernyd3020482019-04-25 07:05:04 +0200132 }
133 }
Jake Wharton2000b2f2019-12-11 20:37:49 -0500134 examplesJava10 {
135 java {
136 srcDirs = ['src/test/examplesJava10']
137 }
138 }
Ian Zernyd3020482019-04-25 07:05:04 +0200139 examplesJava11 {
140 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200141 srcDirs = ['src/test/examplesJava11']
142 }
143 }
Søren Gjessee9966932021-09-15 17:08:37 +0200144 examplesJava17 {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100145 java {
Søren Gjessee9966932021-09-15 17:08:37 +0200146 srcDirs = ['src/test/examplesJava17']
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100147 }
148 }
Søren Gjessed1e08992022-02-07 16:46:31 +0100149 examplesJava18 {
150 java {
151 srcDirs = ['src/test/examplesJava18']
152 }
153 }
clementberaefa10522019-07-11 11:20:46 +0200154 examplesTestNGRunner {
clementbera4f9c2a92019-07-09 08:50:37 +0200155 java {
156 srcDirs = ['src/test/testngrunner']
157 }
158 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200159 examplesAndroidN {
160 java {
161 srcDirs = ['src/test/examplesAndroidN']
162 }
163 output.resourcesDir = 'build/classes/examplesAndroidN'
164 }
165 examplesAndroidO {
166 java {
167 srcDirs = ['src/test/examplesAndroidO']
168 }
169 output.resourcesDir = 'build/classes/examplesAndroidO'
170 }
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +0200171 examplesAndroidP {
172 java {
173 srcDirs = ['src/test/examplesAndroidP']
174 }
175 output.resourcesDir = 'build/classes/examplesAndroidP'
176 }
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200177 examplesProto {
178 java {
179 srcDirs = ['src/test/examplesProto']
180 }
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +0200181 compileClasspath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
182 compileClasspath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200183 output.resourcesDir = 'build/classes/examplesProto'
184 }
Sebastien Hertzd3313772018-01-16 14:12:37 +0100185 kotlinR8TestResources {
186 java {
187 srcDirs = ['src/test/kotlinR8TestResources']
188 }
189 output.resourcesDir = 'build/classes/kotlinR8TestResources'
190 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200191}
192
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800193// Ensure importing into IntelliJ IDEA use the same output directories as Gradle. In tests we
194// use the output path for tests (ultimately through ToolHelper.getClassPathForTests()) and
195// therefore these paths need to be the same. See https://youtrack.jetbrains.com/issue/IDEA-175172
196// for context.
197idea {
198 sourceSets.all { SourceSet sources ->
199 module {
200 if (sources.name == "main") {
201 sourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100202 outputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800203 } else {
204 testSourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100205 testOutputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800206 }
207 }
208 }
209}
210
Yohann Roussel126f6872017-08-03 16:25:32 +0200211configurations {
212 supportLibs
213}
214
Mads Ager418d1ca2017-05-22 09:35:49 +0200215dependencies {
Mads Agerd1d0da92018-12-10 13:56:50 +0100216 implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion"
217 implementation "com.google.code.gson:gson:$gsonVersion"
Mads Ager0aa48052017-09-15 12:39:15 +0200218 // Include all of guava when compiling the code, but exclude annotations that we don't
219 // need from the packaging.
Sebastien Hertz143ed112018-02-13 14:26:41 +0100220 compileOnly("com.google.guava:guava:$guavaVersion")
Mads Agerd1d0da92018-12-10 13:56:50 +0100221 implementation("com.google.guava:guava:$guavaVersion", {
Mads Ager0aa48052017-09-15 12:39:15 +0200222 exclude group: 'com.google.errorprone'
223 exclude group: 'com.google.code.findbugs'
224 exclude group: 'com.google.j2objc'
225 exclude group: 'org.codehaus.mojo'
226 })
Mads Agerd1d0da92018-12-10 13:56:50 +0100227 implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
228 implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
229 implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
230 implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
231 implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
232 implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
233 implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200234
235 main11Implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion"
236 main11Implementation "com.google.code.gson:gson:$gsonVersion"
237 // Include all of guava when compiling the code, but exclude annotations that we don't
238 // need from the packaging.
239 main11CompileOnly("com.google.guava:guava:$guavaVersion")
240 main11Implementation("com.google.guava:guava:$guavaVersion", {
241 exclude group: 'com.google.errorprone'
242 exclude group: 'com.google.code.findbugs'
243 exclude group: 'com.google.j2objc'
244 exclude group: 'org.codehaus.mojo'
245 })
246 main11Implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
247 main11Implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
248 main11Implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
249 main11Implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
250 main11Implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
251 main11Implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
252 main11Implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200253
clementberaefa10522019-07-11 11:20:46 +0200254 examplesTestNGRunnerCompile group: 'org.testng', name: 'testng', version: testngVersion
Ian Zerny161ff742022-01-20 12:39:40 +0100255
Mads Ager418d1ca2017-05-22 09:35:49 +0200256 testCompile sourceSets.examples.output
Sebastien Hertz143ed112018-02-13 14:26:41 +0100257 testCompile "junit:junit:$junitVersion"
Ian Zerny161ff742022-01-20 12:39:40 +0100258 testCompile "com.google.guava:guava:$guavaVersion"
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100259 testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
260 testCompile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100261 testCompile group: 'org.smali', name: 'smali', version: smaliVersion
Mads Ager418d1ca2017-05-22 09:35:49 +0200262 testCompile files('third_party/jasmin/jasmin-2.4.jar')
263 testCompile files('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
Jean-Marie Henaffce162f32017-10-04 10:39:27 +0200264 testCompile files('third_party/ddmlib/ddmlib.jar')
Ian Zerny161ff742022-01-20 12:39:40 +0100265 testCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
266 testCompile group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
267 testCompile group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
268 testCompile group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
269 testCompile group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
270 testCompile group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
271
Sebastien Hertz143ed112018-02-13 14:26:41 +0100272 examplesAndroidOCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
273 examplesAndroidPCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
Stephan Herhut52cb1022017-10-24 15:10:41 +0200274 // Import Guava for @Nullable annotation
Sebastien Hertz143ed112018-02-13 14:26:41 +0100275 examplesCompile "com.google.guava:guava:$guavaVersion"
Jinseong Jeone11145f2018-12-13 10:57:29 -0800276 examplesCompile "junit:junit:$junitVersion"
277 examplesCompile "org.mockito:mockito-core:$mockitoVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100278 supportLibs "com.android.support:support-v4:$androidSupportVersion"
279 supportLibs "junit:junit:$junitVersion"
280 supportLibs "com.android.support.test.espresso:espresso-core:$espressoVersion"
Yohann Rousselbb571622017-11-09 10:47:36 +0100281 apiUsageSampleCompile sourceSets.main.output
Tamas Kenezb865eee2018-12-03 16:50:45 +0100282 apiUsageSampleCompile "com.google.guava:guava:$guavaVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100283 kotlinR8TestResourcesCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100284 errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")
Stephan Herhut417a72a2017-07-18 10:38:30 +0200285}
286
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100287def r8LibPath = "$buildDir/libs/r8lib.jar"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +0100288def r8LibExludeDepsPath = "$buildDir/libs/r8lib-exclude-deps.jar"
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200289def r8DesugaredPath = "$buildDir/libs/r8desugared.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100290def r8LibGeneratedKeepRulesPath = "$buildDir/generated/keep.txt"
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +0100291def r8LibTestPath = "$buildDir/classes/r8libtest"
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +0200292def java11ClassFiles = "$buildDir/classes/java/mainJava11"
293def r8RetracePath = "$buildDir/libs/r8retrace.jar"
294def r8RetraceExludeDepsPath = "$buildDir/libs/r8retrace-exclude-deps.jar"
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100295
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200296def osString = OperatingSystem.current().isLinux() ? "linux" :
297 OperatingSystem.current().isMacOsX() ? "mac" : "windows"
Mads Ager418d1ca2017-05-22 09:35:49 +0200298
299def cloudDependencies = [
300 "tests" : [
mikaelpeltierc2aa6652017-10-06 12:53:37 +0200301 "2017-10-04/art",
Rico Wind132bfb42019-03-08 09:27:36 +0100302 "2016-12-19/art"
Mads Ager418d1ca2017-05-22 09:35:49 +0200303 ],
304 "third_party": [
Rico Windf72fa152018-10-22 15:41:03 +0200305 "android_cts_baseline",
Morten Krogh-Jespersena31c3442022-06-02 21:07:50 +0200306 "android_jar/libcore_latest",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200307 "android_jar/lib-v14",
Stephan Herhutb3aca8b2017-12-22 14:14:53 +0100308 "android_jar/lib-v15",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200309 "android_jar/lib-v19",
310 "android_jar/lib-v21",
Stephan Herhutd48be0d2018-01-04 15:33:10 +0100311 "android_jar/lib-v22",
312 "android_jar/lib-v23",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200313 "android_jar/lib-v24",
314 "android_jar/lib-v25",
315 "android_jar/lib-v26",
Søren Gjessec2ffae82018-12-21 12:20:18 +0100316 "android_jar/lib-v27",
317 "android_jar/lib-v28",
Søren Gjesse02f52852019-09-04 17:44:03 +0200318 "android_jar/lib-v29",
Søren Gjessefa3f8042020-04-20 12:56:11 +0200319 "android_jar/lib-v30",
Søren Gjesse8c15ecd2021-03-22 16:41:53 +0100320 "android_jar/lib-v31",
Søren Gjesse29c8c5b2021-11-01 10:30:57 +0100321 "android_jar/lib-v32",
Søren Gjessea1f2c512022-02-04 09:51:45 +0100322 "android_jar/lib-v33",
Morten Krogh-Jespersen4e10d682022-05-05 15:57:47 +0200323 "api_database/api_database",
Morten Krogh-Jespersen7a47b732021-05-11 17:32:34 +0200324 "api-outlining/simple-app-dump",
Ian Zerny0d806882021-09-30 15:17:40 +0200325 "binary_compatibility_tests/compiler_api_tests",
Rico Windf72fa152018-10-22 15:41:03 +0200326 "core-lambda-stubs",
Søren Gjesse7dee79d2022-03-17 13:50:48 +0100327 "dagger/2.41",
Rico Windf72fa152018-10-22 15:41:03 +0200328 "dart-sdk",
329 "ddmlib",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200330 "gradle/gradle",
Christoffer Quist Adamsene1821392022-02-15 14:58:03 +0100331 "google/google-java-format/1.14.0",
Ian Zerny33c1c582019-09-17 12:43:45 +0200332 "google-java-format",
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +0200333 "iosched_2019",
Søren Gjesse97679312020-10-06 13:44:59 +0200334 "jacoco/0.8.2",
335 "jacoco/0.8.6",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200336 "jasmin",
Morten Krogh-Jespersen4187e162019-03-25 13:19:17 +0100337 "junit",
Rico Windf72fa152018-10-22 15:41:03 +0200338 "jdwp-tests",
Søren Gjesse70f75b12019-08-22 12:32:02 +0200339 "jsr223-api-1.0",
Søren Gjesse8f0e0992019-09-06 09:28:14 +0200340 "rhino-1.7.10",
Søren Gjessef6c0a782019-08-22 12:48:46 +0200341 "rhino-android-1.1.1",
Morten Krogh-Jespersenb328dc62020-05-12 09:11:52 +0200342 "kotlin/kotlin-compiler-1.3.11",
343 "kotlin/kotlin-compiler-1.3.41",
Morten Krogh-Jespersend32c8f22020-05-12 10:56:16 +0200344 "kotlin/kotlin-compiler-1.3.72",
Morten Krogh-Jespersen1c801b02021-02-11 10:15:23 +0100345 "kotlin/kotlin-compiler-1.4.20",
Morten Krogh-Jespersena9705f52021-07-05 11:28:02 +0200346 "kotlin/kotlin-compiler-1.5.0",
Morten Krogh-Jespersen61683192021-11-25 11:14:47 +0100347 "kotlin/kotlin-compiler-1.6.0",
Morten Krogh-Jespersen14153472020-05-19 15:40:47 +0200348 "kotlinx-coroutines-1.3.6",
Mathias Rav5285faf2018-03-20 14:16:32 +0100349 "openjdk/openjdk-rt-1.8",
Søren Gjesse952e1d52019-05-28 12:51:30 +0200350 "openjdk/desugar_jdk_libs",
Clément Béracac269b2021-03-17 07:53:43 +0000351 "openjdk/desugar_jdk_libs_11",
Ian Zernyc4598882022-02-25 19:26:44 +0100352 "openjdk/desugar_jdk_libs_legacy",
Søren Gjesse09c3dd02021-06-17 08:21:51 +0200353 "openjdk/desugar_jdk_libs_releases/1.0.9",
354 "openjdk/desugar_jdk_libs_releases/1.0.10",
355 "openjdk/desugar_jdk_libs_releases/1.1.0",
356 "openjdk/desugar_jdk_libs_releases/1.1.1",
357 "openjdk/desugar_jdk_libs_releases/1.1.5",
clementbera8dbfeda2019-07-03 11:24:13 +0200358 "openjdk/jdk-11-test",
Ian Zernye5886582022-03-03 11:01:08 +0100359 "opensource-apps/tivi",
Rico Windf72fa152018-10-22 15:41:03 +0200360 "proguard/proguard5.2.1",
361 "proguard/proguard6.0.1",
Ian Zerny7c920ac2020-07-01 20:12:01 +0200362 "proguard/proguard-7.0.0",
Morten Krogh-Jespersen0cade312022-03-22 13:40:21 +0000363 "retrace_benchmark",
Morten Krogh-Jespersen7cbae972021-08-31 16:54:31 +0200364 "retrace/binary_compatibility",
Ian Zernyfad3a3c2022-03-30 19:55:42 +0200365 "r8",
Ian Zernye0fd0242020-06-23 13:46:14 +0200366 "r8-releases/2.0.74",
Ian Zerny20d576f2022-03-28 19:16:38 +0200367 "r8-releases/3.2.54",
Morten Krogh-Jespersen1ba55f52020-04-24 12:49:17 +0200368 "r8mappings",
369 "tachiyomi"
Mads Ager418d1ca2017-05-22 09:35:49 +0200370 ],
371 // All dex-vms have a fixed OS of Linux, as they are only supported on Linux, and will be run in a Docker
372 // container on other platforms where supported.
373 "tools" : [
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200374 "linux/art",
375 "linux/art-5.1.1",
376 "linux/art-6.0.1",
377 "linux/art-7.0.0",
Søren Gjesse1528c022018-11-23 15:14:05 +0100378 "linux/art-8.1.0",
Søren Gjessefe7c0112018-12-03 12:33:12 +0100379 "linux/art-9.0.0",
clementbera97d5cce2019-11-22 15:09:27 +0100380 "linux/art-10.0.0",
Søren Gjesse953f7c42021-08-18 16:42:06 +0200381 "linux/host/art-12.0.0-beta4",
Søren Gjesse2ba0f3a2022-04-20 13:55:15 +0200382 "linux/host/art-13-dev",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200383 "linux/dalvik",
Stephan Herhut02f0f9d2018-01-04 10:27:31 +0100384 "linux/dalvik-4.0.4",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200385 "${osString}/dx",
Mads Ager418d1ca2017-05-22 09:35:49 +0200386 ]
387]
388
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100389def cloudSystemDependencies = [
390 linux: [
clementbera81738ec2019-04-11 11:32:31 +0200391 "third_party": ["openjdk/openjdk-9.0.4/linux",
clementberab4fa18d2019-04-12 09:09:40 +0200392 "openjdk/jdk8/linux-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100393 "openjdk/jdk-11/linux",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100394 "openjdk/jdk-17/linux",
395 "openjdk/jdk-18/linux"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100396 ],
397 osx: [
clementbera81738ec2019-04-11 11:32:31 +0200398 "third_party": ["openjdk/openjdk-9.0.4/osx",
clementberab4fa18d2019-04-12 09:09:40 +0200399 "openjdk/jdk8/darwin-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100400 "openjdk/jdk-11/osx",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100401 "openjdk/jdk-17/osx",
402 "openjdk/jdk-18/osx"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100403 ],
404 windows: [
clementberab4fa18d2019-04-12 09:09:40 +0200405 "third_party": ["openjdk/openjdk-9.0.4/windows",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100406 "openjdk/jdk-11/windows",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100407 "openjdk/jdk-17/windows",
408 "openjdk/jdk-18/windows"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100409 ],
410]
411
412if (OperatingSystem.current().isWindows()) {
413 cloudSystemDependencies.windows.each { entry ->
414 cloudDependencies.get(entry.key).addAll(entry.value)
415 }
416} else if (OperatingSystem.current().isLinux()) {
417 cloudSystemDependencies.linux.each { entry ->
418 cloudDependencies.get(entry.key).addAll(entry.value)
419 }
420} else if (OperatingSystem.current().isMacOsX()) {
421 cloudSystemDependencies.osx.each { entry ->
422 cloudDependencies.get(entry.key).addAll(entry.value)
423 }
424} else {
425 println "WARNING: Unsupported system: " + OperatingSystem.current()
426}
427
428def getDownloadDepsTaskName(entryKey, entryFile) {
429 return "download_deps_${entryKey}_${entryFile.replace('/', '_').replace('\\', '_')}"
430}
431
Mads Ager418d1ca2017-05-22 09:35:49 +0200432cloudDependencies.each { entry ->
433 entry.value.each { entryFile ->
Morten Krogh-Jespersenc3e7ab92022-05-03 15:12:04 +0200434 task (getDownloadDepsTaskName(entry.key, entryFile), type: DownloadDependency) {
Ian Zernyb2d27c42019-02-20 09:09:41 +0100435 type DownloadDependency.Type.GOOGLE_STORAGE
436 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200437 }
438 }
439}
440
441def x20Dependencies = [
442 "third_party": [
Rico Windc346c4a2018-10-23 08:04:16 +0200443 "benchmarks/kotlin-benches",
Jinseong Jeonb0c2dc02019-07-18 11:41:11 -0700444 "chrome/chrome_180917_ffbaa8",
Christoffer Quist Adamsence640052020-04-30 11:47:41 +0200445 "chrome/chrome_200430",
Christoffer Quist Adamsen287c1862020-05-20 15:51:12 +0200446 "chrome/monochrome_public_minimal_apks/chrome_200520",
Clément Béra5da4e352021-01-27 18:16:27 +0000447 "chrome/clank_google3_prebuilt",
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +0100448 "classlib",
Morten Krogh-Jespersen480784d2019-02-05 08:10:46 +0100449 "cf_segments",
Rico Windf72fa152018-10-22 15:41:03 +0200450 "desugar/desugar_20180308",
Ian Zernybd2fdcc2019-03-22 13:57:21 +0100451 "internal/issue-127524985",
Rico Windf72fa152018-10-22 15:41:03 +0200452 "framework",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200453 "gmail/gmail_android_170604.16",
Søren Gjesseb552e842018-09-28 12:17:29 +0200454 "gmail/gmail_android_180826.15",
Rico Windf72fa152018-10-22 15:41:03 +0200455 "gmscore/gmscore_v10",
Rico Windf72fa152018-10-22 15:41:03 +0200456 "gmscore/latest",
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +0200457 "nest/nest_20180926_7c6cfb",
Rico Windf72fa152018-10-22 15:41:03 +0200458 "proguard/proguard_internal_159423826",
459 "proguardsettings",
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200460 "proto",
461 "protobuf-lite",
Morten Krogh-Jespersend87c0662020-06-22 10:45:43 +0200462 "retrace_internal",
Christoffer Quist Adamsen62fcc152022-06-03 14:01:35 +0200463 "youtube/youtube.android_16.20",
464 "youtube/youtube.android_17.19"
Mads Ager418d1ca2017-05-22 09:35:49 +0200465 ],
466]
467
468x20Dependencies.each { entry ->
469 entry.value.each { entryFile ->
Ian Zernyb2d27c42019-02-20 09:09:41 +0100470 task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) {
471 type DownloadDependency.Type.X20
472 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200473 }
474 }
475}
476
Rico Wind897bb712017-05-23 10:44:29 +0200477task downloadProguard {
478 cloudDependencies.each { entry ->
479 entry.value.each { entryFile ->
480 if (entryFile.contains("proguard")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100481 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Wind897bb712017-05-23 10:44:29 +0200482 }
483 }
484 }
485}
486
Rico Windf6c74ce2018-12-04 08:50:55 +0100487task downloadOpenJDKrt {
488 cloudDependencies.each { entry ->
489 entry.value.each { entryFile ->
490 if (entryFile.contains("openjdk-rt")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100491 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Windf6c74ce2018-12-04 08:50:55 +0100492 }
493 }
494 }
495}
496
Tamas Kenez427205b2017-06-29 15:57:09 +0200497task downloadDx {
498 cloudDependencies.each { entry ->
499 entry.value.each { entryFile ->
Tamas Kenezcea7c202017-10-13 10:53:32 +0200500 if (entryFile.endsWith("/dx")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100501 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez427205b2017-06-29 15:57:09 +0200502 }
503 }
504 }
505}
506
Tamas Kenez0e10c562017-06-08 10:00:34 +0200507task downloadAndroidCts {
508 cloudDependencies.each { entry ->
509 entry.value.each { entryFile ->
510 if (entryFile.contains("android_cts_baseline")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100511 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez0e10c562017-06-08 10:00:34 +0200512 }
513 }
514 }
515}
516
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200517task downloadCloudDeps() {
Mads Ager418d1ca2017-05-22 09:35:49 +0200518 cloudDependencies.each { entry ->
519 entry.value.each { entryFile ->
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100520 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200521 }
522 }
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200523}
524
525task downloadX20Deps() {
526 x20Dependencies.each { entry ->
527 entry.value.each { entryFile ->
528 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200529 }
530 }
531}
532
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200533task downloadDeps {
534 dependsOn downloadCloudDeps
535 if (!project.hasProperty('no_internal')) {
536 dependsOn downloadX20Deps
537 }
538}
539
Mads Ager418d1ca2017-05-22 09:35:49 +0200540allprojects {
541 sourceCompatibility = JavaVersion.VERSION_1_8
542 targetCompatibility = JavaVersion.VERSION_1_8
543}
544
Rico Wind266336c2019-02-25 10:11:38 +0100545// TODO(ricow): Remove debug prints
546println("NOTE: Current operating system: " + OperatingSystem.current())
547println("NOTE: Current operating system isWindows: " + OperatingSystem.current().isWindows())
548
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100549// Check if running with the JDK location from tools/jdk.py.
550if (OperatingSystem.current().isWindows()) {
551 println "NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome
Morten Krogh-Jespersend9a88452020-01-31 14:13:54 +0100552 compileJava.options.encoding = "UTF-8"
553 compileTestJava.options.encoding = "UTF-8"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100554} else {
555 def javaHomeOut = new StringBuilder()
556 def javaHomeErr = new StringBuilder()
Jake Wharton7c14ce72019-09-17 13:49:18 -0400557 def javaHomeProc = './tools/jdk.py'.execute([], projectDir)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100558 javaHomeProc.waitForProcessOutput(javaHomeOut, javaHomeErr)
559 def jdkHome = new File(javaHomeOut.toString().trim())
560 if (!jdkHome.exists()) {
561 println "WARNING: Failed to find the ./tools/jdk.py specified JDK: " + jdkHome
562 } else if (jdkHome != org.gradle.internal.jvm.Jvm.current().javaHome) {
563 println("WARNING: Gradle is running in a non-pinned Java"
564 + ". Gradle Java Home: " + org.gradle.internal.jvm.Jvm.current().javaHome
Christoffer Quist Adamsen79b126a2020-03-27 17:23:08 +0000565 + ". Expected: " + jdkHome)
Rico Wind266336c2019-02-25 10:11:38 +0100566 } else {
567 println("NOTE: Running with jdk from tools/jdk.py: " + jdkHome)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100568 }
Mads Agerc7d14d32018-09-27 11:09:46 +0200569}
570
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200571compileJava.dependsOn downloadCloudDeps
Morten Krogh-Jespersenc1bc4a02021-06-18 08:13:02 +0200572
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100573sourceSets.configureEach { sourceSet ->
574 tasks.named(sourceSet.compileJavaTaskName).configure {
575 // Default disable errorprone (enabled and setup below).
576 options.errorprone.enabled = false
577 options.compilerArgs << '-Xlint:unchecked'
Ian Zerny09135aa2019-02-12 16:03:34 +0100578 // Run all compilation tasks in a forked subprocess.
579 options.fork = true
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100580 // Javac often runs out of stack space when compiling the tests.
581 // Increase the stack size for the javac process.
Søren Gjesse1af374d2019-09-06 10:44:54 +0200582 options.forkOptions.jvmArgs << "-Xss256m"
Ian Zerny26307fb2019-03-06 15:18:17 +0100583 // Test compilation is sometimes hitting the default limit at 1g, increase it.
Ian Zerny293b8152019-09-20 10:40:53 +0200584 options.forkOptions.jvmArgs << "-Xmx3g"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100585 // Set the bootclass path so compilation is consistent with 1.8 target compatibility.
586 options.forkOptions.jvmArgs << "-Xbootclasspath/a:third_party/openjdk/openjdk-rt-1.8/rt.jar"
587 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200588}
589
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100590def setJdkCompilationWithCompatibility(String sourceSet, String javaHome, JavaVersion compatibility, boolean enablePreview) {
591 tasks.named(sourceSet).get().configure {
592 def jdkDir = "third_party/openjdk/${javaHome}/"
593 options.fork = true
594 options.forkOptions.jvmArgs = []
595 if (enablePreview) {
596 options.compilerArgs.add('--enable-preview')
597 }
598 if (OperatingSystem.current().isLinux()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200599 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/linux")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100600 options.forkOptions.javaHome = file(jdkDir + 'linux')
601 } else if (OperatingSystem.current().isMacOsX()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200602 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/osx")
Jake Whartonbd3196b2021-03-16 15:48:08 -0400603 options.forkOptions.javaHome = compatibility > JavaVersion.VERSION_1_9
604 ? file(jdkDir + 'osx/Contents/Home')
605 : file(jdkDir + 'osx')
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100606 } else {
Søren Gjesse96b37252021-08-09 16:08:05 +0200607 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/windows")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100608 options.forkOptions.javaHome = file(jdkDir + 'windows')
609 }
610 sourceCompatibility = compatibility
611 targetCompatibility = compatibility
Ian Zernyd3020482019-04-25 07:05:04 +0200612 }
Ian Zernyd3020482019-04-25 07:05:04 +0200613}
614
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100615setJdkCompilationWithCompatibility(
616 sourceSets.examplesJava9.compileJavaTaskName,
617 'openjdk-9.0.4',
618 JavaVersion.VERSION_1_9,
619 false)
620setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100621 sourceSets.examplesJava10.compileJavaTaskName,
622 'jdk-11',
623 JavaVersion.VERSION_1_10,
624 false)
625setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200626 sourceSets.main11.compileJavaTaskName,
627 'jdk-11',
628 JavaVersion.VERSION_11,
629 false)
630setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100631 sourceSets.examplesJava11.compileJavaTaskName,
632 'jdk-11',
633 JavaVersion.VERSION_11,
634 false)
635setJdkCompilationWithCompatibility(
636 sourceSets.examplesTestNGRunner.compileJavaTaskName,
637 'jdk-11',
638 JavaVersion.VERSION_11,
639 false)
640setJdkCompilationWithCompatibility(
Søren Gjessee9966932021-09-15 17:08:37 +0200641 sourceSets.examplesJava17.compileJavaTaskName,
642 'jdk-17',
643 JavaVersion.VERSION_17,
644 false)
Søren Gjessed1e08992022-02-07 16:46:31 +0100645setJdkCompilationWithCompatibility(
646 sourceSets.examplesJava18.compileJavaTaskName,
647 'jdk-18',
648 // TODO(b/218293990): Update Gradle to get JavaVersion.VERSION_18.
649 JavaVersion.VERSION_17,
650 false)
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100651
Clément Bérac94b6202021-09-28 11:16:58 +0000652task provideJdk11TestsDependencies(type: org.gradle.api.tasks.Copy) {
653 from sourceSets.examplesTestNGRunner.compileClasspath
654 include "**/**.jar"
655 into file("$buildDir/test/jdk11Tests")
656}
657
658task compileTestNGRunner (type: JavaCompile) {
659 dependsOn provideJdk11TestsDependencies
Clément Béra98d5b602021-09-29 06:27:21 +0000660 destinationDir = file("$buildDir/classes/java/examplesTestNGRunner")
Clément Bérac94b6202021-09-28 11:16:58 +0000661 source = sourceSets.examplesTestNGRunner.allSource
662 classpath = sourceSets.examplesTestNGRunner.compileClasspath
663}
664
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100665if (!project.hasProperty('without_error_prone') &&
666 // Don't enable error prone on Java 8 as the plugin setup does not support it.
667 !org.gradle.internal.jvm.Jvm.current().javaVersion.java8) {
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200668 compileJava {
669 // Enable error prone for D8/R8 sources.
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100670 options.errorprone.enabled = true
671 options.errorprone.disableAllChecks = true
672 options.errorprone.check('ClassCanBeStatic', CheckSeverity.ERROR)
Christoffer Quist Adamsen7bed1092020-05-04 11:08:00 +0200673 options.errorprone.check('CollectionIncompatibleType', CheckSeverity.ERROR)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100674 options.errorprone.check('OperatorPrecedence', CheckSeverity.ERROR)
675 options.errorprone.check('RemoveUnusedImports', CheckSeverity.ERROR)
676 options.errorprone.check('MissingOverride', CheckSeverity.ERROR)
677 options.errorprone.check('IntLongMath', CheckSeverity.ERROR)
678 options.errorprone.check('EqualsHashCode', CheckSeverity.ERROR)
679 options.errorprone.check('InconsistentOverloads', CheckSeverity.ERROR)
680 options.errorprone.check('ArrayHashCode', CheckSeverity.ERROR)
681 options.errorprone.check('EqualsIncompatibleType', CheckSeverity.ERROR)
682 options.errorprone.check('NonOverridingEquals', CheckSeverity.ERROR)
683 options.errorprone.check('FallThrough', CheckSeverity.ERROR)
684 options.errorprone.check('MissingCasesInEnumSwitch', CheckSeverity.ERROR)
685 options.errorprone.check('MissingDefault', CheckSeverity.ERROR)
686 options.errorprone.check('MultipleTopLevelClasses', CheckSeverity.ERROR)
687 options.errorprone.check('NarrowingCompoundAssignment', CheckSeverity.ERROR)
688 options.errorprone.check('BoxedPrimitiveConstructor', CheckSeverity.ERROR)
689 options.errorprone.check('LogicalAssignment', CheckSeverity.ERROR)
690 options.errorprone.check('FloatCast', CheckSeverity.ERROR)
691 options.errorprone.check('ReturnValueIgnored', CheckSeverity.ERROR)
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200692 }
693}
694
Yohann Roussel7f47c032017-09-14 12:19:06 +0200695task consolidatedLicense {
Yohann Roussel7f47c032017-09-14 12:19:06 +0200696 def license = new File(new File(buildDir, 'generatedLicense'), 'LICENSE')
Mads Agerd1d0da92018-12-10 13:56:50 +0100697
Yohann Roussel7f47c032017-09-14 12:19:06 +0200698 inputs.files files('LICENSE', 'LIBRARY-LICENSE') + fileTree(dir: 'library-licensing')
Mads Agerd1d0da92018-12-10 13:56:50 +0100699 def runtimeClasspath = configurations.findByName("runtimeClasspath")
700 inputs.files { runtimeClasspath.getResolvedConfiguration().files }
701
Yohann Roussel7f47c032017-09-14 12:19:06 +0200702 outputs.files license
Mads Agerd1d0da92018-12-10 13:56:50 +0100703
Yohann Roussel7f47c032017-09-14 12:19:06 +0200704 doLast {
Mads Agerd1d0da92018-12-10 13:56:50 +0100705 def dependencies = []
706 runtimeClasspath.resolvedConfiguration.resolvedArtifacts.each {
707 def identifier = (ModuleComponentIdentifier) it.id.componentIdentifier
708 dependencies.add("${identifier.group}:${identifier.module}")
709 }
710 def libraryLicenses = file('LIBRARY-LICENSE').text
711 dependencies.each {
712 if (!libraryLicenses.contains("- artifact: $it")) {
713 throw new GradleException("No license for $it in LIBRARY_LICENSE")
714 }
715 }
716
Yohann Roussel7f47c032017-09-14 12:19:06 +0200717 license.getParentFile().mkdirs()
718 license.createNewFile()
719 license.text = "This file lists all licenses for code distributed.\n"
720 license.text += "All non-library code has the following 3-Clause BSD license.\n"
721 license.text += "\n"
722 license.text += "\n"
723 license.text += file('LICENSE').text
724 license.text += "\n"
725 license.text += "\n"
726 license.text += "Summary of distributed libraries:\n"
727 license.text += "\n"
Mads Agerd1d0da92018-12-10 13:56:50 +0100728 license.text += libraryLicenses
Yohann Roussel7f47c032017-09-14 12:19:06 +0200729 license.text += "\n"
730 license.text += "\n"
731 license.text += "Licenses details:\n"
732 fileTree(dir: 'library-licensing').getFiles().stream().sorted().forEach { file ->
733 license.text += "\n"
734 license.text += "\n"
735 license.text += file.text
736 }
737 }
738}
739
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100740def repackageDepFile(file) {
741 if (file.getName().endsWith('.jar')) {
742 return zipTree(file).matching {
743 exclude '**/module-info.class'
744 exclude 'META-INF/maven/**'
745 exclude 'META-INF/LICENSE.txt'
746 exclude 'META-INF/MANIFEST.MF'
747 }
748 } else {
749 return fileTree(file)
Jinseong Jeon40ceab02018-07-09 14:25:31 -0700750 }
Morten Krogh-Jespersen00699af2018-10-09 10:54:42 +0200751}
752
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100753task repackageDeps(type: Jar) {
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200754 dependsOn downloadCloudDeps
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100755 dependsOn project.configurations.runtimeClasspath
756 project.configurations.runtimeClasspath.forEach {
757 from repackageDepFile(it)
758 }
759 archiveFileName = 'deps_all.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000760}
761
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100762task repackageTestDeps(type: Jar) {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200763 dependsOn downloadCloudDeps
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100764 dependsOn project.configurations.testCompile
765 project.configurations.testCompile.forEach {
766 from repackageDepFile(it)
767 }
768 archiveFileName = 'test_deps_all.jar'
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200769}
770
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100771task repackageSources(type: Jar) {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100772 // If this fails then remove all generated folders from
773 // build/classes/java/test that is not {com,dalvik}
Mads Ager418d1ca2017-05-22 09:35:49 +0200774 from sourceSets.main.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100775 archiveFileName = 'sources_main.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000776}
777
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100778task repackageSources11(type: Jar) {
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200779 from sourceSets.main11.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100780 archiveFileName = 'sources_main_11.jar'
clementbera0bca05e2019-05-29 14:11:18 +0200781}
782
Søren Gjesse145d9e82022-05-24 08:12:13 +0200783def r8CreateTask(name, baseName, sources, includeLibraryLicenses, includeSwissArmyKnife) {
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100784 return tasks.create("r8Create${name}", Jar) {
Morten Krogh-Jespersenb4b33eb2022-05-06 16:47:08 +0200785 entryCompression ZipEntryCompression.STORED
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100786 dependsOn sources
Søren Gjesse145d9e82022-05-24 08:12:13 +0200787 dependsOn files('LICENSE')
788 if (includeLibraryLicenses) {
789 from consolidatedLicense.outputs.files
790 } else {
791 from files('LICENSE')
792 }
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100793 from sources.collect { zipTree(it) }
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100794 exclude "$buildDir/classes/**"
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100795 archiveFileName = baseName
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200796 if (includeSwissArmyKnife) {
797 manifest {
798 attributes 'Main-Class': 'com.android.tools.r8.SwissArmyKnife'
799 }
800 }
801 exclude "META-INF/*.kotlin_module"
802 exclude "**/*.kotlin_metadata"
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200803 }
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200804}
805
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200806def r8RelocateTask(r8Task, output) {
807 return tasks.create("r8Relocate_${r8Task.name}", Exec) {
808 dependsOn r8WithDeps
809 dependsOn r8Task
810 outputs.file output
811 workingDir = projectDir
812 inputs.files r8Task.outputs.files + r8WithDeps.outputs.files
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200813 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200814 "relocator",
815 "--input",
816 r8Task.outputs.files[0],
817 "--output",
818 output,
819 "--map",
820 "com.google.common->com.android.tools.r8.com.google.common",
821 "--map",
822 "com.google.gson->com.android.tools.r8.com.google.gson",
823 "--map",
824 "com.google.thirdparty->com.android.tools.r8.com.google.thirdparty",
825 "--map",
826 "joptsimple->com.android.tools.r8.joptsimple",
827 "--map",
828 "org.objectweb.asm->com.android.tools.r8.org.objectweb.asm",
829 "--map",
830 "it.unimi.dsi.fastutil->com.android.tools.r8.it.unimi.dsi.fastutil",
831 "--map",
832 "kotlin->com.android.tools.r8.jetbrains.kotlin",
833 "--map",
834 "kotlinx->com.android.tools.r8.jetbrains.kotlinx",
835 "--map",
836 "org.jetbrains->com.android.tools.r8.org.jetbrains",
837 "--map",
Søren Gjessebeb5d872021-09-07 12:49:24 +0200838 "org.intellij->com.android.tools.r8.org.intellij",
839 "--map",
840 "org.checkerframework->com.android.tools.r8.org.checkerframework"
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200841 ])
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200842 }
843}
844
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200845task r8WithDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200846 dependsOn repackageSources
847 dependsOn repackageDeps
848 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200849 def r8Task = r8CreateTask(
850 'WithDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100851 'r8_with_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200852 repackageSources.outputs.files + repackageDeps.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200853 true,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200854 true)
855 dependsOn r8Task
856 outputs.files r8Task.outputs.files
clementbera0bca05e2019-05-29 14:11:18 +0200857}
858
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200859task r8WithDeps11 {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200860 dependsOn repackageSources11
861 dependsOn repackageDeps
862 inputs.files ([repackageSources11.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200863 def r8Task = r8CreateTask(
864 'WithDeps11',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100865 'r8_with_deps_11.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200866 repackageSources11.outputs.files + repackageDeps.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200867 true,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200868 true)
869 dependsOn r8Task
870 outputs.files r8Task.outputs.files
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100871}
872
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200873task r8WithRelocatedDeps {
874 def output = "${buildDir}/libs/r8_with_relocated_deps.jar"
875 dependsOn r8RelocateTask(r8WithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200876 inputs.files r8WithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200877 outputs.file output
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200878}
879
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200880task r8WithRelocatedDeps11 {
881 def output = "${buildDir}/libs/r8_with_relocated_deps_11.jar"
882 dependsOn r8RelocateTask(r8WithDeps11, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200883 inputs.files r8WithDeps11.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200884 outputs.file output
885}
886
887task r8WithoutDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200888 dependsOn repackageSources
889 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200890 def r8Task = r8CreateTask(
891 'WithoutDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100892 'r8_without_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200893 repackageSources.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200894 false,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200895 true)
896 dependsOn r8Task
897 outputs.files r8Task.outputs.files
898}
899
900task r8(type: Copy) {
901 def r8Task = project.hasProperty("exclude_deps")
902 ? r8WithoutDeps : r8WithRelocatedDeps
903 dependsOn r8Task
904 from r8Task.outputs.files[0]
905 into file("${buildDir}/libs")
906 rename { String fileName -> "r8.jar" }
907 outputs.file "${buildDir}/libs/r8.jar"
908}
909
910task r8NoManifestWithoutDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200911 dependsOn repackageSources
912 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200913 def r8Task = r8CreateTask(
914 'NoManifestWithoutDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100915 'r8_no_manifest_without_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200916 repackageSources.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200917 false,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200918 false)
919 dependsOn r8Task
920 outputs.files r8Task.outputs.files
921}
922
923task r8NoManifestWithDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200924 dependsOn repackageSources
925 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200926 def r8Task = r8CreateTask(
927 'NoManifestWithDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100928 'r8_no_manifest_with_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200929 repackageSources.outputs.files + repackageDeps.outputs.files,
Søren Gjesse145d9e82022-05-24 08:12:13 +0200930 true,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200931 false)
932 dependsOn r8Task
933 outputs.files r8Task.outputs.files
934}
935
936task r8NoManifestWithRelocatedDeps {
937 def output = "${buildDir}/libs/r8_no_manifest_with_relocated_deps.jar"
938 dependsOn r8RelocateTask(r8NoManifestWithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200939 inputs.files r8NoManifestWithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200940 outputs.file output
941}
942
943task r8NoManifest(type: Copy) {
944 def r8Task = project.hasProperty("exclude_deps")
945 ? r8NoManifestWithoutDeps : r8NoManifestWithRelocatedDeps
946 dependsOn r8Task
947 from r8Task.outputs.files[0]
948 into file("${buildDir}/libs")
949 rename { String fileName -> "r8_no_manifest.jar" }
950 outputs.file "${buildDir}/libs/r8_no_manifest.jar"
Tamas Kenez8224fbc2018-12-10 09:57:56 +0100951}
952
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200953def baseCompilerCommandLine(compiler, args = []) {
954 // Execute r8 commands against a stable r8 with dependencies.
955 // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g).
956 return [org.gradle.internal.jvm.Jvm.current().getJavaExecutable(),
957 "-Xmx8g", "-ea", "-jar", r8WithDeps.outputs.files[0]] + compiler + args
958}
959
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100960def baseR8CommandLine(args = []) {
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200961 // Execute r8 commands against a stable r8 with dependencies.
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200962 return baseCompilerCommandLine("r8", args)
963}
964
965def baseD8CommandLine(args = []) {
966 // Execute r8 commands against a stable r8 with dependencies.
967 return baseCompilerCommandLine("d8", args)
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100968}
969
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200970def r8CfCommandLine(input, output, pgConfs = [], args = ["--release"], libs = []) {
971 def allArgs = [
972 "--classfile",
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100973 input,
974 "--output", output,
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100975 "--pg-map-output", output + ".map",
976 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200977 ] + args + libs.collectMany { ["--lib", it] } + pgConfs.collectMany { ["--pg-conf", it] }
978 return baseR8CommandLine(allArgs)
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100979}
980
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200981def d8CfCommandLine(input, output, args = ["--release"], libs = []) {
982 def allArgs = [
983 "--classfile",
984 input,
985 "--output", output,
986 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
987 ] + args + libs.collectMany { ["--lib", it] }
988 return baseD8CommandLine(allArgs)
989}
990
Ian Zernycf8ef512022-05-04 14:54:16 +0200991def r8LibCreateTask(name, pgConfs = [], r8Task, output, libs = [], classpath = [], excldeps=false) {
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100992 return tasks.create("r8Lib${name}", Exec) {
Ian Zernya0d27cf2021-10-14 13:55:34 +0200993 inputs.files ([pgConfs, r8WithRelocatedDeps.outputs, r8Task.outputs])
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100994 outputs.file output
995 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +0100996 dependsOn r8WithRelocatedDeps
997 dependsOn r8Task
Ian Zernya0d27cf2021-10-14 13:55:34 +0200998 commandLine ([
Ian Zerny99613a02022-02-23 11:50:13 +0100999 "python3", "tools/create_r8lib.py",
Ian Zernya0d27cf2021-10-14 13:55:34 +02001000 "--r8jar", r8Task.outputs.files[0],
1001 "--output", output]
Ian Zernycf8ef512022-05-04 14:54:16 +02001002 + (excldeps ? ['--excldeps-variant'] : [])
Ian Zernya0d27cf2021-10-14 13:55:34 +02001003 + (pgConfs.collectMany { ["--pg-conf", it] })
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001004 + (libs.collectMany { ["--lib", it] })
1005 + (classpath.collectMany { ["--classpath", it] }))
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +01001006 workingDir = projectDir
1007 }
1008}
1009
Søren Gjesse17fc67d2019-12-04 14:50:17 +01001010task buildLibraryDesugarConversions(type: Zip, dependsOn: downloadDeps) {
1011 from sourceSets.libraryDesugarConversions.output
1012 include "java/**/*.class"
1013 baseName 'library_desugar_conversions'
1014 destinationDir file('build/libs')
1015}
1016
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001017task testJarSources(type: Jar, dependsOn: [testClasses, buildLibraryDesugarConversions]) {
1018 archiveFileName = "r8testsbase.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001019 from sourceSets.test.output
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001020 // We only want to include tests that use R8 when generating keep rules for applymapping.
1021 include "com/android/tools/r8/**"
1022 include "dalvik/**"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001023}
1024
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001025task testJar(type: Exec) {
Morten Krogh-Jespersenac1a4d22020-05-04 01:42:13 +02001026 dependsOn r8WithDeps
1027 dependsOn testJarSources
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001028 def output = "$buildDir/libs/r8tests.jar"
1029 outputs.file output
1030 workingDir = projectDir
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001031 inputs.files (testJarSources.outputs.files + r8WithDeps.outputs.files)
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001032 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001033 "relocator",
1034 "--input",
1035 testJarSources.outputs.files[0],
1036 "--output",
1037 output,
1038 "--map",
1039 "kotlinx.metadata->com.android.tools.r8.jetbrains.kotlinx.metadata"
1040 ])
1041}
1042
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001043task generateR8LibKeepRules(type: Exec) {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001044 // Depend on r8WithRelocatedDeps to ensure that we do not have external
1045 // dependencies crossing the boundary.
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001046 dependsOn r8WithDeps
1047 dependsOn r8NoManifestWithRelocatedDeps
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001048 dependsOn testJar
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001049 dependsOn repackageTestDeps
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001050 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001051 inputs.files ([
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001052 r8WithDeps.outputs,
1053 r8NoManifestWithRelocatedDeps.outputs,
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001054 repackageDeps.outputs,
1055 repackageTestDeps.outputs,
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001056 testJar.outputs])
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001057 outputs.file r8LibGeneratedKeepRulesPath
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001058 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001059 "tracereferences",
1060 "--keep-rules",
1061 "--allowobfuscation",
1062 "--lib",
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001063 "third_party/openjdk/openjdk-rt-1.8/rt.jar",
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001064 "--lib",
1065 repackageDeps.outputs.files[0],
1066 "--lib",
1067 repackageTestDeps.outputs.files[0],
1068 "--target",
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001069 r8NoManifestWithRelocatedDeps.outputs.files[0],
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001070 "--source",
1071 testJar.outputs.files[0],
1072 "--output",
1073 r8LibGeneratedKeepRulesPath])
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001074 workingDir = projectDir
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001075}
1076
Morten Krogh-Jespersenb39fbe52018-12-17 14:58:48 +01001077task R8Lib {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001078 dependsOn r8LibCreateTask(
1079 "Main",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001080 ["src/main/keep.txt", generateR8LibKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001081 r8NoManifestWithRelocatedDeps,
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001082 r8LibPath,
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001083 ).dependsOn(generateR8LibKeepRules)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001084 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001085 outputs.file r8LibPath
Tamas Kenezf960e9c2018-12-03 16:13:29 +01001086}
1087
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001088task R8LibNoDeps {
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001089 dependsOn r8LibCreateTask(
Ian Zernya0d27cf2021-10-14 13:55:34 +02001090 "MainNoDeps",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001091 ["src/main/keep.txt"],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001092 r8NoManifestWithoutDeps,
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001093 r8LibExludeDepsPath,
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001094 [],
Ian Zernycf8ef512022-05-04 14:54:16 +02001095 repackageDeps.outputs.files,
1096 true,
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001097 ).dependsOn(repackageDeps)
1098 inputs.files ([r8NoManifestWithoutDeps.outputs, repackageDeps.outputs])
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001099 outputs.file r8LibExludeDepsPath
1100}
1101
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001102task R8Desugared(type: Exec) {
1103 dependsOn downloadOpenJDKrt
1104 dependsOn r8NoManifestWithRelocatedDeps
1105 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
1106 commandLine d8CfCommandLine(
1107 r8NoManifestWithRelocatedDeps.outputs.files[0],
1108 r8DesugaredPath,
1109 ["--release"])
1110 workingDir = projectDir
1111 outputs.file r8DesugaredPath
1112}
1113
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +02001114task R8Retrace {
1115 dependsOn R8Lib
1116 dependsOn r8LibCreateTask(
1117 "Retrace",
1118 ["src/main/keep_retrace.txt"],
1119 R8Lib,
1120 r8RetracePath,
1121 ).dependsOn(R8Lib)
1122 outputs.file r8RetracePath
1123}
1124
1125task R8RetraceNoDeps {
1126 dependsOn R8LibNoDeps
1127 dependsOn r8LibCreateTask(
1128 "RetraceNoDeps",
1129 ["src/main/keep_retrace.txt"],
1130 R8LibNoDeps,
1131 r8RetraceExludeDepsPath,
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001132 [],
Ian Zernycf8ef512022-05-04 14:54:16 +02001133 repackageDeps.outputs.files,
1134 true,
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +02001135 ).dependsOn(R8LibNoDeps)
1136 outputs.file r8RetraceExludeDepsPath
1137}
1138
Mads Ager418d1ca2017-05-22 09:35:49 +02001139task sourceJar(type: Jar, dependsOn: classes) {
1140 classifier = 'src'
1141 from sourceSets.main.allSource
1142}
1143
Mads Ager418d1ca2017-05-22 09:35:49 +02001144artifacts {
1145 archives sourceJar
1146}
1147
1148task createArtTests(type: Exec) {
1149 def outputDir = "build/generated/test/java/com/android/tools/r8/art"
Mads Ager7e5bd722017-05-24 07:17:27 +02001150 def createArtTestsScript = "tools/create_art_tests.py"
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001151 inputs.files files("tests/2017-10-04/art.tar.gz", createArtTestsScript)
Mads Ager418d1ca2017-05-22 09:35:49 +02001152 outputs.dir outputDir
1153 dependsOn downloadDeps
Ian Zerny99613a02022-02-23 11:50:13 +01001154 commandLine "python3", createArtTestsScript
Mads Ager418d1ca2017-05-22 09:35:49 +02001155 workingDir = projectDir
1156}
1157
Mads Ager418d1ca2017-05-22 09:35:49 +02001158compileTestJava {
1159 dependsOn createArtTests
Mads Ager418d1ca2017-05-22 09:35:49 +02001160}
1161
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001162task buildCfSegments(type: Jar, dependsOn: downloadDeps) {
1163 from sourceSets.cfSegments.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001164 archiveFileName = 'cf_segments.jar'
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001165 destinationDir file('build/libs')
1166}
1167
Ian Zerny923a0c12018-01-03 10:59:18 +01001168task buildR8ApiUsageSample(type: Jar) {
1169 from sourceSets.apiUsageSample.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001170 archiveFileName = 'r8_api_usage_sample.jar'
Ian Zerny923a0c12018-01-03 10:59:18 +01001171 destinationDir file('tests')
1172}
1173
Yohann Roussel548ae942018-01-05 11:13:28 +01001174task buildApiSampleJars {
Yohann Roussel548ae942018-01-05 11:13:28 +01001175 dependsOn buildR8ApiUsageSample
1176}
1177
Mads Ager418d1ca2017-05-22 09:35:49 +02001178task buildDebugTestResourcesJars {
Mads Ager418d1ca2017-05-22 09:35:49 +02001179 def resourcesDir = file("src/test/debugTestResources")
1180 def hostJar = "debug_test_resources.jar"
1181 task "compile_debugTestResources"(type: JavaCompile) {
1182 source = fileTree(dir: resourcesDir, include: '**/*.java')
1183 destinationDir = file("build/test/debugTestResources/classes")
1184 classpath = sourceSets.main.compileClasspath
1185 sourceCompatibility = JavaVersion.VERSION_1_7
1186 targetCompatibility = JavaVersion.VERSION_1_7
1187 options.compilerArgs += ["-g", "-Xlint:-options"]
1188 }
1189 task "jar_debugTestResources"(type: Jar, dependsOn: "compile_debugTestResources") {
1190 archiveName = hostJar
1191 destinationDir = file("build/test/")
1192 from "build/test/debugTestResources/classes"
1193 include "**/*.class"
1194 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001195 def java8ResourcesDir = file("src/test/debugTestResourcesJava8")
1196 def java8HostJar = "debug_test_resources_java8.jar"
1197 task "compile_debugTestResourcesJava8"(type: JavaCompile) {
1198 source = fileTree(dir: java8ResourcesDir, include: '**/*.java')
1199 destinationDir = file("build/test/debugTestResourcesJava8/classes")
1200 classpath = sourceSets.main.compileClasspath
1201 sourceCompatibility = JavaVersion.VERSION_1_8
1202 targetCompatibility = JavaVersion.VERSION_1_8
1203 options.compilerArgs += ["-g", "-Xlint:-options"]
1204 }
1205 task "jar_debugTestResourcesJava8"(type: Jar, dependsOn: "compile_debugTestResourcesJava8") {
1206 archiveName = java8HostJar
1207 destinationDir = file("build/test/")
1208 from "build/test/debugTestResourcesJava8/classes"
1209 include "**/*.class"
1210 }
1211 dependsOn downloadDeps
Mads Ager418d1ca2017-05-22 09:35:49 +02001212 dependsOn jar_debugTestResources
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001213 dependsOn jar_debugTestResourcesJava8
Mads Ager418d1ca2017-05-22 09:35:49 +02001214}
1215
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001216// Examples used by tests, where Android specific APIs are used.
1217task buildExampleAndroidApi(type: JavaCompile) {
1218 source = fileTree(dir: file("src/test/examplesAndroidApi"), include: "**/*.java")
1219 destinationDir = file("build/test/examplesAndroidApi/classes")
1220 classpath = files("third_party/android_jar/lib-v26/android.jar")
1221 sourceCompatibility = JavaVersion.VERSION_1_8
1222 targetCompatibility = JavaVersion.VERSION_1_8
1223}
1224
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001225task buildProtoGeneratedSources {
1226 def examplesProtoDir = file("src/test/examplesProto")
1227 examplesProtoDir.eachDir { dir ->
1228 def name = dir.getName()
1229 task "compile_proto_generated_source_${name}"(type: JavaCompile) {
1230 source = {
1231 file('third_party/proto').listFiles()
1232 .findAll { it.name.startsWith(name) && it.name.endsWith('-src.jar') }
1233 .collect { zipTree(it) }
1234 }
1235 destinationDir = file("build/generated/test/proto/${name}_classes")
1236 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1237 sourceCompatibility = JavaVersion.VERSION_1_8
1238 targetCompatibility = JavaVersion.VERSION_1_8
1239 }
1240 task "jar_proto_generated_source_${name}"(type: Jar, dependsOn: "compile_proto_generated_source_${name}") {
1241 archiveName = "${name}.jar"
1242 destinationDir = file("build/generated/test/proto")
1243 from "build/generated/test/proto/${name}_classes"
1244 include "/**/*.class"
1245 }
1246 dependsOn "jar_proto_generated_source_${name}"
1247 }
1248}
1249
1250task buildExamplesProto {
1251 def examplesProtoDir = file("src/test/examplesProto")
1252 def examplesProtoOutputDir = file("build/test/examplesProto");
1253 dependsOn buildProtoGeneratedSources
1254 task "compile_examples_proto"(type: JavaCompile) {
1255 source = fileTree(dir: examplesProtoDir, include: "**/*.java")
1256 destinationDir = file("build/test/examplesProto/classes")
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +02001257 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1258 classpath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001259 sourceCompatibility = JavaVersion.VERSION_1_8
1260 targetCompatibility = JavaVersion.VERSION_1_8
1261 }
1262 examplesProtoDir.eachDir { dir ->
1263 def name = dir.getName()
1264 task "jar_examples_proto_${name}"(type: Jar, dependsOn: "compile_examples_proto") {
1265 archiveName = "${name}.jar"
1266 destinationDir = examplesProtoOutputDir
1267 from "build/test/examplesProto/classes"
1268 include name + "/**/*.class"
1269 }
1270 dependsOn "jar_examples_proto_${name}"
1271 }
1272}
1273
Lars Bakc91e87e2017-08-18 08:53:10 +02001274// Proto lite generated code yields warnings when compiling with javac.
1275// We change the options passed to javac to ignore it.
1276compileExamplesJava.options.compilerArgs = ["-Xlint:none"]
1277
Søren Gjesse7320ce52018-05-07 15:45:22 +02001278
Mads Ager418d1ca2017-05-22 09:35:49 +02001279task buildExampleJars {
Rico Wind897bb712017-05-23 10:44:29 +02001280 dependsOn downloadProguard
Mads Ager418d1ca2017-05-22 09:35:49 +02001281 def examplesDir = file("src/test/examples")
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001282 def proguardScript
1283 if (OperatingSystem.current().isWindows()) {
1284 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.bat"
1285 } else {
1286 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.sh"
1287 }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001288 task extractExamplesRuntime(type: Sync) {
1289 dependsOn configurations.examplesRuntime
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001290 from { configurations.examplesRuntime.collect { zipTree(it) } }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001291 include "**/*.class"
1292 includeEmptyDirs false
1293 into "$buildDir/runtime/examples/"
1294 }
1295
Søren Gjesse7320ce52018-05-07 15:45:22 +02001296 task "copy_examples_resources"(type: org.gradle.api.tasks.Copy) {
1297 from examplesDir
1298 exclude "**/*.java"
1299 exclude "**/keep-rules*.txt"
1300 into file("build/test/examples/classes")
1301 }
1302
1303 task "compile_examples"(type: JavaCompile) {
Søren Gjesse7320ce52018-05-07 15:45:22 +02001304 dependsOn "copy_examples_resources"
Rico Wind40fd2c12018-09-12 12:14:44 +02001305 source examplesDir
Stephan Herhut417a72a2017-07-18 10:38:30 +02001306 include "**/*.java"
Mads Ager418d1ca2017-05-22 09:35:49 +02001307 destinationDir = file("build/test/examples/classes")
Stephan Herhut417a72a2017-07-18 10:38:30 +02001308 classpath = sourceSets.examples.compileClasspath
Mads Ager418d1ca2017-05-22 09:35:49 +02001309 sourceCompatibility = JavaVersion.VERSION_1_7
1310 targetCompatibility = JavaVersion.VERSION_1_7
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001311 options.compilerArgs = ["-g:source,lines", "-Xlint:none"]
1312 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001313 task "compile_examples_debuginfo_all"(type: JavaCompile) {
1314 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001315 include "**/*.java"
1316 destinationDir = file("build/test/examples/classes_debuginfo_all")
1317 classpath = sourceSets.examples.compileClasspath
1318 sourceCompatibility = JavaVersion.VERSION_1_7
1319 targetCompatibility = JavaVersion.VERSION_1_7
1320 options.compilerArgs = ["-g", "-Xlint:none"]
1321 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001322 task "compile_examples_debuginfo_none"(type: JavaCompile) {
1323 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001324 include "**/*.java"
1325 destinationDir = file("build/test/examples/classes_debuginfo_none")
1326 classpath = sourceSets.examples.compileClasspath
1327 sourceCompatibility = JavaVersion.VERSION_1_7
1328 targetCompatibility = JavaVersion.VERSION_1_7
1329 options.compilerArgs = ["-g:none", "-Xlint:none"]
Mads Ager418d1ca2017-05-22 09:35:49 +02001330 }
1331 examplesDir.eachDir { dir ->
1332 def name = dir.getName();
1333 def exampleOutputDir = file("build/test/examples");
1334 def jarName = "${name}.jar"
1335 dependsOn "jar_example_${name}"
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001336 dependsOn "jar_example_${name}_debuginfo_all"
1337 dependsOn "jar_example_${name}_debuginfo_none"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001338 dependsOn "extractExamplesRuntime"
1339 def runtimeDependencies = copySpec { }
Mads Ager418d1ca2017-05-22 09:35:49 +02001340 // The "throwing" test verifies debugging/stack info on the post-proguarded output.
1341 def proguardConfigPath = "${dir}/proguard.cfg"
1342 if (new File(proguardConfigPath).exists()) {
1343 task "pre_proguard_example_${name}"(type: Jar, dependsOn: "compile_examples") {
1344 archiveName = "${name}_pre_proguard.jar"
1345 destinationDir = exampleOutputDir
1346 from "build/test/examples/classes"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001347 include name + "/**/*.class"
1348 with runtimeDependencies
1349 includeEmptyDirs false
Mads Ager418d1ca2017-05-22 09:35:49 +02001350 }
1351 def jarPath = files(tasks.getByPath("pre_proguard_example_${name}")).files.first();
1352 def proguardJarPath = "${exampleOutputDir}/${jarName}"
1353 def proguardMapPath = "${exampleOutputDir}/${name}/${name}.map"
1354 task "jar_example_${name}"(type: Exec, dependsOn: "pre_proguard_example_${name}") {
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001355 inputs.files files(
1356 tasks.getByPath("pre_proguard_example_${name}"),
1357 proguardConfigPath)
Mads Ager418d1ca2017-05-22 09:35:49 +02001358 // Enable these to get stdout and stderr redirected to files...
1359 // standardOutput = new FileOutputStream('proguard.stdout')
1360 // errorOutput = new FileOutputStream('proguard.stderr')
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001361 def proguardArguments = "-verbose -dontwarn java.** -injars ${jarPath}" +
Mads Ager418d1ca2017-05-22 09:35:49 +02001362 " -outjars ${proguardJarPath}" +
1363 " -include ${proguardConfigPath}" +
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001364 " -printmapping ${proguardMapPath}"
1365 if (OperatingSystem.current().isWindows()) {
1366 executable "${proguardScript}"
1367 args "${proguardArguments}"
1368 } else {
1369 executable "bash"
1370 args "-c", "${proguardScript} '${proguardArguments}'"
1371 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001372 outputs.file proguardJarPath
1373 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001374 // TODO: Consider performing distinct proguard compilations.
1375 task "jar_example_${name}_debuginfo_all"(type: Copy, dependsOn: "jar_example_${name}") {
1376 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001377 into "${exampleOutputDir}"
1378 rename(".*", "${name}_debuginfo_all.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001379 }
1380 task "jar_example_${name}_debuginfo_none"(type: Copy, dependsOn: "jar_example_${name}") {
1381 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001382 into "${exampleOutputDir}"
1383 rename(".*", "${name}_debuginfo_none.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001384 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001385 } else {
1386 task "jar_example_${name}"(type: Jar, dependsOn: "compile_examples") {
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001387 archiveName = "${name}.jar"
Mads Ager418d1ca2017-05-22 09:35:49 +02001388 destinationDir = exampleOutputDir
1389 from "build/test/examples/classes"
Søren Gjesse7320ce52018-05-07 15:45:22 +02001390 include name + "/**/*"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001391 with runtimeDependencies
Søren Gjesse7320ce52018-05-07 15:45:22 +02001392 includeEmptyDirs true
Mads Ager418d1ca2017-05-22 09:35:49 +02001393 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001394 task "jar_example_${name}_debuginfo_all"(type: Jar, dependsOn: "compile_examples_debuginfo_all") {
1395 archiveName = "${name}_debuginfo_all.jar"
1396 destinationDir = exampleOutputDir
1397 from "build/test/examples/classes_debuginfo_all"
1398 include name + "/**/*.class"
1399 with runtimeDependencies
1400 includeEmptyDirs false
1401 }
1402 task "jar_example_${name}_debuginfo_none"(type: Jar, dependsOn: "compile_examples_debuginfo_none") {
1403 archiveName = "${name}_debuginfo_none.jar"
1404 destinationDir = exampleOutputDir
1405 from "build/test/examples/classes_debuginfo_none"
1406 include name + "/**/*.class"
1407 with runtimeDependencies
1408 includeEmptyDirs false
1409 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001410 }
1411 }
1412}
1413
1414task buildExampleAndroidNJars {
1415 dependsOn downloadDeps
1416 def examplesDir = file("src/test/examplesAndroidN")
1417 task "compile_examplesAndroidN"(type: JavaCompile) {
1418 source = fileTree(dir: examplesDir, include: '**/*.java')
1419 destinationDir = file("build/test/examplesAndroidN/classes")
1420 classpath = sourceSets.main.compileClasspath
1421 sourceCompatibility = JavaVersion.VERSION_1_8
1422 targetCompatibility = JavaVersion.VERSION_1_8
1423 options.compilerArgs += ["-Xlint:-options"]
1424 }
1425 examplesDir.eachDir { dir ->
1426 def name = dir.getName();
1427 def exampleOutputDir = file("build/test/examplesAndroidN");
1428 def jarName = "${name}.jar"
1429 dependsOn "jar_examplesAndroidN_${name}"
1430 task "jar_examplesAndroidN_${name}"(type: Jar, dependsOn: "compile_examplesAndroidN") {
1431 archiveName = jarName
1432 destinationDir = exampleOutputDir
1433 from "build/test/examplesAndroidN/classes"
1434 include "**/" + name + "/**/*.class"
1435 }
1436 }
1437}
1438
1439
1440task buildExampleAndroidOJars {
1441 dependsOn downloadDeps
1442 def examplesDir = file("src/test/examplesAndroidO")
1443 // NOTE: we want to enable a scenario when test needs to reference some
1444 // classes generated by legacy (1.6) Java compiler to test some specific
1445 // behaviour. To do so we compile all the java files located in sub-directory
1446 // called 'legacy' with Java 1.6, then compile the rest of the files with
1447 // Java 1.8 and a reference to previously generated 1.6 classes.
1448
1449 // Compiling all classes in dirs 'legacy' with old Java version.
1450 task "compile_examplesAndroidO_Legacy"(type: JavaCompile) {
1451 source = fileTree(dir: examplesDir, include: '**/legacy/**/*.java')
1452 destinationDir = file("build/test/examplesAndroidOLegacy/classes")
1453 classpath = sourceSets.main.compileClasspath
1454 sourceCompatibility = JavaVersion.VERSION_1_6
1455 targetCompatibility = JavaVersion.VERSION_1_6
1456 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1457 }
1458 // Compiling the rest of the files as Java 1.8 code.
1459 task "compile_examplesAndroidO"(type: JavaCompile) {
1460 dependsOn "compile_examplesAndroidO_Legacy"
1461 source = fileTree(dir: examplesDir, include: '**/*.java', exclude: '**/legacy/**/*.java')
1462 destinationDir = file("build/test/examplesAndroidO/classes")
1463 classpath = sourceSets.main.compileClasspath
1464 classpath += files("build/test/examplesAndroidOLegacy/classes")
1465 sourceCompatibility = JavaVersion.VERSION_1_8
1466 targetCompatibility = JavaVersion.VERSION_1_8
1467 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1468 }
1469 examplesDir.eachDir { dir ->
1470 def name = dir.getName();
1471 def destinationDir = file("build/test/examplesAndroidO/classes");
1472 if (file("src/test/examplesAndroidO/" + name + "/TestGenerator.java").isFile()) {
1473 task "generate_examplesAndroidO_${name}"(type: JavaExec,
1474 dependsOn: "compile_examplesAndroidO") {
1475 main = name + ".TestGenerator"
1476 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1477 args destinationDir
1478 }
1479 } else {
1480 task "generate_examplesAndroidO_${name}" () {}
1481 }
1482 }
1483 examplesDir.eachDir { dir ->
1484 def name = dir.getName();
1485 def exampleOutputDir = file("build/test/examplesAndroidO");
1486 def jarName = "${name}.jar"
1487 dependsOn "jar_examplesAndroidO_${name}"
1488 task "jar_examplesAndroidO_${name}"(type: Jar, dependsOn: ["compile_examplesAndroidO",
1489 "generate_examplesAndroidO_${name}"]) {
1490 archiveName = jarName
1491 destinationDir = exampleOutputDir
1492 from "build/test/examplesAndroidO/classes" // Java 1.8 classes
1493 from "build/test/examplesAndroidOLegacy/classes" // Java 1.6 classes
1494 include "**/" + name + "/**/*.class"
1495 // Do not include generator into the test runtime jar, it is not useful.
1496 // Otherwise, shrinking will need ASM jars.
1497 exclude "**/TestGenerator*"
1498 }
1499 }
1500}
1501
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001502task buildExampleAndroidPJars {
1503 dependsOn downloadDeps
1504 def examplesDir = file("src/test/examplesAndroidP")
1505
1506 task "compile_examplesAndroidP"(type: JavaCompile) {
1507 source = fileTree(dir: examplesDir, include: '**/*.java')
1508 destinationDir = file("build/test/examplesAndroidP/classes")
1509 classpath = sourceSets.main.compileClasspath
1510 sourceCompatibility = JavaVersion.VERSION_1_8
1511 targetCompatibility = JavaVersion.VERSION_1_8
1512 options.compilerArgs += ["-Xlint:-options"]
1513 }
1514 examplesDir.eachDir { dir ->
1515 def name = dir.getName();
1516 def destinationDir = file("build/test/examplesAndroidP/classes");
1517 if (file("src/test/examplesAndroidP/" + name + "/TestGenerator.java").isFile()) {
1518 task "generate_examplesAndroidP_${name}"(type: JavaExec,
1519 dependsOn: "compile_examplesAndroidP") {
1520 main = name + ".TestGenerator"
1521 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1522 args destinationDir
1523 }
1524 } else {
1525 task "generate_examplesAndroidP_${name}" () {}
1526 }
1527 }
1528 examplesDir.eachDir { dir ->
1529 def name = dir.getName();
1530 def exampleOutputDir = file("build/test/examplesAndroidP");
1531 def jarName = "${name}.jar"
1532 dependsOn "jar_examplesAndroidP_${name}"
1533 task "jar_examplesAndroidP_${name}"(type: Jar,
1534 dependsOn: ["compile_examplesAndroidP",
1535 "generate_examplesAndroidP_${name}"]) {
1536 archiveName = jarName
1537 destinationDir = exampleOutputDir
1538 from "build/test/examplesAndroidP/classes" // Java 1.8 classes
1539 include "**/" + name + "/**/*.class"
1540 // Do not include generator into the test runtime jar, it is not useful.
1541 // Otherwise, shrinking will need ASM jars.
1542 exclude "**/TestGenerator*"
1543 }
1544 }
1545}
1546
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001547def buildExampleJarsCreateTask(javaVersion, sourceSet) {
1548 return tasks.create("buildExample${javaVersion}Jars") {
1549 def examplesDir = file("src/test/examples${javaVersion}")
1550 examplesDir.eachDir { dir ->
1551 def name = dir.getName();
1552 def exampleOutputDir = file("build/test/examples${javaVersion}");
1553 def jarName = "${name}.jar"
1554 dependsOn "jar_examples${javaVersion}_${name}"
1555 task "jar_examples${javaVersion}_${name}"(type: Jar) {
1556 archiveName = jarName
1557 destinationDir = exampleOutputDir
1558 from sourceSet.output
1559 include "**/" + name + "/**/*.class"
1560 }
Mikaël Peltier61633d42017-10-13 16:51:06 +02001561 }
1562 }
1563}
1564
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001565buildExampleJarsCreateTask("Java9", sourceSets.examplesJava9)
1566buildExampleJarsCreateTask("Java10", sourceSets.examplesJava10)
1567buildExampleJarsCreateTask("Java11", sourceSets.examplesJava11)
Søren Gjessee9966932021-09-15 17:08:37 +02001568buildExampleJarsCreateTask("Java17", sourceSets.examplesJava17)
Søren Gjessed1e08992022-02-07 16:46:31 +01001569buildExampleJarsCreateTask("Java18", sourceSets.examplesJava18)
clementberad7ab1dd2019-04-16 16:05:00 +02001570
clementberaa92e3cd2019-07-12 14:13:22 +02001571task provideArtFrameworksDependencies {
1572 cloudDependencies.tools.forEach({ art ->
1573 if (art.contains("art")) {
1574 def taskName = art.replace('/','_')
1575 dependsOn "patch_${taskName}"
1576 task "patch_${taskName}"(type: org.gradle.api.tasks.Copy){
1577 from "tools/${art}/framework"
1578 include "**.jar"
1579 into file("tools/${art}/out/host/linux-x86/framework")
1580 }
1581 }
1582 })
1583}
1584
Sebastien Hertzd3313772018-01-16 14:12:37 +01001585task buildKotlinR8TestResources {
1586 def examplesDir = file("src/test/kotlinR8TestResources")
1587 examplesDir.eachDir { dir ->
Sebastien Hertzfe97a712018-02-13 12:08:59 +01001588 kotlin.Kotlinc.KotlinTargetVersion.values().each { kotlinTargetVersion ->
1589 def name = dir.getName()
1590 def taskName = "jar_kotlinR8TestResources_${name}_${kotlinTargetVersion}"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001591 def javaOutput = "build/test/kotlinR8TestResources/${kotlinTargetVersion}/${name}/java"
Denis Vnukovc22da842018-03-14 12:57:20 -07001592 def javaOutputJarName = "${name}.java.jar"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001593 def javaOutputJarDir = "build/test/kotlinR8TestResources/${kotlinTargetVersion}"
Denis Vnukovc22da842018-03-14 12:57:20 -07001594 task "${taskName}Java"(type: JavaCompile) {
1595 source = fileTree(dir: file("${examplesDir}/${name}"), include: '**/*.java')
1596 destinationDir = file(javaOutput)
1597 classpath = sourceSets.main.compileClasspath
1598 sourceCompatibility = JavaVersion.VERSION_1_6
1599 targetCompatibility = JavaVersion.VERSION_1_6
1600 options.compilerArgs += ["-g", "-Xlint:-options"]
1601 }
1602 task "${taskName}JavaJar"(type: Jar, dependsOn: "${taskName}Java") {
1603 archiveName = javaOutputJarName
1604 destinationDir = file(javaOutputJarDir)
1605 from javaOutput
1606 include "**/*.class"
1607 }
Morten Krogh-Jespersen358c8a72021-02-24 11:07:57 +01001608 dependsOn "${taskName}JavaJar"
Sebastien Hertzd3313772018-01-16 14:12:37 +01001609 }
Sebastien Hertzd3313772018-01-16 14:12:37 +01001610 }
1611}
1612
Mads Ager418d1ca2017-05-22 09:35:49 +02001613task buildExamples {
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001614 if (OperatingSystem.current().isMacOsX() || OperatingSystem.current().isWindows()) {
1615 logger.lifecycle("WARNING: Testing (including building examples) is only partially supported on your " +
1616 "platform (" + OperatingSystem.current().getName() + ").")
Mads Ager418d1ca2017-05-22 09:35:49 +02001617 } else if (!OperatingSystem.current().isLinux()) {
1618 logger.lifecycle("WARNING: Testing (including building examples) is not supported on your platform. " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001619 "It is fully supported on Linux and partially supported on Mac OS and Windows")
Mads Ager418d1ca2017-05-22 09:35:49 +02001620 return;
1621 }
1622 dependsOn buildDebugTestResourcesJars
1623 dependsOn buildExampleJars
1624 dependsOn buildExampleAndroidNJars
1625 dependsOn buildExampleAndroidOJars
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001626 dependsOn buildExampleAndroidPJars
Mikaël Peltier61633d42017-10-13 16:51:06 +02001627 dependsOn buildExampleJava9Jars
Jake Wharton2000b2f2019-12-11 20:37:49 -05001628 dependsOn buildExampleJava10Jars
clementberad7ab1dd2019-04-16 16:05:00 +02001629 dependsOn buildExampleJava11Jars
Søren Gjessee9966932021-09-15 17:08:37 +02001630 dependsOn buildExampleJava17Jars
Søren Gjessed1e08992022-02-07 16:46:31 +01001631 dependsOn buildExampleJava18Jars
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001632 dependsOn buildExampleAndroidApi
Mads Ager418d1ca2017-05-22 09:35:49 +02001633 def examplesDir = file("src/test/examples")
Yohann Rousself820a572017-05-31 20:25:51 +02001634 def noDexTests = [
1635 "multidex",
1636 "multidex002",
1637 "multidex004",
1638 ]
Mads Ager418d1ca2017-05-22 09:35:49 +02001639 examplesDir.eachDir { dir ->
1640 def name = dir.getName();
Yohann Rousself820a572017-05-31 20:25:51 +02001641 if (!(name in noDexTests)) {
1642 dependsOn "dex_example_${name}"
1643 def exampleOutputDir = file("build/test/examples/" + name);
1644 def dexPath = file("${exampleOutputDir}")
1645 def debug = (name == "throwing")
1646 if (!dexPath.exists()) {
1647 dexPath.mkdirs()
1648 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001649 task "dex_example_${name}"(type: DxTask, dependsOn: "jar_example_${name}") {
Yohann Rousself820a572017-05-31 20:25:51 +02001650 source = files(tasks.getByPath("jar_example_${name}")).asFileTree
1651 destination = dexPath
1652 debug = debug
1653 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001654 }
1655 }
1656}
1657
1658task buildSmali {
1659 def smaliDir = file("src/test/smali")
1660 smaliDir.eachDirRecurse() { dir ->
1661 def name = dir.getName();
1662 def relativeDir = smaliDir.toPath().relativize(dir.toPath());
1663 def smaliOutputDir = file("build/test/smali/" + relativeDir);
1664 smaliOutputDir.mkdirs()
1665 outputs.dir smaliOutputDir
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001666 def taskName = "smali_build_${relativeDir.toString().replace('/', '_').replace('\\', '_')}"
Mads Ager418d1ca2017-05-22 09:35:49 +02001667 def smaliFiles = fileTree(dir: dir, include: '*.smali')
1668 def javaFiles = fileTree(dir: dir, include: '*.java')
1669 def destDir = smaliOutputDir;
1670 def destFile = destDir.toPath().resolve("${name}.dex").toFile()
1671 def intermediateFileName = "${name}-intermediate.dex";
1672 def intermediateFile = destDir.toPath().resolve(intermediateFileName).toFile()
1673 if (javaFiles.empty) {
1674 if (!smaliFiles.empty) {
1675 dependsOn "${taskName}_smali"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001676 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001677 source = smaliFiles
1678 destination = destFile
1679 }
1680 }
1681 } else {
Rico Wind01c15c62021-04-22 17:30:41 +00001682 dependsOn "${taskName}_dexmerger"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001683 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001684 source = smaliFiles
1685 destination = intermediateFile
1686 }
1687 task "${taskName}_java"(type: JavaCompile) {
1688 source = javaFiles
1689 destinationDir destDir
1690 classpath = sourceSets.main.compileClasspath
1691 sourceCompatibility = JavaVersion.VERSION_1_7
1692 targetCompatibility = JavaVersion.VERSION_1_7
1693 options.compilerArgs += ["-Xlint:-options"]
1694 }
1695 task "${taskName}_jar"(type: Jar, dependsOn: "${taskName}_java") {
1696 archiveName = "Test.jar"
1697 destinationDir = destDir
1698 from fileTree(dir: destDir, include: 'Test.class')
1699 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001700 task "${taskName}_dx"(type: DxTask, dependsOn: "${taskName}_jar") {
Mads Ager418d1ca2017-05-22 09:35:49 +02001701 source = fileTree(dir: destDir, include: 'Test.jar')
1702 destination = destDir
1703 }
1704 task "${taskName}_dexmerger"(
Jake Wharton2d7aab82019-09-13 10:24:26 -04001705 type: DexMergerTask, dependsOn: ["${taskName}_dx", "${taskName}_smali"]) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001706 source = fileTree(dir: destDir, include: ["classes.dex", intermediateFileName])
1707 destination = destFile
1708 }
1709 }
1710 }
1711}
1712
1713tasks.withType(Test) {
Rico Windc56f21c2019-03-12 07:29:57 +01001714 println("NOTE: Number of processors " + Runtime.runtime.availableProcessors())
Mads Ager418d1ca2017-05-22 09:35:49 +02001715 def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK')
Rico Wind73da9f12019-09-19 09:27:07 +02001716 def processors = Runtime.runtime.availableProcessors()
Mads Ager418d1ca2017-05-22 09:35:49 +02001717 // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
Rico Wind73da9f12019-09-19 09:27:07 +02001718 if (userDefinedCoresPerFork) {
1719 maxParallelForks = processors.intdiv(userDefinedCoresPerFork.toInteger()) ?: 1
1720 } else {
1721 // On normal work machines this seems to give the best test execution time (without freezing)
Rico Wind3d4113e2021-09-30 07:50:43 +02001722 maxParallelForks = processors.intdiv(3) ?: 1
1723 // On low cpu count machines (bots) we under subscribe, so increase the count.
1724 if (processors == 8) {
Rico Wind59f7fb02021-10-25 09:01:39 +02001725 maxParallelForks = 3
Rico Wind3d4113e2021-09-30 07:50:43 +02001726 }
Rico Wind73da9f12019-09-19 09:27:07 +02001727 }
Rico Windc56f21c2019-03-12 07:29:57 +01001728 println("NOTE: Max parallel forks " + maxParallelForks)
Rico Wind73da9f12019-09-19 09:27:07 +02001729
Mads Ager418d1ca2017-05-22 09:35:49 +02001730 forkEvery = 0
Søren Gjesseaf1c5e22017-06-15 12:24:03 +02001731 if (project.hasProperty('disable_assertions')) {
1732 enableAssertions = false
1733 }
Ian Zerny16c2f2d2019-02-19 07:25:11 +01001734 // TODO(b/124091860): Increase the max heap size to avoid OOM when running tests.
Rico Wind97b0a992019-08-30 11:09:15 +02001735 if (project.hasProperty('test_xmx')) {
1736 maxHeapSize = project.property('test_xmx')
1737 } else {
1738 maxHeapSize = "4G"
1739 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001740}
1741
1742task buildPreNJdwpTestsJar(type: Jar) {
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001743 archiveFileName = 'jdwp-tests-preN.jar'
Mads Ager418d1ca2017-05-22 09:35:49 +02001744 from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
1745 // Exclude the classes containing java8
1746 exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
1747 exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
1748 includeEmptyDirs = false
1749}
1750
Ian Zerny74143162017-11-24 13:46:35 +01001751task buildPreNJdwpTestsDex(type: Exec, dependsOn: "buildPreNJdwpTestsJar") {
1752 def inFile = buildPreNJdwpTestsJar.archivePath
1753 def outFile = new File(buildPreNJdwpTestsJar.destinationDir, buildPreNJdwpTestsJar.baseName + '-dex.jar')
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001754 inputs.files files(inFile)
Ian Zerny74143162017-11-24 13:46:35 +01001755 outputs.file outFile
1756 if (OperatingSystem.current().isWindows()) {
1757 executable file("tools/windows/dx/bin/dx.bat")
1758 } else if (OperatingSystem.current().isMacOsX()) {
1759 executable file("tools/mac/dx/bin/dx");
1760 } else {
1761 executable file("tools/linux/dx/bin/dx");
1762 }
1763 args "--dex"
1764 args "--output=${outFile}"
1765 args inFile
1766}
1767
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001768task getJarsFromSupportLibs(type: GetJarsFromConfiguration) {
1769 setConfiguration(configurations.supportLibs)
Yohann Roussel126f6872017-08-03 16:25:32 +02001770}
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001771
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001772task generateR8TestKeepRules {
1773 def path = "build/generated/r8tests-keep.txt"
1774 outputs.file path
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001775 dependsOn R8Lib
1776 doLast {
1777 file(path).write """-keep class ** { *; }
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001778-dontshrink
1779-dontoptimize
1780-keepattributes *
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001781-applymapping ${R8Lib.outputs.files[0]}.map
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001782"""
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001783 }
1784}
1785
1786task buildR8LibCfTestDeps(type: Exec) {
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001787 def outputPath = "build/libs/r8libtestdeps-cf.jar"
1788 dependsOn downloadDeps
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001789 dependsOn r8NoManifest
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001790 dependsOn R8Lib
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001791 dependsOn generateR8TestKeepRules
1792 dependsOn testJar
1793 // Take all .jar files as libraries and append the generated test classes in classes/java/test.
1794 def addedLibraries = sourceSets.test.runtimeClasspath.findAll { pkg ->
1795 return pkg.toString().endsWith(".jar")
1796 } + ["${buildDir}/classes/java/test"]
1797 inputs.files testJar.outputs.files +
1798 generateR8TestKeepRules.outputs.files +
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001799 R8Lib.outputs
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001800 commandLine = r8CfCommandLine(
1801 testJar.outputs.files[0],
1802 outputPath,
1803 [generateR8TestKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001804 ["--debug", "--classpath", r8NoManifest.outputs.files[0]],
1805 r8NoManifest.outputs.files + addedLibraries)
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001806 workingDir = projectDir
1807 outputs.file outputPath
1808}
1809
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001810task configureTestForR8Lib(type: Copy) {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001811 dependsOn testJar
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001812 inputs.files buildR8LibCfTestDeps.outputs
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001813 dependsOn R8Lib
1814 delete r8LibTestPath
1815 from zipTree(buildR8LibCfTestDeps.outputs.files[0])
1816 def examplesDir = file("build/test")
1817 examplesDir.eachDir { dir ->
1818 from ("${buildDir}/test/${dir.getName()}/classes")
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001819 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001820 from ("${buildDir}/runtime/examples")
1821 into r8LibTestPath
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001822 outputs.dir r8LibTestPath
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +01001823}
1824
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001825def shouldRetrace() {
1826 return project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')
1827}
1828
1829def retrace(Throwable exception) {
1830 def out = new StringBuffer()
1831 def err = new StringBuffer()
Ian Zerny99613a02022-02-23 11:50:13 +01001832 def command = "python3 tools/retrace.py --quiet"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001833 def header = "RETRACED STACKTRACE";
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001834 out.append("\n--------------------------------------\n")
1835 out.append("${header}\n")
1836 out.append("--------------------------------------\n")
1837 Process process = command.execute()
1838 def processIn = new PrintStream(process.getOut())
1839 process.consumeProcessOutput(out, err)
1840 exception.printStackTrace(processIn)
1841 processIn.flush()
1842 processIn.close()
1843 def errorDuringRetracing = process.waitFor() != 0
1844 if (errorDuringRetracing) {
1845 out.append("ERROR DURING RETRACING\n")
1846 out.append(err.toString())
1847 }
1848 if (project.hasProperty('print_obfuscated_stacktraces') || errorDuringRetracing) {
1849 out.append("\n\n--------------------------------------\n")
1850 out.append("OBFUSCATED STACKTRACE\n")
1851 out.append("--------------------------------------\n")
1852 }
1853 return out.toString()
1854}
1855
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001856def printStackTrace(TestResult result) {
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001857 filterStackTraces(result)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001858 if (shouldRetrace()) {
1859 def exception = new Exception(retrace(result.exception))
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001860 exception.setStackTrace([] as StackTraceElement[])
1861 result.exceptions.add(0, exception)
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001862 }
1863}
1864
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001865def filterStackTraces(TestResult result) {
1866 for (Throwable throwable : result.getExceptions()) {
1867 filterStackTrace(throwable)
1868 }
1869}
1870
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001871// It would be nice to do this in a non-destructive way...
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001872def filterStackTrace(Throwable exception) {
1873 if (!project.hasProperty('print_full_stacktraces')) {
1874 def elements = []
1875 def skipped = []
1876 for (StackTraceElement element : exception.getStackTrace()) {
1877 if (element.toString().contains("com.android.tools.r8")) {
1878 elements.addAll(skipped)
1879 elements.add(element)
1880 skipped.clear()
1881 } else {
1882 skipped.add(element)
1883 }
1884 }
1885 exception.setStackTrace(elements as StackTraceElement[])
1886 }
1887}
1888
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001889def printAllStackTracesToFile(List<Throwable> exceptions, File out) {
1890 new PrintStream(new FileOutputStream(out)).withCloseable {printer ->
1891 exceptions.forEach { it.printStackTrace(printer) }
1892 }
1893}
1894
Ian Zerny89f16cf2021-04-29 21:10:09 +02001895static def escapeHtml(String string) {
1896 return string.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
1897}
1898
1899static def urlEncode(String string) {
1900 // Not sure why, but the + also needs to be converted to have working links.
1901 return URLEncoder.encode(string, "UTF-8").replace("+","%20")
1902}
1903
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001904def ensureDir(File dir) {
1905 dir.mkdirs()
1906 return dir
1907}
1908
Ian Zerny89f16cf2021-04-29 21:10:09 +02001909// Some of our test parameters have new lines :-( We really don't want test names to span lines.
1910static def sanitizedTestName(testDesc) {
1911 if (testDesc.getName().contains("\n")) {
1912 throw new RuntimeException("Unsupported use of newline in test name: '${testDesc.getName()}'")
1913 }
1914 return testDesc.getName()
1915}
1916
1917static def desanitizedTestName(testName) {
1918 return testName
1919}
1920
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001921def getTestReportEntryDir(reportDir, testDesc) {
1922 return ensureDir(reportDir.toPath()
1923 .resolve(testDesc.getClassName())
Ian Zerny89f16cf2021-04-29 21:10:09 +02001924 .resolve(sanitizedTestName(testDesc))
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001925 .toFile())
1926}
1927
Ian Zerny89f16cf2021-04-29 21:10:09 +02001928def getTestReportEntryURL(reportDir, testDesc) {
1929 def classDir = urlEncode(testDesc.getClassName())
1930 def testDir = urlEncode(sanitizedTestName(testDesc))
1931 return "file://${reportDir}/${classDir}/${testDir}"
1932}
1933
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001934def getTestResultEntryOutputFile(reportDir, testDesc, fileName) {
1935 def dir = getTestReportEntryDir(reportDir, testDesc).toPath()
1936 return dir.resolve(fileName).toFile()
1937}
1938
Ian Zerny89f16cf2021-04-29 21:10:09 +02001939def withTestResultEntryWriter(reportDir, testDesc, fileName, append, fn) {
1940 def file = getTestResultEntryOutputFile(reportDir, testDesc, fileName)
1941 new FileWriter(file, append).withCloseable fn
1942}
1943
Ian Zerny27ea4c72021-04-29 22:35:49 +02001944static def getGitBranchName() {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001945 def out = new StringBuilder()
1946 def err = new StringBuilder()
1947 def proc = "git rev-parse --abbrev-ref HEAD".execute()
1948 proc.waitForProcessOutput(out, err)
Ian Zerny27ea4c72021-04-29 22:35:49 +02001949 return out.toString().trim()
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001950}
1951
Ian Zerny27ea4c72021-04-29 22:35:49 +02001952static def getFreshTestReportIndex(File reportDir) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02001953 def number = 0
1954 while (true) {
1955 def freshIndex = reportDir.toPath().resolve("index.${number++}.html").toFile()
1956 if (!freshIndex.exists()) {
1957 return freshIndex
1958 }
1959 }
1960}
1961
1962def forEachTestReportAlreadyX(File reportDir, fileName, onTest) {
1963 def out = new StringBuilder()
1964 def err = new StringBuilder()
1965 def proc = "find . -name ${fileName}".execute([], reportDir)
1966 proc.waitForProcessOutput(out, err)
1967 def outString = out.toString()
1968 outString.eachLine {
1969 // Lines are of the form: ./<class>/<name>/FAILURE
1970 def clazz = null
1971 def name = null
1972 try {
1973 def trimmed = it.trim()
1974 def line = trimmed.substring(2)
1975 def sep = line.indexOf("/")
1976 clazz = line.substring(0, sep)
1977 name = line.substring(sep + 1, line.length() - fileName.length() - 1)
1978 } catch (Exception e) {
1979 logger.lifecycle("WARNING: failed attempt to read test description from: '${it}'")
1980 return
1981 }
1982 onTest(clazz, desanitizedTestName(name))
1983 }
1984 return !outString.trim().isEmpty()
1985}
1986
1987def forEachTestReportAlreadyFailing(File reportDir, onFailureTest) {
1988 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.FAILURE.name(), onFailureTest)
1989}
1990
1991def forEachTestReportAlreadyPassing(File reportDir, onSucceededTest) {
1992 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SUCCESS.name(), onSucceededTest)
1993}
1994
1995def forEachTestReportAlreadySkipped(File reportDir, onSucceededTest) {
1996 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SKIPPED.name(), onSucceededTest)
1997}
1998
Ian Zerny27ea4c72021-04-29 22:35:49 +02001999def setUpTestingState(Test task) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002000 // Hide all test events from the console, they are written to the report.
2001 task.testLogging { events = [] }
2002
Ian Zernycae764d2021-08-16 08:25:15 +02002003 def branch = project.hasProperty('testing-state-name')
2004 ? project.getProperty('testing-state-name')
2005 : getGitBranchName()
Ian Zerny27ea4c72021-04-29 22:35:49 +02002006 def reportDir = file("${buildDir}/test-state/${branch}")
Ian Zerny89f16cf2021-04-29 21:10:09 +02002007 def index = reportDir.toPath().resolve("index.html").toFile()
Ian Zerny27ea4c72021-04-29 22:35:49 +02002008 def resetState = project.hasProperty('reset-testing-state')
2009 def reportDirExists = reportDir.exists()
2010 def resuming = !resetState && reportDirExists
Ian Zerny89f16cf2021-04-29 21:10:09 +02002011
2012 def hasFailingTests = false;
2013 if (resuming) {
2014 // Test filtering happens before the test execution is initiated so compute it here.
2015 // If there are still failing tests in the report, include only those.
2016 hasFailingTests = forEachTestReportAlreadyFailing(reportDir, {
2017 clazz, name -> task.filter.includeTestsMatching("$clazz.$name")
2018 })
2019 // Otherwise exclude all of the test already marked as succeeding.
2020 if (!hasFailingTests) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002021 // Also allow the test to overall succeed if there are no remaining tests that match,
2022 // which is natural if the state already succeeded in full.
2023 task.filter.failOnNoMatchingTests = false
Ian Zerny89f16cf2021-04-29 21:10:09 +02002024 forEachTestReportAlreadyPassing(reportDir, {
2025 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2026 })
2027 forEachTestReportAlreadySkipped(reportDir, {
2028 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2029 })
2030 }
2031 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002032
2033 task.beforeSuite { desc ->
2034 if (!desc.parent) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002035 def parentReport = null
Ian Zerny27ea4c72021-04-29 22:35:49 +02002036 if (resetState && reportDirExists) {
2037 delete reportDir
2038 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002039 if (resuming) {
2040 if (index.exists()) {
2041 parentReport = getFreshTestReportIndex(reportDir)
2042 index.renameTo(parentReport)
2043 }
2044 } else {
2045 reportDir.mkdirs()
2046 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002047 def runPrefix = resuming ? "Resuming" : "Starting"
2048 def title = "${runPrefix} @ ${branch}"
2049 // Print a console link to the test report for easy access.
2050 println "${runPrefix} test, report written to:"
2051 println " file://${index}"
2052 // Print the new index content.
2053 index << "<html><head><title>${title}</title>"
2054 index << "<style> * { font-family: monospace; }</style>"
Morten Krogh-Jespersende7ddfa2021-09-03 12:37:32 +02002055 index << "<meta http-equiv='refresh' content='10' />"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002056 index << "</head><body><h1>${title}</h1>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002057 index << "<p>Run on: ${new Date()}</p>"
2058 index << "<p>Git branch: ${branch}</p>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002059 if (parentReport != null) {
2060 index << "<p><a href=\"file://${parentReport}\">Previous result index</a></p>"
2061 }
2062 index << "<p><a href=\"file://${index}\">Most recent result index</a></p>"
2063 index << "<p><a href=\"file://${reportDir}\">Test directories</a></p>"
Morten Krogh-Jespersende7ddfa2021-09-03 12:37:32 +02002064 index << "<h2>Failing tests (refreshing automatically every 10 seconds)</h2><ul>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002065 }
2066 }
2067
2068 task.afterSuite { desc, result ->
2069 if (!desc.parent) {
2070 // Update the final test results in the index.
2071 index << "</ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002072 if (result.resultType == TestResult.ResultType.SUCCESS) {
2073 if (hasFailingTests) {
2074 index << "<h2>Rerun of failed tests now pass!</h2>"
2075 index << "<h2>Rerun again to continue with outstanding tests!</h2>"
2076 } else {
2077 index << "<h2 style=\"background-color:#62D856\">GREEN BAR == YOU ROCK!</h2>"
2078 }
2079 } else if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002080 index << "<h2 style=\"background-color:#6D130A\">Some tests failed: ${result.resultType.name()}</h2><ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002081 } else {
2082 index << "<h2>Tests finished: ${result.resultType.name()}</h2><ul>"
2083 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002084 index << "<li>Number of tests: ${result.testCount}"
2085 index << "<li>Failing tests: ${result.failedTestCount}"
2086 index << "<li>Successful tests: ${result.successfulTestCount}"
2087 index << "<li>Skipped tests: ${result.skippedTestCount}"
2088 index << "</ul></body></html>"
2089 }
2090 }
2091
2092 // Events to stdout/err are appended to the files in the test directories.
2093 task.onOutput { desc, event ->
Ian Zerny89f16cf2021-04-29 21:10:09 +02002094 withTestResultEntryWriter(reportDir, desc, event.getDestination().name(), true, {
2095 it.append(event.getMessage())
2096 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002097 }
2098
Ian Zerny27ea4c72021-04-29 22:35:49 +02002099 task.beforeTest { desc ->
2100 // Remove any stale output files before running the test.
2101 for (def destType : TestOutputEvent.Destination.values()) {
2102 def destFile = getTestResultEntryOutputFile(reportDir, desc, destType.name())
2103 if (destFile.exists()) {
2104 delete destFile
2105 }
2106 }
2107 }
2108
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002109 task.afterTest { desc, result ->
2110 if (result.getTestCount() != 1) {
2111 throw new IllegalStateException("Unexpected test with more than one result: ${desc}")
2112 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002113 // Clear any previous result files.
2114 for (def resultType : TestResult.ResultType.values()) {
2115 delete getTestResultEntryOutputFile(reportDir, desc, resultType.name())
2116 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002117 // Emit the result type status in a file of the same name: SUCCESS, FAILURE or SKIPPED.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002118 withTestResultEntryWriter(reportDir, desc, result.getResultType().name(), false, {
2119 it.append(result.getResultType().name())
2120 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002121 // Emit the test time.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002122 withTestResultEntryWriter(reportDir, desc, "time", false, {
2123 it.append("${result.getEndTime() - result.getStartTime()}")
2124 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002125 // For failed tests, update the index and emit stack trace information.
2126 if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002127 def title = escapeHtml("${desc.className}.${desc.name}")
2128 def link = getTestReportEntryURL(reportDir, desc)
2129 index << "<li><a href=\"${link}\">${title}</a></li>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002130 if (!result.exceptions.isEmpty()) {
2131 printAllStackTracesToFile(
2132 result.exceptions,
2133 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002134 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002135 desc,
2136 "exceptions-raw.txt"))
2137 filterStackTraces(result)
2138 printAllStackTracesToFile(
2139 result.exceptions,
2140 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002141 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002142 desc,
2143 "exceptions-filtered.txt"))
2144 if (shouldRetrace()) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002145 withTestResultEntryWriter(reportDir, desc, "exceptions-retraced.txt", false, { writer ->
2146 result.exceptions.forEach { writer.append(retrace(it)) }
2147 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002148 }
2149 }
2150 }
2151 }
2152}
2153
Rico Windf2f4c292021-04-23 07:06:13 +02002154def testTimes = [:]
Ian Zerny475e4012021-04-29 14:01:49 +02002155def numberOfTestTimesToPrint = 100
Rico Windf2f4c292021-04-23 07:06:13 +02002156
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002157test { task ->
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002158
2159 dependsOn buildLibraryDesugarConversions
2160 dependsOn getJarsFromSupportLibs
2161 // R8.jar is required for running bootstrap tests.
2162 dependsOn r8
2163
Ian Zerny27ea4c72021-04-29 22:35:49 +02002164 def useTestingState = project.hasProperty('testing-state')
2165 if (useTestingState) {
2166 setUpTestingState(task)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002167 }
2168
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +02002169 if (project.hasProperty('generate_golden_files_to')) {
2170 systemProperty 'generate_golden_files_to', project.property('generate_golden_files_to')
2171 assert project.hasProperty('HEAD_sha1')
2172 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2173 }
2174
2175 if (project.hasProperty('use_golden_files_in')) {
2176 systemProperty 'use_golden_files_in', project.property('use_golden_files_in')
2177 assert project.hasProperty('HEAD_sha1')
2178 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2179 }
Ian Zerny4b0de282019-06-28 09:32:24 +02002180
Morten Krogh-Jespersendcb967e2021-12-02 11:18:39 +01002181 if (project.hasProperty('kotlin_compiler_dev')) {
2182 systemProperty 'com.android.tools.r8.kotlincompilerdev', '1';
2183 }
2184
2185 if (project.hasProperty('kotlin_compiler_old')) {
2186 systemProperty 'com.android.tools.r8.kotlincompilerold', '1';
2187 }
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002188
Ian Zerny27ea4c72021-04-29 22:35:49 +02002189 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002190 testLogging.exceptionFormat = 'full'
2191 if (project.hasProperty('print_test_stdout')) {
2192 testLogging.showStandardStreams = true
2193 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002194 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002195 if (project.hasProperty('dex_vm') && project.property('dex_vm') != 'default') {
Ian Zerny324d7612019-03-20 10:52:28 +01002196 println "NOTE: Running with non default vm: " + project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002197 systemProperty 'dex_vm', project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002198 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002199
Ian Zerny324d7612019-03-20 10:52:28 +01002200 // Forward runtime configurations for test parameters.
2201 if (project.hasProperty('runtimes')) {
2202 println "NOTE: Running with runtimes: " + project.property('runtimes')
2203 systemProperty 'runtimes', project.property('runtimes')
Ian Zerny4dfd5a52019-03-12 07:56:11 +01002204 }
2205
Christoffer Quist Adamsen748e4662019-08-23 14:53:49 +02002206 if (project.hasProperty('slow_tests')) {
2207 systemProperty 'slow_tests', project.property('slow_tests')
2208 }
2209
Søren Gjesseef195772021-03-11 16:04:42 +01002210
2211 if (project.hasProperty('desugar_jdk_json_dir')) {
2212 systemProperty 'desugar_jdk_json_dir', project.property('desugar_jdk_json_dir')
2213 }
Søren Gjesse4a45f9b2021-02-11 14:05:29 +01002214 if (project.hasProperty('desugar_jdk_libs')) {
2215 systemProperty 'desugar_jdk_libs', project.property('desugar_jdk_libs')
2216 }
2217
Ian Zerny27ea4c72021-04-29 22:35:49 +02002218 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002219 if (project.hasProperty('print_times') || project.hasProperty('one_line_per_test')) {
2220 afterTest { desc, result ->
2221 def executionTime = (result.endTime - result.startTime) / 1000
2222 testTimes["${desc.name} [${desc.className}]"] = executionTime
2223 }
2224 afterSuite { desc, result ->
2225 // parent is null if all tests are done.
2226 if (desc.parent == null) {
2227 def sortedTimes = testTimes.sort({ e1, e2 -> e2.value <=> e1.value })
2228 sortedTimes.eachWithIndex { key, value, i ->
2229 if (i < numberOfTestTimesToPrint) println "$key: $value"
2230 }
2231 }
2232 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002233 }
Rico Windf2f4c292021-04-23 07:06:13 +02002234
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002235 if (project.hasProperty('one_line_per_test')) {
2236 beforeTest { desc ->
2237 println "Start executing test ${desc.name} [${desc.className}]"
Rico Windf88b6be2018-12-11 15:14:05 +01002238 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002239
2240 afterTest { desc, result ->
2241 if (result.resultType == TestResult.ResultType.FAILURE) {
2242 printStackTrace(result)
2243 }
2244 if (project.hasProperty('update_test_timestamp')) {
2245 file(project.getProperty('update_test_timestamp')).text = new Date().getTime()
2246 }
2247 println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
Rico Windda6836e2018-12-07 12:32:03 +01002248 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002249 } else {
2250 afterTest { desc, result ->
2251 if (result.resultType == TestResult.ResultType.FAILURE) {
2252 printStackTrace(result)
2253 }
Rico Windf88b6be2018-12-11 15:14:05 +01002254 }
2255 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002256 }
2257 if (project.hasProperty('no_internal')) {
2258 exclude "com/android/tools/r8/internal/**"
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02002259 } else {
2260 dependsOn buildExamplesProto
Mads Ager418d1ca2017-05-22 09:35:49 +02002261 }
2262 if (project.hasProperty('only_internal')) {
2263 include "com/android/tools/r8/internal/**"
2264 }
Rico Wind4e218292019-03-07 12:44:49 +01002265
Rico Windba151112020-10-01 08:16:33 +02002266 if (project.hasProperty('test_namespace')) {
2267 include "com/android/tools/r8/" + project.getProperty('test_namespace') + "/**"
2268 }
2269
Ian Zerny3ced9262022-03-29 11:06:02 +02002270 if (project.hasProperty('tool') && project.property('tool') == 'd8') {
2271 // Don't run anything, deprecated
2272 println "Running with deprecated tool d8, not running any tests"
2273 include ""
Mads Ager418d1ca2017-05-22 09:35:49 +02002274 }
2275 if (!project.hasProperty('all_tests')) {
2276 exclude "com/android/tools/r8/art/dx/**"
Mads Ager418d1ca2017-05-22 09:35:49 +02002277 }
Rico Windbc820812022-05-31 09:19:56 +02002278 if (project.hasProperty('no_arttests')) {
2279 exclude "com/android/tools/r8/art/**"
2280 }
Rico Wind8e2f7e42019-02-21 10:13:21 +01002281 if (project.hasProperty('shard_count') ) {
2282 assert project.hasProperty('shard_number')
2283 int shard_count = project.getProperty('shard_count') as Integer
2284 int shard_number = project.getProperty('shard_number') as Integer
2285 assert shard_count < 65536
2286 assert shard_number < shard_count
2287 exclude {
2288 entry ->
2289 // Don't leave out directories. Leaving out a directory means all entries below.
2290 if (entry.file.isDirectory()) {
2291 return false
2292 }
2293 def first4 = entry.getRelativePath().toString().md5().substring(0, 4)
2294 int hash = Integer.parseInt(first4, 16)
2295 return hash % shard_count != shard_number
2296 }
2297 }
Tamas Kenezb77b7d82017-08-17 14:05:16 +02002298 if (project.hasProperty('test_dir')) {
2299 systemProperty 'test_dir', project.property('test_dir')
2300 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002301 if (project.hasProperty('r8lib')) {
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002302 dependsOn configureTestForR8Lib
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002303 // R8lib should be used instead of the main output and all the tests in
2304 // r8 should be mapped and exists in r8LibTestPath.
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02002305 classpath = sourceSets.test.runtimeClasspath.filter {
2306 !it.getAbsolutePath().contains("/build/")
2307 }
2308 classpath += files([r8LibPath, r8LibTestPath])
Ian Zerny5fffb0a2019-02-11 13:54:22 +01002309 testClassesDirs = files(r8LibTestPath)
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002310 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002311 if (OperatingSystem.current().isLinux()
2312 || OperatingSystem.current().isMacOsX()
2313 || OperatingSystem.current().isWindows()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002314 if (OperatingSystem.current().isMacOsX()) {
2315 logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " +
2316 "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " +
2317 "See tools/docker/README.md for details.")
2318 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002319 if (OperatingSystem.current().isWindows()) {
2320 logger.lifecycle("WARNING: Testing in only partially supported on Windows. " +
2321 "Art only runs on Linux and tests requiring Art will be skipped")
2322 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002323 dependsOn downloadDeps
2324 dependsOn buildExamples
Sebastien Hertzd3313772018-01-16 14:12:37 +01002325 dependsOn buildKotlinR8TestResources
Mads Ager418d1ca2017-05-22 09:35:49 +02002326 dependsOn buildSmali
Mads Ager418d1ca2017-05-22 09:35:49 +02002327 dependsOn buildPreNJdwpTestsJar
Mathias Ravcd795072018-03-22 12:47:32 +01002328 dependsOn buildPreNJdwpTestsDex
Clément Bérac94b6202021-09-28 11:16:58 +00002329 dependsOn compileTestNGRunner
clementberaa92e3cd2019-07-12 14:13:22 +02002330 dependsOn provideArtFrameworksDependencies
Mads Ager418d1ca2017-05-22 09:35:49 +02002331 } else {
2332 logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002333 "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.")
Mads Ager418d1ca2017-05-22 09:35:49 +02002334 }
2335}
2336
2337// The Art tests we use for R8 are pre-build and downloaded from Google Cloud Storage.
2338//
2339// To build and upload a new set of the Art tests for use with R8 follow these steps:
2340//
2341// First of all an Android checkout is required. Currently it must be located
2342// in $HOME/android/master.
2343//
2344// TODO(ricow): simplify this
2345//
2346// Before: update the checked in art, see scripts/update-host-art.sh
2347//
2348// 1. Get an android checkout in $HOME/android/master and apply the patch from
2349// https://android-review.googlesource.com/#/c/294187/
2350//
2351// 2. run the following commands in the Android checkout directory:
2352//
2353// source build/envsetup.sh
Søren Gjesse34b77732017-07-07 13:56:21 +02002354// lunch aosp_angler-userdebug # or lunch aosp_angler-eng
2355// m desugar
2356// m -j30 test-art-host
2357// DESUGAR=false ANDROID_COMPILE_WITH_JACK=false art/test.py --host -t 001-HelloWorld
2358//
2359// Without running the test.py command the classes.jar file used by desugar in
2360// $HOME/android/master/out/host/common/obj/JAVA_LIBRARIES/core-oj-hostdex_intermediates/
2361// seems to be missing - there is probably also a make target to build it more directly
Mads Ager418d1ca2017-05-22 09:35:49 +02002362//
2363// 3. In the R8 project root directory, make sure we have a clean state before starting:
2364// tools/gradle.py downloadDeps
2365// tools/gradle.py clean
2366// rm -rf tests/art
2367//
2368// 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 +02002369// Make sure you have smali on your path, please use the build binary in the
2370// out/host/linux-x86/bin directory of the android checkout. Currently this is version pre 2.2.1,
2371// if that is updated the call to smali in "task "${smaliToDexTask}"(type: Exec)" below might
2372// 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 +02002373// After Android O, Jack is no longer alive, do not forget to uncomment call to buildArtTest for
2374// Jack if you build an android version using Jack.
Mads Ager418d1ca2017-05-22 09:35:49 +02002375//
Søren Gjesse34b77732017-07-07 13:56:21 +02002376// PATH=$HOME/android/master/out/host/linux-x86/bin:$PATH tools/gradle.py -Pandroid_source buildArtTests
Mads Ager418d1ca2017-05-22 09:35:49 +02002377//
2378// 4a. If any failures are produced in step 4, figure out what went wrong and add an entry in
2379// skippedTests with an explanation. Rerun from step 3.
2380//
2381// 5. Run the tests:
2382// tools/gradle.py clean
2383// tools/test.py
2384//
Søren Gjesse34b77732017-07-07 13:56:21 +02002385// 5a. If any more tests fail, either fix the issue or add them to the failuresToTriage list (note
2386// that you need to change "_" to "-" from stdout). Rerun from step 5 if anything was added to
2387// failuresToTriage.
Mads Ager418d1ca2017-05-22 09:35:49 +02002388//
Søren Gjesse34b77732017-07-07 13:56:21 +02002389// 6. To upload a new version to Google Cloud Storage:
Mads Ager418d1ca2017-05-22 09:35:49 +02002390// cd tests
2391// upload_to_google_storage.py -a --bucket r8-deps art
Søren Gjesse34b77732017-07-07 13:56:21 +02002392//
2393// 7. Update the manifest file describing the Android repo used:
2394// repo manifest -o <r8-checkout-root>/tools/linux/aosp_master_manifest.xml -r
Mads Ager418d1ca2017-05-22 09:35:49 +02002395
Mads Ager418d1ca2017-05-22 09:35:49 +02002396def androidCheckoutDir = file("${System.env.HOME}/android/master")
Mads Ager418d1ca2017-05-22 09:35:49 +02002397
2398def artTestDir = file("${androidCheckoutDir}/art/test")
2399
2400if (project.hasProperty('android_source')) {
2401 task buildArtTests {
2402 outputs.upToDateWhen { false }
2403 def toBeTriaged = [
2404 "903-hello-tagging",
2405 "904-object-allocation",
2406 "905-object-free",
2407 "906-iterate-heap",
2408 "907-get-loaded-classes",
2409 "908-gc-start-finish",
2410 "954-invoke-polymorphic-verifier",
2411 "955-methodhandles-smali",
2412 "596-monitor-inflation",
2413 ]
2414 def skippedTests = toBeTriaged + [
2415 // This test produces no jar.
2416 "000-nop",
2417 // This does not build, as it tests the error when the application exceeds more
2418 // than 65536 methods
2419 "089-many-methods",
2420 // Requires some jack beta jar
2421 "956-methodhandles",
2422 ]
2423
2424 def skippedTestsDx = [
2425 // Tests with custom build scripts, where javac is not passed the options
2426 // -source 1.7 -target 1.7.
2427 "462-checker-inlining-across-dex-files",
2428 "556-invoke-super",
2429 "569-checker-pattern-replacement",
2430 // These tests use jack even when --build-with-javac-dx is specified.
2431 "004-JniTest",
2432 "048-reflect-v8",
2433 "146-bad-interface",
2434 "563-checker-invoke-super",
2435 "580-checker-string-fact-intrinsics", // java.lang.StringFactory
2436 "604-hot-static-interface",
2437 "957-methodhandle-transforms",
2438 "958-methodhandle-emulated-stackframe",
2439 "959-invoke-polymorphic-accessors",
2440 "961-default-iface-resolution-gen",
2441 "962-iface-static",
2442 "963-default-range-smali",
2443 "964-default-iface-init-gen",
2444 "965-default-verify",
2445 "966-default-conflict",
2446 "967-default-ame",
2447 "968-default-partial-compile-gen",
2448 "969-iface-super",
2449 "970-iface-super-resolution-gen",
2450 "971-iface-super",
2451 // These tests does not build with --build-with-javac-dx
2452 "004-NativeAllocations", // Javac error
2453 "031-class-attributes",
2454 "138-duplicate-classes-check",
2455 "157-void-class", // Javac error
2456 "580-checker-string-factory-intrinsics",
2457 "612-jit-dex-cache",
2458 "613-inlining-dex-cache",
2459 "900-hello-plugin", // --experimental agents
2460 "901-hello-ti-agent", // --experimental agents
2461 "902-hello-transformation", // --experimental agents
2462 "909-attach-agent", // --experimental agents
2463 "946-obsolete-throw", // -source 1.7 -target 1.7, but use lambda
2464 "950-redefine-intrinsic", // -source 1.7 -target 1.7, but use method references
2465 "951-threaded-obsolete", // -source 1.7 -target 1.7, but use lambda
2466 "960-default-smali", // --experimental default-methods
2467 // These tests force the build to use jack
2468 "953-invoke-polymorphic-compiler",
2469 "958-methodhandle-stackframe",
2470 ]
2471
2472 def artTestBuildDir = file("${projectDir}/tests/art")
2473
2474 if (androidCheckoutDir.exists()) {
2475 dependsOn downloadDeps
2476 artTestBuildDir.mkdirs()
Mads Ager418d1ca2017-05-22 09:35:49 +02002477 artTestDir.eachDir { dir ->
2478 def name = dir.getName();
2479 def markerFile = dir.toPath().resolve("info.txt").toFile();
2480 if (markerFile.exists() && !(name in skippedTests)) {
2481 if (!(name in skippedTestsDx)) {
Rico Windde2af6c2019-03-26 15:21:08 +01002482 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir);
Mads Ager418d1ca2017-05-22 09:35:49 +02002483 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002484 }
2485 }
2486 }
2487 doFirst {
2488 if (!androidCheckoutDir.exists()) {
2489 throw new InvalidUserDataException(
2490 "This task requires an Android checkout in ${androidCheckoutDir}");
Mads Ager418d1ca2017-05-22 09:35:49 +02002491 }
2492 }
2493 doLast {
2494 copy {
2495 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest64")
2496 into file("${artTestBuildDir}/lib64")
2497 include 'lib*.so'
2498 }
2499 copy {
2500 from file("${androidCheckoutDir}/out/host/linux-x86/lib64")
2501 into file("${artTestBuildDir}/lib64")
2502 include 'libart.so'
2503 include 'libbacktrace.so'
2504 include 'libbase.so'
2505 include 'libc++.so'
2506 include 'libcutils.so'
2507 include 'liblz4.so'
2508 include 'liblzma.so'
2509 include 'libnativebridge.so'
2510 include 'libnativeloader.so'
2511 include 'libsigchain.so'
2512 include 'libunwind.so'
2513 include 'libziparchive.so'
2514 }
2515 copy {
2516 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest")
2517 into file("${artTestBuildDir}/lib")
2518 include 'lib*.so'
2519 }
2520 copy {
2521 from file("${androidCheckoutDir}/out/host/linux-x86/lib")
2522 into file("${artTestBuildDir}/lib")
2523 include 'libart.so'
2524 include 'libbacktrace.so'
2525 include 'libbase.so'
2526 include 'libc++.so'
2527 include 'libcutils.so'
2528 include 'liblz4.so'
2529 include 'liblzma.so'
2530 include 'libnativebridge.so'
2531 include 'libnativeloader.so'
2532 include 'libsigchain.so'
2533 include 'libunwind.so'
2534 include 'libziparchive.so'
2535 }
2536 }
2537 }
2538}
2539
Rico Windde2af6c2019-03-26 15:21:08 +01002540def buildArtTest(androidCheckoutDir, artTestBuildDir, dir) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002541 def artTestDir = file("${androidCheckoutDir}/art/test")
2542 def artRunTestScript = file("${artTestDir}/run-test")
2543 def dxExecutable = new File("tools/linux/dx/bin/dx");
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02002544 def dexMergerExecutable = Utils.dexMergerExecutable()
Mads Ager418d1ca2017-05-22 09:35:49 +02002545
Søren Gjesse34b77732017-07-07 13:56:21 +02002546 def name = dir.getName()
Rico Windde2af6c2019-03-26 15:21:08 +01002547 def buildTask = "build_art_test_dx_${name}"
2548 def sanitizeTask = "sanitize_art_test_dx_${name}"
2549 def copyCheckTask = "copy_check_art_test_dx_${name}"
2550 def smaliToDexTask = "smali_to_dex_dx_${name}"
Mads Ager418d1ca2017-05-22 09:35:49 +02002551
2552 def buildInputs = fileTree(dir: dir, include: '**/*')
Rico Windde2af6c2019-03-26 15:21:08 +01002553 def testDir = file("${artTestBuildDir}/dx/${name}")
Mads Ager418d1ca2017-05-22 09:35:49 +02002554 def outputJar = testDir.toPath().resolve("${name}.jar").toFile()
2555 testDir.mkdirs()
Rico Windde2af6c2019-03-26 15:21:08 +01002556 task "$buildTask"(type: Exec) {
2557 outputs.upToDateWhen { false }
2558 inputs.file buildInputs
2559 executable "${artRunTestScript}"
2560 args "--host"
2561 args "--build-only"
2562 args "--build-with-javac-dx"
2563 args "--output-path", "${testDir}"
2564 args "${name}"
2565 environment DX: "${dxExecutable.absolutePath}"
2566 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
2567 environment ANDROID_BUILD_TOP: "${androidCheckoutDir}"
2568 outputs.file outputJar
Mads Ager418d1ca2017-05-22 09:35:49 +02002569 }
2570 task "${sanitizeTask}"(type: Exec, dependsOn: buildTask) {
2571 outputs.upToDateWhen { false }
2572 executable "/bin/bash"
2573 args "-c"
2574 args "rm -rf ${testDir}/smali_*.dex ${testDir}/*-ex.dex ${testDir}/*-ex.jar" +
2575 " ${testDir}/classes-ex ${testDir}/check"
2576 }
2577
2578 task "${smaliToDexTask}"(type: Exec) {
Mikaël Peltiere116cb62017-10-05 10:50:30 +02002579 // Directory that contains smali files is either smali, or smali/art
2580 def smali_dir = file("${dir}/smali/art")
2581 if (smali_dir.exists()) {
2582 workingDir "${testDir}/smali/art"
2583 } else {
2584 workingDir "${testDir}/smali"
2585 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002586 executable "/bin/bash"
Søren Gjesse34b77732017-07-07 13:56:21 +02002587 // This is the command line options for smali prior to 2.2.1, where smali got a new
2588 // command line interface.
2589 args "-c", "smali a *.smali"
2590 // This is the command line options for smali 2.2.1 and later.
2591 // args "-c", "smali -o out.dex *.smali"
Mads Ager418d1ca2017-05-22 09:35:49 +02002592 }
2593
2594 task "${copyCheckTask}"(type: Copy, dependsOn: sanitizeTask) {
2595 def smali_dir = file("${dir}/smali")
2596 outputs.upToDateWhen { false }
Rico Windde2af6c2019-03-26 15:21:08 +01002597 if (smali_dir.exists()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002598 dependsOn smaliToDexTask
2599 }
2600 from("${artTestDir}/${name}") {
2601 include 'check'
2602 }
2603 into testDir
2604 }
2605
2606 return copyCheckTask
2607}
2608
2609task javadocD8(type: Javadoc) {
Ian Zerny850f13d2018-01-04 11:25:38 +01002610 title "D8 API"
Mads Ager418d1ca2017-05-22 09:35:49 +02002611 classpath = sourceSets.main.compileClasspath
2612 source = sourceSets.main.allJava
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002613 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002614 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002615 include '**/com/android/tools/r8/BaseCommand.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002616 include '**/com/android/tools/r8/BaseCompilerCommand.java'
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002617 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002618 include '**/com/android/tools/r8/CompilationFailedException.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002619 include '**/com/android/tools/r8/CompilationMode.java'
2620 include '**/com/android/tools/r8/D8.java'
2621 include '**/com/android/tools/r8/D8Command.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002622 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2623 include '**/com/android/tools/r8/DexFilePerClassFileConsumer.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002624 include '**/com/android/tools/r8/Diagnostic.java'
2625 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002626 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2627 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002628 include '**/com/android/tools/r8/ProgramConsumer.java'
2629 include '**/com/android/tools/r8/ProgramResource.java'
2630 include '**/com/android/tools/r8/ProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002631 include '**/com/android/tools/r8/Resource.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002632 include '**/com/android/tools/r8/ResourceException.java'
2633 include '**/com/android/tools/r8/StringConsumer.java'
2634 include '**/com/android/tools/r8/StringResource.java'
2635 include '**/com/android/tools/r8/Version.java'
2636 include '**/com/android/tools/r8/origin/*.java'
2637}
2638
2639task javadocR8(type: Javadoc) {
2640 title "R8 API"
2641 classpath = sourceSets.main.compileClasspath
2642 source = sourceSets.main.allJava
2643 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
2644 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
2645 include '**/com/android/tools/r8/BaseCommand.java'
2646 include '**/com/android/tools/r8/BaseCompilerCommand.java'
2647 include '**/com/android/tools/r8/ClassFileConsumer.java'
2648 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
2649 include '**/com/android/tools/r8/CompilationFailedException.java'
2650 include '**/com/android/tools/r8/CompilationMode.java'
2651 include '**/com/android/tools/r8/R8.java'
2652 include '**/com/android/tools/r8/R8Command.java'
2653 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2654 include '**/com/android/tools/r8/Diagnostic.java'
2655 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002656 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2657 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002658 include '**/com/android/tools/r8/ProgramConsumer.java'
2659 include '**/com/android/tools/r8/ProgramResource.java'
2660 include '**/com/android/tools/r8/ProgramResourceProvider.java'
2661 include '**/com/android/tools/r8/Resource.java'
2662 include '**/com/android/tools/r8/ResourceException.java'
2663 include '**/com/android/tools/r8/StringConsumer.java'
2664 include '**/com/android/tools/r8/StringResource.java'
2665 include '**/com/android/tools/r8/Version.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002666 include '**/com/android/tools/r8/origin/*.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002667}
Søren Gjesse39a909a2017-10-12 09:49:20 +02002668
2669task copyMavenDeps(type: Copy) {
2670 from configurations.compile into "$buildDir/deps"
Morten Krogh-Jespersen75773302019-01-07 09:45:08 +01002671 from configurations.compileClasspath into "$buildDir/deps"
Søren Gjesse39a909a2017-10-12 09:49:20 +02002672 from configurations.testCompile into "$buildDir/deps"
2673}
Mikaël Peltier61633d42017-10-13 16:51:06 +02002674
Rico Wind23a05112019-03-27 08:00:44 +01002675task printMavenDeps {
2676 // Only actually print to stdout when we are updating.
2677 if (project.hasProperty('updatemavendeps')) {
2678 for (Configuration config : configurations) {
2679 if (!config.isCanBeResolved()) {
2680 continue
2681 }
2682 def componentIds = config.incoming.resolutionResult.allDependencies.collect {
2683 it.selected.id
2684 }
2685 def result = dependencies.createArtifactResolutionQuery()
2686 .forComponents(componentIds)
2687 .withArtifacts(MavenModule, MavenPomArtifact)
2688 .execute()
2689 for (component in result.resolvedComponents) {
2690 component.getArtifacts(MavenPomArtifact).each {
2691 println "POM: ${it.file} ${component.id}"
2692 }
2693 }
2694 config.each {
2695 println "JAR: ${it}"
2696 }
2697 }
2698 }
2699}
Ian Zerny9713c032020-01-23 11:41:58 +01002700
2701allprojects {
2702 tasks.withType(Exec) {
2703 doFirst {
Ian Zerny9794cfd2020-02-04 07:57:35 +01002704 println commandLine.join(' ')
Ian Zerny9713c032020-01-23 11:41:58 +01002705 }
2706 }
Søren Gjesse494609e2020-05-29 15:35:12 +02002707}