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