blob: dfb4623ceb508ecef5d96bc6eb11327a0bca66a4 [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.
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +02004import org.gradle.internal.os.OperatingSystem
5import utils.Utils;
Mads Ager418d1ca2017-05-22 09:35:49 +02006
7apply plugin: 'java'
8apply plugin: 'idea'
9apply plugin: 'jacoco'
10
11apply from: 'copyAdditionalJctfCommonFiles.gradle'
12
13repositories {
14 mavenCentral()
15}
16
17// Custom source set for example tests and generated tests.
18sourceSets {
19 test {
20 java {
21 srcDirs = [
22 'src/test/java',
23 'build/generated/test/java',
24 ]
25 }
26 }
27 debugTestResources {
28 java {
29 srcDirs = ['src/test/debugTestResources']
30 }
31 output.resourcesDir = 'build/classes/debugTestResources'
32 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +020033 debugTestResourcesJava8 {
34 java {
35 srcDirs = ['src/test/debugTestResourcesJava8']
36 }
37 output.resourcesDir = 'build/classes/debugTestResourcesJava8'
38 }
Mads Ager418d1ca2017-05-22 09:35:49 +020039 examples {
40 java {
41 srcDirs = ['src/test/examples']
42 }
43 output.resourcesDir = 'build/classes/examples'
44 }
45 examplesAndroidN {
46 java {
47 srcDirs = ['src/test/examplesAndroidN']
48 }
49 output.resourcesDir = 'build/classes/examplesAndroidN'
50 }
51 examplesAndroidO {
52 java {
53 srcDirs = ['src/test/examplesAndroidO']
54 }
55 output.resourcesDir = 'build/classes/examplesAndroidO'
56 }
57 jctfCommon {
58 java {
59 srcDirs = [
60 'third_party/jctf/Harness/src',
61 'third_party/jctf/LibTests/src/com/google/jctf/test/categories',
62 'third_party/jctf/LibTests/src/com/google/jctf/test/helper',
63 'third_party/jctf/LibTests/src/com/google/jctf/testHelpers',
64 'third_party/jctf/LibTests/src/org',
65 'build/additionalJctfCommonFiles'
66 ]
67 }
68 resources {
69 srcDirs = ['third_party/jctf/LibTests/resources']
70 }
71 }
72 jctfTests {
73 java {
74 srcDirs = [
75 'third_party/jctf/LibTests/src/com/google/jctf/test/lib',
76 // 'third_party/jctf/VMTests/src',
77 ]
78 }
79 }
80}
81
82dependencies {
83 compile 'net.sf.jopt-simple:jopt-simple:4.6'
84 compile group: 'com.google.guava', name: 'guava', version: '19.0'
Stephan Herhutb17bb8d2017-05-23 12:34:55 +020085 compile group: 'it.unimi.dsi', name: 'fastutil', version: '7.2.0'
Mads Ager418d1ca2017-05-22 09:35:49 +020086 compile group: 'org.apache.commons', name: 'commons-compress', version: '1.12'
87 compile group: 'org.ow2.asm', name: 'asm', version: '5.1'
88 compile group: 'org.ow2.asm', name: 'asm-commons', version: '5.1'
89 compile group: 'org.ow2.asm', name: 'asm-tree', version: '5.1'
90 compile group: 'org.ow2.asm', name: 'asm-util', version: '5.1'
91 testCompile sourceSets.examples.output
92 testCompile 'junit:junit:4.12'
93 testCompile group: 'org.smali', name: 'smali', version: '2.2b4'
94 testCompile files('third_party/jasmin/jasmin-2.4.jar')
95 testCompile files('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
96 jctfCommonCompile 'junit:junit:4.12'
97 jctfTestsCompile 'junit:junit:4.12'
98 jctfTestsCompile sourceSets.jctfCommon.output
99 examplesAndroidOCompile group: 'org.ow2.asm', name: 'asm', version: '5.1'
100}
101
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200102def osString = OperatingSystem.current().isLinux() ? "linux" :
103 OperatingSystem.current().isMacOsX() ? "mac" : "windows"
Mads Ager418d1ca2017-05-22 09:35:49 +0200104
105def cloudDependencies = [
106 "tests" : [
107 "art.tar.gz"
108 ],
109 "third_party": [
110 "android_jar/lib-v14.tar.gz",
111 "android_jar/lib-v19.tar.gz",
112 "android_jar/lib-v24.tar.gz",
113 "android_jar/lib-v25.tar.gz",
114 "android_jar/lib-v26.tar.gz",
115 "proguard/proguard5.2.1.tar.gz",
116 "gradle/gradle.tar.gz",
117 "jdwp-tests.tar.gz",
118 "jasmin.tar.gz",
119 "jctf.tar.gz",
120 "android_cts_baseline.tar.gz",
121 ],
122 // All dex-vms have a fixed OS of Linux, as they are only supported on Linux, and will be run in a Docker
123 // container on other platforms where supported.
124 "tools" : [
125 "linux/art.tar.gz",
126 "linux/art-5.1.1.tar.gz",
127 "linux/art-6.0.1.tar.gz",
128 "linux/art-7.0.0.tar.gz",
129 "linux/dalvik.tar.gz",
130 "${osString}/dx.tar.gz",
131 ]
132]
133
134cloudDependencies.each { entry ->
135 entry.value.each { entryFile ->
136 task "download_deps_${entry.key}/${entryFile}"(type: Exec) {
137 def gzFile = "${entry.key}/${entryFile}"
138 def sha1File = "${gzFile}.sha1"
139 inputs.file sha1File
140 outputs.file gzFile
Jean-Marie Henaff872e4422017-06-13 10:26:20 +0200141 List<String> dlFromStorageArgs = ["-n", "-b", "r8-deps", "-u", "-s", "${sha1File}"]
142 if (OperatingSystem.current().isWindows()) {
143 executable "download_from_google_storage.bat"
144 args dlFromStorageArgs
145 } else {
146 executable "bash"
147 args "-c", "download_from_google_storage " + String.join(" ", dlFromStorageArgs)
148 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200149 }
150 }
151}
152
153def x20Dependencies = [
154 "third_party": [
Søren Gjesse5ecb04a2017-06-13 09:44:32 +0200155 "gmail/gmail_android_170604.16.tar.gz",
Mads Ager418d1ca2017-05-22 09:35:49 +0200156 "gmscore/v4.tar.gz",
157 "gmscore/v5.tar.gz",
158 "gmscore/v6.tar.gz",
159 "gmscore/v7.tar.gz",
160 "gmscore/v8.tar.gz",
161 "gmscore/gmscore_v9.tar.gz",
162 "gmscore/gmscore_v10.tar.gz",
Stephan Herhut4e743302017-06-09 13:09:03 +0200163 "gmscore/latest.tar.gz",
Mads Agerae646402017-06-07 13:32:43 +0200164 "photos/2017-06-06.tar.gz",
Mads Ager418d1ca2017-05-22 09:35:49 +0200165 "youtube/youtube.android_12.10.tar.gz",
Søren Gjessefeac2ef2017-05-22 17:09:29 +0200166 "youtube/youtube.android_12.17.tar.gz",
Søren Gjesse9be84982017-06-09 14:21:03 +0200167 "youtube/youtube.android_12.22.tar.gz",
Mads Ager418d1ca2017-05-22 09:35:49 +0200168 "proguardsettings.tar.gz",
Tamas Kenez5febf242017-06-20 16:00:44 +0200169 "proguard/proguard_internal_159423826.tar.gz",
Mads Ager418d1ca2017-05-22 09:35:49 +0200170 ],
171]
172
173x20Dependencies.each { entry ->
174 entry.value.each { entryFile ->
175 task "download_deps_${entry.key}/${entryFile}"(type: Exec) {
176 def gzFile = "${entry.key}/${entryFile}"
177 def sha1File = "${gzFile}.sha1"
178 inputs.file sha1File
179 outputs.file gzFile
180 executable "bash"
181 args "-c", "tools/download_from_x20.py ${sha1File}"
182 }
183 }
184}
185
Rico Wind897bb712017-05-23 10:44:29 +0200186task downloadProguard {
187 cloudDependencies.each { entry ->
188 entry.value.each { entryFile ->
189 if (entryFile.contains("proguard")) {
190 dependsOn "download_deps_${entry.key}/${entryFile}"
191 }
192 }
193 }
194}
195
Tamas Kenez0e10c562017-06-08 10:00:34 +0200196task downloadAndroidCts {
197 cloudDependencies.each { entry ->
198 entry.value.each { entryFile ->
199 if (entryFile.contains("android_cts_baseline")) {
200 dependsOn "download_deps_${entry.key}/${entryFile}"
201 }
202 }
203 }
204}
205
Mads Ager418d1ca2017-05-22 09:35:49 +0200206task downloadDeps {
207 cloudDependencies.each { entry ->
208 entry.value.each { entryFile ->
209 dependsOn "download_deps_${entry.key}/${entryFile}"
210 }
211 }
212 if (!project.hasProperty('no_internal')) {
213 x20Dependencies.each { entry ->
214 entry.value.each { entryFile ->
215 dependsOn "download_deps_${entry.key}/${entryFile}"
216 }
217 }
218 }
219}
220
221allprojects {
222 sourceCompatibility = JavaVersion.VERSION_1_8
223 targetCompatibility = JavaVersion.VERSION_1_8
224}
225
226tasks.withType(JavaCompile) {
227 options.compilerArgs << '-Xlint:unchecked'
228}
229
230compileJctfCommonJava {
231 dependsOn 'copyAdditionalJctfCommonFiles'
232 options.compilerArgs = ['-Xlint:none']
233}
234
235compileJctfTestsJava {
236 dependsOn 'jctfCommonClasses'
237 options.compilerArgs = ['-Xlint:none']
238}
239
240task R8(type: Jar) {
241 from sourceSets.main.output
242 baseName 'r8'
243 manifest {
244 attributes 'Main-Class': 'com.android.tools.r8.R8'
245 }
246 // In order to build without dependencies, pass the exclude_deps property using:
247 // gradle -Pexclude_deps R8
248 if (!project.hasProperty('exclude_deps')) {
249 // Also include dependencies
250 from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
251 }
252}
253
254task D8(type: Jar) {
255 from sourceSets.main.output
256 baseName 'd8'
257 manifest {
258 attributes 'Main-Class': 'com.android.tools.r8.D8'
259 }
260 // In order to build without dependencies, pass the exclude_deps property using:
261 // gradle -Pexclude_deps D8
262 if (!project.hasProperty('exclude_deps')) {
263 // Also include dependencies
264 from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
265 }
266}
267
268task CompatDx(type: Jar) {
269 from sourceSets.main.output
270 baseName 'compatdx'
271 manifest {
272 attributes 'Main-Class': 'com.android.tools.r8.compatdx.CompatDx'
273 }
274 // In order to build without dependencies, pass the exclude_deps property using:
275 // gradle -Pexclude_deps CompatDx
276 if (!project.hasProperty('exclude_deps')) {
277 // Also include dependencies
278 from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
279 }
280}
281
Tamas Kenez971eec62017-05-24 11:08:40 +0200282task D8Logger(type: Jar) {
283 from sourceSets.main.output
284 baseName 'd8logger'
285 manifest {
286 attributes 'Main-Class': 'com.android.tools.r8.D8Logger'
287 }
288 // In order to build without dependencies, pass the exclude_deps property using:
289 // gradle -Pexclude_deps D8Logger
290 if (!project.hasProperty('exclude_deps')) {
291 // Also include dependencies
292 from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
293 }
294}
295
Mads Ager418d1ca2017-05-22 09:35:49 +0200296task disasm(type: Jar) {
297 from sourceSets.main.output
298 baseName 'disasm'
299 manifest {
300 attributes 'Main-Class': 'com.android.tools.r8.Disassemble'
301 }
302 // In order to build without dependencies, pass the exclude_deps property using:
303 // gradle -Pexclude_deps D8
304 if (!project.hasProperty('exclude_deps')) {
305 // Also include dependencies
306 from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
307 }
308}
309
310task bisect(type: Jar) {
311 from sourceSets.main.output
312 baseName 'bisect'
313 manifest {
314 attributes 'Main-Class': 'com.android.tools.r8.bisect.Bisect'
315 }
316 // In order to build without dependencies, pass the exclude_deps property using:
317 // gradle -Pexclude_deps R8
318 if (!project.hasProperty('exclude_deps')) {
319 // Also include dependencies
320 from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
321 }
322}
323
324task sourceJar(type: Jar, dependsOn: classes) {
325 classifier = 'src'
326 from sourceSets.main.allSource
327}
328
329task jctfCommonJar(type: Jar) {
330 from sourceSets.jctfCommon.output
331 baseName 'jctfCommon'
332}
333
334artifacts {
335 archives sourceJar
336}
337
338task createArtTests(type: Exec) {
339 def outputDir = "build/generated/test/java/com/android/tools/r8/art"
Mads Ager7e5bd722017-05-24 07:17:27 +0200340 def createArtTestsScript = "tools/create_art_tests.py"
Mads Ager418d1ca2017-05-22 09:35:49 +0200341 inputs.file "tests/art.tar.gz"
342 inputs.file createArtTestsScript
343 outputs.dir outputDir
344 dependsOn downloadDeps
Mads Ager677e3002017-05-24 07:54:51 +0200345 commandLine "python", createArtTestsScript
Mads Ager418d1ca2017-05-22 09:35:49 +0200346 workingDir = projectDir
347}
348
349task createJctfTests(type: Exec) {
Stephan Herhutea6ee582017-05-23 13:14:34 +0200350 def outputDir = "build/generated/test/java/com/android/tools/r8/jctf"
Tamas Kenez25a99e92017-05-29 10:15:30 +0200351 def script = "tools/create_jctf_tests.py"
Mads Ager418d1ca2017-05-22 09:35:49 +0200352 inputs.file script
353 outputs.dir outputDir
354 dependsOn downloadDeps
Tamas Kenez25a99e92017-05-29 10:15:30 +0200355 commandLine "python", script
Mads Ager418d1ca2017-05-22 09:35:49 +0200356 workingDir = projectDir
357}
358
359compileTestJava {
360 dependsOn createArtTests
361 dependsOn createJctfTests
362}
363
364task buildDebugInfoExamplesDex {
365 def examplesDir = file("src/test/java")
366 def hostJar = "debuginfo_examples.jar"
367 def hostDexJar = "debuginfo_examples_dex.jar"
368 task "compile_debuginfo_examples"(type: JavaCompile) {
369 source = fileTree(dir: examplesDir, include: "com/android/tools/r8/debuginfo/*Test.java")
370 destinationDir = file("build/test/debuginfo_examples/classes")
371 classpath = sourceSets.main.compileClasspath
372 sourceCompatibility = JavaVersion.VERSION_1_7
373 targetCompatibility = JavaVersion.VERSION_1_7
374 options.compilerArgs += ["-Xlint:-options"]
375 }
376 task "jar_debuginfo_examples"(type: Jar, dependsOn: "compile_debuginfo_examples") {
377 archiveName = hostJar
378 destinationDir = file("build/test/")
379 from "build/test/debuginfo_examples/classes"
380 include "**/*.class"
381 }
382 task "dex_debuginfo_examples"(type: Exec,
383 dependsOn: ["jar_debuginfo_examples", "downloadDeps"]) {
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200384 if (OperatingSystem.current().isWindows()) {
385 executable file("tools/windows/dx/bin/dx.bat")
386 } else {
387 executable file("tools/linux/dx/bin/dx");
388 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200389 args "--dex"
390 args "--output=build/test/${hostDexJar}"
391 args "build/test/${hostJar}"
392 inputs.file file("build/test/${hostJar}")
393 outputs.file file("build/test/${hostDexJar}")
394 }
395 dependsOn dex_debuginfo_examples
396}
397
398task buildDebugTestResourcesJars {
Mads Ager418d1ca2017-05-22 09:35:49 +0200399 def resourcesDir = file("src/test/debugTestResources")
400 def hostJar = "debug_test_resources.jar"
401 task "compile_debugTestResources"(type: JavaCompile) {
402 source = fileTree(dir: resourcesDir, include: '**/*.java')
403 destinationDir = file("build/test/debugTestResources/classes")
404 classpath = sourceSets.main.compileClasspath
405 sourceCompatibility = JavaVersion.VERSION_1_7
406 targetCompatibility = JavaVersion.VERSION_1_7
407 options.compilerArgs += ["-g", "-Xlint:-options"]
408 }
409 task "jar_debugTestResources"(type: Jar, dependsOn: "compile_debugTestResources") {
410 archiveName = hostJar
411 destinationDir = file("build/test/")
412 from "build/test/debugTestResources/classes"
413 include "**/*.class"
414 }
Sebastien Hertz964c5c22017-05-23 15:22:23 +0200415 def java8ResourcesDir = file("src/test/debugTestResourcesJava8")
416 def java8HostJar = "debug_test_resources_java8.jar"
417 task "compile_debugTestResourcesJava8"(type: JavaCompile) {
418 source = fileTree(dir: java8ResourcesDir, include: '**/*.java')
419 destinationDir = file("build/test/debugTestResourcesJava8/classes")
420 classpath = sourceSets.main.compileClasspath
421 sourceCompatibility = JavaVersion.VERSION_1_8
422 targetCompatibility = JavaVersion.VERSION_1_8
423 options.compilerArgs += ["-g", "-Xlint:-options"]
424 }
425 task "jar_debugTestResourcesJava8"(type: Jar, dependsOn: "compile_debugTestResourcesJava8") {
426 archiveName = java8HostJar
427 destinationDir = file("build/test/")
428 from "build/test/debugTestResourcesJava8/classes"
429 include "**/*.class"
430 }
431 dependsOn downloadDeps
Mads Ager418d1ca2017-05-22 09:35:49 +0200432 dependsOn jar_debugTestResources
Sebastien Hertz964c5c22017-05-23 15:22:23 +0200433 dependsOn jar_debugTestResourcesJava8
Mads Ager418d1ca2017-05-22 09:35:49 +0200434}
435
436task buildExampleJars {
Rico Wind897bb712017-05-23 10:44:29 +0200437 dependsOn downloadProguard
Mads Ager418d1ca2017-05-22 09:35:49 +0200438 def examplesDir = file("src/test/examples")
Jean-Marie Henaff872e4422017-06-13 10:26:20 +0200439 def proguardScript
440 if (OperatingSystem.current().isWindows()) {
441 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.bat"
442 } else {
443 proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.sh"
444 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200445 task "compile_examples"(type: JavaCompile) {
446 source = fileTree(dir: examplesDir, include: '**/*.java')
447 destinationDir = file("build/test/examples/classes")
448 classpath = sourceSets.main.compileClasspath
449 sourceCompatibility = JavaVersion.VERSION_1_7
450 targetCompatibility = JavaVersion.VERSION_1_7
451 options.compilerArgs += ["-Xlint:-options"]
452 }
453 examplesDir.eachDir { dir ->
454 def name = dir.getName();
455 def exampleOutputDir = file("build/test/examples");
456 def jarName = "${name}.jar"
457 dependsOn "jar_example_${name}"
458 // The "throwing" test verifies debugging/stack info on the post-proguarded output.
459 def proguardConfigPath = "${dir}/proguard.cfg"
460 if (new File(proguardConfigPath).exists()) {
461 task "pre_proguard_example_${name}"(type: Jar, dependsOn: "compile_examples") {
462 archiveName = "${name}_pre_proguard.jar"
463 destinationDir = exampleOutputDir
464 from "build/test/examples/classes"
465 include "**/" + name + "/**/*.class"
466 }
467 def jarPath = files(tasks.getByPath("pre_proguard_example_${name}")).files.first();
468 def proguardJarPath = "${exampleOutputDir}/${jarName}"
469 def proguardMapPath = "${exampleOutputDir}/${name}/${name}.map"
470 task "jar_example_${name}"(type: Exec, dependsOn: "pre_proguard_example_${name}") {
471 inputs.files tasks.getByPath("pre_proguard_example_${name}")
472 inputs.file proguardConfigPath
473 // Enable these to get stdout and stderr redirected to files...
474 // standardOutput = new FileOutputStream('proguard.stdout')
475 // errorOutput = new FileOutputStream('proguard.stderr')
Jean-Marie Henaff872e4422017-06-13 10:26:20 +0200476 def proguardArguments = "-verbose -dontwarn java.** -injars ${jarPath}" +
Mads Ager418d1ca2017-05-22 09:35:49 +0200477 " -outjars ${proguardJarPath}" +
478 " -include ${proguardConfigPath}" +
Jean-Marie Henaff872e4422017-06-13 10:26:20 +0200479 " -printmapping ${proguardMapPath}"
480 if (OperatingSystem.current().isWindows()) {
481 executable "${proguardScript}"
482 args "${proguardArguments}"
483 } else {
484 executable "bash"
485 args "-c", "${proguardScript} '${proguardArguments}'"
486 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200487 outputs.file proguardJarPath
488 }
489 } else {
490 task "jar_example_${name}"(type: Jar, dependsOn: "compile_examples") {
491 archiveName = jarName
492 destinationDir = exampleOutputDir
493 from "build/test/examples/classes"
494 include "**/" + name + "/**/*.class"
495 }
496 }
497 }
498}
499
500task buildExampleAndroidNJars {
501 dependsOn downloadDeps
502 def examplesDir = file("src/test/examplesAndroidN")
503 task "compile_examplesAndroidN"(type: JavaCompile) {
504 source = fileTree(dir: examplesDir, include: '**/*.java')
505 destinationDir = file("build/test/examplesAndroidN/classes")
506 classpath = sourceSets.main.compileClasspath
507 sourceCompatibility = JavaVersion.VERSION_1_8
508 targetCompatibility = JavaVersion.VERSION_1_8
509 options.compilerArgs += ["-Xlint:-options"]
510 }
511 examplesDir.eachDir { dir ->
512 def name = dir.getName();
513 def exampleOutputDir = file("build/test/examplesAndroidN");
514 def jarName = "${name}.jar"
515 dependsOn "jar_examplesAndroidN_${name}"
516 task "jar_examplesAndroidN_${name}"(type: Jar, dependsOn: "compile_examplesAndroidN") {
517 archiveName = jarName
518 destinationDir = exampleOutputDir
519 from "build/test/examplesAndroidN/classes"
520 include "**/" + name + "/**/*.class"
521 }
522 }
523}
524
525
526task buildExampleAndroidOJars {
527 dependsOn downloadDeps
528 def examplesDir = file("src/test/examplesAndroidO")
529 // NOTE: we want to enable a scenario when test needs to reference some
530 // classes generated by legacy (1.6) Java compiler to test some specific
531 // behaviour. To do so we compile all the java files located in sub-directory
532 // called 'legacy' with Java 1.6, then compile the rest of the files with
533 // Java 1.8 and a reference to previously generated 1.6 classes.
534
535 // Compiling all classes in dirs 'legacy' with old Java version.
536 task "compile_examplesAndroidO_Legacy"(type: JavaCompile) {
537 source = fileTree(dir: examplesDir, include: '**/legacy/**/*.java')
538 destinationDir = file("build/test/examplesAndroidOLegacy/classes")
539 classpath = sourceSets.main.compileClasspath
540 sourceCompatibility = JavaVersion.VERSION_1_6
541 targetCompatibility = JavaVersion.VERSION_1_6
542 options.compilerArgs += ["-Xlint:-options", "-parameters"]
543 }
544 // Compiling the rest of the files as Java 1.8 code.
545 task "compile_examplesAndroidO"(type: JavaCompile) {
546 dependsOn "compile_examplesAndroidO_Legacy"
547 source = fileTree(dir: examplesDir, include: '**/*.java', exclude: '**/legacy/**/*.java')
548 destinationDir = file("build/test/examplesAndroidO/classes")
549 classpath = sourceSets.main.compileClasspath
550 classpath += files("build/test/examplesAndroidOLegacy/classes")
551 sourceCompatibility = JavaVersion.VERSION_1_8
552 targetCompatibility = JavaVersion.VERSION_1_8
553 options.compilerArgs += ["-Xlint:-options", "-parameters"]
554 }
555 examplesDir.eachDir { dir ->
556 def name = dir.getName();
557 def destinationDir = file("build/test/examplesAndroidO/classes");
558 if (file("src/test/examplesAndroidO/" + name + "/TestGenerator.java").isFile()) {
559 task "generate_examplesAndroidO_${name}"(type: JavaExec,
560 dependsOn: "compile_examplesAndroidO") {
561 main = name + ".TestGenerator"
562 classpath = files(destinationDir, sourceSets.main.compileClasspath)
563 args destinationDir
564 }
565 } else {
566 task "generate_examplesAndroidO_${name}" () {}
567 }
568 }
569 examplesDir.eachDir { dir ->
570 def name = dir.getName();
571 def exampleOutputDir = file("build/test/examplesAndroidO");
572 def jarName = "${name}.jar"
573 dependsOn "jar_examplesAndroidO_${name}"
574 task "jar_examplesAndroidO_${name}"(type: Jar, dependsOn: ["compile_examplesAndroidO",
575 "generate_examplesAndroidO_${name}"]) {
576 archiveName = jarName
577 destinationDir = exampleOutputDir
578 from "build/test/examplesAndroidO/classes" // Java 1.8 classes
579 from "build/test/examplesAndroidOLegacy/classes" // Java 1.6 classes
580 include "**/" + name + "/**/*.class"
581 // Do not include generator into the test runtime jar, it is not useful.
582 // Otherwise, shrinking will need ASM jars.
583 exclude "**/TestGenerator*"
584 }
585 }
586}
587
588task buildExamples {
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200589 if (OperatingSystem.current().isMacOsX() || OperatingSystem.current().isWindows()) {
590 logger.lifecycle("WARNING: Testing (including building examples) is only partially supported on your " +
591 "platform (" + OperatingSystem.current().getName() + ").")
Mads Ager418d1ca2017-05-22 09:35:49 +0200592 } else if (!OperatingSystem.current().isLinux()) {
593 logger.lifecycle("WARNING: Testing (including building examples) is not supported on your platform. " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200594 "It is fully supported on Linux and partially supported on Mac OS and Windows")
Mads Ager418d1ca2017-05-22 09:35:49 +0200595 return;
596 }
597 dependsOn buildDebugTestResourcesJars
598 dependsOn buildExampleJars
599 dependsOn buildExampleAndroidNJars
600 dependsOn buildExampleAndroidOJars
601 def examplesDir = file("src/test/examples")
Yohann Rousself820a572017-05-31 20:25:51 +0200602 def noDexTests = [
603 "multidex",
604 "multidex002",
605 "multidex004",
606 ]
Mads Ager418d1ca2017-05-22 09:35:49 +0200607 examplesDir.eachDir { dir ->
608 def name = dir.getName();
Yohann Rousself820a572017-05-31 20:25:51 +0200609 if (!(name in noDexTests)) {
610 dependsOn "dex_example_${name}"
611 def exampleOutputDir = file("build/test/examples/" + name);
612 def dexPath = file("${exampleOutputDir}")
613 def debug = (name == "throwing")
614 if (!dexPath.exists()) {
615 dexPath.mkdirs()
616 }
617 task "dex_example_${name}"(type: dx.Dx, dependsOn: "jar_example_${name}") {
618 source = files(tasks.getByPath("jar_example_${name}")).asFileTree
619 destination = dexPath
620 debug = debug
621 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200622 }
623 }
624}
625
626task buildSmali {
627 def smaliDir = file("src/test/smali")
628 smaliDir.eachDirRecurse() { dir ->
629 def name = dir.getName();
630 def relativeDir = smaliDir.toPath().relativize(dir.toPath());
631 def smaliOutputDir = file("build/test/smali/" + relativeDir);
632 smaliOutputDir.mkdirs()
633 outputs.dir smaliOutputDir
634 def taskName = "smali_build_${relativeDir.toString().replace('/', '_')}"
635 def smaliFiles = fileTree(dir: dir, include: '*.smali')
636 def javaFiles = fileTree(dir: dir, include: '*.java')
637 def destDir = smaliOutputDir;
638 def destFile = destDir.toPath().resolve("${name}.dex").toFile()
639 def intermediateFileName = "${name}-intermediate.dex";
640 def intermediateFile = destDir.toPath().resolve(intermediateFileName).toFile()
641 if (javaFiles.empty) {
642 if (!smaliFiles.empty) {
643 dependsOn "${taskName}_smali"
644 task "${taskName}_smali"(type: smali.Smali) {
645 source = smaliFiles
646 destination = destFile
647 }
648 }
649 } else {
650 dependsOn "${taskName}_dexmerger"
651 task "${taskName}_smali"(type: smali.Smali) {
652 source = smaliFiles
653 destination = intermediateFile
654 }
655 task "${taskName}_java"(type: JavaCompile) {
656 source = javaFiles
657 destinationDir destDir
658 classpath = sourceSets.main.compileClasspath
659 sourceCompatibility = JavaVersion.VERSION_1_7
660 targetCompatibility = JavaVersion.VERSION_1_7
661 options.compilerArgs += ["-Xlint:-options"]
662 }
663 task "${taskName}_jar"(type: Jar, dependsOn: "${taskName}_java") {
664 archiveName = "Test.jar"
665 destinationDir = destDir
666 from fileTree(dir: destDir, include: 'Test.class')
667 }
668 task "${taskName}_dx"(type: dx.Dx, dependsOn: "${taskName}_jar") {
669 source = fileTree(dir: destDir, include: 'Test.jar')
670 destination = destDir
671 }
672 task "${taskName}_dexmerger"(
673 type: dx.DexMerger, dependsOn: ["${taskName}_dx", "${taskName}_smali"]) {
674 source = fileTree(dir: destDir, include: ["classes.dex", intermediateFileName])
675 destination = destFile
676 }
677 }
678 }
679}
680
681tasks.withType(Test) {
682 def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK')
683 def coresPerFork = userDefinedCoresPerFork ? userDefinedCoresPerFork.toInteger() : 3
684 // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
685 maxParallelForks = Runtime.runtime.availableProcessors().intdiv(coresPerFork) ?: 1
686 forkEvery = 0
687 // Use the Concurrent Mark Sweep GC (CMS) to keep memory usage at a resonable level.
688 jvmArgs = ["-XX:+UseConcMarkSweepGC"]
Søren Gjesseaf1c5e22017-06-15 12:24:03 +0200689 if (project.hasProperty('disable_assertions')) {
690 enableAssertions = false
691 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200692}
693
694task buildPreNJdwpTestsJar(type: Jar) {
695 baseName = 'jdwp-tests-preN'
696 from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
697 // Exclude the classes containing java8
698 exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
699 exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
700 includeEmptyDirs = false
701}
702
703test {
704 testLogging.exceptionFormat = 'full'
705 if (project.hasProperty('print_test_stdout')) {
706 testLogging.showStandardStreams = true
707 }
708 if (project.hasProperty('dex_vm')) {
709 println "Running with non default vm: " + project.property('dex_vm')
710 systemProperty 'dex_vm', project.property('dex_vm')
711 if (project.property('dex_vm') == '5.1.1' || project.property('dex_vm') == '6.0.1') {
712 // R8 and D8 compute the dex file version number based on the input.
713 // Jack generates dex files with version 37 which art 5.1.1 and 6.0.1 will not run.
714 // Therefore we skip the jack generated art tests with those art versions.
715 exclude "com/android/tools/r8/art/jack/**"
716 }
717 }
718 if (project.hasProperty('one_line_per_test')) {
719 beforeTest { desc ->
720 println "Start executing test ${desc.name} [${desc.className}]"
721 }
722 afterTest { desc, result ->
723 println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
724 }
725 }
726 if (project.hasProperty('no_internal')) {
727 exclude "com/android/tools/r8/internal/**"
728 }
729 if (project.hasProperty('only_internal')) {
730 include "com/android/tools/r8/internal/**"
731 }
732 if (project.hasProperty('tool')) {
733 if (project.property('tool') == 'r8') {
734 exclude "com/android/tools/r8/art/*/d8/**"
Tamas Kenez69c2e8b2017-05-31 13:41:07 +0200735 exclude "com/android/tools/r8/jctf/d8/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200736 } else {
737 assert(project.property('tool') == 'd8')
738 exclude "com/android/tools/r8/art/*/r8/**"
Tamas Kenez69c2e8b2017-05-31 13:41:07 +0200739 exclude "com/android/tools/r8/jctf/r8/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200740 }
741 }
742 if (!project.hasProperty('all_tests')) {
743 exclude "com/android/tools/r8/art/dx/**"
744 exclude "com/android/tools/r8/art/jack/**"
745 }
746 // TODO(tamaskenez) enable jctf on all_tests when consolidated
747 if (!project.hasProperty('jctf') && !project.hasProperty('only_jctf')) {
Stephan Herhutea6ee582017-05-23 13:14:34 +0200748 exclude "com/android/tools/r8/jctf/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200749 }
750 if (project.hasProperty('only_jctf')) {
Stephan Herhutea6ee582017-05-23 13:14:34 +0200751 include "com/android/tools/r8/jctf/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200752 }
753 if (project.hasProperty('jctf_compile_only')) {
754 println "JCTF: compiling only"
755 systemProperty 'jctf_compile_only', '1'
756 }
757
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200758 if (OperatingSystem.current().isLinux()
759 || OperatingSystem.current().isMacOsX()
760 || OperatingSystem.current().isWindows()) {
Mads Ager418d1ca2017-05-22 09:35:49 +0200761 if (OperatingSystem.current().isMacOsX()) {
762 logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " +
763 "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " +
764 "See tools/docker/README.md for details.")
765 }
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200766 if (OperatingSystem.current().isWindows()) {
767 logger.lifecycle("WARNING: Testing in only partially supported on Windows. " +
768 "Art only runs on Linux and tests requiring Art will be skipped")
769 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200770 dependsOn downloadDeps
771 dependsOn buildExamples
772 dependsOn buildSmali
773 dependsOn jctfCommonJar
774 dependsOn jctfTestsClasses
775 dependsOn buildDebugInfoExamplesDex
776 dependsOn buildPreNJdwpTestsJar
777 } else {
778 logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
Jean-Marie Henaff39587a82017-06-08 15:20:13 +0200779 "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.")
Mads Ager418d1ca2017-05-22 09:35:49 +0200780 }
781}
782
783// The Art tests we use for R8 are pre-build and downloaded from Google Cloud Storage.
784//
785// To build and upload a new set of the Art tests for use with R8 follow these steps:
786//
787// First of all an Android checkout is required. Currently it must be located
788// in $HOME/android/master.
789//
790// TODO(ricow): simplify this
791//
792// Before: update the checked in art, see scripts/update-host-art.sh
793//
794// 1. Get an android checkout in $HOME/android/master and apply the patch from
795// https://android-review.googlesource.com/#/c/294187/
796//
797// 2. run the following commands in the Android checkout directory:
798//
799// source build/envsetup.sh
800// lunch aosp_angler-userdebug
801// make -j30 test-art-host
802//
803// 3. In the R8 project root directory, make sure we have a clean state before starting:
804// tools/gradle.py downloadDeps
805// tools/gradle.py clean
806// rm -rf tests/art
807//
808// 4. Now build in the R8 checkout (-P hack to not generate dirs when not running this target)
809// Make sure you have smali on your path, there is a build binary in the out directory of
810// the android checkout:
811//
812// tools/gradle.py -Pandroid_source buildArtTests
813//
814// 4a. If any failures are produced in step 4, figure out what went wrong and add an entry in
815// skippedTests with an explanation. Rerun from step 3.
816//
817// 5. Run the tests:
818// tools/gradle.py clean
819// tools/test.py
820//
821// 5a. If any more tests fail, either fix the issue or add them to the toBeTriaged list (note that
822// you need to change "_" to "-" from stdout). Rerun from step 3 if anything was added to
823// toBeTriaged.
824//
825// 6. To upload a new version to Google Cloud Storage
826// cd tests
827// upload_to_google_storage.py -a --bucket r8-deps art
828
829enum DexTool {
830 JACK,
831 DX
832}
833
834def androidCheckoutDir = file("${System.env.HOME}/android/master")
835def androidCheckoutJack = file("${androidCheckoutDir}/out/host/linux-x86/bin/jack");
836def androidCheckoutJackServer = file("${androidCheckoutDir}/out/host/linux-x86/bin/jack-admin");
837
838def artTestDir = file("${androidCheckoutDir}/art/test")
839
840if (project.hasProperty('android_source')) {
841 task buildArtTests {
842 outputs.upToDateWhen { false }
843 def toBeTriaged = [
844 "903-hello-tagging",
845 "904-object-allocation",
846 "905-object-free",
847 "906-iterate-heap",
848 "907-get-loaded-classes",
849 "908-gc-start-finish",
850 "954-invoke-polymorphic-verifier",
851 "955-methodhandles-smali",
852 "596-monitor-inflation",
853 ]
854 def skippedTests = toBeTriaged + [
855 // This test produces no jar.
856 "000-nop",
857 // This does not build, as it tests the error when the application exceeds more
858 // than 65536 methods
859 "089-many-methods",
860 // Requires some jack beta jar
861 "956-methodhandles",
862 ]
863
864 def skippedTestsDx = [
865 // Tests with custom build scripts, where javac is not passed the options
866 // -source 1.7 -target 1.7.
867 "462-checker-inlining-across-dex-files",
868 "556-invoke-super",
869 "569-checker-pattern-replacement",
870 // These tests use jack even when --build-with-javac-dx is specified.
871 "004-JniTest",
872 "048-reflect-v8",
873 "146-bad-interface",
874 "563-checker-invoke-super",
875 "580-checker-string-fact-intrinsics", // java.lang.StringFactory
876 "604-hot-static-interface",
877 "957-methodhandle-transforms",
878 "958-methodhandle-emulated-stackframe",
879 "959-invoke-polymorphic-accessors",
880 "961-default-iface-resolution-gen",
881 "962-iface-static",
882 "963-default-range-smali",
883 "964-default-iface-init-gen",
884 "965-default-verify",
885 "966-default-conflict",
886 "967-default-ame",
887 "968-default-partial-compile-gen",
888 "969-iface-super",
889 "970-iface-super-resolution-gen",
890 "971-iface-super",
891 // These tests does not build with --build-with-javac-dx
892 "004-NativeAllocations", // Javac error
893 "031-class-attributes",
894 "138-duplicate-classes-check",
895 "157-void-class", // Javac error
896 "580-checker-string-factory-intrinsics",
897 "612-jit-dex-cache",
898 "613-inlining-dex-cache",
899 "900-hello-plugin", // --experimental agents
900 "901-hello-ti-agent", // --experimental agents
901 "902-hello-transformation", // --experimental agents
902 "909-attach-agent", // --experimental agents
903 "946-obsolete-throw", // -source 1.7 -target 1.7, but use lambda
904 "950-redefine-intrinsic", // -source 1.7 -target 1.7, but use method references
905 "951-threaded-obsolete", // -source 1.7 -target 1.7, but use lambda
906 "960-default-smali", // --experimental default-methods
907 // These tests force the build to use jack
908 "953-invoke-polymorphic-compiler",
909 "958-methodhandle-stackframe",
910 ]
911
912 def artTestBuildDir = file("${projectDir}/tests/art")
913
914 if (androidCheckoutDir.exists()) {
915 dependsOn downloadDeps
916 artTestBuildDir.mkdirs()
917 // Ensure Jack server is running.
918 "${androidCheckoutJackServer} start-server".execute()
919 artTestDir.eachDir { dir ->
920 def name = dir.getName();
921 def markerFile = dir.toPath().resolve("info.txt").toFile();
922 if (markerFile.exists() && !(name in skippedTests)) {
923 if (!(name in skippedTestsDx)) {
924 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir, DexTool.DX);
925 }
926 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir, DexTool.JACK);
927 }
928 }
929 }
930 doFirst {
931 if (!androidCheckoutDir.exists()) {
932 throw new InvalidUserDataException(
933 "This task requires an Android checkout in ${androidCheckoutDir}");
934 } else if (!androidCheckoutJack.exists() ||
935 !androidCheckoutJackServer.exists()) {
936 throw new InvalidUserDataException(
937 "This task requires that tools for host testing have been build in the " +
938 "Android checkout in ${androidCheckoutDir}");
939 }
940 }
941 doLast {
942 copy {
943 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest64")
944 into file("${artTestBuildDir}/lib64")
945 include 'lib*.so'
946 }
947 copy {
948 from file("${androidCheckoutDir}/out/host/linux-x86/lib64")
949 into file("${artTestBuildDir}/lib64")
950 include 'libart.so'
951 include 'libbacktrace.so'
952 include 'libbase.so'
953 include 'libc++.so'
954 include 'libcutils.so'
955 include 'liblz4.so'
956 include 'liblzma.so'
957 include 'libnativebridge.so'
958 include 'libnativeloader.so'
959 include 'libsigchain.so'
960 include 'libunwind.so'
961 include 'libziparchive.so'
962 }
963 copy {
964 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest")
965 into file("${artTestBuildDir}/lib")
966 include 'lib*.so'
967 }
968 copy {
969 from file("${androidCheckoutDir}/out/host/linux-x86/lib")
970 into file("${artTestBuildDir}/lib")
971 include 'libart.so'
972 include 'libbacktrace.so'
973 include 'libbase.so'
974 include 'libc++.so'
975 include 'libcutils.so'
976 include 'liblz4.so'
977 include 'liblzma.so'
978 include 'libnativebridge.so'
979 include 'libnativeloader.so'
980 include 'libsigchain.so'
981 include 'libunwind.so'
982 include 'libziparchive.so'
983 }
984 }
985 }
986}
987
988def buildArtTest(androidCheckoutDir, artTestBuildDir, dir, dexTool) {
989 def artTestDir = file("${androidCheckoutDir}/art/test")
990 def artRunTestScript = file("${artTestDir}/run-test")
991 def dxExecutable = new File("tools/linux/dx/bin/dx");
Jean-Marie Henaff34d85f72017-06-14 10:32:04 +0200992 def dexMergerExecutable = Utils.dexMergerExecutable()
Mads Ager418d1ca2017-05-22 09:35:49 +0200993 def dexToolName = dexTool == DexTool.DX ? "dx" : "jack"
994
995 def name = dir.getName();
996 def buildTask = "build_art_test_${dexToolName}_${name}"
997 def sanitizeTask = "sanitize_art_test_${dexToolName}_${name}"
998 def copyCheckTask = "copy_check_art_test_${dexToolName}_${name}"
999 def smaliToDexTask = "smali_to_dex_${dexToolName}_${name}"
1000
1001 def buildInputs = fileTree(dir: dir, include: '**/*')
1002 def testDir = file("${artTestBuildDir}/${dexToolName}/${name}")
1003 def outputJar = testDir.toPath().resolve("${name}.jar").toFile()
1004 testDir.mkdirs()
1005 if (dexTool == DexTool.DX) {
1006 task "$buildTask"(type: Exec) {
1007 outputs.upToDateWhen { false }
1008 inputs.file buildInputs
1009 executable "${artRunTestScript}"
1010 args "--host"
1011 args "--build-only"
1012 args "--build-with-javac-dx"
1013 args "--output-path", "${testDir}"
1014 args "${name}"
1015 environment DX: "${dxExecutable.absolutePath}"
1016 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
1017 outputs.file outputJar
1018 }
1019 } else {
1020 assert dexTool == DexTool.JACK
1021 def javaLibs = "${androidCheckoutDir}/out/host/common/obj/JAVA_LIBRARIES"
1022 def jackClasspath = "${javaLibs}/core-libart-hostdex_intermediates/classes.jack:" +
1023 "${javaLibs}/core-oj-hostdex_intermediates/classes.jack"
1024 task "$buildTask"(type: Exec) {
1025 outputs.upToDateWhen { false }
1026 inputs.file buildInputs
1027 executable "${artRunTestScript}"
1028 args "--host"
1029 args "--build-only"
1030 args "--output-path", "${testDir}"
1031 args "${name}"
1032 environment JACK: "${androidCheckoutDir}/out/host/linux-x86/bin/jack"
1033 environment JACK_CLASSPATH: jackClasspath
1034 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
1035 environment ANDROID_BUILD_TOP: "${androidCheckoutDir}"
1036 outputs.file outputJar
1037 }
1038 }
1039 task "${sanitizeTask}"(type: Exec, dependsOn: buildTask) {
1040 outputs.upToDateWhen { false }
1041 executable "/bin/bash"
1042 args "-c"
1043 args "rm -rf ${testDir}/smali_*.dex ${testDir}/*-ex.dex ${testDir}/*-ex.jar" +
1044 " ${testDir}/classes-ex ${testDir}/check"
1045 }
1046
1047 task "${smaliToDexTask}"(type: Exec) {
1048 workingDir "${testDir}/smali"
1049 executable "/bin/bash"
1050 args "-c", "smali -o out.dex *.smali"
1051 }
1052
1053 task "${copyCheckTask}"(type: Copy, dependsOn: sanitizeTask) {
1054 def smali_dir = file("${dir}/smali")
1055 outputs.upToDateWhen { false }
1056 if (smali_dir.exists() && dexTool == DexTool.DX) {
1057 dependsOn smaliToDexTask
1058 }
1059 from("${artTestDir}/${name}") {
1060 include 'check'
1061 }
1062 into testDir
1063 }
1064
1065 return copyCheckTask
1066}
1067
1068task javadocD8(type: Javadoc) {
1069 classpath = sourceSets.main.compileClasspath
1070 source = sourceSets.main.allJava
1071 include '**/com/android/tools/r8/BaseCommand.java'
1072 include '**/com/android/tools/r8/BaseOutput.java'
1073 include '**/com/android/tools/r8/CompilationException.java'
1074 include '**/com/android/tools/r8/CompilationMode.java'
1075 include '**/com/android/tools/r8/D8.java'
1076 include '**/com/android/tools/r8/D8Command.java'
1077 include '**/com/android/tools/r8/D8Output.java'
1078 include '**/com/android/tools/r8/Resource.java'
1079}