Initial configuration for new gradle setup

This is the first step towards cleaning up our build.gradle file by
moving to a new version. tools/gradle.py and tools/test.py should still
work the same.

Bug: b/270105162
Change-Id: I157cc9314dbdd4a0580f9351a6e0bb8c99b3a386
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 3f4e21f..88e29ab 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -7,18 +7,19 @@
 repositories {
     mavenCentral()
 }
+
 ext {
     asmVersion = '9.4'
 }
 
 dependencies {
-    compile group: 'com.google.guava', name: 'guava', version: '19.0'
-    compile group: 'org.smali', name: 'smali', version: '2.2b4'
-    compile group: 'org.ow2.asm', name: 'asm', version: asmVersion
-    compile group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
-    compile group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
-    compile group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
-    compile group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
+    implementation group: 'com.google.guava', name: 'guava', version: '30.1.1-jre'
+    implementation group: 'org.smali', name: 'smali', version: '2.2b4'
+    implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
+    implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
+    implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
+    implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
+    implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
 }
 
 sourceCompatibility = JavaVersion.VERSION_1_8
diff --git a/commonBuildSrc/build.gradle.kts b/commonBuildSrc/build.gradle.kts
new file mode 100644
index 0000000..ba393c7
--- /dev/null
+++ b/commonBuildSrc/build.gradle.kts
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+plugins {
+  `kotlin-dsl`
+  `java-gradle-plugin`
+}
+
+gradlePlugin {
+  plugins.register("dependencies-plugin") {
+    id = "dependencies-plugin"
+    implementationClass = "DependenciesPlugin"
+  }
+}
diff --git a/commonBuildSrc/settings.gradle.kts b/commonBuildSrc/settings.gradle.kts
new file mode 100644
index 0000000..b7d4523
--- /dev/null
+++ b/commonBuildSrc/settings.gradle.kts
@@ -0,0 +1,18 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+pluginManagement {
+    repositories {
+        gradlePluginPortal()
+    }
+}
+
+dependencyResolutionManagement {
+    repositories {
+        mavenCentral()
+        gradlePluginPortal()
+    }
+}
+
+rootProject.name = "common-build-src"
diff --git a/commonBuildSrc/src/main/kotlin/Dependencies.kt b/commonBuildSrc/src/main/kotlin/Dependencies.kt
new file mode 100644
index 0000000..b93dbcf
--- /dev/null
+++ b/commonBuildSrc/src/main/kotlin/Dependencies.kt
@@ -0,0 +1,63 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.JavaVersion
+import java.io.File
+
+class DependenciesPlugin: Plugin<Project> {
+  override fun apply(target: Project) {
+    // Intentionally empty
+  }
+}
+
+fun Project.getRoot() : File {
+  var parent = this.projectDir
+  while (!parent.getName().equals("d8_r8")) {
+    parent = parent.getParentFile()
+  }
+  return parent.getParentFile()
+}
+
+fun File.resolveAll(vararg xs: String) : File {
+  var that = this;
+  for (x in xs) {
+    that = that.resolve(x)
+  }
+  return that
+}
+
+object JvmCompatibility {
+  val sourceCompatibility = JavaVersion.VERSION_11
+  val targetCompatibility = JavaVersion.VERSION_11
+}
+
+object Versions {
+  const val asmVersion = "9.4"
+  const val fastUtilVersion = "7.2.0"
+  const val gsonVersion = "2.7"
+  const val guavaVersion = "30.1.1-jre"
+  const val joptSimpleVersion = "4.6"
+  const val junitVersion = "4.13-beta-2"
+  const val kotlinVersion = "1.8.0"
+  const val kotlinMetadataVersion = "0.6.0"
+  const val smaliVersion = "2.2b4"
+}
+
+object Deps {
+  val asm by lazy { "org.ow2.asm:asm:${Versions.asmVersion}" }
+  val asmUtil by lazy { "org.ow2.asm:asm-util:${Versions.asmVersion}" }
+  val asmCommons by lazy { "org.ow2.asm:asm-commons:${Versions.asmVersion}" }
+  val fastUtil by lazy { "it.unimi.dsi:fastutil:${Versions.fastUtilVersion}"}
+  val gson by lazy { "com.google.code.gson:gson:${Versions.gsonVersion}"}
+  val guava by lazy { "com.google.guava:guava:${Versions.guavaVersion}" }
+  val joptSimple by lazy { "net.sf.jopt-simple:jopt-simple:${Versions.joptSimpleVersion}" }
+  val junit by lazy { "junit:junit:${Versions.junitVersion}"}
+  val kotlinMetadata by lazy {
+    "org.jetbrains.kotlinx:kotlinx-metadata-jvm:${Versions.kotlinMetadataVersion}" }
+  val kotlinStdLib by lazy { "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlinVersion}" }
+  val kotlinReflect by lazy { "org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlinVersion}" }
+  val smali by lazy { "org.smali:smali:${Versions.smaliVersion}" }
+}
diff --git a/d8_r8/gradle.properties b/d8_r8/gradle.properties
new file mode 100644
index 0000000..ef0be28
--- /dev/null
+++ b/d8_r8/gradle.properties
@@ -0,0 +1,17 @@
+# Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx3g -Dkotlin.js.compiler.legacy.force_enabled=true
+systemProp.file.encoding=UTF-8
+
+# Enable new incremental compilation
+kotlin.incremental.useClasspathSnapshot=true
+
+org.gradle.parallel=true
+org.gradle.caching=true
+
+# Do not download any jdks or detect them. We provide them
+org.gradle.java.installations.auto-detect=false
+org.gradle.java.installations.auto-download=false
diff --git a/d8_r8/keepanno/build.gradle.kts b/d8_r8/keepanno/build.gradle.kts
new file mode 100644
index 0000000..b7a2acf
--- /dev/null
+++ b/d8_r8/keepanno/build.gradle.kts
@@ -0,0 +1,21 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+plugins {
+  `kotlin-dsl`
+  id("dependencies-plugin")
+}
+
+java {
+  sourceSets.main.configure {
+    java.srcDir(getRoot().resolveAll("src", "keepanno", "java"))
+  }
+  sourceCompatibility = JvmCompatibility.sourceCompatibility
+  targetCompatibility = JvmCompatibility.targetCompatibility
+}
+
+dependencies {
+  compileOnly(Deps.asm)
+  compileOnly(Deps.guava)
+}
diff --git a/d8_r8/keepanno/gradle.properties b/d8_r8/keepanno/gradle.properties
new file mode 100644
index 0000000..ef0be28
--- /dev/null
+++ b/d8_r8/keepanno/gradle.properties
@@ -0,0 +1,17 @@
+# Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx3g -Dkotlin.js.compiler.legacy.force_enabled=true
+systemProp.file.encoding=UTF-8
+
+# Enable new incremental compilation
+kotlin.incremental.useClasspathSnapshot=true
+
+org.gradle.parallel=true
+org.gradle.caching=true
+
+# Do not download any jdks or detect them. We provide them
+org.gradle.java.installations.auto-detect=false
+org.gradle.java.installations.auto-download=false
diff --git a/d8_r8/keepanno/settings.gradle.kts b/d8_r8/keepanno/settings.gradle.kts
new file mode 100644
index 0000000..7b4d459
--- /dev/null
+++ b/d8_r8/keepanno/settings.gradle.kts
@@ -0,0 +1,18 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+pluginManagement {
+    repositories {
+        gradlePluginPortal()
+    }
+}
+
+dependencyResolutionManagement {
+    repositories {
+        mavenCentral()
+        gradlePluginPortal()
+    }
+}
+
+rootProject.name = "keepanno"
diff --git a/d8_r8/main/build.gradle.kts b/d8_r8/main/build.gradle.kts
new file mode 100644
index 0000000..e664753
--- /dev/null
+++ b/d8_r8/main/build.gradle.kts
@@ -0,0 +1,33 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+plugins {
+  `kotlin-dsl`
+  id("dependencies-plugin")
+}
+
+java {
+  sourceSets.main.configure {
+    java.srcDir(getRoot().resolveAll("src", "main", "java"))
+    resources.srcDirs(getRoot().resolveAll("third_party", "api_database", "api_database"))
+  }
+  sourceCompatibility = JvmCompatibility.sourceCompatibility
+  targetCompatibility = JvmCompatibility.targetCompatibility
+}
+
+dependencies {
+  implementation(":keepanno")
+  implementation(Deps.asm)
+  implementation(Deps.asmUtil)
+  implementation(Deps.asmCommons)
+  implementation(Deps.fastUtil)
+  implementation(Deps.gson)
+  implementation(Deps.guava)
+  implementation(Deps.joptSimple)
+  implementation(Deps.kotlinMetadata)
+}
+
+tasks.withType<JavaCompile> {
+  println("NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome)
+}
diff --git a/d8_r8/main/gradle.properties b/d8_r8/main/gradle.properties
new file mode 100644
index 0000000..ef0be28
--- /dev/null
+++ b/d8_r8/main/gradle.properties
@@ -0,0 +1,17 @@
+# Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx3g -Dkotlin.js.compiler.legacy.force_enabled=true
+systemProp.file.encoding=UTF-8
+
+# Enable new incremental compilation
+kotlin.incremental.useClasspathSnapshot=true
+
+org.gradle.parallel=true
+org.gradle.caching=true
+
+# Do not download any jdks or detect them. We provide them
+org.gradle.java.installations.auto-detect=false
+org.gradle.java.installations.auto-download=false
diff --git a/d8_r8/main/settings.gradle.kts b/d8_r8/main/settings.gradle.kts
new file mode 100644
index 0000000..2d727f0
--- /dev/null
+++ b/d8_r8/main/settings.gradle.kts
@@ -0,0 +1,18 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+pluginManagement {
+    repositories {
+        gradlePluginPortal()
+    }
+}
+
+dependencyResolutionManagement {
+    repositories {
+        mavenCentral()
+        gradlePluginPortal()
+    }
+}
+
+rootProject.name = "r8"
diff --git a/d8_r8/settings.gradle.kts b/d8_r8/settings.gradle.kts
new file mode 100644
index 0000000..2feb93c
--- /dev/null
+++ b/d8_r8/settings.gradle.kts
@@ -0,0 +1,30 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// TODO(X): Move this file out the repository root when old gradle is removed.
+
+pluginManagement {
+    repositories {
+        gradlePluginPortal()
+    }
+}
+
+dependencyResolutionManagement {
+  repositories {
+    mavenCentral()
+    gradlePluginPortal()
+  }
+}
+
+rootProject.name = "d8-r8"
+
+// This project is temporarily located in d8_r8. When moved to root, the parent
+// folder should just be removed.
+includeBuild(rootProject.projectDir.parentFile.resolve("commonBuildSrc"))
+includeBuild("keepanno")
+
+// We need to include src/main as a composite-build otherwise our test-modules
+// will compete with the test to compile the source files.
+includeBuild("main")
+includeBuild("test")
diff --git a/d8_r8/test/build.gradle.kts b/d8_r8/test/build.gradle.kts
new file mode 100644
index 0000000..34f153b
--- /dev/null
+++ b/d8_r8/test/build.gradle.kts
@@ -0,0 +1,55 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+plugins {
+  `kotlin-dsl`
+  id("dependencies-plugin")
+}
+
+val root = getRoot();
+
+java {
+  sourceSets.test.configure {
+    java.srcDir(root.resolveAll("src", "test", "java"))
+  }
+  sourceCompatibility = JvmCompatibility.sourceCompatibility
+  targetCompatibility = JvmCompatibility.targetCompatibility
+}
+
+// We cannot use languageVersion.set(JavaLanguageVersion.of("8")) because gradle cannot figure
+// out that the jdk is 1_8 and will try to download it.
+tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
+  kotlinOptions {
+    jvmTarget = "11"
+  }
+}
+
+
+dependencies {
+  implementation(":r8")
+  implementation(":keepanno")
+  implementation(Deps.asm)
+  implementation(Deps.gson)
+  implementation(Deps.guava)
+  implementation(Deps.junit)
+  implementation(Deps.kotlinStdLib)
+  implementation(Deps.kotlinReflect)
+  implementation(Deps.kotlinMetadata)
+  implementation(files(root.resolveAll("third_party", "ddmlib", "ddmlib.jar")))
+  implementation(
+    files(
+      root.resolveAll("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar")))
+  implementation(files(root.resolveAll("third_party", "jasmin", "jasmin-2.4.jar")))
+  implementation(Deps.fastUtil)
+  implementation(Deps.smali)
+  implementation(Deps.asmUtil)
+}
+
+tasks.named("test") {
+  dependsOn(gradle.includedBuild("tests_java_8").task(":compileJava"))
+}
+
+tasks.withType<Test> {
+  environment("USE_NEW_GRADLE_SETUP", "true")
+}
diff --git a/d8_r8/test/gradle.properties b/d8_r8/test/gradle.properties
new file mode 100644
index 0000000..ef0be28
--- /dev/null
+++ b/d8_r8/test/gradle.properties
@@ -0,0 +1,17 @@
+# Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx3g -Dkotlin.js.compiler.legacy.force_enabled=true
+systemProp.file.encoding=UTF-8
+
+# Enable new incremental compilation
+kotlin.incremental.useClasspathSnapshot=true
+
+org.gradle.parallel=true
+org.gradle.caching=true
+
+# Do not download any jdks or detect them. We provide them
+org.gradle.java.installations.auto-detect=false
+org.gradle.java.installations.auto-download=false
diff --git a/d8_r8/test/settings.gradle.kts b/d8_r8/test/settings.gradle.kts
new file mode 100644
index 0000000..3138d52
--- /dev/null
+++ b/d8_r8/test/settings.gradle.kts
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+dependencyResolutionManagement {
+    repositories {
+        mavenCentral()
+        gradlePluginPortal()
+    }
+}
+
+rootProject.name = "r8-tests"
+
+val root = rootProject.projectDir.parentFile
+includeBuild(root.resolve("test_modules").resolve("tests_java_8"))
diff --git a/d8_r8/test_modules/tests_java_8/build.gradle.kts b/d8_r8/test_modules/tests_java_8/build.gradle.kts
new file mode 100644
index 0000000..9908599
--- /dev/null
+++ b/d8_r8/test_modules/tests_java_8/build.gradle.kts
@@ -0,0 +1,88 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import org.gradle.api.JavaVersion
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+plugins {
+  `kotlin-dsl`
+  `java-library`
+  id("dependencies-plugin")
+}
+
+val root = getRoot()
+
+java {
+  sourceSets.main.configure {
+    java.srcDir(root.resolveAll("src", "test", "java"))
+  }
+  sourceCompatibility = JavaVersion.VERSION_1_8
+  targetCompatibility = JavaVersion.VERSION_1_8
+}
+
+
+// We cannot use languageVersion.set(JavaLanguageVersion.of("8")) because gradle cannot figure
+// out that the jdk is 1_8 and will try to download it.
+tasks.withType<KotlinCompile> {
+  kotlinOptions {
+    jvmTarget = "1.8"
+  }
+}
+
+// The test module compilation depends on main and keep anno output, but we cannot directly
+// reference the task we only obtain a task reference. To obtain the actual reference by creating
+// a dummy.
+tasks.register("dummy-keepanno-reference") {
+  dependsOn(gradle.includedBuild("keepanno").task(":jar"))
+}
+val keepAnnoTask = tasks.getByName("dummy-keepanno-reference")
+  .taskDependencies
+  .getDependencies(tasks.getByName("dummy-keepanno-reference"))
+  .iterator()
+  .next()
+
+tasks.register("dummy-r8-reference") {
+  dependsOn(gradle.includedBuild("main").task(":jar"))
+}
+val r8Task = tasks.getByName("dummy-r8-reference")
+  .taskDependencies
+  .getDependencies(tasks.getByName("dummy-r8-reference"))
+  .iterator()
+  .next()
+
+dependencies {
+  implementation(keepAnnoTask.outputs.files)
+  implementation(r8Task.outputs.files)
+  implementation(Deps.asm)
+  implementation(Deps.gson)
+  implementation(Deps.guava)
+  implementation(Deps.junit)
+  implementation(Deps.kotlinStdLib)
+  implementation(Deps.kotlinReflect)
+  implementation(Deps.kotlinMetadata)
+  implementation(files(root.resolveAll("third_party", "ddmlib", "ddmlib.jar")))
+  implementation(
+    files(
+      root.resolveAll("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar")))
+  implementation(files(root.resolveAll("third_party", "jasmin", "jasmin-2.4.jar")))
+  implementation(Deps.fastUtil)
+  implementation(Deps.smali)
+  implementation(Deps.asmUtil)
+}
+
+tasks.withType<JavaCompile> {
+  dependsOn(keepAnnoTask)
+  dependsOn(r8Task)
+  options.setFork(true)
+  options.forkOptions.memoryMaximumSize = "3g"
+  options.forkOptions.jvmArgs = listOf(
+    "-Xss256m",
+    // Set the bootclass path so compilation is consistent with 1.8 target compatibility.
+    "-Xbootclasspath/a:third_party/openjdk/openjdk-rt-1.8/rt.jar")
+}
+
+tasks.withType<KotlinCompile> {
+    dependsOn(keepAnnoTask)
+    dependsOn(r8Task)
+}
diff --git a/d8_r8/test_modules/tests_java_8/gradle.properties b/d8_r8/test_modules/tests_java_8/gradle.properties
new file mode 100644
index 0000000..ef0be28
--- /dev/null
+++ b/d8_r8/test_modules/tests_java_8/gradle.properties
@@ -0,0 +1,17 @@
+# Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx3g -Dkotlin.js.compiler.legacy.force_enabled=true
+systemProp.file.encoding=UTF-8
+
+# Enable new incremental compilation
+kotlin.incremental.useClasspathSnapshot=true
+
+org.gradle.parallel=true
+org.gradle.caching=true
+
+# Do not download any jdks or detect them. We provide them
+org.gradle.java.installations.auto-detect=false
+org.gradle.java.installations.auto-download=false
diff --git a/d8_r8/test_modules/tests_java_8/settings.gradle.kts b/d8_r8/test_modules/tests_java_8/settings.gradle.kts
new file mode 100644
index 0000000..290b820
--- /dev/null
+++ b/d8_r8/test_modules/tests_java_8/settings.gradle.kts
@@ -0,0 +1,28 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+pluginManagement {
+  repositories {
+    gradlePluginPortal()
+  }
+}
+
+dependencyResolutionManagement {
+  repositories {
+    mavenCentral()
+    gradlePluginPortal()
+  }
+}
+
+rootProject.name = "r8-java8-tests"
+
+val d8Root = rootProject.projectDir.parentFile.parentFile
+val root = d8Root.parentFile
+
+includeBuild(root.resolve("commonBuildSrc"))
+includeBuild(d8Root.resolve("keepanno"))
+
+// We need to include src/main as a composite-build otherwise our test-modules
+// will compete with the test to compile the source files.
+includeBuild(d8Root.resolve("main"))
diff --git a/gradle.properties b/gradle.properties
index 41fabcc..b2b8d2a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,4 +2,16 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-org.gradle.jvmargs=-Xmx2048M
\ No newline at end of file
+org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx3g -Dkotlin.js.compiler.legacy.force_enabled=true
+systemProp.file.encoding=UTF-8
+
+# Enable new incremental compilation
+kotlin.incremental.useClasspathSnapshot=true
+
+org.gradle.parallel=true
+org.gradle.caching=true
+
+# Do not download any jdks or detect them. We provide them
+org.gradle.java.installations.auto-detect=false
+org.gradle.java.installations.auto-download=false
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 459fbce..bbdc05b 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -92,13 +92,26 @@
 
   static final Path[] EMPTY_PATH = {};
 
