blob: 0663b8a39163ad452cbea3bcc6db09e186ee0261 [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")
Yohann Rousself820a572017-05-31 20:25:51 +0200564 def noDexTests = [
565 "multidex",
566 "multidex002",
567 "multidex004",
568 ]
Mads Ager418d1ca2017-05-22 09:35:49 +0200569 examplesDir.eachDir { dir ->
570 def name = dir.getName();
Yohann Rousself820a572017-05-31 20:25:51 +0200571 if (!(name in noDexTests)) {
572 dependsOn "dex_example_${name}"
573 def exampleOutputDir = file("build/test/examples/" + name);
574 def dexPath = file("${exampleOutputDir}")
575 def debug = (name == "throwing")
576 if (!dexPath.exists()) {
577 dexPath.mkdirs()
578 }
579 task "dex_example_${name}"(type: dx.Dx, dependsOn: "jar_example_${name}") {
580 source = files(tasks.getByPath("jar_example_${name}")).asFileTree
581 destination = dexPath
582 debug = debug
583 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200584 }
585 }
586}
587
588task buildSmali {
589 def smaliDir = file("src/test/smali")
590 smaliDir.eachDirRecurse() { dir ->
591 def name = dir.getName();
592 def relativeDir = smaliDir.toPath().relativize(dir.toPath());
593 def smaliOutputDir = file("build/test/smali/" + relativeDir);
594 smaliOutputDir.mkdirs()
595 outputs.dir smaliOutputDir
596 def taskName = "smali_build_${relativeDir.toString().replace('/', '_')}"
597 def smaliFiles = fileTree(dir: dir, include: '*.smali')
598 def javaFiles = fileTree(dir: dir, include: '*.java')
599 def destDir = smaliOutputDir;
600 def destFile = destDir.toPath().resolve("${name}.dex").toFile()
601 def intermediateFileName = "${name}-intermediate.dex";
602 def intermediateFile = destDir.toPath().resolve(intermediateFileName).toFile()
603 if (javaFiles.empty) {
604 if (!smaliFiles.empty) {
605 dependsOn "${taskName}_smali"
606 task "${taskName}_smali"(type: smali.Smali) {
607 source = smaliFiles
608 destination = destFile
609 }
610 }
611 } else {
612 dependsOn "${taskName}_dexmerger"
613 task "${taskName}_smali"(type: smali.Smali) {
614 source = smaliFiles
615 destination = intermediateFile
616 }
617 task "${taskName}_java"(type: JavaCompile) {
618 source = javaFiles
619 destinationDir destDir
620 classpath = sourceSets.main.compileClasspath
621 sourceCompatibility = JavaVersion.VERSION_1_7
622 targetCompatibility = JavaVersion.VERSION_1_7
623 options.compilerArgs += ["-Xlint:-options"]
624 }
625 task "${taskName}_jar"(type: Jar, dependsOn: "${taskName}_java") {
626 archiveName = "Test.jar"
627 destinationDir = destDir
628 from fileTree(dir: destDir, include: 'Test.class')
629 }
630 task "${taskName}_dx"(type: dx.Dx, dependsOn: "${taskName}_jar") {
631 source = fileTree(dir: destDir, include: 'Test.jar')
632 destination = destDir
633 }
634 task "${taskName}_dexmerger"(
635 type: dx.DexMerger, dependsOn: ["${taskName}_dx", "${taskName}_smali"]) {
636 source = fileTree(dir: destDir, include: ["classes.dex", intermediateFileName])
637 destination = destFile
638 }
639 }
640 }
641}
642
643tasks.withType(Test) {
644 def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK')
645 def coresPerFork = userDefinedCoresPerFork ? userDefinedCoresPerFork.toInteger() : 3
646 // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
647 maxParallelForks = Runtime.runtime.availableProcessors().intdiv(coresPerFork) ?: 1
648 forkEvery = 0
649 // Use the Concurrent Mark Sweep GC (CMS) to keep memory usage at a resonable level.
650 jvmArgs = ["-XX:+UseConcMarkSweepGC"]
651}
652
653task buildPreNJdwpTestsJar(type: Jar) {
654 baseName = 'jdwp-tests-preN'
655 from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
656 // Exclude the classes containing java8
657 exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
658 exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
659 includeEmptyDirs = false
660}
661
662test {
663 testLogging.exceptionFormat = 'full'
664 if (project.hasProperty('print_test_stdout')) {
665 testLogging.showStandardStreams = true
666 }
667 if (project.hasProperty('dex_vm')) {
668 println "Running with non default vm: " + project.property('dex_vm')
669 systemProperty 'dex_vm', project.property('dex_vm')
670 if (project.property('dex_vm') == '5.1.1' || project.property('dex_vm') == '6.0.1') {
671 // R8 and D8 compute the dex file version number based on the input.
672 // Jack generates dex files with version 37 which art 5.1.1 and 6.0.1 will not run.
673 // Therefore we skip the jack generated art tests with those art versions.
674 exclude "com/android/tools/r8/art/jack/**"
675 }
676 }
677 if (project.hasProperty('one_line_per_test')) {
678 beforeTest { desc ->
679 println "Start executing test ${desc.name} [${desc.className}]"
680 }
681 afterTest { desc, result ->
682 println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
683 }
684 }
685 if (project.hasProperty('no_internal')) {
686 exclude "com/android/tools/r8/internal/**"
687 }
688 if (project.hasProperty('only_internal')) {
689 include "com/android/tools/r8/internal/**"
690 }
691 if (project.hasProperty('tool')) {
692 if (project.property('tool') == 'r8') {
693 exclude "com/android/tools/r8/art/*/d8/**"
Tamas Kenez69c2e8b2017-05-31 13:41:07 +0200694 exclude "com/android/tools/r8/jctf/d8/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200695 } else {
696 assert(project.property('tool') == 'd8')
697 exclude "com/android/tools/r8/art/*/r8/**"
Tamas Kenez69c2e8b2017-05-31 13:41:07 +0200698 exclude "com/android/tools/r8/jctf/r8/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200699 }
700 }
701 if (!project.hasProperty('all_tests')) {
702 exclude "com/android/tools/r8/art/dx/**"
703 exclude "com/android/tools/r8/art/jack/**"
704 }
705 // TODO(tamaskenez) enable jctf on all_tests when consolidated
706 if (!project.hasProperty('jctf') && !project.hasProperty('only_jctf')) {
Stephan Herhutea6ee582017-05-23 13:14:34 +0200707 exclude "com/android/tools/r8/jctf/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200708 }
709 if (project.hasProperty('only_jctf')) {
Stephan Herhutea6ee582017-05-23 13:14:34 +0200710 include "com/android/tools/r8/jctf/**"
Mads Ager418d1ca2017-05-22 09:35:49 +0200711 }
712 if (project.hasProperty('jctf_compile_only')) {
713 println "JCTF: compiling only"
714 systemProperty 'jctf_compile_only', '1'
715 }
716
717 if (OperatingSystem.current().isLinux() || OperatingSystem.current().isMacOsX()) {
718 if (OperatingSystem.current().isMacOsX()) {
719 logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " +
720 "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " +
721 "See tools/docker/README.md for details.")
722 }
723 dependsOn downloadDeps
724 dependsOn buildExamples
725 dependsOn buildSmali
726 dependsOn jctfCommonJar
727 dependsOn jctfTestsClasses
728 dependsOn buildDebugInfoExamplesDex
729 dependsOn buildPreNJdwpTestsJar
730 } else {
731 logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
732 "Linux and partially supported on Mac OS. Art does not run on other platforms.")
733 }
734}
735
736// The Art tests we use for R8 are pre-build and downloaded from Google Cloud Storage.
737//
738// To build and upload a new set of the Art tests for use with R8 follow these steps:
739//
740// First of all an Android checkout is required. Currently it must be located
741// in $HOME/android/master.
742//
743// TODO(ricow): simplify this
744//
745// Before: update the checked in art, see scripts/update-host-art.sh
746//
747// 1. Get an android checkout in $HOME/android/master and apply the patch from
748// https://android-review.googlesource.com/#/c/294187/
749//
750// 2. run the following commands in the Android checkout directory:
751//
752// source build/envsetup.sh
753// lunch aosp_angler-userdebug
754// make -j30 test-art-host
755//
756// 3. In the R8 project root directory, make sure we have a clean state before starting:
757// tools/gradle.py downloadDeps
758// tools/gradle.py clean
759// rm -rf tests/art
760//
761// 4. Now build in the R8 checkout (-P hack to not generate dirs when not running this target)
762// Make sure you have smali on your path, there is a build binary in the out directory of
763// the android checkout:
764//
765// tools/gradle.py -Pandroid_source buildArtTests
766//
767// 4a. If any failures are produced in step 4, figure out what went wrong and add an entry in
768// skippedTests with an explanation. Rerun from step 3.
769//
770// 5. Run the tests:
771// tools/gradle.py clean
772// tools/test.py
773//
774// 5a. If any more tests fail, either fix the issue or add them to the toBeTriaged list (note that
775// you need to change "_" to "-" from stdout). Rerun from step 3 if anything was added to
776// toBeTriaged.
777//
778// 6. To upload a new version to Google Cloud Storage
779// cd tests
780// upload_to_google_storage.py -a --bucket r8-deps art
781
782enum DexTool {
783 JACK,
784 DX
785}
786
787def androidCheckoutDir = file("${System.env.HOME}/android/master")
788def androidCheckoutJack = file("${androidCheckoutDir}/out/host/linux-x86/bin/jack");
789def androidCheckoutJackServer = file("${androidCheckoutDir}/out/host/linux-x86/bin/jack-admin");
790
791def artTestDir = file("${androidCheckoutDir}/art/test")
792
793if (project.hasProperty('android_source')) {
794 task buildArtTests {
795 outputs.upToDateWhen { false }
796 def toBeTriaged = [
797 "903-hello-tagging",
798 "904-object-allocation",
799 "905-object-free",
800 "906-iterate-heap",
801 "907-get-loaded-classes",
802 "908-gc-start-finish",
803 "954-invoke-polymorphic-verifier",
804 "955-methodhandles-smali",
805 "596-monitor-inflation",
806 ]
807 def skippedTests = toBeTriaged + [
808 // This test produces no jar.
809 "000-nop",
810 // This does not build, as it tests the error when the application exceeds more
811 // than 65536 methods
812 "089-many-methods",
813 // Requires some jack beta jar
814 "956-methodhandles",
815 ]
816
817 def skippedTestsDx = [
818 // Tests with custom build scripts, where javac is not passed the options
819 // -source 1.7 -target 1.7.
820 "462-checker-inlining-across-dex-files",
821 "556-invoke-super",
822 "569-checker-pattern-replacement",
823 // These tests use jack even when --build-with-javac-dx is specified.
824 "004-JniTest",
825 "048-reflect-v8",
826 "146-bad-interface",
827 "563-checker-invoke-super",
828 "580-checker-string-fact-intrinsics", // java.lang.StringFactory
829 "604-hot-static-interface",
830 "957-methodhandle-transforms",
831 "958-methodhandle-emulated-stackframe",
832 "959-invoke-polymorphic-accessors",
833 "961-default-iface-resolution-gen",
834 "962-iface-static",
835 "963-default-range-smali",
836 "964-default-iface-init-gen",
837 "965-default-verify",
838 "966-default-conflict",
839 "967-default-ame",
840 "968-default-partial-compile-gen",
841 "969-iface-super",
842 "970-iface-super-resolution-gen",
843 "971-iface-super",
844 // These tests does not build with --build-with-javac-dx
845 "004-NativeAllocations", // Javac error
846 "031-class-attributes",
847 "138-duplicate-classes-check",
848 "157-void-class", // Javac error
849 "580-checker-string-factory-intrinsics",
850 "612-jit-dex-cache",
851 "613-inlining-dex-cache",
852 "900-hello-plugin", // --experimental agents
853 "901-hello-ti-agent", // --experimental agents
854 "902-hello-transformation", // --experimental agents
855 "909-attach-agent", // --experimental agents
856 "946-obsolete-throw", // -source 1.7 -target 1.7, but use lambda
857 "950-redefine-intrinsic", // -source 1.7 -target 1.7, but use method references
858 "951-threaded-obsolete", // -source 1.7 -target 1.7, but use lambda
859 "960-default-smali", // --experimental default-methods
860 // These tests force the build to use jack
861 "953-invoke-polymorphic-compiler",
862 "958-methodhandle-stackframe",
863 ]
864
865 def artTestBuildDir = file("${projectDir}/tests/art")
866
867 if (androidCheckoutDir.exists()) {
868 dependsOn downloadDeps
869 artTestBuildDir.mkdirs()
870 // Ensure Jack server is running.
871 "${androidCheckoutJackServer} start-server".execute()
872 artTestDir.eachDir { dir ->
873 def name = dir.getName();
874 def markerFile = dir.toPath().resolve("info.txt").toFile();
875 if (markerFile.exists() && !(name in skippedTests)) {
876 if (!(name in skippedTestsDx)) {
877 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir, DexTool.DX);
878 }
879 dependsOn buildArtTest(androidCheckoutDir, artTestBuildDir, dir, DexTool.JACK);
880 }
881 }
882 }
883 doFirst {
884 if (!androidCheckoutDir.exists()) {
885 throw new InvalidUserDataException(
886 "This task requires an Android checkout in ${androidCheckoutDir}");
887 } else if (!androidCheckoutJack.exists() ||
888 !androidCheckoutJackServer.exists()) {
889 throw new InvalidUserDataException(
890 "This task requires that tools for host testing have been build in the " +
891 "Android checkout in ${androidCheckoutDir}");
892 }
893 }
894 doLast {
895 copy {
896 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest64")
897 into file("${artTestBuildDir}/lib64")
898 include 'lib*.so'
899 }
900 copy {
901 from file("${androidCheckoutDir}/out/host/linux-x86/lib64")
902 into file("${artTestBuildDir}/lib64")
903 include 'libart.so'
904 include 'libbacktrace.so'
905 include 'libbase.so'
906 include 'libc++.so'
907 include 'libcutils.so'
908 include 'liblz4.so'
909 include 'liblzma.so'
910 include 'libnativebridge.so'
911 include 'libnativeloader.so'
912 include 'libsigchain.so'
913 include 'libunwind.so'
914 include 'libziparchive.so'
915 }
916 copy {
917 from file("${androidCheckoutDir}/out/host/linux-x86/nativetest")
918 into file("${artTestBuildDir}/lib")
919 include 'lib*.so'
920 }
921 copy {
922 from file("${androidCheckoutDir}/out/host/linux-x86/lib")
923 into file("${artTestBuildDir}/lib")
924 include 'libart.so'
925 include 'libbacktrace.so'
926 include 'libbase.so'
927 include 'libc++.so'
928 include 'libcutils.so'
929 include 'liblz4.so'
930 include 'liblzma.so'
931 include 'libnativebridge.so'
932 include 'libnativeloader.so'
933 include 'libsigchain.so'
934 include 'libunwind.so'
935 include 'libziparchive.so'
936 }
937 }
938 }
939}
940
941def buildArtTest(androidCheckoutDir, artTestBuildDir, dir, dexTool) {
942 def artTestDir = file("${androidCheckoutDir}/art/test")
943 def artRunTestScript = file("${artTestDir}/run-test")
944 def dxExecutable = new File("tools/linux/dx/bin/dx");
945 def dexMergerExecutable = new File("tools/linux/dx/bin/dexmerger");
946 def dexToolName = dexTool == DexTool.DX ? "dx" : "jack"
947
948 def name = dir.getName();
949 def buildTask = "build_art_test_${dexToolName}_${name}"
950 def sanitizeTask = "sanitize_art_test_${dexToolName}_${name}"
951 def copyCheckTask = "copy_check_art_test_${dexToolName}_${name}"
952 def smaliToDexTask = "smali_to_dex_${dexToolName}_${name}"
953
954 def buildInputs = fileTree(dir: dir, include: '**/*')
955 def testDir = file("${artTestBuildDir}/${dexToolName}/${name}")
956 def outputJar = testDir.toPath().resolve("${name}.jar").toFile()
957 testDir.mkdirs()
958 if (dexTool == DexTool.DX) {
959 task "$buildTask"(type: Exec) {
960 outputs.upToDateWhen { false }
961 inputs.file buildInputs
962 executable "${artRunTestScript}"
963 args "--host"
964 args "--build-only"
965 args "--build-with-javac-dx"
966 args "--output-path", "${testDir}"
967 args "${name}"
968 environment DX: "${dxExecutable.absolutePath}"
969 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
970 outputs.file outputJar
971 }
972 } else {
973 assert dexTool == DexTool.JACK
974 def javaLibs = "${androidCheckoutDir}/out/host/common/obj/JAVA_LIBRARIES"
975 def jackClasspath = "${javaLibs}/core-libart-hostdex_intermediates/classes.jack:" +
976 "${javaLibs}/core-oj-hostdex_intermediates/classes.jack"
977 task "$buildTask"(type: Exec) {
978 outputs.upToDateWhen { false }
979 inputs.file buildInputs
980 executable "${artRunTestScript}"
981 args "--host"
982 args "--build-only"
983 args "--output-path", "${testDir}"
984 args "${name}"
985 environment JACK: "${androidCheckoutDir}/out/host/linux-x86/bin/jack"
986 environment JACK_CLASSPATH: jackClasspath
987 environment DXMERGER: "${dexMergerExecutable.absolutePath}"
988 environment ANDROID_BUILD_TOP: "${androidCheckoutDir}"
989 outputs.file outputJar
990 }
991 }
992 task "${sanitizeTask}"(type: Exec, dependsOn: buildTask) {
993 outputs.upToDateWhen { false }
994 executable "/bin/bash"
995 args "-c"
996 args "rm -rf ${testDir}/smali_*.dex ${testDir}/*-ex.dex ${testDir}/*-ex.jar" +
997 " ${testDir}/classes-ex ${testDir}/check"
998 }
999
1000 task "${smaliToDexTask}"(type: Exec) {
1001 workingDir "${testDir}/smali"
1002 executable "/bin/bash"
1003 args "-c", "smali -o out.dex *.smali"
1004 }
1005
1006 task "${copyCheckTask}"(type: Copy, dependsOn: sanitizeTask) {
1007 def smali_dir = file("${dir}/smali")
1008 outputs.upToDateWhen { false }
1009 if (smali_dir.exists() && dexTool == DexTool.DX) {
1010 dependsOn smaliToDexTask
1011 }
1012 from("${artTestDir}/${name}") {
1013 include 'check'
1014 }
1015 into testDir
1016 }
1017
1018 return copyCheckTask
1019}
1020
1021task javadocD8(type: Javadoc) {
1022 classpath = sourceSets.main.compileClasspath
1023 source = sourceSets.main.allJava
1024 include '**/com/android/tools/r8/BaseCommand.java'
1025 include '**/com/android/tools/r8/BaseOutput.java'
1026 include '**/com/android/tools/r8/CompilationException.java'
1027 include '**/com/android/tools/r8/CompilationMode.java'
1028 include '**/com/android/tools/r8/D8.java'
1029 include '**/com/android/tools/r8/D8Command.java'
1030 include '**/com/android/tools/r8/D8Output.java'
1031 include '**/com/android/tools/r8/Resource.java'
1032}