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