+  public static boolean isNewGradleSetup() {
+    return "true".equals(System.getenv("USE_NEW_GRADLE_SETUP"));
+  }
+
+  public static String getProjectRoot() {
+    String property = System.getProperty("user.dir");
+    if (property.endsWith("d8_r8/test")) {
+      return "../../";
+    }
+    return "";
+  }
+
   public static final String SOURCE_DIR = "src/main/java/";
   public static final String RESOURCES_DIR = "src/main/resources/";
   public static final String BUILD_DIR = "build/";
+  public static final String TEST_MODULE_DIR = getProjectRoot() + "d8_r8/test_modules/";
   public static final String GENERATED_TEST_BUILD_DIR = BUILD_DIR + "generated/test/";
   public static final String LIBS_DIR = BUILD_DIR + "libs/";
-  public static final String THIRD_PARTY_DIR = "third_party/";
-  public static final String TOOLS_DIR = "tools/";
+  public static final String THIRD_PARTY_DIR = getProjectRoot() + "third_party/";
+  public static final String TOOLS_DIR = getProjectRoot() + "tools/";
   public static final String TESTS_DIR = "src/test/";
   public static final String TESTS_SOURCE_DIR = "src/test/java";
   public static final String EXAMPLES_DIR = TESTS_DIR + "examples/";
