Warn when startup classes do not fit in classes.dex
Bug: b/294189439
Change-Id: I279b09ec92dbc5e5d4718c268e92b8fab1b3dfd7
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index 7e8904d..73b009b 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.dex;
+import static com.android.tools.r8.errors.StartupClassesOverflowDiagnostic.Factory.createStartupClassesOverflowDiagnostic;
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import com.android.tools.r8.FeatureSplit;
@@ -1444,6 +1445,9 @@
virtualFile.commitTransaction();
}
}
+
+ options.reporter.warning(
+ createStartupClassesOverflowDiagnostic(cycler.filesForDistribution.size()));
}
if (options.getStartupOptions().isMinimalStartupDexEnabled()) {
diff --git a/src/main/java/com/android/tools/r8/errors/StartupClassesOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/StartupClassesOverflowDiagnostic.java
new file mode 100644
index 0000000..00290a2
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/StartupClassesOverflowDiagnostic.java
@@ -0,0 +1,51 @@
+// 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.
+
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+@Keep
+public class StartupClassesOverflowDiagnostic implements Diagnostic {
+
+ private final int numberOfStartupDexFiles;
+
+ StartupClassesOverflowDiagnostic(int numberOfStartupDexFiles) {
+ this.numberOfStartupDexFiles = numberOfStartupDexFiles;
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return Origin.unknown();
+ }
+
+ @Override
+ public Position getPosition() {
+ return Position.UNKNOWN;
+ }
+
+ @Override
+ public String getDiagnosticMessage() {
+ return "Unable to include all startup classes in classes.dex. "
+ + "Startup classes were distributed in: classes.dex, "
+ + IntStream.range(2, numberOfStartupDexFiles + 1)
+ .mapToObj(i -> "classes" + i + ".dex")
+ .collect(Collectors.joining(", "))
+ + ".";
+ }
+
+ // Public factory to keep the constructor of the diagnostic out of the public API.
+ public static class Factory {
+
+ public static StartupClassesOverflowDiagnostic createStartupClassesOverflowDiagnostic(
+ int numberOfStartupDexFiles) {
+ return new StartupClassesOverflowDiagnostic(numberOfStartupDexFiles);
+ }
+ }
+}