blob: f365f9f71a9b6b7482c054b005d01d052ea538de [file] [log] [blame]
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +01001// Copyright (c) 2023, 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.
4
Søren Gjesse4569e472023-10-25 15:15:17 +02005import java.net.URI
6import java.nio.file.Path
7import java.nio.file.Paths
8import kotlin.io.path.exists
9import java.nio.file.Files.readString
Ian Zerny8efb7cc2023-03-02 16:48:54 +010010import net.ltgt.gradle.errorprone.errorprone
Søren Gjesse4569e472023-10-25 15:15:17 +020011import org.gradle.api.artifacts.ModuleVersionIdentifier
Morten Krogh-Jespersendd3a14e2023-09-08 20:39:43 +020012import org.gradle.api.artifacts.component.ModuleComponentIdentifier
Søren Gjesse4569e472023-10-25 15:15:17 +020013import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
14import org.spdx.sbom.gradle.SpdxSbomTask
15import org.spdx.sbom.gradle.extensions.DefaultSpdxSbomTaskExtension
16
17import com.google.gson.Gson
Søren Gjesse7ec4b3f2023-11-01 09:39:20 +010018import java.util.UUID
Ian Zerny8efb7cc2023-03-02 16:48:54 +010019
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +010020plugins {
21 `kotlin-dsl`
22 id("dependencies-plugin")
Ian Zerny8efb7cc2023-03-02 16:48:54 +010023 id("net.ltgt.errorprone") version "3.0.1"
Søren Gjesse50a858a2023-12-12 12:44:11 +010024 id("org.spdx.sbom") version "0.4.0"
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +010025}
26
27java {
28 sourceSets.main.configure {
29 java.srcDir(getRoot().resolveAll("src", "main", "java"))
30 resources.srcDirs(getRoot().resolveAll("third_party", "api_database", "api_database"))
31 }
32 sourceCompatibility = JvmCompatibility.sourceCompatibility
33 targetCompatibility = JvmCompatibility.targetCompatibility
Morten Krogh-Jespersenc06e2222023-09-18 17:52:21 +020034 withSourcesJar()
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +010035}
36
37dependencies {
38 implementation(":keepanno")
Rico Winde633b582023-08-03 08:38:22 +020039 implementation(":resourceshrinker")
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +020040 compileOnly(Deps.asm)
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +020041 compileOnly(Deps.asmCommons)
Morten Krogh-Jespersen91584d72023-06-21 13:45:07 +020042 compileOnly(Deps.asmUtil)
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +020043 compileOnly(Deps.fastUtil)
44 compileOnly(Deps.gson)
45 compileOnly(Deps.guava)
46 compileOnly(Deps.kotlinMetadata)
Ian Zerny8efb7cc2023-03-02 16:48:54 +010047 errorprone(Deps.errorprone)
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +010048}
49
Søren Gjesse4569e472023-10-25 15:15:17 +020050if (project.hasProperty("spdxVersion")) {
Søren Gjesse7ec4b3f2023-11-01 09:39:20 +010051 project.version = project.property("spdxVersion")!!
Søren Gjesse4569e472023-10-25 15:15:17 +020052}
53
54spdxSbom {
55 targets {
56 create("r8") {
57 // Use of both compileClasspath and runtimeClasspath due to how the
58 // dependencies jar is built and dependencies above therefore use
59 // compileOnly for actual runtime dependencies.
60 configurations.set(listOf("compileClasspath", "runtimeClasspath"))
61 scm {
62 uri.set("https://r8.googlesource.com/r8/")
Søren Gjesse00dd7da2023-11-01 09:16:04 +010063 if (project.hasProperty("spdxRevision")) {
64 revision.set(project.property("spdxRevision").toString())
65 }
Søren Gjesse4569e472023-10-25 15:15:17 +020066 }
67 document {
68 name.set("R8 Compiler Suite")
Søren Gjesse7ec4b3f2023-11-01 09:39:20 +010069 // Generate version 5 UUID from fixed namespace UUID and name generated from revision
70 // (git hash) and artifact name.
71 if (project.hasProperty("spdxRevision")) {
72 namespace.set(
73 "https://spdx.google/"
74 + uuid5(
75 UUID.fromString("df17ea25-709b-4edc-8dc1-d3ca82c74e8e"),
76 project.property("spdxRevision").toString() + "-r8"
77 )
78 )
79 }
Søren Gjesse4569e472023-10-25 15:15:17 +020080 creator.set("Organization: Google LLC")
81 packageSupplier.set("Organization: Google LLC")
82 }
83 }
84 }
85}
86
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +020087val keepAnnoJarTask = projectTask("keepanno", "jar")
Rico Winde633b582023-08-03 08:38:22 +020088val resourceShrinkerJarTask = projectTask("resourceshrinker", "jar")
89val resourceShrinkerDepsTask = projectTask("resourceshrinker", "depsJar")
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +020090
91fun mainJarDependencies() : FileCollection {
92 return sourceSets
93 .main
94 .get()
95 .compileClasspath
96 .filter({ "$it".contains("third_party")
97 && "$it".contains("dependencies")
98 && !"$it".contains("errorprone")
99 })
100}
101
102tasks {
103 withType<Exec> {
104 doFirst {
105 println("Executing command: ${commandLine.joinToString(" ")}")
106 }
107 }
108
Morten Krogh-Jespersen91584d72023-06-21 13:45:07 +0200109 withType<ProcessResources> {
Morten Krogh-Jespersenad74d682023-09-14 15:55:18 +0200110 dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
Morten Krogh-Jespersen91584d72023-06-21 13:45:07 +0200111 }
112
Søren Gjesse4569e472023-10-25 15:15:17 +0200113 withType<SpdxSbomTask> {
114 taskExtension.set(object : DefaultSpdxSbomTaskExtension() {
115 override fun mapRepoUri(input: URI?, moduleId: ModuleVersionIdentifier): URI? {
116
117 // Locate the file origin.json with URL for download location.
118 fun getOriginJson() : java.nio.file.Path {
119 var repositoryDir =
120 moduleId.group.replace('.', '/') + "/" + moduleId.name + "/" + moduleId.version
Søren Gjesse80ae2c72023-10-26 12:04:01 +0200121 return Paths.get("third_party", "dependencies", repositoryDir, "origin.json");
Søren Gjesse4569e472023-10-25 15:15:17 +0200122 }
123
124 // Simple data model of the content of origin.json generated by the tool to download
125 // and create a local repository. E.g.:
126 /*
127 {
128 "artifacts": [
129 {
130 "file": "org/ow2/asm/asm/9.5/asm-9.5.pom",
131 "repo": "https://repo1.maven.org/maven2/",
132 "artifact": "org.ow2.asm:asm:pom:9.5"
133 },
134 {
135 "file": "org/ow2/asm/asm/9.5/asm-9.5.jar",
136 "repo": "https://repo1.maven.org/maven2/",
137 "artifact": "org.ow2.asm:asm:jar:9.5"
138 }
139 ]
140 }
141 */
142 data class Artifact(val file: String, val repo: String, val artifact: String)
143 data class Artifacts(val artifacts: List<Artifact>)
144
145 // Read origin.json.
146 val json = readString(getOriginJson());
147 val artifacts = Gson().fromJson(json, Artifacts::class.java);
148 return URI.create(artifacts.artifacts.get(0).repo)
149 }
150 })
151 }
152
Morten Krogh-Jespersencef9a9d2023-09-10 23:06:41 +0200153 val consolidatedLicense by registering {
Morten Krogh-Jespersenad74d682023-09-14 15:55:18 +0200154 dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
Morten Krogh-Jespersendd3a14e2023-09-08 20:39:43 +0200155 val root = getRoot()
156 val r8License = root.resolve("LICENSE")
157 val libraryLicense = root.resolve("LIBRARY-LICENSE")
158 val libraryLicenseFiles = fileTree(root.resolve("library-licensing"))
159 inputs.files(
160 listOf(r8License, libraryLicense),
161 libraryLicenseFiles,
162 mainJarDependencies().map(::zipTree))
163
Rico Winde386dc72023-09-19 10:45:02 +0200164 val license = getRoot().resolveAll("build", "generatedLicense", "LICENSE")
Morten Krogh-Jespersendd3a14e2023-09-08 20:39:43 +0200165 outputs.files(license)
Rico Windde900d22023-10-12 08:53:28 +0200166 val dependencies = mutableListOf<String>()
167 configurations
168 .findByName("runtimeClasspath")!!
169 .resolvedConfiguration
170 .resolvedArtifacts
171 .forEach {
172 val identifier = it.id.componentIdentifier
173 if (identifier is ModuleComponentIdentifier) {
174 dependencies.add("${identifier.group}:${identifier.module}")
175 }
176 }
Morten Krogh-Jespersendd3a14e2023-09-08 20:39:43 +0200177
178 doLast {
Morten Krogh-Jespersendd3a14e2023-09-08 20:39:43 +0200179 val libraryLicenses = libraryLicense.readText()
180 dependencies.forEach {
181 if (!libraryLicenses.contains("- artifact: $it")) {
182 throw GradleException("No license for $it in LIBRARY_LICENSE")
183 }
184 }
185 license.getParentFile().mkdirs()
186 license.createNewFile()
187 license.writeText(buildString {
188 append("This file lists all licenses for code distributed.\n")
189 .append("All non-library code has the following 3-Clause BSD license.\n")
190 .append("\n")
191 .append("\n")
192 .append(r8License.readText())
193 .append("\n")
194 .append("\n")
195 .append("Summary of distributed libraries:\n")
196 .append("\n")
197 .append(libraryLicenses)
198 .append("\n")
199 .append("\n")
200 .append("Licenses details:\n")
201 libraryLicenseFiles.sorted().forEach { file ->
202 append("\n").append("\n").append(file.readText())
203 }
204 })
205 }
206 }
207
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200208 val swissArmyKnife by registering(Jar::class) {
Rico Wind34f80642023-09-14 10:45:17 +0200209 dependsOn(keepAnnoJarTask)
210 dependsOn(resourceShrinkerJarTask)
Morten Krogh-Jespersenad74d682023-09-14 15:55:18 +0200211 dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200212 from(sourceSets.main.get().output)
Ian Zerny3fb99fb2023-10-31 08:16:41 +0100213 exclude("com/android/tools/r8/threading/providers/**")
Rico Wind34f80642023-09-14 10:45:17 +0200214 from(keepAnnoJarTask.outputs.files.map(::zipTree))
215 from(resourceShrinkerJarTask.outputs.files.map(::zipTree))
Rico Windd0a656e2023-09-25 09:40:07 +0200216 from(getRoot().resolve("LICENSE"))
Rico Wind5be586a2023-09-22 13:47:54 +0200217 entryCompression = ZipEntryCompression.STORED
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200218 manifest {
219 attributes["Main-Class"] = "com.android.tools.r8.SwissArmyKnife"
220 }
221 exclude("META-INF/*.kotlin_module")
222 exclude("**/*.kotlin_metadata")
Rico Wind293d6e02023-09-14 15:15:47 +0200223 destinationDirectory.set(getRoot().resolveAll("build", "libs"))
224 archiveFileName.set("r8-full-exclude-deps.jar")
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200225 }
226
Ian Zerny3fb99fb2023-10-31 08:16:41 +0100227 val threadingModuleBlockingJar by registering(Zip::class) {
228 from(sourceSets.main.get().output)
229 include("com/android/tools/r8/threading/providers/blocking/**")
230 destinationDirectory.set(getRoot().resolveAll("build", "libs"))
231 archiveFileName.set("threading-module-blocking.jar")
232 }
233
234 val threadingModuleSingleThreadedJar by registering(Zip::class) {
235 from(sourceSets.main.get().output)
236 include("com/android/tools/r8/threading/providers/singlethreaded/**")
237 destinationDirectory.set(getRoot().resolveAll("build", "libs"))
238 archiveFileName.set("threading-module-single-threaded.jar")
239 }
240
Rico Windd0a656e2023-09-25 09:40:07 +0200241 val depsJar by registering(Zip::class) {
Morten Krogh-Jespersenad74d682023-09-14 15:55:18 +0200242 dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
Rico Winde633b582023-08-03 08:38:22 +0200243 dependsOn(resourceShrinkerDepsTask)
Ian Zerny3fb99fb2023-10-31 08:16:41 +0100244 dependsOn(threadingModuleBlockingJar)
245 dependsOn(threadingModuleSingleThreadedJar)
246 from(threadingModuleBlockingJar.get().outputs.getFiles().map(::zipTree))
247 from(threadingModuleSingleThreadedJar.get().outputs.getFiles().map(::zipTree))
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200248 from(mainJarDependencies().map(::zipTree))
Rico Winde633b582023-08-03 08:38:22 +0200249 from(resourceShrinkerDepsTask.outputs.files.map(::zipTree))
Rico Windd0a656e2023-09-25 09:40:07 +0200250 from(consolidatedLicense)
Morten Krogh-Jespersen7096e542023-08-18 08:09:19 +0200251 exclude("**/module-info.class")
252 exclude("**/*.kotlin_metadata")
253 exclude("META-INF/*.kotlin_module")
254 exclude("META-INF/com.android.tools/**")
255 exclude("META-INF/LICENSE*")
256 exclude("META-INF/MANIFEST.MF")
257 exclude("META-INF/maven/**")
258 exclude("META-INF/proguard/**")
Morten Krogh-Jespersen7096e542023-08-18 08:09:19 +0200259 exclude("META-INF/versions/**")
Morten Krogh-Jespersen782e4662023-09-11 16:24:59 +0200260 exclude("META-INF/services/kotlin.reflect.**")
Morten Krogh-Jespersen81d8bb62023-08-18 15:30:38 +0200261 exclude("**/*.xml")
262 exclude("com/android/version.properties")
Morten Krogh-Jespersen7096e542023-08-18 08:09:19 +0200263 exclude("NOTICE")
264 exclude("README.md")
Morten Krogh-Jespersen81d8bb62023-08-18 15:30:38 +0200265 exclude("javax/annotation/**")
266 exclude("wireless/**")
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200267 duplicatesStrategy = DuplicatesStrategy.EXCLUDE
268 archiveFileName.set("deps.jar")
269 }
270
Rico Windd0a656e2023-09-25 09:40:07 +0200271
272val swissArmyKnifeWithoutLicense by registering(Zip::class) {
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200273 dependsOn(swissArmyKnife)
Rico Windd0a656e2023-09-25 09:40:07 +0200274 from(swissArmyKnife.get().outputs.files.map(::zipTree))
275 exclude("LICENSE")
276 archiveFileName.set("swiss-army-no-license.jar")
277}
278
279val r8WithRelocatedDeps by registering(Exec::class) {
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200280 dependsOn(depsJar)
Rico Windd0a656e2023-09-25 09:40:07 +0200281 dependsOn(swissArmyKnifeWithoutLicense)
282 val swissArmy = swissArmyKnifeWithoutLicense.get().outputs.getFiles().getSingleFile()
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200283 val deps = depsJar.get().outputs.files.getSingleFile()
284 inputs.files(listOf(swissArmy, deps))
Rico Windb267e5d2023-09-14 13:14:14 +0200285 val output = getRoot().resolveAll("build", "libs", "r8.jar")
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200286 outputs.file(output)
287 commandLine = baseCompilerCommandLine(
288 swissArmy,
289 deps,
290 "relocator",
291 listOf("--input",
292 "$swissArmy",
293 "--input",
294 "$deps",
295 "--output",
296 "$output",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200297 // Add identity mapping to enforce no relocation of things already in package
298 // com.android.tools.r8.
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200299 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200300 "com.android.tools.r8.**->com.android.tools.r8",
Ian Zerny0538c072024-02-20 10:24:06 +0100301 // Add identify for the public annotation surface of keepanno
302 "--map",
303 "com.android.tools.r8.keepanno.annotations.**->com.android.tools.r8.keepanno.annotations",
304 // Explicitly move all other keepanno utilities.
305 "--map",
306 "com.android.tools.r8.keepanno.**->com.android.tools.r8.relocated.keepanno",
Rico Winded6c1cc2023-08-08 08:39:15 +0200307 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200308 "com.android.**->com.android.tools.r8.com.android",
Morten Krogh-Jespersen81d8bb62023-08-18 15:30:38 +0200309 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200310 "com.android.build.shrinker.**->com.android.tools.r8.resourceshrinker",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200311 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200312 "com.google.common.**->com.android.tools.r8.com.google.common",
Rico Winded6c1cc2023-08-08 08:39:15 +0200313 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200314 "com.google.gson.**->com.android.tools.r8.com.google.gson",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200315 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200316 "com.google.thirdparty.**->com.android.tools.r8.com.google.thirdparty",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200317 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200318 "org.objectweb.asm.**->com.android.tools.r8.org.objectweb.asm",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200319 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200320 "it.unimi.dsi.fastutil.**->com.android.tools.r8.it.unimi.dsi.fastutil",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200321 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200322 "kotlin.**->com.android.tools.r8.jetbrains.kotlin",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200323 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200324 "kotlinx.**->com.android.tools.r8.jetbrains.kotlinx",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200325 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200326 "org.jetbrains.**->com.android.tools.r8.org.jetbrains",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200327 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200328 "org.intellij.**->com.android.tools.r8.org.intellij",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200329 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200330 "org.checkerframework.**->com.android.tools.r8.org.checkerframework",
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200331 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200332 "com.google.j2objc.**->com.android.tools.r8.com.google.j2objc",
Morten Krogh-Jespersen81d8bb62023-08-18 15:30:38 +0200333 "--map",
Morten Krogh-Jespersen74215b42023-08-25 09:55:56 +0200334 "com.google.protobuf.**->com.android.tools.r8.com.google.protobuf",
Morten Krogh-Jespersen81d8bb62023-08-18 15:30:38 +0200335 "--map",
Rico Wind17d78152023-12-04 12:23:02 +0100336 "android.aapt.**->com.android.tools.r8.android.aapt"
Morten Krogh-Jespersend1a11852023-06-14 14:48:44 +0200337 ))
338 }
339}
340
Rico Wind51853ee2023-09-06 11:26:42 +0200341tasks.withType<KotlinCompile> {
342 enabled = false
343}
344
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +0100345tasks.withType<JavaCompile> {
Morten Krogh-Jespersenad74d682023-09-14 15:55:18 +0200346 dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +0100347 println("NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome)
Ian Zerny8efb7cc2023-03-02 16:48:54 +0100348
Christoffer Quist Adamsend139da02023-09-05 19:05:13 +0200349 // Enable error prone for D8/R8 main sources.
Christoffer Quist Adamsen08da5e52023-09-22 09:37:37 +0200350 options.errorprone.isEnabled.set(!project.hasProperty("disable_errorprone"))
Ian Zerny8efb7cc2023-03-02 16:48:54 +0100351
Christoffer Quist Adamsend139da02023-09-05 19:05:13 +0200352 // Make all warnings errors. Warnings that we have chosen not to fix (or suppress) are disabled
353 // outright below.
354 options.compilerArgs.add("-Werror")
355
356 // Increase number of reported errors to 1000 (default is 100).
357 options.compilerArgs.add("-Xmaxerrs")
358 options.compilerArgs.add("1000")
359
Ian Zerny8efb7cc2023-03-02 16:48:54 +0100360 // Non-default / Experimental checks - explicitly enforced.
361 options.errorprone.error("RemoveUnusedImports")
362 options.errorprone.error("InconsistentOverloads")
363 options.errorprone.error("MissingDefault")
364 options.errorprone.error("MultipleTopLevelClasses")
365 options.errorprone.error("NarrowingCompoundAssignment")
366
Ian Zerny8efb7cc2023-03-02 16:48:54 +0100367 // Warnings that cause unwanted edits (e.g., inability to write informative asserts).
368 options.errorprone.disable("AlreadyChecked")
369
370 // JavaDoc related warnings. Would be nice to resolve but of no real consequence.
371 options.errorprone.disable("InvalidLink")
372 options.errorprone.disable("InvalidBlockTag")
373 options.errorprone.disable("InvalidInlineTag")
374 options.errorprone.disable("EmptyBlockTag")
375 options.errorprone.disable("MissingSummary")
376 options.errorprone.disable("UnrecognisedJavadocTag")
377 options.errorprone.disable("AlmostJavadoc")
378
379 // Moving away from identity and canonical items is not planned.
Ian Zerny8efb7cc2023-03-02 16:48:54 +0100380 options.errorprone.disable("IdentityHashMapUsage")
Morten Krogh-Jespersen5a37de82023-03-02 01:42:28 +0100381}