@@ -137,29 +150,33 @@
   public static final String DEFAULT_PROGUARD_MAP_FILE = "proguard.map";
 
   public static final String CORE_LAMBDA_STUBS =
-      "third_party/core-lambda-stubs/core-lambda-stubs.jar";
-  public static final String JSR223_RI_JAR = "third_party/jsr223-api-1.0/jsr223-api-1.0.jar";
+      THIRD_PARTY_DIR + "core-lambda-stubs/core-lambda-stubs.jar";
+  public static final String JSR223_RI_JAR = THIRD_PARTY_DIR + "jsr223-api-1.0/jsr223-api-1.0.jar";
   public static final String RHINO_ANDROID_JAR =
-      "third_party/rhino-android-1.1.1/rhino-android-1.1.1.jar";
-  public static final String RHINO_JAR = "third_party/rhino-1.7.10/rhino-1.7.10.jar";
+      THIRD_PARTY_DIR + "rhino-android-1.1.1/rhino-android-1.1.1.jar";
+  public static final String RHINO_JAR = THIRD_PARTY_DIR + "rhino-1.7.10/rhino-1.7.10.jar";
   public static final String K2JVMCompiler = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler";
-  private static final String ANDROID_JAR_PATTERN = "third_party/android_jar/lib-v%d/android.jar";
+  private static final String ANDROID_JAR_PATTERN =
+      THIRD_PARTY_DIR + "android_jar/lib-v%d/android.jar";
   private static final String ANDROID_API_VERSIONS_XML_PATTERN =
