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