blob: e5467f0ed40d6a78df062bc0c31bfe952d50e137 [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-Jespersen013c30b2021-10-06 10:32:10 +020065 main11 {
66 java {
67 srcDirs = ['src/main/java']
68 }
Morten Krogh-Jespersen798aac02021-10-06 15:32:20 +020069 resources {
70 srcDirs = ['src/main/resources']
71 }
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +020072 }
Mads Ager418d1ca2017-05-22 09:35:49 +020073 test {
74 java {
75 srcDirs = [
clementbera0fe940d2019-04-23 12:45:18 +020076 'src/test/java',
77 'build/generated/test/java',
78 ]
79 }
80 }
Yohann Rousselbb571622017-11-09 10:47:36 +010081 apiUsageSample {
82 java {
Mathias Rave3f3c522018-05-30 08:22:17 +020083 srcDirs = ['src/test/apiUsageSample', 'src/main/java']
84 include 'com/android/tools/apiusagesample/*.java'
85 include 'com/android/tools/r8/BaseCompilerCommandParser.java'
86 include 'com/android/tools/r8/D8CommandParser.java'
87 include 'com/android/tools/r8/R8CommandParser.java'
88 include 'com/android/tools/r8/utils/FlagFile.java'
Yohann Rousselbb571622017-11-09 10:47:36 +010089 }
Yohann Rousselbb571622017-11-09 10:47:36 +010090 }
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +010091 cfSegments {
92 java {
93 srcDirs = ['third_party/classlib/java', 'src/cf_segments/java']
94 }
95 output.resourcesDir = 'build/classes/cfSegments'
96 }
Søren Gjesse17fc67d2019-12-04 14:50:17 +010097 libraryDesugarConversions {
98 java {
99 srcDirs = ['src/library_desugar/java']
100 }
101 output.resourcesDir = 'build/classes/library_desugar_conversions'
102 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200103 debugTestResources {
104 java {
105 srcDirs = ['src/test/debugTestResources']
106 }
107 output.resourcesDir = 'build/classes/debugTestResources'
108 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +0200109 debugTestResourcesJava8 {
110 java {
111 srcDirs = ['src/test/debugTestResourcesJava8']
112 }
113 output.resourcesDir = 'build/classes/debugTestResourcesJava8'
114 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200115 examples {
116 java {
Ivan Gavrilovic664f34d2018-11-09 10:02:40 -0800117 srcDirs = ['src/test/examples']
Mads Ager418d1ca2017-05-22 09:35:49 +0200118 }
119 output.resourcesDir = 'build/classes/examples'
120 }
Ian Zernyd3020482019-04-25 07:05:04 +0200121 examplesJava9 {
122 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200123 srcDirs = ['src/test/examplesJava9']
Ian Zernyd3020482019-04-25 07:05:04 +0200124 }
125 }
Jake Wharton2000b2f2019-12-11 20:37:49 -0500126 examplesJava10 {
127 java {
128 srcDirs = ['src/test/examplesJava10']
129 }
130 }
Ian Zernyd3020482019-04-25 07:05:04 +0200131 examplesJava11 {
132 java {
clementbera0bdd90f2019-07-06 11:15:23 +0200133 srcDirs = ['src/test/examplesJava11']
134 }
135 }
Søren Gjessee9966932021-09-15 17:08:37 +0200136 examplesJava17 {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100137 java {
Søren Gjessee9966932021-09-15 17:08:37 +0200138 srcDirs = ['src/test/examplesJava17']
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100139 }
140 }
Søren Gjessed1e08992022-02-07 16:46:31 +0100141 examplesJava18 {
142 java {
143 srcDirs = ['src/test/examplesJava18']
144 }
145 }
clementberaefa10522019-07-11 11:20:46 +0200146 examplesTestNGRunner {
clementbera4f9c2a92019-07-09 08:50:37 +0200147 java {
148 srcDirs = ['src/test/testngrunner']
149 }
150 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200151 examplesAndroidN {
152 java {
153 srcDirs = ['src/test/examplesAndroidN']
154 }
155 output.resourcesDir = 'build/classes/examplesAndroidN'
156 }
157 examplesAndroidO {
158 java {
159 srcDirs = ['src/test/examplesAndroidO']
160 }
161 output.resourcesDir = 'build/classes/examplesAndroidO'
162 }
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +0200163 examplesAndroidP {
164 java {
165 srcDirs = ['src/test/examplesAndroidP']
166 }
167 output.resourcesDir = 'build/classes/examplesAndroidP'
168 }
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200169 examplesProto {
170 java {
171 srcDirs = ['src/test/examplesProto']
172 }
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +0200173 compileClasspath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
174 compileClasspath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200175 output.resourcesDir = 'build/classes/examplesProto'
176 }
Sebastien Hertzd3313772018-01-16 14:12:37 +0100177 kotlinR8TestResources {
178 java {
179 srcDirs = ['src/test/kotlinR8TestResources']
180 }
181 output.resourcesDir = 'build/classes/kotlinR8TestResources'
182 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200183}
184
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800185// Ensure importing into IntelliJ IDEA use the same output directories as Gradle. In tests we
186// use the output path for tests (ultimately through ToolHelper.getClassPathForTests()) and
187// therefore these paths need to be the same. See https://youtrack.jetbrains.com/issue/IDEA-175172
188// for context.
189idea {
190 sourceSets.all { SourceSet sources ->
191 module {
192 if (sources.name == "main") {
193 sourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100194 outputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800195 } else {
196 testSourceDirs += sources.java.srcDirs
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100197 testOutputDir sources.output.classesDirs[0]
Ivan Gavrilovic22790f32018-11-07 17:34:38 -0800198 }
199 }
200 }
201}
202
Yohann Roussel126f6872017-08-03 16:25:32 +0200203configurations {
204 supportLibs
205}
206
Mads Ager418d1ca2017-05-22 09:35:49 +0200207dependencies {
Mads Agerd1d0da92018-12-10 13:56:50 +0100208 implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion"
209 implementation "com.google.code.gson:gson:$gsonVersion"
Mads Ager0aa48052017-09-15 12:39:15 +0200210 // Include all of guava when compiling the code, but exclude annotations that we don't
211 // need from the packaging.
Sebastien Hertz143ed112018-02-13 14:26:41 +0100212 compileOnly("com.google.guava:guava:$guavaVersion")
Mads Agerd1d0da92018-12-10 13:56:50 +0100213 implementation("com.google.guava:guava:$guavaVersion", {
Mads Ager0aa48052017-09-15 12:39:15 +0200214 exclude group: 'com.google.errorprone'
215 exclude group: 'com.google.code.findbugs'
216 exclude group: 'com.google.j2objc'
217 exclude group: 'org.codehaus.mojo'
218 })
Mads Agerd1d0da92018-12-10 13:56:50 +0100219 implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
220 implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
221 implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
222 implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
223 implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
224 implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
225 implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200226
227 main11Implementation "net.sf.jopt-simple:jopt-simple:$joptSimpleVersion"
228 main11Implementation "com.google.code.gson:gson:$gsonVersion"
229 // Include all of guava when compiling the code, but exclude annotations that we don't
230 // need from the packaging.
231 main11CompileOnly("com.google.guava:guava:$guavaVersion")
232 main11Implementation("com.google.guava:guava:$guavaVersion", {
233 exclude group: 'com.google.errorprone'
234 exclude group: 'com.google.code.findbugs'
235 exclude group: 'com.google.j2objc'
236 exclude group: 'org.codehaus.mojo'
237 })
238 main11Implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
239 main11Implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
240 main11Implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
241 main11Implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
242 main11Implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
243 main11Implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
244 main11Implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200245
clementberaefa10522019-07-11 11:20:46 +0200246 examplesTestNGRunnerCompile group: 'org.testng', name: 'testng', version: testngVersion
Ian Zerny161ff742022-01-20 12:39:40 +0100247
Mads Ager418d1ca2017-05-22 09:35:49 +0200248 testCompile sourceSets.examples.output
Sebastien Hertz143ed112018-02-13 14:26:41 +0100249 testCompile "junit:junit:$junitVersion"
Ian Zerny161ff742022-01-20 12:39:40 +0100250 testCompile "com.google.guava:guava:$guavaVersion"
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100251 testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
252 testCompile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100253 testCompile group: 'org.smali', name: 'smali', version: smaliVersion
Mads Ager418d1ca2017-05-22 09:35:49 +0200254 testCompile files('third_party/jasmin/jasmin-2.4.jar')
255 testCompile files('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
Jean-Marie Henaffce162f32017-10-04 10:39:27 +0200256 testCompile files('third_party/ddmlib/ddmlib.jar')
Ian Zerny161ff742022-01-20 12:39:40 +0100257 testCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
258 testCompile group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
259 testCompile group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
260 testCompile group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
261 testCompile group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
262 testCompile group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
263
Sebastien Hertz143ed112018-02-13 14:26:41 +0100264 examplesAndroidOCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
265 examplesAndroidPCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
Stephan Herhut52cb1022017-10-24 15:10:41 +0200266 // Import Guava for @Nullable annotation
Sebastien Hertz143ed112018-02-13 14:26:41 +0100267 examplesCompile "com.google.guava:guava:$guavaVersion"
Jinseong Jeone11145f2018-12-13 10:57:29 -0800268 examplesCompile "junit:junit:$junitVersion"
269 examplesCompile "org.mockito:mockito-core:$mockitoVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100270 supportLibs "com.android.support:support-v4:$androidSupportVersion"
271 supportLibs "junit:junit:$junitVersion"
272 supportLibs "com.android.support.test.espresso:espresso-core:$espressoVersion"
Yohann Rousselbb571622017-11-09 10:47:36 +0100273 apiUsageSampleCompile sourceSets.main.output
Tamas Kenezb865eee2018-12-03 16:50:45 +0100274 apiUsageSampleCompile "com.google.guava:guava:$guavaVersion"
Sebastien Hertz143ed112018-02-13 14:26:41 +0100275 kotlinR8TestResourcesCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100276 errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")
Stephan Herhut417a72a2017-07-18 10:38:30 +0200277}
278
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100279def r8LibPath = "$buildDir/libs/r8lib.jar"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +0100280def r8LibExludeDepsPath = "$buildDir/libs/r8lib-exclude-deps.jar"
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200281def r8DesugaredPath = "$buildDir/libs/r8desugared.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100282def r8LibGeneratedKeepRulesPath = "$buildDir/generated/keep.txt"
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +0100283def r8LibTestPath = "$buildDir/classes/r8libtest"
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +0200284def java11ClassFiles = "$buildDir/classes/java/mainJava11"
285def r8RetracePath = "$buildDir/libs/r8retrace.jar"
286def r8RetraceExludeDepsPath = "$buildDir/libs/r8retrace-exclude-deps.jar"
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100287
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200288def osString = OperatingSystem.current().isLinux() ? "linux" :
289 OperatingSystem.current().isMacOsX() ? "mac" : "windows"
Mads Ager418d1ca2017-05-22 09:35:49 +0200290
291def cloudDependencies = [
292 "tests" : [
mikaelpeltierc2aa6652017-10-06 12:53:37 +0200293 "2017-10-04/art",
Rico Wind132bfb42019-03-08 09:27:36 +0100294 "2016-12-19/art"
Mads Ager418d1ca2017-05-22 09:35:49 +0200295 ],
296 "third_party": [
Rico Windf72fa152018-10-22 15:41:03 +0200297 "android_cts_baseline",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200298 "android_jar/lib-v14",
Stephan Herhutb3aca8b2017-12-22 14:14:53 +0100299 "android_jar/lib-v15",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200300 "android_jar/lib-v19",
301 "android_jar/lib-v21",
Stephan Herhutd48be0d2018-01-04 15:33:10 +0100302 "android_jar/lib-v22",
303 "android_jar/lib-v23",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200304 "android_jar/lib-v24",
305 "android_jar/lib-v25",
306 "android_jar/lib-v26",
Søren Gjessec2ffae82018-12-21 12:20:18 +0100307 "android_jar/lib-v27",
308 "android_jar/lib-v28",
Søren Gjesse02f52852019-09-04 17:44:03 +0200309 "android_jar/lib-v29",
Søren Gjessefa3f8042020-04-20 12:56:11 +0200310 "android_jar/lib-v30",
Søren Gjesse8c15ecd2021-03-22 16:41:53 +0100311 "android_jar/lib-v31",
Søren Gjesse29c8c5b2021-11-01 10:30:57 +0100312 "android_jar/lib-v32",
Søren Gjessea1f2c512022-02-04 09:51:45 +0100313 "android_jar/lib-v33",
Morten Krogh-Jespersen7a47b732021-05-11 17:32:34 +0200314 "api-outlining/simple-app-dump",
Ian Zerny0d806882021-09-30 15:17:40 +0200315 "binary_compatibility_tests/compiler_api_tests",
Rico Windf72fa152018-10-22 15:41:03 +0200316 "core-lambda-stubs",
Søren Gjesse7dee79d2022-03-17 13:50:48 +0100317 "dagger/2.41",
Rico Windf72fa152018-10-22 15:41:03 +0200318 "dart-sdk",
319 "ddmlib",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200320 "gradle/gradle",
Christoffer Quist Adamsene1821392022-02-15 14:58:03 +0100321 "google/google-java-format/1.14.0",
Ian Zerny33c1c582019-09-17 12:43:45 +0200322 "google-java-format",
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +0200323 "iosched_2019",
Søren Gjesse97679312020-10-06 13:44:59 +0200324 "jacoco/0.8.2",
325 "jacoco/0.8.6",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200326 "jasmin",
Morten Krogh-Jespersen4187e162019-03-25 13:19:17 +0100327 "junit",
Rico Windf72fa152018-10-22 15:41:03 +0200328 "jdwp-tests",
Søren Gjesse70f75b12019-08-22 12:32:02 +0200329 "jsr223-api-1.0",
Søren Gjesse8f0e0992019-09-06 09:28:14 +0200330 "rhino-1.7.10",
Søren Gjessef6c0a782019-08-22 12:48:46 +0200331 "rhino-android-1.1.1",
Morten Krogh-Jespersenb328dc62020-05-12 09:11:52 +0200332 "kotlin/kotlin-compiler-1.3.11",
333 "kotlin/kotlin-compiler-1.3.41",
Morten Krogh-Jespersend32c8f22020-05-12 10:56:16 +0200334 "kotlin/kotlin-compiler-1.3.72",
Morten Krogh-Jespersen1c801b02021-02-11 10:15:23 +0100335 "kotlin/kotlin-compiler-1.4.20",
Morten Krogh-Jespersena9705f52021-07-05 11:28:02 +0200336 "kotlin/kotlin-compiler-1.5.0",
Morten Krogh-Jespersen61683192021-11-25 11:14:47 +0100337 "kotlin/kotlin-compiler-1.6.0",
Morten Krogh-Jespersen14153472020-05-19 15:40:47 +0200338 "kotlinx-coroutines-1.3.6",
Mathias Rav5285faf2018-03-20 14:16:32 +0100339 "openjdk/openjdk-rt-1.8",
Søren Gjesse952e1d52019-05-28 12:51:30 +0200340 "openjdk/desugar_jdk_libs",
Clément Béracac269b2021-03-17 07:53:43 +0000341 "openjdk/desugar_jdk_libs_11",
Ian Zernyc4598882022-02-25 19:26:44 +0100342 "openjdk/desugar_jdk_libs_legacy",
Søren Gjesse09c3dd02021-06-17 08:21:51 +0200343 "openjdk/desugar_jdk_libs_releases/1.0.9",
344 "openjdk/desugar_jdk_libs_releases/1.0.10",
345 "openjdk/desugar_jdk_libs_releases/1.1.0",
346 "openjdk/desugar_jdk_libs_releases/1.1.1",
347 "openjdk/desugar_jdk_libs_releases/1.1.5",
clementbera8dbfeda2019-07-03 11:24:13 +0200348 "openjdk/jdk-11-test",
Ian Zernye5886582022-03-03 11:01:08 +0100349 "opensource-apps/tivi",
Rico Windf72fa152018-10-22 15:41:03 +0200350 "proguard/proguard5.2.1",
351 "proguard/proguard6.0.1",
Ian Zerny7c920ac2020-07-01 20:12:01 +0200352 "proguard/proguard-7.0.0",
Morten Krogh-Jespersen0cade312022-03-22 13:40:21 +0000353 "retrace_benchmark",
Morten Krogh-Jespersen7cbae972021-08-31 16:54:31 +0200354 "retrace/binary_compatibility",
Ian Zernyfad3a3c2022-03-30 19:55:42 +0200355 "r8",
Ian Zernye0fd0242020-06-23 13:46:14 +0200356 "r8-releases/2.0.74",
Ian Zerny20d576f2022-03-28 19:16:38 +0200357 "r8-releases/3.2.54",
Morten Krogh-Jespersen1ba55f52020-04-24 12:49:17 +0200358 "r8mappings",
359 "tachiyomi"
Mads Ager418d1ca2017-05-22 09:35:49 +0200360 ],
361 // All dex-vms have a fixed OS of Linux, as they are only supported on Linux, and will be run in a Docker
362 // container on other platforms where supported.
363 "tools" : [
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200364 "linux/art",
365 "linux/art-5.1.1",
366 "linux/art-6.0.1",
367 "linux/art-7.0.0",
Søren Gjesse1528c022018-11-23 15:14:05 +0100368 "linux/art-8.1.0",
Søren Gjessefe7c0112018-12-03 12:33:12 +0100369 "linux/art-9.0.0",
clementbera97d5cce2019-11-22 15:09:27 +0100370 "linux/art-10.0.0",
Søren Gjesse953f7c42021-08-18 16:42:06 +0200371 "linux/host/art-12.0.0-beta4",
Søren Gjesse12a45f62022-02-04 12:05:27 +0100372 "linux/host/art-13-master",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200373 "linux/dalvik",
Stephan Herhut02f0f9d2018-01-04 10:27:31 +0100374 "linux/dalvik-4.0.4",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200375 "${osString}/dx",
Mads Ager418d1ca2017-05-22 09:35:49 +0200376 ]
377]
378
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100379def cloudSystemDependencies = [
380 linux: [
clementbera81738ec2019-04-11 11:32:31 +0200381 "third_party": ["openjdk/openjdk-9.0.4/linux",
clementberab4fa18d2019-04-12 09:09:40 +0200382 "openjdk/jdk8/linux-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100383 "openjdk/jdk-11/linux",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100384 "openjdk/jdk-17/linux",
385 "openjdk/jdk-18/linux"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100386 ],
387 osx: [
clementbera81738ec2019-04-11 11:32:31 +0200388 "third_party": ["openjdk/openjdk-9.0.4/osx",
clementberab4fa18d2019-04-12 09:09:40 +0200389 "openjdk/jdk8/darwin-x86",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100390 "openjdk/jdk-11/osx",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100391 "openjdk/jdk-17/osx",
392 "openjdk/jdk-18/osx"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100393 ],
394 windows: [
clementberab4fa18d2019-04-12 09:09:40 +0200395 "third_party": ["openjdk/openjdk-9.0.4/windows",
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100396 "openjdk/jdk-11/windows",
Søren Gjesse0b11ff82022-02-07 12:57:07 +0100397 "openjdk/jdk-17/windows",
398 "openjdk/jdk-18/windows"],
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100399 ],
400]
401
402if (OperatingSystem.current().isWindows()) {
403 cloudSystemDependencies.windows.each { entry ->
404 cloudDependencies.get(entry.key).addAll(entry.value)
405 }
406} else if (OperatingSystem.current().isLinux()) {
407 cloudSystemDependencies.linux.each { entry ->
408 cloudDependencies.get(entry.key).addAll(entry.value)
409 }
410} else if (OperatingSystem.current().isMacOsX()) {
411 cloudSystemDependencies.osx.each { entry ->
412 cloudDependencies.get(entry.key).addAll(entry.value)
413 }
414} else {
415 println "WARNING: Unsupported system: " + OperatingSystem.current()
416}
417
418def getDownloadDepsTaskName(entryKey, entryFile) {
419 return "download_deps_${entryKey}_${entryFile.replace('/', '_').replace('\\', '_')}"
420}
421
Mads Ager418d1ca2017-05-22 09:35:49 +0200422cloudDependencies.each { entry ->
423 entry.value.each { entryFile ->
Ian Zernyb2d27c42019-02-20 09:09:41 +0100424 task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) {
425 type DownloadDependency.Type.GOOGLE_STORAGE
426 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200427 }
428 }
429}
430
431def x20Dependencies = [
432 "third_party": [
Rico Windc346c4a2018-10-23 08:04:16 +0200433 "benchmarks/kotlin-benches",
Jinseong Jeonb0c2dc02019-07-18 11:41:11 -0700434 "chrome/chrome_180917_ffbaa8",
Christoffer Quist Adamsence640052020-04-30 11:47:41 +0200435 "chrome/chrome_200430",
Christoffer Quist Adamsen287c1862020-05-20 15:51:12 +0200436 "chrome/monochrome_public_minimal_apks/chrome_200520",
Clément Béra5da4e352021-01-27 18:16:27 +0000437 "chrome/clank_google3_prebuilt",
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +0100438 "classlib",
Morten Krogh-Jespersen480784d2019-02-05 08:10:46 +0100439 "cf_segments",
Rico Windf72fa152018-10-22 15:41:03 +0200440 "desugar/desugar_20180308",
Ian Zernybd2fdcc2019-03-22 13:57:21 +0100441 "internal/issue-127524985",
Rico Windf72fa152018-10-22 15:41:03 +0200442 "framework",
Sebastien Hertzf83b5902017-10-02 11:55:41 +0200443 "gmail/gmail_android_170604.16",
Søren Gjesseb552e842018-09-28 12:17:29 +0200444 "gmail/gmail_android_180826.15",
Rico Windf72fa152018-10-22 15:41:03 +0200445 "gmscore/gmscore_v10",
Rico Windf72fa152018-10-22 15:41:03 +0200446 "gmscore/latest",
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +0200447 "nest/nest_20180926_7c6cfb",
Rico Windf72fa152018-10-22 15:41:03 +0200448 "proguard/proguard_internal_159423826",
449 "proguardsettings",
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +0200450 "proto",
451 "protobuf-lite",
Morten Krogh-Jespersend87c0662020-06-22 10:45:43 +0200452 "retrace_internal",
Christoffer Quist Adamsene44d6532021-04-14 16:07:06 +0200453 "youtube/youtube.android_15.33",
Christoffer Quist Adamsene18f9202021-05-31 13:14:20 +0200454 "youtube/youtube.android_16.20"
Mads Ager418d1ca2017-05-22 09:35:49 +0200455 ],
456]
457
458x20Dependencies.each { entry ->
459 entry.value.each { entryFile ->
Ian Zernyb2d27c42019-02-20 09:09:41 +0100460 task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) {
461 type DownloadDependency.Type.X20
462 dependency "${entry.key}/${entryFile}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200463 }
464 }
465}
466
Rico Wind897bb712017-05-23 10:44:29 +0200467task downloadProguard {
468 cloudDependencies.each { entry ->
469 entry.value.each { entryFile ->
470 if (entryFile.contains("proguard")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100471 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Wind897bb712017-05-23 10:44:29 +0200472 }
473 }
474 }
475}
476
Rico Windf6c74ce2018-12-04 08:50:55 +0100477task downloadOpenJDKrt {
478 cloudDependencies.each { entry ->
479 entry.value.each { entryFile ->
480 if (entryFile.contains("openjdk-rt")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100481 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Rico Windf6c74ce2018-12-04 08:50:55 +0100482 }
483 }
484 }
485}
486
Tamas Kenez427205b2017-06-29 15:57:09 +0200487task downloadDx {
488 cloudDependencies.each { entry ->
489 entry.value.each { entryFile ->
Tamas Kenezcea7c202017-10-13 10:53:32 +0200490 if (entryFile.endsWith("/dx")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100491 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez427205b2017-06-29 15:57:09 +0200492 }
493 }
494 }
495}
496
Tamas Kenez0e10c562017-06-08 10:00:34 +0200497task downloadAndroidCts {
498 cloudDependencies.each { entry ->
499 entry.value.each { entryFile ->
500 if (entryFile.contains("android_cts_baseline")) {
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100501 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Tamas Kenez0e10c562017-06-08 10:00:34 +0200502 }
503 }
504 }
505}
506
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200507task downloadCloudDeps() {
Mads Ager418d1ca2017-05-22 09:35:49 +0200508 cloudDependencies.each { entry ->
509 entry.value.each { entryFile ->
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100510 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200511 }
512 }
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200513}
514
515task downloadX20Deps() {
516 x20Dependencies.each { entry ->
517 entry.value.each { entryFile ->
518 dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
Mads Ager418d1ca2017-05-22 09:35:49 +0200519 }
520 }
521}
522
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200523task downloadDeps {
524 dependsOn downloadCloudDeps
525 if (!project.hasProperty('no_internal')) {
526 dependsOn downloadX20Deps
527 }
528}
529
Mads Ager418d1ca2017-05-22 09:35:49 +0200530allprojects {
531 sourceCompatibility = JavaVersion.VERSION_1_8
532 targetCompatibility = JavaVersion.VERSION_1_8
533}
534
Rico Wind266336c2019-02-25 10:11:38 +0100535// TODO(ricow): Remove debug prints
536println("NOTE: Current operating system: " + OperatingSystem.current())
537println("NOTE: Current operating system isWindows: " + OperatingSystem.current().isWindows())
538
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100539// Check if running with the JDK location from tools/jdk.py.
540if (OperatingSystem.current().isWindows()) {
541 println "NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome
Morten Krogh-Jespersend9a88452020-01-31 14:13:54 +0100542 compileJava.options.encoding = "UTF-8"
543 compileTestJava.options.encoding = "UTF-8"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100544} else {
545 def javaHomeOut = new StringBuilder()
546 def javaHomeErr = new StringBuilder()
Jake Wharton7c14ce72019-09-17 13:49:18 -0400547 def javaHomeProc = './tools/jdk.py'.execute([], projectDir)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100548 javaHomeProc.waitForProcessOutput(javaHomeOut, javaHomeErr)
549 def jdkHome = new File(javaHomeOut.toString().trim())
550 if (!jdkHome.exists()) {
551 println "WARNING: Failed to find the ./tools/jdk.py specified JDK: " + jdkHome
552 } else if (jdkHome != org.gradle.internal.jvm.Jvm.current().javaHome) {
553 println("WARNING: Gradle is running in a non-pinned Java"
554 + ". Gradle Java Home: " + org.gradle.internal.jvm.Jvm.current().javaHome
Christoffer Quist Adamsen79b126a2020-03-27 17:23:08 +0000555 + ". Expected: " + jdkHome)
Rico Wind266336c2019-02-25 10:11:38 +0100556 } else {
557 println("NOTE: Running with jdk from tools/jdk.py: " + jdkHome)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100558 }
Mads Agerc7d14d32018-09-27 11:09:46 +0200559}
560
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200561compileJava.dependsOn downloadCloudDeps
Morten Krogh-Jespersenc1bc4a02021-06-18 08:13:02 +0200562
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100563sourceSets.configureEach { sourceSet ->
564 tasks.named(sourceSet.compileJavaTaskName).configure {
565 // Default disable errorprone (enabled and setup below).
566 options.errorprone.enabled = false
567 options.compilerArgs << '-Xlint:unchecked'
Ian Zerny09135aa2019-02-12 16:03:34 +0100568 // Run all compilation tasks in a forked subprocess.
569 options.fork = true
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100570 // Javac often runs out of stack space when compiling the tests.
571 // Increase the stack size for the javac process.
Søren Gjesse1af374d2019-09-06 10:44:54 +0200572 options.forkOptions.jvmArgs << "-Xss256m"
Ian Zerny26307fb2019-03-06 15:18:17 +0100573 // Test compilation is sometimes hitting the default limit at 1g, increase it.
Ian Zerny293b8152019-09-20 10:40:53 +0200574 options.forkOptions.jvmArgs << "-Xmx3g"
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100575 // Set the bootclass path so compilation is consistent with 1.8 target compatibility.
576 options.forkOptions.jvmArgs << "-Xbootclasspath/a:third_party/openjdk/openjdk-rt-1.8/rt.jar"
577 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200578}
579
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100580def setJdkCompilationWithCompatibility(String sourceSet, String javaHome, JavaVersion compatibility, boolean enablePreview) {
581 tasks.named(sourceSet).get().configure {
582 def jdkDir = "third_party/openjdk/${javaHome}/"
583 options.fork = true
584 options.forkOptions.jvmArgs = []
585 if (enablePreview) {
586 options.compilerArgs.add('--enable-preview')
587 }
588 if (OperatingSystem.current().isLinux()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200589 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/linux")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100590 options.forkOptions.javaHome = file(jdkDir + 'linux')
591 } else if (OperatingSystem.current().isMacOsX()) {
Søren Gjesse96b37252021-08-09 16:08:05 +0200592 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/osx")
Jake Whartonbd3196b2021-03-16 15:48:08 -0400593 options.forkOptions.javaHome = compatibility > JavaVersion.VERSION_1_9
594 ? file(jdkDir + 'osx/Contents/Home')
595 : file(jdkDir + 'osx')
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100596 } else {
Søren Gjesse96b37252021-08-09 16:08:05 +0200597 dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/windows")
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100598 options.forkOptions.javaHome = file(jdkDir + 'windows')
599 }
600 sourceCompatibility = compatibility
601 targetCompatibility = compatibility
Ian Zernyd3020482019-04-25 07:05:04 +0200602 }
Ian Zernyd3020482019-04-25 07:05:04 +0200603}
604
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100605setJdkCompilationWithCompatibility(
606 sourceSets.examplesJava9.compileJavaTaskName,
607 'openjdk-9.0.4',
608 JavaVersion.VERSION_1_9,
609 false)
610setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100611 sourceSets.examplesJava10.compileJavaTaskName,
612 'jdk-11',
613 JavaVersion.VERSION_1_10,
614 false)
615setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200616 sourceSets.main11.compileJavaTaskName,
617 'jdk-11',
618 JavaVersion.VERSION_11,
619 false)
620setJdkCompilationWithCompatibility(
Morten Krogh-Jespersen43a4ef32020-11-25 16:59:33 +0100621 sourceSets.examplesJava11.compileJavaTaskName,
622 'jdk-11',
623 JavaVersion.VERSION_11,
624 false)
625setJdkCompilationWithCompatibility(
626 sourceSets.examplesTestNGRunner.compileJavaTaskName,
627 'jdk-11',
628 JavaVersion.VERSION_11,
629 false)
630setJdkCompilationWithCompatibility(
Søren Gjessee9966932021-09-15 17:08:37 +0200631 sourceSets.examplesJava17.compileJavaTaskName,
632 'jdk-17',
633 JavaVersion.VERSION_17,
634 false)
Søren Gjessed1e08992022-02-07 16:46:31 +0100635setJdkCompilationWithCompatibility(
636 sourceSets.examplesJava18.compileJavaTaskName,
637 'jdk-18',
638 // TODO(b/218293990): Update Gradle to get JavaVersion.VERSION_18.
639 JavaVersion.VERSION_17,
640 false)
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100641
Clément Bérac94b6202021-09-28 11:16:58 +0000642task provideJdk11TestsDependencies(type: org.gradle.api.tasks.Copy) {
643 from sourceSets.examplesTestNGRunner.compileClasspath
644 include "**/**.jar"
645 into file("$buildDir/test/jdk11Tests")
646}
647
648task compileTestNGRunner (type: JavaCompile) {
649 dependsOn provideJdk11TestsDependencies
Clément Béra98d5b602021-09-29 06:27:21 +0000650 destinationDir = file("$buildDir/classes/java/examplesTestNGRunner")
Clément Bérac94b6202021-09-28 11:16:58 +0000651 source = sourceSets.examplesTestNGRunner.allSource
652 classpath = sourceSets.examplesTestNGRunner.compileClasspath
653}
654
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100655if (!project.hasProperty('without_error_prone') &&
656 // Don't enable error prone on Java 8 as the plugin setup does not support it.
657 !org.gradle.internal.jvm.Jvm.current().javaVersion.java8) {
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200658 compileJava {
659 // Enable error prone for D8/R8 sources.
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100660 options.errorprone.enabled = true
661 options.errorprone.disableAllChecks = true
662 options.errorprone.check('ClassCanBeStatic', CheckSeverity.ERROR)
Christoffer Quist Adamsen7bed1092020-05-04 11:08:00 +0200663 options.errorprone.check('CollectionIncompatibleType', CheckSeverity.ERROR)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100664 options.errorprone.check('OperatorPrecedence', CheckSeverity.ERROR)
665 options.errorprone.check('RemoveUnusedImports', CheckSeverity.ERROR)
666 options.errorprone.check('MissingOverride', CheckSeverity.ERROR)
667 options.errorprone.check('IntLongMath', CheckSeverity.ERROR)
668 options.errorprone.check('EqualsHashCode', CheckSeverity.ERROR)
669 options.errorprone.check('InconsistentOverloads', CheckSeverity.ERROR)
670 options.errorprone.check('ArrayHashCode', CheckSeverity.ERROR)
671 options.errorprone.check('EqualsIncompatibleType', CheckSeverity.ERROR)
672 options.errorprone.check('NonOverridingEquals', CheckSeverity.ERROR)
673 options.errorprone.check('FallThrough', CheckSeverity.ERROR)
674 options.errorprone.check('MissingCasesInEnumSwitch', CheckSeverity.ERROR)
675 options.errorprone.check('MissingDefault', CheckSeverity.ERROR)
676 options.errorprone.check('MultipleTopLevelClasses', CheckSeverity.ERROR)
677 options.errorprone.check('NarrowingCompoundAssignment', CheckSeverity.ERROR)
678 options.errorprone.check('BoxedPrimitiveConstructor', CheckSeverity.ERROR)
679 options.errorprone.check('LogicalAssignment', CheckSeverity.ERROR)
680 options.errorprone.check('FloatCast', CheckSeverity.ERROR)
681 options.errorprone.check('ReturnValueIgnored', CheckSeverity.ERROR)
Mikaël Peltierc9c1e8f2017-10-17 15:45:42 +0200682 }
683}
684
Yohann Roussel7f47c032017-09-14 12:19:06 +0200685task consolidatedLicense {
Yohann Roussel7f47c032017-09-14 12:19:06 +0200686 def license = new File(new File(buildDir, 'generatedLicense'), 'LICENSE')
Mads Agerd1d0da92018-12-10 13:56:50 +0100687
Yohann Roussel7f47c032017-09-14 12:19:06 +0200688 inputs.files files('LICENSE', 'LIBRARY-LICENSE') + fileTree(dir: 'library-licensing')
Mads Agerd1d0da92018-12-10 13:56:50 +0100689 def runtimeClasspath = configurations.findByName("runtimeClasspath")
690 inputs.files { runtimeClasspath.getResolvedConfiguration().files }
691
Yohann Roussel7f47c032017-09-14 12:19:06 +0200692 outputs.files license
Mads Agerd1d0da92018-12-10 13:56:50 +0100693
Yohann Roussel7f47c032017-09-14 12:19:06 +0200694 doLast {
Mads Agerd1d0da92018-12-10 13:56:50 +0100695 def dependencies = []
696 runtimeClasspath.resolvedConfiguration.resolvedArtifacts.each {
697 def identifier = (ModuleComponentIdentifier) it.id.componentIdentifier
698 dependencies.add("${identifier.group}:${identifier.module}")
699 }
700 def libraryLicenses = file('LIBRARY-LICENSE').text
701 dependencies.each {
702 if (!libraryLicenses.contains("- artifact: $it")) {
703 throw new GradleException("No license for $it in LIBRARY_LICENSE")
704 }
705 }
706
Yohann Roussel7f47c032017-09-14 12:19:06 +0200707 license.getParentFile().mkdirs()
708 license.createNewFile()
709 license.text = "This file lists all licenses for code distributed.\n"
710 license.text += "All non-library code has the following 3-Clause BSD license.\n"
711 license.text += "\n"
712 license.text += "\n"
713 license.text += file('LICENSE').text
714 license.text += "\n"
715 license.text += "\n"
716 license.text += "Summary of distributed libraries:\n"
717 license.text += "\n"
Mads Agerd1d0da92018-12-10 13:56:50 +0100718 license.text += libraryLicenses
Yohann Roussel7f47c032017-09-14 12:19:06 +0200719 license.text += "\n"
720 license.text += "\n"
721 license.text += "Licenses details:\n"
722 fileTree(dir: 'library-licensing').getFiles().stream().sorted().forEach { file ->
723 license.text += "\n"
724 license.text += "\n"
725 license.text += file.text
726 }
727 }
728}
729
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100730def repackageDepFile(file) {
731 if (file.getName().endsWith('.jar')) {
732 return zipTree(file).matching {
733 exclude '**/module-info.class'
734 exclude 'META-INF/maven/**'
735 exclude 'META-INF/LICENSE.txt'
736 exclude 'META-INF/MANIFEST.MF'
737 }
738 } else {
739 return fileTree(file)
Jinseong Jeon40ceab02018-07-09 14:25:31 -0700740 }
Morten Krogh-Jespersen00699af2018-10-09 10:54:42 +0200741}
742
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100743task repackageDeps(type: Jar) {
Morten Krogh-Jespersenb9620512021-06-18 11:01:05 +0200744 dependsOn downloadCloudDeps
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100745 dependsOn project.configurations.runtimeClasspath
746 project.configurations.runtimeClasspath.forEach {
747 from repackageDepFile(it)
748 }
749 archiveFileName = 'deps_all.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000750}
751
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100752task repackageTestDeps(type: Jar) {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200753 dependsOn downloadCloudDeps
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100754 dependsOn project.configurations.testCompile
755 project.configurations.testCompile.forEach {
756 from repackageDepFile(it)
757 }
758 archiveFileName = 'test_deps_all.jar'
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200759}
760
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100761task repackageSources(type: Jar) {
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100762 // If this fails then remove all generated folders from
763 // build/classes/java/test that is not {com,dalvik}
Mads Ager418d1ca2017-05-22 09:35:49 +0200764 from sourceSets.main.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100765 archiveFileName = 'sources_main.jar'
Ivan Gavrilovic4876d2a2017-11-30 18:57:48 +0000766}
767
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100768task repackageSources11(type: Jar) {
Morten Krogh-Jespersen013c30b2021-10-06 10:32:10 +0200769 from sourceSets.main11.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100770 archiveFileName = 'sources_main_11.jar'
clementbera0bca05e2019-05-29 14:11:18 +0200771}
772
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100773def r8CreateTask(name, baseName, sources, includeSwissArmyKnife) {
774 return tasks.create("r8Create${name}", Jar) {
775 dependsOn sources
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200776 from consolidatedLicense.outputs.files
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100777 from sources.collect { zipTree(it) }
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +0100778 exclude "$buildDir/classes/**"
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100779 archiveFileName = baseName
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200780 if (includeSwissArmyKnife) {
781 manifest {
782 attributes 'Main-Class': 'com.android.tools.r8.SwissArmyKnife'
783 }
784 }
785 exclude "META-INF/*.kotlin_module"
786 exclude "**/*.kotlin_metadata"
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200787 }
Morten Krogh-Jespersene47021f2018-10-10 11:08:23 +0200788}
789
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200790def r8RelocateTask(r8Task, output) {
791 return tasks.create("r8Relocate_${r8Task.name}", Exec) {
792 dependsOn r8WithDeps
793 dependsOn r8Task
794 outputs.file output
795 workingDir = projectDir
796 inputs.files r8Task.outputs.files + r8WithDeps.outputs.files
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200797 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200798 "relocator",
799 "--input",
800 r8Task.outputs.files[0],
801 "--output",
802 output,
803 "--map",
804 "com.google.common->com.android.tools.r8.com.google.common",
805 "--map",
806 "com.google.gson->com.android.tools.r8.com.google.gson",
807 "--map",
808 "com.google.thirdparty->com.android.tools.r8.com.google.thirdparty",
809 "--map",
810 "joptsimple->com.android.tools.r8.joptsimple",
811 "--map",
812 "org.objectweb.asm->com.android.tools.r8.org.objectweb.asm",
813 "--map",
814 "it.unimi.dsi.fastutil->com.android.tools.r8.it.unimi.dsi.fastutil",
815 "--map",
816 "kotlin->com.android.tools.r8.jetbrains.kotlin",
817 "--map",
818 "kotlinx->com.android.tools.r8.jetbrains.kotlinx",
819 "--map",
820 "org.jetbrains->com.android.tools.r8.org.jetbrains",
821 "--map",
Søren Gjessebeb5d872021-09-07 12:49:24 +0200822 "org.intellij->com.android.tools.r8.org.intellij",
823 "--map",
824 "org.checkerframework->com.android.tools.r8.org.checkerframework"
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200825 ])
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200826 }
827}
828
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200829task r8WithDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200830 dependsOn repackageSources
831 dependsOn repackageDeps
832 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200833 def r8Task = r8CreateTask(
834 'WithDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100835 'r8_with_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200836 repackageSources.outputs.files + repackageDeps.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200837 true)
838 dependsOn r8Task
839 outputs.files r8Task.outputs.files
clementbera0bca05e2019-05-29 14:11:18 +0200840}
841
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200842task r8WithDeps11 {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200843 dependsOn repackageSources11
844 dependsOn repackageDeps
845 inputs.files ([repackageSources11.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200846 def r8Task = r8CreateTask(
847 'WithDeps11',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100848 'r8_with_deps_11.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200849 repackageSources11.outputs.files + repackageDeps.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200850 true)
851 dependsOn r8Task
852 outputs.files r8Task.outputs.files
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100853}
854
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200855task r8WithRelocatedDeps {
856 def output = "${buildDir}/libs/r8_with_relocated_deps.jar"
857 dependsOn r8RelocateTask(r8WithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200858 inputs.files r8WithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200859 outputs.file output
Morten Krogh-Jespersen8c812bd2020-04-29 15:50:24 +0200860}
861
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200862task r8WithRelocatedDeps11 {
863 def output = "${buildDir}/libs/r8_with_relocated_deps_11.jar"
864 dependsOn r8RelocateTask(r8WithDeps11, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200865 inputs.files r8WithDeps11.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200866 outputs.file output
867}
868
869task r8WithoutDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200870 dependsOn repackageSources
871 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200872 def r8Task = r8CreateTask(
873 'WithoutDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100874 'r8_without_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200875 repackageSources.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200876 true)
877 dependsOn r8Task
878 outputs.files r8Task.outputs.files
879}
880
881task r8(type: Copy) {
882 def r8Task = project.hasProperty("exclude_deps")
883 ? r8WithoutDeps : r8WithRelocatedDeps
884 dependsOn r8Task
885 from r8Task.outputs.files[0]
886 into file("${buildDir}/libs")
887 rename { String fileName -> "r8.jar" }
888 outputs.file "${buildDir}/libs/r8.jar"
889}
890
891task r8NoManifestWithoutDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200892 dependsOn repackageSources
893 inputs.files repackageSources.outputs
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200894 def r8Task = r8CreateTask(
895 'NoManifestWithoutDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100896 'r8_no_manifest_without_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200897 repackageSources.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200898 false)
899 dependsOn r8Task
900 outputs.files r8Task.outputs.files
901}
902
903task r8NoManifestWithDeps {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200904 dependsOn repackageSources
905 inputs.files ([repackageSources.outputs, repackageDeps.outputs])
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200906 def r8Task = r8CreateTask(
907 'NoManifestWithDeps',
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100908 'r8_no_manifest_with_deps.jar',
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +0200909 repackageSources.outputs.files + repackageDeps.outputs.files,
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200910 false)
911 dependsOn r8Task
912 outputs.files r8Task.outputs.files
913}
914
915task r8NoManifestWithRelocatedDeps {
916 def output = "${buildDir}/libs/r8_no_manifest_with_relocated_deps.jar"
917 dependsOn r8RelocateTask(r8NoManifestWithDeps, output)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +0200918 inputs.files r8NoManifestWithDeps.outputs.files
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200919 outputs.file output
920}
921
922task r8NoManifest(type: Copy) {
923 def r8Task = project.hasProperty("exclude_deps")
924 ? r8NoManifestWithoutDeps : r8NoManifestWithRelocatedDeps
925 dependsOn r8Task
926 from r8Task.outputs.files[0]
927 into file("${buildDir}/libs")
928 rename { String fileName -> "r8_no_manifest.jar" }
929 outputs.file "${buildDir}/libs/r8_no_manifest.jar"
Tamas Kenez8224fbc2018-12-10 09:57:56 +0100930}
931
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100932task D8(type: Jar) {
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200933 dependsOn r8
Morten Krogh-Jespersen6ecff012021-12-20 14:08:44 +0100934 from zipTree(r8.outputs.files[0])
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +0100935 archiveFileName = 'd8.jar'
Mads Ager418d1ca2017-05-22 09:35:49 +0200936 manifest {
mikaelpeltier80939312017-08-17 15:00:09 +0200937 attributes 'Main-Class': 'com.android.tools.r8.D8'
Mads Ager418d1ca2017-05-22 09:35:49 +0200938 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200939}
940
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200941def baseCompilerCommandLine(compiler, args = []) {
942 // Execute r8 commands against a stable r8 with dependencies.
943 // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g).
944 return [org.gradle.internal.jvm.Jvm.current().getJavaExecutable(),
945 "-Xmx8g", "-ea", "-jar", r8WithDeps.outputs.files[0]] + compiler + args
946}
947
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100948def baseR8CommandLine(args = []) {
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +0200949 // Execute r8 commands against a stable r8 with dependencies.
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200950 return baseCompilerCommandLine("r8", args)
951}
952
953def baseD8CommandLine(args = []) {
954 // Execute r8 commands against a stable r8 with dependencies.
955 return baseCompilerCommandLine("d8", args)
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100956}
957
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200958def r8CfCommandLine(input, output, pgConfs = [], args = ["--release"], libs = []) {
959 def allArgs = [
960 "--classfile",
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100961 input,
962 "--output", output,
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +0100963 "--pg-map-output", output + ".map",
964 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +0200965 ] + args + libs.collectMany { ["--lib", it] } + pgConfs.collectMany { ["--pg-conf", it] }
966 return baseR8CommandLine(allArgs)
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100967}
968
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +0200969def d8CfCommandLine(input, output, args = ["--release"], libs = []) {
970 def allArgs = [
971 "--classfile",
972 input,
973 "--output", output,
974 "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
975 ] + args + libs.collectMany { ["--lib", it] }
976 return baseD8CommandLine(allArgs)
977}
978
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +0100979def r8LibCreateTask(name, pgConfs = [], r8Task, output, libs = [], classpath = []) {
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100980 return tasks.create("r8Lib${name}", Exec) {
Ian Zernya0d27cf2021-10-14 13:55:34 +0200981 inputs.files ([pgConfs, r8WithRelocatedDeps.outputs, r8Task.outputs])
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100982 outputs.file output
983 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +0100984 dependsOn r8WithRelocatedDeps
985 dependsOn r8Task
Ian Zernya0d27cf2021-10-14 13:55:34 +0200986 commandLine ([
Ian Zerny99613a02022-02-23 11:50:13 +0100987 "python3", "tools/create_r8lib.py",
Ian Zernya0d27cf2021-10-14 13:55:34 +0200988 "--r8jar", r8Task.outputs.files[0],
989 "--output", output]
990 + (pgConfs.collectMany { ["--pg-conf", it] })
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +0100991 + (libs.collectMany { ["--lib", it] })
992 + (classpath.collectMany { ["--classpath", it] }))
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100993 workingDir = projectDir
994 }
995}
996
Søren Gjesse17fc67d2019-12-04 14:50:17 +0100997task buildLibraryDesugarConversions(type: Zip, dependsOn: downloadDeps) {
998 from sourceSets.libraryDesugarConversions.output
999 include "java/**/*.class"
1000 baseName 'library_desugar_conversions'
1001 destinationDir file('build/libs')
1002}
1003
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001004task testJarSources(type: Jar, dependsOn: [testClasses, buildLibraryDesugarConversions]) {
1005 archiveFileName = "r8testsbase.jar"
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001006 from sourceSets.test.output
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001007 // We only want to include tests that use R8 when generating keep rules for applymapping.
1008 include "com/android/tools/r8/**"
1009 include "dalvik/**"
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001010}
1011
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001012task testJar(type: Exec) {
Morten Krogh-Jespersenac1a4d22020-05-04 01:42:13 +02001013 dependsOn r8WithDeps
1014 dependsOn testJarSources
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001015 def output = "$buildDir/libs/r8tests.jar"
1016 outputs.file output
1017 workingDir = projectDir
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001018 inputs.files (testJarSources.outputs.files + r8WithDeps.outputs.files)
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001019 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersen4a5b1012020-05-02 21:54:11 +02001020 "relocator",
1021 "--input",
1022 testJarSources.outputs.files[0],
1023 "--output",
1024 output,
1025 "--map",
1026 "kotlinx.metadata->com.android.tools.r8.jetbrains.kotlinx.metadata"
1027 ])
1028}
1029
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001030task generateR8LibKeepRules(type: Exec) {
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001031 // Depend on r8WithRelocatedDeps to ensure that we do not have external
1032 // dependencies crossing the boundary.
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001033 dependsOn r8WithDeps
1034 dependsOn r8NoManifestWithRelocatedDeps
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001035 dependsOn testJar
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001036 dependsOn repackageTestDeps
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001037 dependsOn downloadOpenJDKrt
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001038 inputs.files ([
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001039 r8WithDeps.outputs,
1040 r8NoManifestWithRelocatedDeps.outputs,
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001041 repackageDeps.outputs,
1042 repackageTestDeps.outputs,
Morten Krogh-Jespersen30b07902020-05-03 00:35:45 +02001043 testJar.outputs])
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001044 outputs.file r8LibGeneratedKeepRulesPath
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001045 commandLine baseCompilerCommandLine([
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001046 "tracereferences",
1047 "--keep-rules",
1048 "--allowobfuscation",
1049 "--lib",
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001050 "third_party/openjdk/openjdk-rt-1.8/rt.jar",
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001051 "--lib",
1052 repackageDeps.outputs.files[0],
1053 "--lib",
1054 repackageTestDeps.outputs.files[0],
1055 "--target",
Morten Krogh-Jespersen23d77af2020-05-05 09:34:53 +02001056 r8NoManifestWithRelocatedDeps.outputs.files[0],
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001057 "--source",
1058 testJar.outputs.files[0],
1059 "--output",
1060 r8LibGeneratedKeepRulesPath])
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001061 workingDir = projectDir
Morten Krogh-Jespersen4aa109f2018-12-21 13:27:51 +01001062}
1063
Morten Krogh-Jespersenb39fbe52018-12-17 14:58:48 +01001064task R8Lib {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001065 dependsOn r8LibCreateTask(
1066 "Main",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001067 ["src/main/keep.txt", generateR8LibKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001068 r8NoManifestWithRelocatedDeps,
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001069 r8LibPath,
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001070 ).dependsOn(generateR8LibKeepRules)
Morten Krogh-Jespersen40ac0e42020-05-04 11:26:50 +02001071 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001072 outputs.file r8LibPath
Tamas Kenezf960e9c2018-12-03 16:13:29 +01001073}
1074
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001075task R8LibNoDeps {
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001076 dependsOn r8LibCreateTask(
Ian Zernya0d27cf2021-10-14 13:55:34 +02001077 "MainNoDeps",
Morten Krogh-Jespersen60cb2622020-09-25 21:52:26 +02001078 ["src/main/keep.txt"],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001079 r8NoManifestWithoutDeps,
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001080 r8LibExludeDepsPath,
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001081 [],
Morten Krogh-Jespersenb329ac42021-09-09 09:16:16 +02001082 repackageDeps.outputs.files
1083 ).dependsOn(repackageDeps)
1084 inputs.files ([r8NoManifestWithoutDeps.outputs, repackageDeps.outputs])
Morten Krogh-Jespersencae32a72019-01-11 11:02:19 +01001085 outputs.file r8LibExludeDepsPath
1086}
1087
Morten Krogh-Jespersen0b2bac72020-08-14 17:51:06 +02001088task R8Desugared(type: Exec) {
1089 dependsOn downloadOpenJDKrt
1090 dependsOn r8NoManifestWithRelocatedDeps
1091 inputs.files r8NoManifestWithRelocatedDeps.outputs.files
1092 commandLine d8CfCommandLine(
1093 r8NoManifestWithRelocatedDeps.outputs.files[0],
1094 r8DesugaredPath,
1095 ["--release"])
1096 workingDir = projectDir
1097 outputs.file r8DesugaredPath
1098}
1099
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +02001100task R8Retrace {
1101 dependsOn R8Lib
1102 dependsOn r8LibCreateTask(
1103 "Retrace",
1104 ["src/main/keep_retrace.txt"],
1105 R8Lib,
1106 r8RetracePath,
1107 ).dependsOn(R8Lib)
1108 outputs.file r8RetracePath
1109}
1110
1111task R8RetraceNoDeps {
1112 dependsOn R8LibNoDeps
1113 dependsOn r8LibCreateTask(
1114 "RetraceNoDeps",
1115 ["src/main/keep_retrace.txt"],
1116 R8LibNoDeps,
1117 r8RetraceExludeDepsPath,
Morten Krogh-Jespersen378aa612021-11-23 13:27:25 +01001118 [],
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +02001119 repackageDeps.outputs.files
1120 ).dependsOn(R8LibNoDeps)
1121 outputs.file r8RetraceExludeDepsPath
1122}
1123
Mads Ager418d1ca2017-05-22 09:35:49 +02001124task sourceJar(type: Jar, dependsOn: classes) {
1125 classifier = 'src'
1126 from sourceSets.main.allSource
1127}
1128
Mads Ager418d1ca2017-05-22 09:35:49 +02001129artifacts {
1130 archives sourceJar
1131}
1132
1133task createArtTests(type: Exec) {
1134 def outputDir = "build/generated/test/java/com/android/tools/r8/art"
Mads Ager7e5bd722017-05-24 07:17:27 +02001135 def createArtTestsScript = "tools/create_art_tests.py"
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001136 inputs.files files("tests/2017-10-04/art.tar.gz", createArtTestsScript)
Mads Ager418d1ca2017-05-22 09:35:49 +02001137 outputs.dir outputDir
1138 dependsOn downloadDeps
Ian Zerny99613a02022-02-23 11:50:13 +01001139 commandLine "python3", createArtTestsScript
Mads Ager418d1ca2017-05-22 09:35:49 +02001140 workingDir = projectDir
1141}
1142
Mads Ager418d1ca2017-05-22 09:35:49 +02001143compileTestJava {
1144 dependsOn createArtTests
Mads Ager418d1ca2017-05-22 09:35:49 +02001145}
1146
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001147task buildCfSegments(type: Jar, dependsOn: downloadDeps) {
1148 from sourceSets.cfSegments.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001149 archiveFileName = 'cf_segments.jar'
Morten Krogh-Jespersen7bc93dc2019-01-29 09:53:08 +01001150 destinationDir file('build/libs')
1151}
1152
Ian Zerny923a0c12018-01-03 10:59:18 +01001153task buildR8ApiUsageSample(type: Jar) {
1154 from sourceSets.apiUsageSample.output
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001155 archiveFileName = 'r8_api_usage_sample.jar'
Ian Zerny923a0c12018-01-03 10:59:18 +01001156 destinationDir file('tests')
1157}
1158
Yohann Roussel548ae942018-01-05 11:13:28 +01001159task buildApiSampleJars {
Yohann Roussel548ae942018-01-05 11:13:28 +01001160 dependsOn buildR8ApiUsageSample
1161}
1162
Mads Ager418d1ca2017-05-22 09:35:49 +02001163task buildDebugTestResourcesJars {
Mads Ager418d1ca2017-05-22 09:35:49 +02001164 def resourcesDir = file("src/test/debugTestResources")
1165 def hostJar = "debug_test_resources.jar"
1166 task "compile_debugTestResources"(type: JavaCompile) {
1167 source = fileTree(dir: resourcesDir, include: '**/*.java')
1168 destinationDir = file("build/test/debugTestResources/classes")
1169 classpath = sourceSets.main.compileClasspath
1170 sourceCompatibility = JavaVersion.VERSION_1_7
1171 targetCompatibility = JavaVersion.VERSION_1_7
1172 options.compilerArgs += ["-g", "-Xlint:-options"]
1173 }
1174 task "jar_debugTestResources"(type: Jar, dependsOn: "compile_debugTestResources") {
1175 archiveName = hostJar
1176 destinationDir = file("build/test/")
1177 from "build/test/debugTestResources/classes"
1178 include "**/*.class"
1179 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001180 def java8ResourcesDir = file("src/test/debugTestResourcesJava8")
1181 def java8HostJar = "debug_test_resources_java8.jar"
1182 task "compile_debugTestResourcesJava8"(type: JavaCompile) {
1183 source = fileTree(dir: java8ResourcesDir, include: '**/*.java')
1184 destinationDir = file("build/test/debugTestResourcesJava8/classes")
1185 classpath = sourceSets.main.compileClasspath
1186 sourceCompatibility = JavaVersion.VERSION_1_8
1187 targetCompatibility = JavaVersion.VERSION_1_8
1188 options.compilerArgs += ["-g", "-Xlint:-options"]
1189 }
1190 task "jar_debugTestResourcesJava8"(type: Jar, dependsOn: "compile_debugTestResourcesJava8") {
1191 archiveName = java8HostJar
1192 destinationDir = file("build/test/")
1193 from "build/test/debugTestResourcesJava8/classes"
1194 include "**/*.class"
1195 }
1196 dependsOn downloadDeps
Mads Ager418d1ca2017-05-22 09:35:49 +02001197 dependsOn jar_debugTestResources
Sebastien Hertz964c5c22017-05-23 15:22:23 +02001198 dependsOn jar_debugTestResourcesJava8
Mads Ager418d1ca2017-05-22 09:35:49 +02001199}
1200
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001201// Examples used by tests, where Android specific APIs are used.
1202task buildExampleAndroidApi(type: JavaCompile) {
1203 source = fileTree(dir: file("src/test/examplesAndroidApi"), include: "**/*.java")
1204 destinationDir = file("build/test/examplesAndroidApi/classes")
1205 classpath = files("third_party/android_jar/lib-v26/android.jar")
1206 sourceCompatibility = JavaVersion.VERSION_1_8
1207 targetCompatibility = JavaVersion.VERSION_1_8
1208}
1209
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001210task buildProtoGeneratedSources {
1211 def examplesProtoDir = file("src/test/examplesProto")
1212 examplesProtoDir.eachDir { dir ->
1213 def name = dir.getName()
1214 task "compile_proto_generated_source_${name}"(type: JavaCompile) {
1215 source = {
1216 file('third_party/proto').listFiles()
1217 .findAll { it.name.startsWith(name) && it.name.endsWith('-src.jar') }
1218 .collect { zipTree(it) }
1219 }
1220 destinationDir = file("build/generated/test/proto/${name}_classes")
1221 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1222 sourceCompatibility = JavaVersion.VERSION_1_8
1223 targetCompatibility = JavaVersion.VERSION_1_8
1224 }
1225 task "jar_proto_generated_source_${name}"(type: Jar, dependsOn: "compile_proto_generated_source_${name}") {
1226 archiveName = "${name}.jar"
1227 destinationDir = file("build/generated/test/proto")
1228 from "build/generated/test/proto/${name}_classes"
1229 include "/**/*.class"
1230 }
1231 dependsOn "jar_proto_generated_source_${name}"
1232 }
1233}
1234
1235task buildExamplesProto {
1236 def examplesProtoDir = file("src/test/examplesProto")
1237 def examplesProtoOutputDir = file("build/test/examplesProto");
1238 dependsOn buildProtoGeneratedSources
1239 task "compile_examples_proto"(type: JavaCompile) {
1240 source = fileTree(dir: examplesProtoDir, include: "**/*.java")
1241 destinationDir = file("build/test/examplesProto/classes")
Christoffer Quist Adamsen5d398fe2019-06-14 15:00:14 +02001242 classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
1243 classpath += fileTree(dir: "build/generated/test/proto", include: "*.jar")
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02001244 sourceCompatibility = JavaVersion.VERSION_1_8
1245 targetCompatibility = JavaVersion.VERSION_1_8
1246 }
1247 examplesProtoDir.eachDir { dir ->
1248 def name = dir.getName()
1249 task "jar_examples_proto_${name}"(type: Jar, dependsOn: "compile_examples_proto") {
1250 archiveName = "${name}.jar"
1251 destinationDir = examplesProtoOutputDir
1252 from "build/test/examplesProto/classes"
1253 include name + "/**/*.class"
1254 }
1255 dependsOn "jar_examples_proto_${name}"
1256 }
1257}
1258
Lars Bakc91e87e2017-08-18 08:53:10 +02001259// Proto lite generated code yields warnings when compiling with javac.
1260// We change the options passed to javac to ignore it.
1261compileExamplesJava.options.compilerArgs = ["-Xlint:none"]
1262
Søren Gjesse7320ce52018-05-07 15:45:22 +02001263
Mads Ager418d1ca2017-05-22 09:35:49 +02001264task buildExampleJars {
Rico Wind897bb712017-05-23 10:44:29 +02001265 dependsOn downloadProguard
Mads Ager418d1ca2017-05-22 09:35:49 +02001266 def examplesDir = file("src/test/examples")
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001267 def proguardScript
1268 if (OperatingSystem.current().isWindows()) {
1269 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.bat"
1270 } else {
1271 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.sh"
1272 }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001273 task extractExamplesRuntime(type: Sync) {
1274 dependsOn configurations.examplesRuntime
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001275 from { configurations.examplesRuntime.collect { zipTree(it) } }
Stephan Herhut417a72a2017-07-18 10:38:30 +02001276 include "**/*.class"
1277 includeEmptyDirs false
1278 into "$buildDir/runtime/examples/"
1279 }
1280
Søren Gjesse7320ce52018-05-07 15:45:22 +02001281 task "copy_examples_resources"(type: org.gradle.api.tasks.Copy) {
1282 from examplesDir
1283 exclude "**/*.java"
1284 exclude "**/keep-rules*.txt"
1285 into file("build/test/examples/classes")
1286 }
1287
1288 task "compile_examples"(type: JavaCompile) {
Søren Gjesse7320ce52018-05-07 15:45:22 +02001289 dependsOn "copy_examples_resources"
Rico Wind40fd2c12018-09-12 12:14:44 +02001290 source examplesDir
Stephan Herhut417a72a2017-07-18 10:38:30 +02001291 include "**/*.java"
Mads Ager418d1ca2017-05-22 09:35:49 +02001292 destinationDir = file("build/test/examples/classes")
Stephan Herhut417a72a2017-07-18 10:38:30 +02001293 classpath = sourceSets.examples.compileClasspath
Mads Ager418d1ca2017-05-22 09:35:49 +02001294 sourceCompatibility = JavaVersion.VERSION_1_7
1295 targetCompatibility = JavaVersion.VERSION_1_7
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001296 options.compilerArgs = ["-g:source,lines", "-Xlint:none"]
1297 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001298 task "compile_examples_debuginfo_all"(type: JavaCompile) {
1299 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001300 include "**/*.java"
1301 destinationDir = file("build/test/examples/classes_debuginfo_all")
1302 classpath = sourceSets.examples.compileClasspath
1303 sourceCompatibility = JavaVersion.VERSION_1_7
1304 targetCompatibility = JavaVersion.VERSION_1_7
1305 options.compilerArgs = ["-g", "-Xlint:none"]
1306 }
Rico Wind40fd2c12018-09-12 12:14:44 +02001307 task "compile_examples_debuginfo_none"(type: JavaCompile) {
1308 source examplesDir
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001309 include "**/*.java"
1310 destinationDir = file("build/test/examples/classes_debuginfo_none")
1311 classpath = sourceSets.examples.compileClasspath
1312 sourceCompatibility = JavaVersion.VERSION_1_7
1313 targetCompatibility = JavaVersion.VERSION_1_7
1314 options.compilerArgs = ["-g:none", "-Xlint:none"]
Mads Ager418d1ca2017-05-22 09:35:49 +02001315 }
1316 examplesDir.eachDir { dir ->
1317 def name = dir.getName();
1318 def exampleOutputDir = file("build/test/examples");
1319 def jarName = "${name}.jar"
1320 dependsOn "jar_example_${name}"
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001321 dependsOn "jar_example_${name}_debuginfo_all"
1322 dependsOn "jar_example_${name}_debuginfo_none"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001323 dependsOn "extractExamplesRuntime"
1324 def runtimeDependencies = copySpec { }
Mads Ager418d1ca2017-05-22 09:35:49 +02001325 // The "throwing" test verifies debugging/stack info on the post-proguarded output.
1326 def proguardConfigPath = "${dir}/proguard.cfg"
1327 if (new File(proguardConfigPath).exists()) {
1328 task "pre_proguard_example_${name}"(type: Jar, dependsOn: "compile_examples") {
1329 archiveName = "${name}_pre_proguard.jar"
1330 destinationDir = exampleOutputDir
1331 from "build/test/examples/classes"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001332 include name + "/**/*.class"
1333 with runtimeDependencies
1334 includeEmptyDirs false
Mads Ager418d1ca2017-05-22 09:35:49 +02001335 }
1336 def jarPath = files(tasks.getByPath("pre_proguard_example_${name}")).files.first();
1337 def proguardJarPath = "${exampleOutputDir}/${jarName}"
1338 def proguardMapPath = "${exampleOutputDir}/${name}/${name}.map"
1339 task "jar_example_${name}"(type: Exec, dependsOn: "pre_proguard_example_${name}") {
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001340 inputs.files files(
1341 tasks.getByPath("pre_proguard_example_${name}"),
1342 proguardConfigPath)
Mads Ager418d1ca2017-05-22 09:35:49 +02001343 // Enable these to get stdout and stderr redirected to files...
1344 // standardOutput = new FileOutputStream('proguard.stdout')
1345 // errorOutput = new FileOutputStream('proguard.stderr')
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001346 def proguardArguments = "-verbose -dontwarn java.** -injars ${jarPath}" +
Mads Ager418d1ca2017-05-22 09:35:49 +02001347 " -outjars ${proguardJarPath}" +
1348 " -include ${proguardConfigPath}" +
Jean-Marie Henaff872e4422017-06-13 10:26:20 +02001349 " -printmapping ${proguardMapPath}"
1350 if (OperatingSystem.current().isWindows()) {
1351 executable "${proguardScript}"
1352 args "${proguardArguments}"
1353 } else {
1354 executable "bash"
1355 args "-c", "${proguardScript} '${proguardArguments}'"
1356 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001357 outputs.file proguardJarPath
1358 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001359 // TODO: Consider performing distinct proguard compilations.
1360 task "jar_example_${name}_debuginfo_all"(type: Copy, dependsOn: "jar_example_${name}") {
1361 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001362 into "${exampleOutputDir}"
1363 rename(".*", "${name}_debuginfo_all.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001364 }
1365 task "jar_example_${name}_debuginfo_none"(type: Copy, dependsOn: "jar_example_${name}") {
1366 from "${exampleOutputDir}/${name}.jar"
Tamas Kenez925cb642017-09-19 10:41:15 +02001367 into "${exampleOutputDir}"
1368 rename(".*", "${name}_debuginfo_none.jar")
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001369 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001370 } else {
1371 task "jar_example_${name}"(type: Jar, dependsOn: "compile_examples") {
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001372 archiveName = "${name}.jar"
Mads Ager418d1ca2017-05-22 09:35:49 +02001373 destinationDir = exampleOutputDir
1374 from "build/test/examples/classes"
Søren Gjesse7320ce52018-05-07 15:45:22 +02001375 include name + "/**/*"
Stephan Herhut417a72a2017-07-18 10:38:30 +02001376 with runtimeDependencies
Søren Gjesse7320ce52018-05-07 15:45:22 +02001377 includeEmptyDirs true
Mads Ager418d1ca2017-05-22 09:35:49 +02001378 }
Tamas Kenezc5163ed2017-09-19 09:27:37 +02001379 task "jar_example_${name}_debuginfo_all"(type: Jar, dependsOn: "compile_examples_debuginfo_all") {
1380 archiveName = "${name}_debuginfo_all.jar"
1381 destinationDir = exampleOutputDir
1382 from "build/test/examples/classes_debuginfo_all"
1383 include name + "/**/*.class"
1384 with runtimeDependencies
1385 includeEmptyDirs false
1386 }
1387 task "jar_example_${name}_debuginfo_none"(type: Jar, dependsOn: "compile_examples_debuginfo_none") {
1388 archiveName = "${name}_debuginfo_none.jar"
1389 destinationDir = exampleOutputDir
1390 from "build/test/examples/classes_debuginfo_none"
1391 include name + "/**/*.class"
1392 with runtimeDependencies
1393 includeEmptyDirs false
1394 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001395 }
1396 }
1397}
1398
1399task buildExampleAndroidNJars {
1400 dependsOn downloadDeps
1401 def examplesDir = file("src/test/examplesAndroidN")
1402 task "compile_examplesAndroidN"(type: JavaCompile) {
1403 source = fileTree(dir: examplesDir, include: '**/*.java')
1404 destinationDir = file("build/test/examplesAndroidN/classes")
1405 classpath = sourceSets.main.compileClasspath
1406 sourceCompatibility = JavaVersion.VERSION_1_8
1407 targetCompatibility = JavaVersion.VERSION_1_8
1408 options.compilerArgs += ["-Xlint:-options"]
1409 }
1410 examplesDir.eachDir { dir ->
1411 def name = dir.getName();
1412 def exampleOutputDir = file("build/test/examplesAndroidN");
1413 def jarName = "${name}.jar"
1414 dependsOn "jar_examplesAndroidN_${name}"
1415 task "jar_examplesAndroidN_${name}"(type: Jar, dependsOn: "compile_examplesAndroidN") {
1416 archiveName = jarName
1417 destinationDir = exampleOutputDir
1418 from "build/test/examplesAndroidN/classes"
1419 include "**/" + name + "/**/*.class"
1420 }
1421 }
1422}
1423
1424
1425task buildExampleAndroidOJars {
1426 dependsOn downloadDeps
1427 def examplesDir = file("src/test/examplesAndroidO")
1428 // NOTE: we want to enable a scenario when test needs to reference some
1429 // classes generated by legacy (1.6) Java compiler to test some specific
1430 // behaviour. To do so we compile all the java files located in sub-directory
1431 // called 'legacy' with Java 1.6, then compile the rest of the files with
1432 // Java 1.8 and a reference to previously generated 1.6 classes.
1433
1434 // Compiling all classes in dirs 'legacy' with old Java version.
1435 task "compile_examplesAndroidO_Legacy"(type: JavaCompile) {
1436 source = fileTree(dir: examplesDir, include: '**/legacy/**/*.java')
1437 destinationDir = file("build/test/examplesAndroidOLegacy/classes")
1438 classpath = sourceSets.main.compileClasspath
1439 sourceCompatibility = JavaVersion.VERSION_1_6
1440 targetCompatibility = JavaVersion.VERSION_1_6
1441 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1442 }
1443 // Compiling the rest of the files as Java 1.8 code.
1444 task "compile_examplesAndroidO"(type: JavaCompile) {
1445 dependsOn "compile_examplesAndroidO_Legacy"
1446 source = fileTree(dir: examplesDir, include: '**/*.java', exclude: '**/legacy/**/*.java')
1447 destinationDir = file("build/test/examplesAndroidO/classes")
1448 classpath = sourceSets.main.compileClasspath
1449 classpath += files("build/test/examplesAndroidOLegacy/classes")
1450 sourceCompatibility = JavaVersion.VERSION_1_8
1451 targetCompatibility = JavaVersion.VERSION_1_8
1452 options.compilerArgs += ["-Xlint:-options", "-parameters"]
1453 }
1454 examplesDir.eachDir { dir ->
1455 def name = dir.getName();
1456 def destinationDir = file("build/test/examplesAndroidO/classes");
1457 if (file("src/test/examplesAndroidO/" + name + "/TestGenerator.java").isFile()) {
1458 task "generate_examplesAndroidO_${name}"(type: JavaExec,
1459 dependsOn: "compile_examplesAndroidO") {
1460 main = name + ".TestGenerator"
1461 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1462 args destinationDir
1463 }
1464 } else {
1465 task "generate_examplesAndroidO_${name}" () {}
1466 }
1467 }
1468 examplesDir.eachDir { dir ->
1469 def name = dir.getName();
1470 def exampleOutputDir = file("build/test/examplesAndroidO");
1471 def jarName = "${name}.jar"
1472 dependsOn "jar_examplesAndroidO_${name}"
1473 task "jar_examplesAndroidO_${name}"(type: Jar, dependsOn: ["compile_examplesAndroidO",
1474 "generate_examplesAndroidO_${name}"]) {
1475 archiveName = jarName
1476 destinationDir = exampleOutputDir
1477 from "build/test/examplesAndroidO/classes" // Java 1.8 classes
1478 from "build/test/examplesAndroidOLegacy/classes" // Java 1.6 classes
1479 include "**/" + name + "/**/*.class"
1480 // Do not include generator into the test runtime jar, it is not useful.
1481 // Otherwise, shrinking will need ASM jars.
1482 exclude "**/TestGenerator*"
1483 }
1484 }
1485}
1486
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001487task buildExampleAndroidPJars {
1488 dependsOn downloadDeps
1489 def examplesDir = file("src/test/examplesAndroidP")
1490
1491 task "compile_examplesAndroidP"(type: JavaCompile) {
1492 source = fileTree(dir: examplesDir, include: '**/*.java')
1493 destinationDir = file("build/test/examplesAndroidP/classes")
1494 classpath = sourceSets.main.compileClasspath
1495 sourceCompatibility = JavaVersion.VERSION_1_8
1496 targetCompatibility = JavaVersion.VERSION_1_8
1497 options.compilerArgs += ["-Xlint:-options"]
1498 }
1499 examplesDir.eachDir { dir ->
1500 def name = dir.getName();
1501 def destinationDir = file("build/test/examplesAndroidP/classes");
1502 if (file("src/test/examplesAndroidP/" + name + "/TestGenerator.java").isFile()) {
1503 task "generate_examplesAndroidP_${name}"(type: JavaExec,
1504 dependsOn: "compile_examplesAndroidP") {
1505 main = name + ".TestGenerator"
1506 classpath = files(destinationDir, sourceSets.main.compileClasspath)
1507 args destinationDir
1508 }
1509 } else {
1510 task "generate_examplesAndroidP_${name}" () {}
1511 }
1512 }
1513 examplesDir.eachDir { dir ->
1514 def name = dir.getName();
1515 def exampleOutputDir = file("build/test/examplesAndroidP");
1516 def jarName = "${name}.jar"
1517 dependsOn "jar_examplesAndroidP_${name}"
1518 task "jar_examplesAndroidP_${name}"(type: Jar,
1519 dependsOn: ["compile_examplesAndroidP",
1520 "generate_examplesAndroidP_${name}"]) {
1521 archiveName = jarName
1522 destinationDir = exampleOutputDir
1523 from "build/test/examplesAndroidP/classes" // Java 1.8 classes
1524 include "**/" + name + "/**/*.class"
1525 // Do not include generator into the test runtime jar, it is not useful.
1526 // Otherwise, shrinking will need ASM jars.
1527 exclude "**/TestGenerator*"
1528 }
1529 }
1530}
1531
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001532def buildExampleJarsCreateTask(javaVersion, sourceSet) {
1533 return tasks.create("buildExample${javaVersion}Jars") {
1534 def examplesDir = file("src/test/examples${javaVersion}")
1535 examplesDir.eachDir { dir ->
1536 def name = dir.getName();
1537 def exampleOutputDir = file("build/test/examples${javaVersion}");
1538 def jarName = "${name}.jar"
1539 dependsOn "jar_examples${javaVersion}_${name}"
1540 task "jar_examples${javaVersion}_${name}"(type: Jar) {
1541 archiveName = jarName
1542 destinationDir = exampleOutputDir
1543 from sourceSet.output
1544 include "**/" + name + "/**/*.class"
1545 }
Mikaël Peltier61633d42017-10-13 16:51:06 +02001546 }
1547 }
1548}
1549
Morten Krogh-Jespersen0ed04d42020-11-25 15:46:21 +01001550buildExampleJarsCreateTask("Java9", sourceSets.examplesJava9)
1551buildExampleJarsCreateTask("Java10", sourceSets.examplesJava10)
1552buildExampleJarsCreateTask("Java11", sourceSets.examplesJava11)
Søren Gjessee9966932021-09-15 17:08:37 +02001553buildExampleJarsCreateTask("Java17", sourceSets.examplesJava17)
Søren Gjessed1e08992022-02-07 16:46:31 +01001554buildExampleJarsCreateTask("Java18", sourceSets.examplesJava18)
clementberad7ab1dd2019-04-16 16:05:00 +02001555
clementberaa92e3cd2019-07-12 14:13:22 +02001556task provideArtFrameworksDependencies {
1557 cloudDependencies.tools.forEach({ art ->
1558 if (art.contains("art")) {
1559 def taskName = art.replace('/','_')
1560 dependsOn "patch_${taskName}"
1561 task "patch_${taskName}"(type: org.gradle.api.tasks.Copy){
1562 from "tools/${art}/framework"
1563 include "**.jar"
1564 into file("tools/${art}/out/host/linux-x86/framework")
1565 }
1566 }
1567 })
1568}
1569
Sebastien Hertzd3313772018-01-16 14:12:37 +01001570task buildKotlinR8TestResources {
1571 def examplesDir = file("src/test/kotlinR8TestResources")
1572 examplesDir.eachDir { dir ->
Sebastien Hertzfe97a712018-02-13 12:08:59 +01001573 kotlin.Kotlinc.KotlinTargetVersion.values().each { kotlinTargetVersion ->
1574 def name = dir.getName()
1575 def taskName = "jar_kotlinR8TestResources_${name}_${kotlinTargetVersion}"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001576 def javaOutput = "build/test/kotlinR8TestResources/${kotlinTargetVersion}/${name}/java"
Denis Vnukovc22da842018-03-14 12:57:20 -07001577 def javaOutputJarName = "${name}.java.jar"
Morten Krogh-Jespersen6c1f2fa2019-01-04 13:23:13 +00001578 def javaOutputJarDir = "build/test/kotlinR8TestResources/${kotlinTargetVersion}"
Denis Vnukovc22da842018-03-14 12:57:20 -07001579 task "${taskName}Java"(type: JavaCompile) {
1580 source = fileTree(dir: file("${examplesDir}/${name}"), include: '**/*.java')
1581 destinationDir = file(javaOutput)
1582 classpath = sourceSets.main.compileClasspath
1583 sourceCompatibility = JavaVersion.VERSION_1_6
1584 targetCompatibility = JavaVersion.VERSION_1_6
1585 options.compilerArgs += ["-g", "-Xlint:-options"]
1586 }
1587 task "${taskName}JavaJar"(type: Jar, dependsOn: "${taskName}Java") {
1588 archiveName = javaOutputJarName
1589 destinationDir = file(javaOutputJarDir)
1590 from javaOutput
1591 include "**/*.class"
1592 }
Morten Krogh-Jespersen358c8a72021-02-24 11:07:57 +01001593 dependsOn "${taskName}JavaJar"
Sebastien Hertzd3313772018-01-16 14:12:37 +01001594 }
Sebastien Hertzd3313772018-01-16 14:12:37 +01001595 }
1596}
1597
Mads Ager418d1ca2017-05-22 09:35:49 +02001598task buildExamples {
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001599 if (OperatingSystem.current().isMacOsX() || OperatingSystem.current().isWindows()) {
1600 logger.lifecycle("WARNING: Testing (including building examples) is only partially supported on your " +
1601 "platform (" + OperatingSystem.current().getName() + ").")
Mads Ager418d1ca2017-05-22 09:35:49 +02001602 } else if (!OperatingSystem.current().isLinux()) {
1603 logger.lifecycle("WARNING: Testing (including building examples) is not supported on your platform. " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02001604 "It is fully supported on Linux and partially supported on Mac OS and Windows")
Mads Ager418d1ca2017-05-22 09:35:49 +02001605 return;
1606 }
1607 dependsOn buildDebugTestResourcesJars
1608 dependsOn buildExampleJars
1609 dependsOn buildExampleAndroidNJars
1610 dependsOn buildExampleAndroidOJars
Mikaël Peltier7b7b53a2017-10-09 13:33:21 +02001611 dependsOn buildExampleAndroidPJars
Mikaël Peltier61633d42017-10-13 16:51:06 +02001612 dependsOn buildExampleJava9Jars
Jake Wharton2000b2f2019-12-11 20:37:49 -05001613 dependsOn buildExampleJava10Jars
clementberad7ab1dd2019-04-16 16:05:00 +02001614 dependsOn buildExampleJava11Jars
Søren Gjessee9966932021-09-15 17:08:37 +02001615 dependsOn buildExampleJava17Jars
Søren Gjessed1e08992022-02-07 16:46:31 +01001616 dependsOn buildExampleJava18Jars
Søren Gjesse5b4ee0a2018-01-30 13:46:39 +01001617 dependsOn buildExampleAndroidApi
Mads Ager418d1ca2017-05-22 09:35:49 +02001618 def examplesDir = file("src/test/examples")
Yohann Rousself820a572017-05-31 20:25:51 +02001619 def noDexTests = [
1620 "multidex",
1621 "multidex002",
1622 "multidex004",
1623 ]
Mads Ager418d1ca2017-05-22 09:35:49 +02001624 examplesDir.eachDir { dir ->
1625 def name = dir.getName();
Yohann Rousself820a572017-05-31 20:25:51 +02001626 if (!(name in noDexTests)) {
1627 dependsOn "dex_example_${name}"
1628 def exampleOutputDir = file("build/test/examples/" + name);
1629 def dexPath = file("${exampleOutputDir}")
1630 def debug = (name == "throwing")
1631 if (!dexPath.exists()) {
1632 dexPath.mkdirs()
1633 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001634 task "dex_example_${name}"(type: DxTask, dependsOn: "jar_example_${name}") {
Yohann Rousself820a572017-05-31 20:25:51 +02001635 source = files(tasks.getByPath("jar_example_${name}")).asFileTree
1636 destination = dexPath
1637 debug = debug
1638 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001639 }
1640 }
1641}
1642
1643task buildSmali {
1644 def smaliDir = file("src/test/smali")
1645 smaliDir.eachDirRecurse() { dir ->
1646 def name = dir.getName();
1647 def relativeDir = smaliDir.toPath().relativize(dir.toPath());
1648 def smaliOutputDir = file("build/test/smali/" + relativeDir);
1649 smaliOutputDir.mkdirs()
1650 outputs.dir smaliOutputDir
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001651 def taskName = "smali_build_${relativeDir.toString().replace('/', '_').replace('\\', '_')}"
Mads Ager418d1ca2017-05-22 09:35:49 +02001652 def smaliFiles = fileTree(dir: dir, include: '*.smali')
1653 def javaFiles = fileTree(dir: dir, include: '*.java')
1654 def destDir = smaliOutputDir;
1655 def destFile = destDir.toPath().resolve("${name}.dex").toFile()
1656 def intermediateFileName = "${name}-intermediate.dex";
1657 def intermediateFile = destDir.toPath().resolve(intermediateFileName).toFile()
1658 if (javaFiles.empty) {
1659 if (!smaliFiles.empty) {
1660 dependsOn "${taskName}_smali"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001661 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001662 source = smaliFiles
1663 destination = destFile
1664 }
1665 }
1666 } else {
Rico Wind01c15c62021-04-22 17:30:41 +00001667 dependsOn "${taskName}_dexmerger"
Jake Wharton2d7aab82019-09-13 10:24:26 -04001668 task "${taskName}_smali"(type: SmaliTask) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001669 source = smaliFiles
1670 destination = intermediateFile
1671 }
1672 task "${taskName}_java"(type: JavaCompile) {
1673 source = javaFiles
1674 destinationDir destDir
1675 classpath = sourceSets.main.compileClasspath
1676 sourceCompatibility = JavaVersion.VERSION_1_7
1677 targetCompatibility = JavaVersion.VERSION_1_7
1678 options.compilerArgs += ["-Xlint:-options"]
1679 }
1680 task "${taskName}_jar"(type: Jar, dependsOn: "${taskName}_java") {
1681 archiveName = "Test.jar"
1682 destinationDir = destDir
1683 from fileTree(dir: destDir, include: 'Test.class')
1684 }
Jake Wharton2d7aab82019-09-13 10:24:26 -04001685 task "${taskName}_dx"(type: DxTask, dependsOn: "${taskName}_jar") {
Mads Ager418d1ca2017-05-22 09:35:49 +02001686 source = fileTree(dir: destDir, include: 'Test.jar')
1687 destination = destDir
1688 }
1689 task "${taskName}_dexmerger"(
Jake Wharton2d7aab82019-09-13 10:24:26 -04001690 type: DexMergerTask, dependsOn: ["${taskName}_dx", "${taskName}_smali"]) {
Mads Ager418d1ca2017-05-22 09:35:49 +02001691 source = fileTree(dir: destDir, include: ["classes.dex", intermediateFileName])
1692 destination = destFile
1693 }
1694 }
1695 }
1696}
1697
1698tasks.withType(Test) {
Rico Windc56f21c2019-03-12 07:29:57 +01001699 println("NOTE: Number of processors " + Runtime.runtime.availableProcessors())
Mads Ager418d1ca2017-05-22 09:35:49 +02001700 def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK')
Rico Wind73da9f12019-09-19 09:27:07 +02001701 def processors = Runtime.runtime.availableProcessors()
Mads Ager418d1ca2017-05-22 09:35:49 +02001702 // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
Rico Wind73da9f12019-09-19 09:27:07 +02001703 if (userDefinedCoresPerFork) {
1704 maxParallelForks = processors.intdiv(userDefinedCoresPerFork.toInteger()) ?: 1
1705 } else {
1706 // On normal work machines this seems to give the best test execution time (without freezing)
Rico Wind3d4113e2021-09-30 07:50:43 +02001707 maxParallelForks = processors.intdiv(3) ?: 1
1708 // On low cpu count machines (bots) we under subscribe, so increase the count.
1709 if (processors == 8) {
Rico Wind59f7fb02021-10-25 09:01:39 +02001710 maxParallelForks = 3
Rico Wind3d4113e2021-09-30 07:50:43 +02001711 }
Rico Wind73da9f12019-09-19 09:27:07 +02001712 }
Rico Windc56f21c2019-03-12 07:29:57 +01001713 println("NOTE: Max parallel forks " + maxParallelForks)
Rico Wind73da9f12019-09-19 09:27:07 +02001714
Mads Ager418d1ca2017-05-22 09:35:49 +02001715 forkEvery = 0
Søren Gjesseaf1c5e22017-06-15 12:24:03 +02001716 if (project.hasProperty('disable_assertions')) {
1717 enableAssertions = false
1718 }
Ian Zerny16c2f2d2019-02-19 07:25:11 +01001719 // TODO(b/124091860): Increase the max heap size to avoid OOM when running tests.
Rico Wind97b0a992019-08-30 11:09:15 +02001720 if (project.hasProperty('test_xmx')) {
1721 maxHeapSize = project.property('test_xmx')
1722 } else {
1723 maxHeapSize = "4G"
1724 }
Mads Ager418d1ca2017-05-22 09:35:49 +02001725}
1726
1727task buildPreNJdwpTestsJar(type: Jar) {
Morten Krogh-Jespersenfe0edea2021-12-20 13:36:45 +01001728 archiveFileName = 'jdwp-tests-preN.jar'
Mads Ager418d1ca2017-05-22 09:35:49 +02001729 from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
1730 // Exclude the classes containing java8
1731 exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
1732 exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
1733 includeEmptyDirs = false
1734}
1735
Ian Zerny74143162017-11-24 13:46:35 +01001736task buildPreNJdwpTestsDex(type: Exec, dependsOn: "buildPreNJdwpTestsJar") {
1737 def inFile = buildPreNJdwpTestsJar.archivePath
1738 def outFile = new File(buildPreNJdwpTestsJar.destinationDir, buildPreNJdwpTestsJar.baseName + '-dex.jar')
Ian Zerny5fffb0a2019-02-11 13:54:22 +01001739 inputs.files files(inFile)
Ian Zerny74143162017-11-24 13:46:35 +01001740 outputs.file outFile
1741 if (OperatingSystem.current().isWindows()) {
1742 executable file("tools/windows/dx/bin/dx.bat")
1743 } else if (OperatingSystem.current().isMacOsX()) {
1744 executable file("tools/mac/dx/bin/dx");
1745 } else {
1746 executable file("tools/linux/dx/bin/dx");
1747 }
1748 args "--dex"
1749 args "--output=${outFile}"
1750 args inFile
1751}
1752
Ivan Gavrilovic635c7e52017-12-01 15:10:45 +00001753task getJarsFromSupportLibs(type: GetJarsFromConfiguration) {
1754 setConfiguration(configurations.supportLibs)
Yohann Roussel126f6872017-08-03 16:25:32 +02001755}
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001756
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001757task generateR8TestKeepRules {
1758 def path = "build/generated/r8tests-keep.txt"
1759 outputs.file path
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001760 dependsOn R8Lib
1761 doLast {
1762 file(path).write """-keep class ** { *; }
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001763-dontshrink
1764-dontoptimize
1765-keepattributes *
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001766-applymapping ${R8Lib.outputs.files[0]}.map
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001767"""
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001768 }
1769}
1770
1771task buildR8LibCfTestDeps(type: Exec) {
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001772 def outputPath = "build/libs/r8libtestdeps-cf.jar"
1773 dependsOn downloadDeps
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001774 dependsOn r8NoManifest
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001775 dependsOn R8Lib
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001776 dependsOn generateR8TestKeepRules
1777 dependsOn testJar
1778 // Take all .jar files as libraries and append the generated test classes in classes/java/test.
1779 def addedLibraries = sourceSets.test.runtimeClasspath.findAll { pkg ->
1780 return pkg.toString().endsWith(".jar")
1781 } + ["${buildDir}/classes/java/test"]
1782 inputs.files testJar.outputs.files +
1783 generateR8TestKeepRules.outputs.files +
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001784 R8Lib.outputs
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001785 commandLine = r8CfCommandLine(
1786 testJar.outputs.files[0],
1787 outputPath,
1788 [generateR8TestKeepRules.outputs.files[0]],
Morten Krogh-Jespersen47393d92020-05-01 12:39:38 +02001789 ["--debug", "--classpath", r8NoManifest.outputs.files[0]],
1790 r8NoManifest.outputs.files + addedLibraries)
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001791 workingDir = projectDir
1792 outputs.file outputPath
1793}
1794
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001795task configureTestForR8Lib(type: Copy) {
Morten Krogh-Jespersene28db462019-01-09 13:32:15 +01001796 dependsOn testJar
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02001797 inputs.files buildR8LibCfTestDeps.outputs
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001798 dependsOn R8Lib
1799 delete r8LibTestPath
1800 from zipTree(buildR8LibCfTestDeps.outputs.files[0])
1801 def examplesDir = file("build/test")
1802 examplesDir.eachDir { dir ->
1803 from ("${buildDir}/test/${dir.getName()}/classes")
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001804 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02001805 from ("${buildDir}/runtime/examples")
1806 into r8LibTestPath
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01001807 outputs.dir r8LibTestPath
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +01001808}
1809
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001810def shouldRetrace() {
1811 return project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')
1812}
1813
1814def retrace(Throwable exception) {
1815 def out = new StringBuffer()
1816 def err = new StringBuffer()
Ian Zerny99613a02022-02-23 11:50:13 +01001817 def command = "python3 tools/retrace.py --quiet"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001818 def header = "RETRACED STACKTRACE";
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001819 out.append("\n--------------------------------------\n")
1820 out.append("${header}\n")
1821 out.append("--------------------------------------\n")
1822 Process process = command.execute()
1823 def processIn = new PrintStream(process.getOut())
1824 process.consumeProcessOutput(out, err)
1825 exception.printStackTrace(processIn)
1826 processIn.flush()
1827 processIn.close()
1828 def errorDuringRetracing = process.waitFor() != 0
1829 if (errorDuringRetracing) {
1830 out.append("ERROR DURING RETRACING\n")
1831 out.append(err.toString())
1832 }
1833 if (project.hasProperty('print_obfuscated_stacktraces') || errorDuringRetracing) {
1834 out.append("\n\n--------------------------------------\n")
1835 out.append("OBFUSCATED STACKTRACE\n")
1836 out.append("--------------------------------------\n")
1837 }
1838 return out.toString()
1839}
1840
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001841def printStackTrace(TestResult result) {
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001842 filterStackTraces(result)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001843 if (shouldRetrace()) {
1844 def exception = new Exception(retrace(result.exception))
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001845 exception.setStackTrace([] as StackTraceElement[])
1846 result.exceptions.add(0, exception)
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01001847 }
1848}
1849
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001850def filterStackTraces(TestResult result) {
1851 for (Throwable throwable : result.getExceptions()) {
1852 filterStackTrace(throwable)
1853 }
1854}
1855
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001856// It would be nice to do this in a non-destructive way...
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +01001857def filterStackTrace(Throwable exception) {
1858 if (!project.hasProperty('print_full_stacktraces')) {
1859 def elements = []
1860 def skipped = []
1861 for (StackTraceElement element : exception.getStackTrace()) {
1862 if (element.toString().contains("com.android.tools.r8")) {
1863 elements.addAll(skipped)
1864 elements.add(element)
1865 skipped.clear()
1866 } else {
1867 skipped.add(element)
1868 }
1869 }
1870 exception.setStackTrace(elements as StackTraceElement[])
1871 }
1872}
1873
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001874def printAllStackTracesToFile(List<Throwable> exceptions, File out) {
1875 new PrintStream(new FileOutputStream(out)).withCloseable {printer ->
1876 exceptions.forEach { it.printStackTrace(printer) }
1877 }
1878}
1879
Ian Zerny89f16cf2021-04-29 21:10:09 +02001880static def escapeHtml(String string) {
1881 return string.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
1882}
1883
1884static def urlEncode(String string) {
1885 // Not sure why, but the + also needs to be converted to have working links.
1886 return URLEncoder.encode(string, "UTF-8").replace("+","%20")
1887}
1888
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001889def ensureDir(File dir) {
1890 dir.mkdirs()
1891 return dir
1892}
1893
Ian Zerny89f16cf2021-04-29 21:10:09 +02001894// Some of our test parameters have new lines :-( We really don't want test names to span lines.
1895static def sanitizedTestName(testDesc) {
1896 if (testDesc.getName().contains("\n")) {
1897 throw new RuntimeException("Unsupported use of newline in test name: '${testDesc.getName()}'")
1898 }
1899 return testDesc.getName()
1900}
1901
1902static def desanitizedTestName(testName) {
1903 return testName
1904}
1905
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001906def getTestReportEntryDir(reportDir, testDesc) {
1907 return ensureDir(reportDir.toPath()
1908 .resolve(testDesc.getClassName())
Ian Zerny89f16cf2021-04-29 21:10:09 +02001909 .resolve(sanitizedTestName(testDesc))
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001910 .toFile())
1911}
1912
Ian Zerny89f16cf2021-04-29 21:10:09 +02001913def getTestReportEntryURL(reportDir, testDesc) {
1914 def classDir = urlEncode(testDesc.getClassName())
1915 def testDir = urlEncode(sanitizedTestName(testDesc))
1916 return "file://${reportDir}/${classDir}/${testDir}"
1917}
1918
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001919def getTestResultEntryOutputFile(reportDir, testDesc, fileName) {
1920 def dir = getTestReportEntryDir(reportDir, testDesc).toPath()
1921 return dir.resolve(fileName).toFile()
1922}
1923
Ian Zerny89f16cf2021-04-29 21:10:09 +02001924def withTestResultEntryWriter(reportDir, testDesc, fileName, append, fn) {
1925 def file = getTestResultEntryOutputFile(reportDir, testDesc, fileName)
1926 new FileWriter(file, append).withCloseable fn
1927}
1928
Ian Zerny27ea4c72021-04-29 22:35:49 +02001929static def getGitBranchName() {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001930 def out = new StringBuilder()
1931 def err = new StringBuilder()
1932 def proc = "git rev-parse --abbrev-ref HEAD".execute()
1933 proc.waitForProcessOutput(out, err)
Ian Zerny27ea4c72021-04-29 22:35:49 +02001934 return out.toString().trim()
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001935}
1936
Ian Zerny27ea4c72021-04-29 22:35:49 +02001937static def getFreshTestReportIndex(File reportDir) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02001938 def number = 0
1939 while (true) {
1940 def freshIndex = reportDir.toPath().resolve("index.${number++}.html").toFile()
1941 if (!freshIndex.exists()) {
1942 return freshIndex
1943 }
1944 }
1945}
1946
1947def forEachTestReportAlreadyX(File reportDir, fileName, onTest) {
1948 def out = new StringBuilder()
1949 def err = new StringBuilder()
1950 def proc = "find . -name ${fileName}".execute([], reportDir)
1951 proc.waitForProcessOutput(out, err)
1952 def outString = out.toString()
1953 outString.eachLine {
1954 // Lines are of the form: ./<class>/<name>/FAILURE
1955 def clazz = null
1956 def name = null
1957 try {
1958 def trimmed = it.trim()
1959 def line = trimmed.substring(2)
1960 def sep = line.indexOf("/")
1961 clazz = line.substring(0, sep)
1962 name = line.substring(sep + 1, line.length() - fileName.length() - 1)
1963 } catch (Exception e) {
1964 logger.lifecycle("WARNING: failed attempt to read test description from: '${it}'")
1965 return
1966 }
1967 onTest(clazz, desanitizedTestName(name))
1968 }
1969 return !outString.trim().isEmpty()
1970}
1971
1972def forEachTestReportAlreadyFailing(File reportDir, onFailureTest) {
1973 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.FAILURE.name(), onFailureTest)
1974}
1975
1976def forEachTestReportAlreadyPassing(File reportDir, onSucceededTest) {
1977 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SUCCESS.name(), onSucceededTest)
1978}
1979
1980def forEachTestReportAlreadySkipped(File reportDir, onSucceededTest) {
1981 return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SKIPPED.name(), onSucceededTest)
1982}
1983
Ian Zerny27ea4c72021-04-29 22:35:49 +02001984def setUpTestingState(Test task) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02001985 // Hide all test events from the console, they are written to the report.
1986 task.testLogging { events = [] }
1987
Ian Zernycae764d2021-08-16 08:25:15 +02001988 def branch = project.hasProperty('testing-state-name')
1989 ? project.getProperty('testing-state-name')
1990 : getGitBranchName()
Ian Zerny27ea4c72021-04-29 22:35:49 +02001991 def reportDir = file("${buildDir}/test-state/${branch}")
Ian Zerny89f16cf2021-04-29 21:10:09 +02001992 def index = reportDir.toPath().resolve("index.html").toFile()
Ian Zerny27ea4c72021-04-29 22:35:49 +02001993 def resetState = project.hasProperty('reset-testing-state')
1994 def reportDirExists = reportDir.exists()
1995 def resuming = !resetState && reportDirExists
Ian Zerny89f16cf2021-04-29 21:10:09 +02001996
1997 def hasFailingTests = false;
1998 if (resuming) {
1999 // Test filtering happens before the test execution is initiated so compute it here.
2000 // If there are still failing tests in the report, include only those.
2001 hasFailingTests = forEachTestReportAlreadyFailing(reportDir, {
2002 clazz, name -> task.filter.includeTestsMatching("$clazz.$name")
2003 })
2004 // Otherwise exclude all of the test already marked as succeeding.
2005 if (!hasFailingTests) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002006 // Also allow the test to overall succeed if there are no remaining tests that match,
2007 // which is natural if the state already succeeded in full.
2008 task.filter.failOnNoMatchingTests = false
Ian Zerny89f16cf2021-04-29 21:10:09 +02002009 forEachTestReportAlreadyPassing(reportDir, {
2010 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2011 })
2012 forEachTestReportAlreadySkipped(reportDir, {
2013 clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
2014 })
2015 }
2016 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002017
2018 task.beforeSuite { desc ->
2019 if (!desc.parent) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002020 def parentReport = null
Ian Zerny27ea4c72021-04-29 22:35:49 +02002021 if (resetState && reportDirExists) {
2022 delete reportDir
2023 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002024 if (resuming) {
2025 if (index.exists()) {
2026 parentReport = getFreshTestReportIndex(reportDir)
2027 index.renameTo(parentReport)
2028 }
2029 } else {
2030 reportDir.mkdirs()
2031 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002032 def runPrefix = resuming ? "Resuming" : "Starting"
2033 def title = "${runPrefix} @ ${branch}"
2034 // Print a console link to the test report for easy access.
2035 println "${runPrefix} test, report written to:"
2036 println " file://${index}"
2037 // Print the new index content.
2038 index << "<html><head><title>${title}</title>"
2039 index << "<style> * { font-family: monospace; }</style>"
Morten Krogh-Jespersende7ddfa2021-09-03 12:37:32 +02002040 index << "<meta http-equiv='refresh' content='10' />"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002041 index << "</head><body><h1>${title}</h1>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002042 index << "<p>Run on: ${new Date()}</p>"
2043 index << "<p>Git branch: ${branch}</p>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002044 if (parentReport != null) {
2045 index << "<p><a href=\"file://${parentReport}\">Previous result index</a></p>"
2046 }
2047 index << "<p><a href=\"file://${index}\">Most recent result index</a></p>"
2048 index << "<p><a href=\"file://${reportDir}\">Test directories</a></p>"
Morten Krogh-Jespersende7ddfa2021-09-03 12:37:32 +02002049 index << "<h2>Failing tests (refreshing automatically every 10 seconds)</h2><ul>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002050 }
2051 }
2052
2053 task.afterSuite { desc, result ->
2054 if (!desc.parent) {
2055 // Update the final test results in the index.
2056 index << "</ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002057 if (result.resultType == TestResult.ResultType.SUCCESS) {
2058 if (hasFailingTests) {
2059 index << "<h2>Rerun of failed tests now pass!</h2>"
2060 index << "<h2>Rerun again to continue with outstanding tests!</h2>"
2061 } else {
2062 index << "<h2 style=\"background-color:#62D856\">GREEN BAR == YOU ROCK!</h2>"
2063 }
2064 } else if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny27ea4c72021-04-29 22:35:49 +02002065 index << "<h2 style=\"background-color:#6D130A\">Some tests failed: ${result.resultType.name()}</h2><ul>"
Ian Zerny89f16cf2021-04-29 21:10:09 +02002066 } else {
2067 index << "<h2>Tests finished: ${result.resultType.name()}</h2><ul>"
2068 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002069 index << "<li>Number of tests: ${result.testCount}"
2070 index << "<li>Failing tests: ${result.failedTestCount}"
2071 index << "<li>Successful tests: ${result.successfulTestCount}"
2072 index << "<li>Skipped tests: ${result.skippedTestCount}"
2073 index << "</ul></body></html>"
2074 }
2075 }
2076
2077 // Events to stdout/err are appended to the files in the test directories.
2078 task.onOutput { desc, event ->
Ian Zerny89f16cf2021-04-29 21:10:09 +02002079 withTestResultEntryWriter(reportDir, desc, event.getDestination().name(), true, {
2080 it.append(event.getMessage())
2081 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002082 }
2083
Ian Zerny27ea4c72021-04-29 22:35:49 +02002084 task.beforeTest { desc ->
2085 // Remove any stale output files before running the test.
2086 for (def destType : TestOutputEvent.Destination.values()) {
2087 def destFile = getTestResultEntryOutputFile(reportDir, desc, destType.name())
2088 if (destFile.exists()) {
2089 delete destFile
2090 }
2091 }
2092 }
2093
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002094 task.afterTest { desc, result ->
2095 if (result.getTestCount() != 1) {
2096 throw new IllegalStateException("Unexpected test with more than one result: ${desc}")
2097 }
Ian Zerny89f16cf2021-04-29 21:10:09 +02002098 // Clear any previous result files.
2099 for (def resultType : TestResult.ResultType.values()) {
2100 delete getTestResultEntryOutputFile(reportDir, desc, resultType.name())
2101 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002102 // Emit the result type status in a file of the same name: SUCCESS, FAILURE or SKIPPED.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002103 withTestResultEntryWriter(reportDir, desc, result.getResultType().name(), false, {
2104 it.append(result.getResultType().name())
2105 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002106 // Emit the test time.
Ian Zerny89f16cf2021-04-29 21:10:09 +02002107 withTestResultEntryWriter(reportDir, desc, "time", false, {
2108 it.append("${result.getEndTime() - result.getStartTime()}")
2109 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002110 // For failed tests, update the index and emit stack trace information.
2111 if (result.resultType == TestResult.ResultType.FAILURE) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002112 def title = escapeHtml("${desc.className}.${desc.name}")
2113 def link = getTestReportEntryURL(reportDir, desc)
2114 index << "<li><a href=\"${link}\">${title}</a></li>"
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002115 if (!result.exceptions.isEmpty()) {
2116 printAllStackTracesToFile(
2117 result.exceptions,
2118 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002119 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002120 desc,
2121 "exceptions-raw.txt"))
2122 filterStackTraces(result)
2123 printAllStackTracesToFile(
2124 result.exceptions,
2125 getTestResultEntryOutputFile(
Ian Zerny89f16cf2021-04-29 21:10:09 +02002126 reportDir,
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002127 desc,
2128 "exceptions-filtered.txt"))
2129 if (shouldRetrace()) {
Ian Zerny89f16cf2021-04-29 21:10:09 +02002130 withTestResultEntryWriter(reportDir, desc, "exceptions-retraced.txt", false, { writer ->
2131 result.exceptions.forEach { writer.append(retrace(it)) }
2132 })
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002133 }
2134 }
2135 }
2136 }
2137}
2138
Rico Windf2f4c292021-04-23 07:06:13 +02002139def testTimes = [:]
Ian Zerny475e4012021-04-29 14:01:49 +02002140def numberOfTestTimesToPrint = 100
Rico Windf2f4c292021-04-23 07:06:13 +02002141
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002142test { task ->
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002143
2144 dependsOn buildLibraryDesugarConversions
2145 dependsOn getJarsFromSupportLibs
2146 // R8.jar is required for running bootstrap tests.
2147 dependsOn r8
2148
Ian Zerny27ea4c72021-04-29 22:35:49 +02002149 def useTestingState = project.hasProperty('testing-state')
2150 if (useTestingState) {
2151 setUpTestingState(task)
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002152 }
2153
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +02002154 if (project.hasProperty('generate_golden_files_to')) {
2155 systemProperty 'generate_golden_files_to', project.property('generate_golden_files_to')
2156 assert project.hasProperty('HEAD_sha1')
2157 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2158 }
2159
2160 if (project.hasProperty('use_golden_files_in')) {
2161 systemProperty 'use_golden_files_in', project.property('use_golden_files_in')
2162 assert project.hasProperty('HEAD_sha1')
2163 systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
2164 }
Ian Zerny4b0de282019-06-28 09:32:24 +02002165
Morten Krogh-Jespersendcb967e2021-12-02 11:18:39 +01002166 if (project.hasProperty('kotlin_compiler_dev')) {
2167 systemProperty 'com.android.tools.r8.kotlincompilerdev', '1';
2168 }
2169
2170 if (project.hasProperty('kotlin_compiler_old')) {
2171 systemProperty 'com.android.tools.r8.kotlincompilerold', '1';
2172 }
Morten Krogh-Jespersen52a26852021-04-28 16:20:36 +02002173
Ian Zerny27ea4c72021-04-29 22:35:49 +02002174 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002175 testLogging.exceptionFormat = 'full'
2176 if (project.hasProperty('print_test_stdout')) {
2177 testLogging.showStandardStreams = true
2178 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002179 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002180 if (project.hasProperty('dex_vm') && project.property('dex_vm') != 'default') {
Ian Zerny324d7612019-03-20 10:52:28 +01002181 println "NOTE: Running with non default vm: " + project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002182 systemProperty 'dex_vm', project.property('dex_vm')
Mads Ager418d1ca2017-05-22 09:35:49 +02002183 }
Tamas Kenez0cad51c2017-08-21 14:42:01 +02002184
Ian Zerny324d7612019-03-20 10:52:28 +01002185 // Forward runtime configurations for test parameters.
2186 if (project.hasProperty('runtimes')) {
2187 println "NOTE: Running with runtimes: " + project.property('runtimes')
2188 systemProperty 'runtimes', project.property('runtimes')
Ian Zerny4dfd5a52019-03-12 07:56:11 +01002189 }
2190
Christoffer Quist Adamsen748e4662019-08-23 14:53:49 +02002191 if (project.hasProperty('slow_tests')) {
2192 systemProperty 'slow_tests', project.property('slow_tests')
2193 }
2194
Søren Gjesseef195772021-03-11 16:04:42 +01002195
2196 if (project.hasProperty('desugar_jdk_json_dir')) {
2197 systemProperty 'desugar_jdk_json_dir', project.property('desugar_jdk_json_dir')
2198 }
Søren Gjesse4a45f9b2021-02-11 14:05:29 +01002199 if (project.hasProperty('desugar_jdk_libs')) {
2200 systemProperty 'desugar_jdk_libs', project.property('desugar_jdk_libs')
2201 }
2202
Ian Zerny27ea4c72021-04-29 22:35:49 +02002203 if (!useTestingState) {
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002204 if (project.hasProperty('print_times') || project.hasProperty('one_line_per_test')) {
2205 afterTest { desc, result ->
2206 def executionTime = (result.endTime - result.startTime) / 1000
2207 testTimes["${desc.name} [${desc.className}]"] = executionTime
2208 }
2209 afterSuite { desc, result ->
2210 // parent is null if all tests are done.
2211 if (desc.parent == null) {
2212 def sortedTimes = testTimes.sort({ e1, e2 -> e2.value <=> e1.value })
2213 sortedTimes.eachWithIndex { key, value, i ->
2214 if (i < numberOfTestTimesToPrint) println "$key: $value"
2215 }
2216 }
2217 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002218 }
Rico Windf2f4c292021-04-23 07:06:13 +02002219
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002220 if (project.hasProperty('one_line_per_test')) {
2221 beforeTest { desc ->
2222 println "Start executing test ${desc.name} [${desc.className}]"
Rico Windf88b6be2018-12-11 15:14:05 +01002223 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002224
2225 afterTest { desc, result ->
2226 if (result.resultType == TestResult.ResultType.FAILURE) {
2227 printStackTrace(result)
2228 }
2229 if (project.hasProperty('update_test_timestamp')) {
2230 file(project.getProperty('update_test_timestamp')).text = new Date().getTime()
2231 }
2232 println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
Rico Windda6836e2018-12-07 12:32:03 +01002233 }
Ian Zerny9a0e96a2021-04-28 12:35:49 +02002234 } else {
2235 afterTest { desc, result ->
2236 if (result.resultType == TestResult.ResultType.FAILURE) {
2237 printStackTrace(result)
2238 }
Rico Windf88b6be2018-12-11 15:14:05 +01002239 }
2240 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002241 }
2242 if (project.hasProperty('no_internal')) {
2243 exclude "com/android/tools/r8/internal/**"
Christoffer Quist Adamsen74288f02019-06-14 12:30:17 +02002244 } else {
2245 dependsOn buildExamplesProto
Mads Ager418d1ca2017-05-22 09:35:49 +02002246 }
2247 if (project.hasProperty('only_internal')) {
2248 include "com/android/tools/r8/internal/**"
2249 }
Rico Wind4e218292019-03-07 12:44:49 +01002250
Rico Windba151112020-10-01 08:16:33 +02002251 if (project.hasProperty('test_namespace')) {
2252 include "com/android/tools/r8/" + project.getProperty('test_namespace') + "/**"
2253 }
2254
Ian Zerny3ced9262022-03-29 11:06:02 +02002255 if (project.hasProperty('tool') && project.property('tool') == 'd8') {
2256 // Don't run anything, deprecated
2257 println "Running with deprecated tool d8, not running any tests"
2258 include ""
Mads Ager418d1ca2017-05-22 09:35:49 +02002259 }
2260 if (!project.hasProperty('all_tests')) {
2261 exclude "com/android/tools/r8/art/dx/**"
Mads Ager418d1ca2017-05-22 09:35:49 +02002262 }
Rico Wind8e2f7e42019-02-21 10:13:21 +01002263 if (project.hasProperty('shard_count') ) {
2264 assert project.hasProperty('shard_number')
2265 int shard_count = project.getProperty('shard_count') as Integer
2266 int shard_number = project.getProperty('shard_number') as Integer
2267 assert shard_count < 65536
2268 assert shard_number < shard_count
2269 exclude {
2270 entry ->
2271 // Don't leave out directories. Leaving out a directory means all entries below.
2272 if (entry.file.isDirectory()) {
2273 return false
2274 }
2275 def first4 = entry.getRelativePath().toString().md5().substring(0, 4)
2276 int hash = Integer.parseInt(first4, 16)
2277 return hash % shard_count != shard_number
2278 }
2279 }
Tamas Kenezb77b7d82017-08-17 14:05:16 +02002280 if (project.hasProperty('test_dir')) {
2281 systemProperty 'test_dir', project.property('test_dir')
2282 }
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002283 if (project.hasProperty('r8lib')) {
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002284 dependsOn configureTestForR8Lib
Morten Krogh-Jespersendfa3f512020-04-23 09:34:40 +02002285 // R8lib should be used instead of the main output and all the tests in
2286 // r8 should be mapped and exists in r8LibTestPath.
Morten Krogh-Jespersenf0f528d2019-08-19 19:25:03 +02002287 classpath = sourceSets.test.runtimeClasspath.filter {
2288 !it.getAbsolutePath().contains("/build/")
2289 }
2290 classpath += files([r8LibPath, r8LibTestPath])
Ian Zerny5fffb0a2019-02-11 13:54:22 +01002291 testClassesDirs = files(r8LibTestPath)
Morten Krogh-Jespersen7df24322018-12-21 13:39:54 +01002292 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002293 if (OperatingSystem.current().isLinux()
2294 || OperatingSystem.current().isMacOsX()
2295 || OperatingSystem.current().isWindows()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002296 if (OperatingSystem.current().isMacOsX()) {
2297 logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " +
2298 "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " +
2299 "See tools/docker/README.md for details.")
2300 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002301 if (OperatingSystem.current().isWindows()) {
2302 logger.lifecycle("WARNING: Testing in only partially supported on Windows. " +
2303 "Art only runs on Linux and tests requiring Art will be skipped")
2304 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002305 dependsOn downloadDeps
2306 dependsOn buildExamples
Sebastien Hertzd3313772018-01-16 14:12:37 +01002307 dependsOn buildKotlinR8TestResources
Mads Ager418d1ca2017-05-22 09:35:49 +02002308 dependsOn buildSmali
Mads Ager418d1ca2017-05-22 09:35:49 +02002309 dependsOn buildPreNJdwpTestsJar
Mathias Ravcd795072018-03-22 12:47:32 +01002310 dependsOn buildPreNJdwpTestsDex
Clément Bérac94b6202021-09-28 11:16:58 +00002311 dependsOn compileTestNGRunner
clementberaa92e3cd2019-07-12 14:13:22 +02002312 dependsOn provideArtFrameworksDependencies
Mads Ager418d1ca2017-05-22 09:35:49 +02002313 } else {
2314 logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +02002315 "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.")
Mads Ager418d1ca2017-05-22 09:35:49 +02002316 }
2317}
2318
2319// The Art tests we use for R8 are pre-build and downloaded from Google Cloud Storage.
2320//
2321// To build and upload a new set of the Art tests for use with R8 follow these steps:
2322//
2323// First of all an Android checkout is required. Currently it must be located
2324// in $HOME/android/master.
2325//
2326// TODO(ricow): simplify this
2327//
2328// Before: update the checked in art, see scripts/update-host-art.sh
2329//
2330// 1. Get an android checkout in $HOME/android/master and apply the patch from
2331// https://android-review.googlesource.com/#/c/294187/
2332//
2333// 2. run the following commands in the Android checkout directory:
2334//
2335// source build/envsetup.sh
Søren Gjesse34b77732017-07-07 13:56:21 +02002336// lunch aosp_angler-userdebug # or lunch aosp_angler-eng
2337// m desugar
2338// m -j30 test-art-host
2339// DESUGAR=false ANDROID_COMPILE_WITH_JACK=false art/test.py --host -t 001-HelloWorld
2340//
2341// Without running the test.py command the classes.jar file used by desugar in
2342// $HOME/android/master/out/host/common/obj/JAVA_LIBRARIES/core-oj-hostdex_intermediates/
2343// seems to be missing - there is probably also a make target to build it more directly
Mads Ager418d1ca2017-05-22 09:35:49 +02002344//
2345// 3. In the R8 project root directory, make sure we have a clean state before starting:
2346// tools/gradle.py downloadDeps
2347// tools/gradle.py clean
2348// rm -rf tests/art
2349//
2350// 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 +02002351// Make sure you have smali on your path, please use the build binary in the
2352// out/host/linux-x86/bin directory of the android checkout. Currently this is version pre 2.2.1,
2353// if that is updated the call to smali in "task "${smaliToDexTask}"(type: Exec)" below might
2354// 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 +02002355// After Android O, Jack is no longer alive, do not forget to uncomment call to buildArtTest for
2356// Jack if you build an android version using Jack.
Mads Ager418d1ca2017-05-22 09:35:49 +02002357//
Søren Gjesse34b77732017-07-07 13:56:21 +02002358// PATH=$HOME/android/master/out/host/linux-x86/bin:$PATH tools/gradle.py -Pandroid_source buildArtTests
Mads Ager418d1ca2017-05-22 09:35:49 +02002359//
2360// 4a. If any failures are produced in step 4, figure out what went wrong and add an entry in
2361// skippedTests with an explanation. Rerun from step 3.
2362//
2363// 5. Run the tests:
2364// tools/gradle.py clean
2365// tools/test.py
2366//
Søren Gjesse34b77732017-07-07 13:56:21 +02002367// 5a. If any more tests fail, either fix the issue or add them to the failuresToTriage list (note
2368// that you need to change "_" to "-" from stdout). Rerun from step 5 if anything was added to
2369// failuresToTriage.
Mads Ager418d1ca2017-05-22 09:35:49 +02002370//
Søren Gjesse34b77732017-07-07 13:56:21 +02002371// 6. To upload a new version to Google Cloud Storage:
Mads Ager418d1ca2017-05-22 09:35:49 +02002372// cd tests
2373// upload_to_google_storage.py -a --bucket r8-deps art
Søren Gjesse34b77732017-07-07 13:56:21 +02002374//
2375// 7. Update the manifest file describing the Android repo used:
2376// repo manifest -o <r8-checkout-root>/tools/linux/aosp_master_manifest.xml -r
Mads Ager418d1ca2017-05-22 09:35:49 +02002377
Mads Ager418d1ca2017-05-22 09:35:49 +02002378def androidCheckoutDir = file("${System.env.HOME}/android/master")
Mads Ager418d1ca2017-05-22 09:35:49 +02002379
2380def artTestDir = file("${androidCheckoutDir}/art/test")
2381
2382if (project.hasProperty('android_source')) {
2383 task buildArtTests {
2384 outputs.upToDateWhen { false }
2385 def toBeTriaged = [
2386 "903-hello-tagging",
2387 "904-object-allocation",
2388 "905-object-free",
2389 "906-iterate-heap",
2390 "907-get-loaded-classes",
2391 "908-gc-start-finish",
2392 "954-invoke-polymorphic-verifier",
2393 "955-methodhandles-smali",
2394 "596-monitor-inflation",
2395 ]
2396 def skippedTests = toBeTriaged + [
2397 // This test produces no jar.
2398 "000-nop",
2399 // This does not build, as it tests the error when the application exceeds more
2400 // than 65536 methods
2401 "089-many-methods",
2402 // Requires some jack beta jar
2403 "956-methodhandles",
2404 ]
2405
2406 def skippedTestsDx = [
2407 // Tests with custom build scripts, where javac is not passed the options
2408 // -source 1.7 -target 1.7.
2409 "462-checker-inlining-across-dex-files",
2410 "556-invoke-super",
2411 "569-checker-pattern-replacement",
2412 // These tests use jack even when --build-with-javac-dx is specified.
2413 "004-JniTest",
2414 "048-reflect-v8",
2415 "146-bad-interface",
2416 "563-checker-invoke-super",
2417 "580-checker-string-fact-intrinsics", // java.lang.StringFactory
2418 "604-hot-static-interface",
2419 "957-methodhandle-transforms",
2420 "958-methodhandle-emulated-stackframe",
2421 "959-invoke-polymorphic-accessors",
2422 "961-default-iface-resolution-gen",
2423 "962-iface-static",
2424 "963-default-range-smali",
2425 "964-default-iface-init-gen",
2426 "965-default-verify",
2427 "966-default-conflict",
2428 "967-default-ame",
2429 "968-default-partial-compile-gen",
2430 "969-iface-super",
2431 "970-iface-super-resolution-gen",
2432 "971-iface-super",
2433 // These tests does not build with --build-with-javac-dx
2434 "004-NativeAllocations", // Javac error
2435 "031-class-attributes",
2436 "138-duplicate-classes-check",
2437 "157-void-class", // Javac error
2438 "580-checker-string-factory-intrinsics",
2439 "612-jit-dex-cache",
2440 "613-inlining-dex-cache",
2441 "900-hello-plugin", // --experimental agents
2442 "901-hello-ti-agent", // --experimental agents
2443 "902-hello-transformation", // --experimental agents
2444 "909-attach-agent", // --experimental agents
2445 "946-obsolete-throw", // -source 1.7 -target 1.7, but use lambda
2446 "950-redefine-intrinsic", // -source 1.7 -target 1.7, but use method references
2447 "951-threaded-obsolete", // -source 1.7 -target 1.7, but use lambda
2448 "960-default-smali", // --experimental default-methods
2449 // These tests force the build to use jack
2450 "953-invoke-polymorphic-compiler",
2451 "958-methodhandle-stackframe",
2452 ]
2453
2454 def artTestBuildDir = file("${projectDir}/tests/art")
2455
2456 if (androidCheckoutDir.exists()) {
2457 dependsOn downloadDeps
2458 artTestBuildDir.mkdirs()
Mads Ager418d1ca2017-05-22 09:35:49 +02002459 artTestDir.eachDir { dir ->
2460 def name = dir.getName();
2461 def markerFile = dir.toPath().resolve("info.txt").toFile();
2462 if (markerFile.exists() && !(name in skippedTests)) {
2463 if (!(name in skippedTestsDx)) {
Rico Windde2af6c2019-03-26 15:21:08 +01002464 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir);
Mads Ager418d1ca2017-05-22 09:35:49 +02002465 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002466 }
2467 }
2468 }
2469 doFirst {
2470 if (!androidCheckoutDir.exists()) {
2471 throw new InvalidUserDataException(
2472 "This task requires an Android checkout in ${androidCheckoutDir}");
Mads Ager418d1ca2017-05-22 09:35:49 +02002473 }
2474 }
2475 doLast {
2476 copy {
2477 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest64")
2478 into file("${artTestBuildDir}/lib64")
2479 include 'lib*.so'
2480 }
2481 copy {
2482 from file("${androidCheckoutDir}/out/host/linux-x86/lib64")
2483 into file("${artTestBuildDir}/lib64")
2484 include 'libart.so'
2485 include 'libbacktrace.so'
2486 include 'libbase.so'
2487 include 'libc++.so'
2488 include 'libcutils.so'
2489 include 'liblz4.so'
2490 include 'liblzma.so'
2491 include 'libnativebridge.so'
2492 include 'libnativeloader.so'
2493 include 'libsigchain.so'
2494 include 'libunwind.so'
2495 include 'libziparchive.so'
2496 }
2497 copy {
2498 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest")
2499 into file("${artTestBuildDir}/lib")
2500 include 'lib*.so'
2501 }
2502 copy {
2503 from file("${androidCheckoutDir}/out/host/linux-x86/lib")
2504 into file("${artTestBuildDir}/lib")
2505 include 'libart.so'
2506 include 'libbacktrace.so'
2507 include 'libbase.so'
2508 include 'libc++.so'
2509 include 'libcutils.so'
2510 include 'liblz4.so'
2511 include 'liblzma.so'
2512 include 'libnativebridge.so'
2513 include 'libnativeloader.so'
2514 include 'libsigchain.so'
2515 include 'libunwind.so'
2516 include 'libziparchive.so'
2517 }
2518 }
2519 }
2520}
2521
Rico Windde2af6c2019-03-26 15:21:08 +01002522def buildArtTest(androidCheckoutDir, artTestBuildDir, dir) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002523 def artTestDir = file("${androidCheckoutDir}/art/test")
2524 def artRunTestScript = file("${artTestDir}/run-test")
2525 def dxExecutable = new File("tools/linux/dx/bin/dx");
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02002526 def dexMergerExecutable = Utils.dexMergerExecutable()
Mads Ager418d1ca2017-05-22 09:35:49 +02002527
Søren Gjesse34b77732017-07-07 13:56:21 +02002528 def name = dir.getName()
Rico Windde2af6c2019-03-26 15:21:08 +01002529 def buildTask = "build_art_test_dx_${name}"
2530 def sanitizeTask = "sanitize_art_test_dx_${name}"
2531 def copyCheckTask = "copy_check_art_test_dx_${name}"
2532 def smaliToDexTask = "smali_to_dex_dx_${name}"
Mads Ager418d1ca2017-05-22 09:35:49 +02002533
2534 def buildInputs = fileTree(dir: dir, include: '**/*')
Rico Windde2af6c2019-03-26 15:21:08 +01002535 def testDir = file("${artTestBuildDir}/dx/${name}")
Mads Ager418d1ca2017-05-22 09:35:49 +02002536 def outputJar = testDir.toPath().resolve("${name}.jar").toFile()
2537 testDir.mkdirs()
Rico Windde2af6c2019-03-26 15:21:08 +01002538 task "$buildTask"(type: Exec) {
2539 outputs.upToDateWhen { false }
2540 inputs.file buildInputs
2541 executable "${artRunTestScript}"
2542 args "--host"
2543 args "--build-only"
2544 args "--build-with-javac-dx"
2545 args "--output-path", "${testDir}"
2546 args "${name}"
2547 environment DX: "${dxExecutable.absolutePath}"
2548 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
2549 environment ANDROID_BUILD_TOP: "${androidCheckoutDir}"
2550 outputs.file outputJar
Mads Ager418d1ca2017-05-22 09:35:49 +02002551 }
2552 task "${sanitizeTask}"(type: Exec, dependsOn: buildTask) {
2553 outputs.upToDateWhen { false }
2554 executable "/bin/bash"
2555 args "-c"
2556 args "rm -rf ${testDir}/smali_*.dex ${testDir}/*-ex.dex ${testDir}/*-ex.jar" +
2557 " ${testDir}/classes-ex ${testDir}/check"
2558 }
2559
2560 task "${smaliToDexTask}"(type: Exec) {
Mikaël Peltiere116cb62017-10-05 10:50:30 +02002561 // Directory that contains smali files is either smali, or smali/art
2562 def smali_dir = file("${dir}/smali/art")
2563 if (smali_dir.exists()) {
2564 workingDir "${testDir}/smali/art"
2565 } else {
2566 workingDir "${testDir}/smali"
2567 }
Mads Ager418d1ca2017-05-22 09:35:49 +02002568 executable "/bin/bash"
Søren Gjesse34b77732017-07-07 13:56:21 +02002569 // This is the command line options for smali prior to 2.2.1, where smali got a new
2570 // command line interface.
2571 args "-c", "smali a *.smali"
2572 // This is the command line options for smali 2.2.1 and later.
2573 // args "-c", "smali -o out.dex *.smali"
Mads Ager418d1ca2017-05-22 09:35:49 +02002574 }
2575
2576 task "${copyCheckTask}"(type: Copy, dependsOn: sanitizeTask) {
2577 def smali_dir = file("${dir}/smali")
2578 outputs.upToDateWhen { false }
Rico Windde2af6c2019-03-26 15:21:08 +01002579 if (smali_dir.exists()) {
Mads Ager418d1ca2017-05-22 09:35:49 +02002580 dependsOn smaliToDexTask
2581 }
2582 from("${artTestDir}/${name}") {
2583 include 'check'
2584 }
2585 into testDir
2586 }
2587
2588 return copyCheckTask
2589}
2590
2591task javadocD8(type: Javadoc) {
Ian Zerny850f13d2018-01-04 11:25:38 +01002592 title "D8 API"
Mads Ager418d1ca2017-05-22 09:35:49 +02002593 classpath = sourceSets.main.compileClasspath
2594 source = sourceSets.main.allJava
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002595 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002596 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002597 include '**/com/android/tools/r8/BaseCommand.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002598 include '**/com/android/tools/r8/BaseCompilerCommand.java'
Yohann Rousselb16d0f62017-10-09 16:08:09 +02002599 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002600 include '**/com/android/tools/r8/CompilationFailedException.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002601 include '**/com/android/tools/r8/CompilationMode.java'
2602 include '**/com/android/tools/r8/D8.java'
2603 include '**/com/android/tools/r8/D8Command.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002604 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2605 include '**/com/android/tools/r8/DexFilePerClassFileConsumer.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002606 include '**/com/android/tools/r8/Diagnostic.java'
2607 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002608 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2609 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002610 include '**/com/android/tools/r8/ProgramConsumer.java'
2611 include '**/com/android/tools/r8/ProgramResource.java'
2612 include '**/com/android/tools/r8/ProgramResourceProvider.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002613 include '**/com/android/tools/r8/Resource.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002614 include '**/com/android/tools/r8/ResourceException.java'
2615 include '**/com/android/tools/r8/StringConsumer.java'
2616 include '**/com/android/tools/r8/StringResource.java'
2617 include '**/com/android/tools/r8/Version.java'
2618 include '**/com/android/tools/r8/origin/*.java'
2619}
2620
2621task javadocR8(type: Javadoc) {
2622 title "R8 API"
2623 classpath = sourceSets.main.compileClasspath
2624 source = sourceSets.main.allJava
2625 include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
2626 include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
2627 include '**/com/android/tools/r8/BaseCommand.java'
2628 include '**/com/android/tools/r8/BaseCompilerCommand.java'
2629 include '**/com/android/tools/r8/ClassFileConsumer.java'
2630 include '**/com/android/tools/r8/ClassFileResourceProvider.java'
2631 include '**/com/android/tools/r8/CompilationFailedException.java'
2632 include '**/com/android/tools/r8/CompilationMode.java'
2633 include '**/com/android/tools/r8/R8.java'
2634 include '**/com/android/tools/r8/R8Command.java'
2635 include '**/com/android/tools/r8/DexIndexedConsumer.java'
2636 include '**/com/android/tools/r8/Diagnostic.java'
2637 include '**/com/android/tools/r8/DiagnosticsHandler.java'
Ian Zernyef028f52018-01-08 14:23:17 +01002638 include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
2639 include '**/com/android/tools/r8/OutputMode.java'
Ian Zerny850f13d2018-01-04 11:25:38 +01002640 include '**/com/android/tools/r8/ProgramConsumer.java'
2641 include '**/com/android/tools/r8/ProgramResource.java'
2642 include '**/com/android/tools/r8/ProgramResourceProvider.java'
2643 include '**/com/android/tools/r8/Resource.java'
2644 include '**/com/android/tools/r8/ResourceException.java'
2645 include '**/com/android/tools/r8/StringConsumer.java'
2646 include '**/com/android/tools/r8/StringResource.java'
2647 include '**/com/android/tools/r8/Version.java'
Yohann Roussel078c9942017-11-28 15:55:46 +01002648 include '**/com/android/tools/r8/origin/*.java'
Mads Ager418d1ca2017-05-22 09:35:49 +02002649}
Søren Gjesse39a909a2017-10-12 09:49:20 +02002650
2651task copyMavenDeps(type: Copy) {
2652 from configurations.compile into "$buildDir/deps"
Morten Krogh-Jespersen75773302019-01-07 09:45:08 +01002653 from configurations.compileClasspath into "$buildDir/deps"
Søren Gjesse39a909a2017-10-12 09:49:20 +02002654 from configurations.testCompile into "$buildDir/deps"
2655}
Mikaël Peltier61633d42017-10-13 16:51:06 +02002656
Rico Wind23a05112019-03-27 08:00:44 +01002657task printMavenDeps {
2658 // Only actually print to stdout when we are updating.
2659 if (project.hasProperty('updatemavendeps')) {
2660 for (Configuration config : configurations) {
2661 if (!config.isCanBeResolved()) {
2662 continue
2663 }
2664 def componentIds = config.incoming.resolutionResult.allDependencies.collect {
2665 it.selected.id
2666 }
2667 def result = dependencies.createArtifactResolutionQuery()
2668 .forComponents(componentIds)
2669 .withArtifacts(MavenModule, MavenPomArtifact)
2670 .execute()
2671 for (component in result.resolvedComponents) {
2672 component.getArtifacts(MavenPomArtifact).each {
2673 println "POM: ${it.file} ${component.id}"
2674 }
2675 }
2676 config.each {
2677 println "JAR: ${it}"
2678 }
2679 }
2680 }
2681}
Ian Zerny9713c032020-01-23 11:41:58 +01002682
2683allprojects {
2684 tasks.withType(Exec) {
2685 doFirst {
Ian Zerny9794cfd2020-02-04 07:57:35 +01002686 println commandLine.join(' ')
Ian Zerny9713c032020-01-23 11:41:58 +01002687 }
2688 }
Søren Gjesse494609e2020-05-29 15:35:12 +02002689}