-      "third_party/android_jar/lib-v%d/api-versions.xml";
+      THIRD_PARTY_DIR + "android_jar/lib-v%d/api-versions.xml";
   private static final AndroidApiLevel DEFAULT_MIN_SDK = AndroidApiLevel.I;
 
-  public static final String OPEN_JDK_DIR = "third_party/openjdk/";
+  public static final String OPEN_JDK_DIR = THIRD_PARTY_DIR + "openjdk/";
   public static final String JAVA_8_RUNTIME = OPEN_JDK_DIR + "openjdk-rt-1.8/rt.jar";
   public static final String JDK_11_TESTS_DIR = OPEN_JDK_DIR + "jdk-11-test/";
   public static final String JDK_11_TIME_TESTS_DIR = JDK_11_TESTS_DIR + "java/time/";
 
-  private static final String PROGUARD5_2_1 = "third_party/proguard/proguard5.2.1/bin/proguard";
-  private static final String PROGUARD6_0_1 = "third_party/proguard/proguard6.0.1/bin/proguard";
+  private static final String PROGUARD5_2_1 =
+      THIRD_PARTY_DIR + "proguard/proguard5.2.1/bin/proguard";
+  private static final String PROGUARD6_0_1 =
+      THIRD_PARTY_DIR + "proguard/proguard6.0.1/bin/proguard";
   private static final String PROGUARD = PROGUARD5_2_1;
   public static final Path JACOCO_ROOT = Paths.get("third_party", "jacoco", "0.8.6");
   public static final Path JACOCO_AGENT = JACOCO_ROOT.resolve(Paths.get("lib", "jacocoagent.jar"));
   public static final Path JACOCO_CLI = JACOCO_ROOT.resolve(Paths.get("lib", "jacococli.jar"));
-  public static final String PROGUARD_SETTINGS_FOR_INTERNAL_APPS = "third_party/proguardsettings/";
+  public static final String PROGUARD_SETTINGS_FOR_INTERNAL_APPS =
+      THIRD_PARTY_DIR + "proguardsettings/";
 
   public static final Path RETRACE_MAPS_DIR = Paths.get(THIRD_PARTY_DIR, "r8mappings");
 
@@ -609,8 +626,6 @@
     }
   }
 
-  private static final String TOOLS = "tools";
-
   private static final Map<DexVm, String> ART_DIRS =
       ImmutableMap.<DexVm, String>builder()
           .put(DexVm.ART_DEFAULT, "art")
@@ -715,7 +730,7 @@
 
   private static Path getDexVmPath(DexVm vm) {
     DexVm.Version version = vm.getVersion();
-    Path base = Paths.get(TOOLS, "linux");
+    Path base = Paths.get(TOOLS_DIR, "linux");
     switch (version) {
       case DEFAULT:
         return base.resolve("art");
@@ -799,7 +814,7 @@
     }
     if (isLinux() || isMac()) {
       // The Linux version is used on Mac, where it is run in a Docker container.
-      return TOOLS + "/linux/" + dir;
+      return TOOLS_DIR + "/linux/" + dir;
     }
     fail("Unsupported platform, we currently only support mac and linux: " + getPlatform());
     return ""; //never here
@@ -840,7 +855,7 @@
   private static Path getDxExecutablePath() {
     String toolsDir = toolsDir();
     String executableName = toolsDir.equals("windows") ? "dx.bat" : "dx";
-    return Paths.get(TOOLS, toolsDir(), "dx", "bin", executableName);
+    return Paths.get(TOOLS_DIR, toolsDir(), "dx", "bin", executableName);
   }
 
   public static String getArtBinary(DexVm version) {
@@ -895,7 +910,7 @@
 
   private static Path getAndroidJarPath(AndroidApiLevel apiLevel) {
     if (apiLevel == AndroidApiLevel.MASTER) {
-      return Paths.get("third_party/android_jar/lib-master/android.jar");
+      return Paths.get(THIRD_PARTY_DIR + "android_jar/lib-master/android.jar");
     }
     String jar = String.format(
         ANDROID_JAR_PATTERN,
@@ -1135,7 +1150,11 @@
   }
 
   public static Path getClassPathForTests() {
-    return Paths.get(BUILD_DIR, "classes", "java", "test");
+    if (isNewGradleSetup()) {
+      return Paths.get(TEST_MODULE_DIR, "tests_java_8", "build", "classes", "java", "main");
+    } else {
+      return Paths.get(BUILD_DIR, "classes", "java", "test");
+    }
   }
 
   private static List<String> getNamePartsForTestPackage(Package pkg) {
@@ -1201,7 +1220,7 @@
   public static Collection<Path> getClassFilesForInnerClasses(Collection<Class<?>> classes)
       throws IOException {
     Set<Path> paths = new HashSet<>();
-    for (Class clazz : classes) {
+    for (Class<?> clazz : classes) {
       Path path = ToolHelper.getClassFileForTestClass(clazz);
       String prefix = path.toString().replace(CLASS_EXTENSION, "$");
       paths.addAll(
diff --git a/tools/gradle.py b/tools/gradle.py
index 92503a7..b4bb786 100755
--- a/tools/gradle.py
+++ b/tools/gradle.py
@@ -19,16 +19,21 @@
 GRADLE_SHA1 = os.path.join(GRADLE_DIR, 'gradle.tar.gz.sha1')
 GRADLE_TGZ = os.path.join(GRADLE_DIR, 'gradle.tar.gz')
 
-if utils.IsWindows():
-  GRADLE = os.path.join(GRADLE_DIR, 'gradle', 'bin', 'gradle.bat')
-else:
-  GRADLE = os.path.join(GRADLE_DIR, 'gradle', 'bin', 'gradle')
+def get_gradle(new_gradle):
+  gradle_dir = 'gradle-8.0' if new_gradle else 'gradle'
+  if utils.IsWindows():
+    return os.path.join(GRADLE_DIR, gradle_dir, 'bin', 'gradle.bat')
+  else:
+    return os.path.join(GRADLE_DIR, gradle_dir, 'bin', 'gradle')
 
 def ParseOptions():
   parser = argparse.ArgumentParser(description = 'Call gradle.')
   parser.add_argument('--exclude-deps', '--exclude_deps',
       help='Build without internalized dependencies.',
       default=False, action='store_true')
+  parser.add_argument('--new-gradle', '--new_gradle',
+                      help='Run with new experimental gradle configuration',
+                      default=False, action='store_true')
   parser.add_argument('--no-internal', '--no_internal',
       help='Do not build with support for Google internal tests.',
       default=False, action='store_true')
@@ -54,9 +59,9 @@
   # I know this will hit os on windows eventually if we don't do this.
   sys.stdout.flush()
 
-def EnsureGradle():
+def EnsureGradle(new_gradle):
   utils.EnsureDepFromGoogleCloudStorage(
-    GRADLE, GRADLE_TGZ, GRADLE_SHA1, 'Gradle binary')
+    get_gradle(new_gradle), GRADLE_TGZ, GRADLE_SHA1, 'Gradle binary')
 
 def EnsureJdk():
   jdkRoot = jdk.GetJdkRoot()
@@ -64,13 +69,16 @@
   jdkSha1 = jdkTgz + '.sha1'
   utils.EnsureDepFromGoogleCloudStorage(jdkRoot, jdkTgz, jdkSha1, 'JDK')
 
-def EnsureDeps():
-  EnsureGradle()
+def EnsureDeps(new_gradle):
+  EnsureGradle(new_gradle)
   EnsureJdk()
 
-def RunGradleIn(gradleCmd, args, cwd, throw_on_failure=True, env=None):
-  EnsureDeps()
+def RunGradleIn(
+    gradleCmd, args, cwd, throw_on_failure=True, env=None, new_gradle=False):
+  EnsureDeps(new_gradle)
   cmd = [gradleCmd]
+  args.append(
+    '-c=d8_r8/settings.gradle.kts' if new_gradle else '-b=build.gradle')
   cmd.extend(args)
   utils.PrintCmd(cmd)
   with utils.ChangedWorkingDirectory(cwd):
@@ -82,16 +90,23 @@
 def RunGradleWrapperIn(args, cwd, throw_on_failure=True, env=None):
   return RunGradleIn('./gradlew', args, cwd, throw_on_failure, env=env)
 
-def RunGradle(args, throw_on_failure=True, env=None):
-  return RunGradleIn(GRADLE, args, utils.REPO_ROOT, throw_on_failure, env=env)
+def RunGradle(args, throw_on_failure=True, env=None, new_gradle=False):
+  return RunGradleIn(
+    get_gradle(new_gradle),
+    args,
+    utils.REPO_ROOT,
+    throw_on_failure,
+    env=env,
+    new_gradle=new_gradle)
 
-def RunGradleExcludeDeps(args, throw_on_failure=True, env=None):
-  EnsureDeps()
+def RunGradleExcludeDeps(
+    args, throw_on_failure=True, env=None, new_gradle=False):
+  EnsureDeps(new_gradle)
   args.append('-Pexclude_deps')
   return RunGradle(args, throw_on_failure, env=env)
 
-def RunGradleInGetOutput(gradleCmd, args, cwd, env=None):
-  EnsureDeps()
+def RunGradleInGetOutput(gradleCmd, args, cwd, env=None, new_gradle=False):
+  EnsureDeps(new_gradle)
   cmd = [gradleCmd]
   cmd.extend(args)
   utils.PrintCmd(cmd)
@@ -101,8 +116,13 @@
 def RunGradleWrapperInGetOutput(args, cwd, env=None):
   return RunGradleInGetOutput('./gradlew', args, cwd, env=env)
 
-def RunGradleGetOutput(args, env=None):
-  return RunGradleInGetOutput(GRADLE, args, utils.REPO_ROOT, env=env)
+def RunGradleGetOutput(args, env=None, new_gradle=False):
+  return RunGradleInGetOutput(
+    get_gradle(new_gradle),
+    args,
+    utils.REPO_ROOT,
+    env=env,
+    new_gradle=new_gradle)
 
 def Main():
   (options, args) = ParseOptions()
@@ -114,7 +134,7 @@
     args.append('-Pexclude_deps')
   if options.worktree:
     args.append('-g=' + os.path.join(utils.REPO_ROOT, ".gradle_user_home"))
-  return RunGradle(args)
+  return RunGradle(args, new_gradle=options.new_gradle)
 
 if __name__ == '__main__':
   sys.exit(Main())