Merge "Add simple flag file support to D8 and R8."
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 1db187e..250f2e9 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.ExceptionUtils;
+import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
@@ -93,8 +94,9 @@
});
}
- private static void run(String[] args) throws CompilationFailedException {
- D8Command command = D8Command.parse(args, CommandLineOrigin.INSTANCE).build();
+ private static void run(String[] args) throws CompilationFailedException, IOException {
+ String[] expandedArgs = FlagFile.expandFlagFiles(args);
+ D8Command command = D8Command.parse(expandedArgs, CommandLineOrigin.INSTANCE).build();
if (command.isPrintHelp()) {
System.out.println(USAGE_MESSAGE);
return;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 53e2f87..8e1722e 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -51,6 +51,7 @@
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.android.tools.r8.utils.LineNumberOptimizer;
@@ -89,7 +90,7 @@
* <p>R8 supports some configuration using configuration files mostly compatible with the format of
* the <a href="https://www.guardsquare.com/en/proguard">ProGuard</a> optimizer.
*
- * <p>The compiler is invoked by calling {@link #run(R8Command) R8.run} with an appropriate {@link
+ * <p>The compiler is invoked by calling {@link #run(R8Command) R8.run} with an appropriate {link
* R8Command}. For example:
*
* <pre>
@@ -533,8 +534,9 @@
}
}
- private static void run(String[] args) throws CompilationFailedException {
- R8Command command = R8Command.parse(args, CommandLineOrigin.INSTANCE).build();
+ private static void run(String[] args) throws CompilationFailedException, IOException {
+ String[] expandedArgs = FlagFile.expandFlagFiles(args);
+ R8Command command = R8Command.parse(expandedArgs, CommandLineOrigin.INSTANCE).build();
if (command.isPrintHelp()) {
System.out.println(USAGE_MESSAGE);
return;
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index dafa35a..ced17d4 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -23,7 +23,6 @@
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -581,29 +580,6 @@
builder.addProguardConfigurationFiles(Paths.get(args[++i]));
} else if (arg.equals("--pg-map-output")) {
builder.setProguardMapOutputPath(Paths.get(args[++i]));
- } else if (arg.startsWith("@")) {
- // TODO(zerny): Replace this with pipe reading.
- Path argsFile = Paths.get(arg.substring(1));
- Origin argsFileOrigin = new PathOrigin(argsFile);
- try {
- List<String> linesInFile = FileUtils.readAllLines(argsFile);
- List<String> argsInFile = new ArrayList<>();
- for (String line : linesInFile) {
- for (String word : line.split("\\s")) {
- String trimmed = word.trim();
- if (!trimmed.isEmpty()) {
- argsInFile.add(trimmed);
- }
- }
- }
- // TODO(zerny): We need to define what CWD should be for files referenced in an args file.
- state = parse(argsInFile.toArray(new String[argsInFile.size()]),
- argsFileOrigin, builder, state);
- } catch (IOException e) {
- builder.getReporter().error(new StringDiagnostic(
- "Failed to read arguments from file " + argsFile + ": " + e.getMessage(),
- argsFileOrigin));
- }
} else {
if (arg.startsWith("--")) {
builder.getReporter().error(new StringDiagnostic("Unknown option: " + arg, argsOrigin));
diff --git a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
index 9c7f525..577632a 100644
--- a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
@@ -74,7 +74,7 @@
}
public interface MainAction {
- void run() throws CompilationFailedException;
+ void run() throws CompilationFailedException, IOException;
}
public static void withMainProgramHandler(MainAction action) {
@@ -84,7 +84,7 @@
// Detail of the errors were already reported
System.err.println("Compilation failed");
System.exit(STATUS_ERROR);
- } catch (RuntimeException e) {
+ } catch (RuntimeException | IOException e) {
System.err.println("Compilation failed with an internal error.");
Throwable cause = e.getCause() == null ? e : e.getCause();
cause.printStackTrace();
diff --git a/src/main/java/com/android/tools/r8/utils/FlagFile.java b/src/main/java/com/android/tools/r8/utils/FlagFile.java
new file mode 100644
index 0000000..2354066
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/FlagFile.java
@@ -0,0 +1,25 @@
+// Copyright (c) 2018, 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.utils;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlagFile {
+ public static String[] expandFlagFiles(String[] args) throws IOException {
+ List<String> flags = new ArrayList<>(args.length);
+ for (String arg : args) {
+ if (arg.startsWith("@")) {
+ flags.addAll(Files.readAllLines(Paths.get(arg.substring(1))));
+ } else {
+ flags.add(arg);
+ }
+ }
+ return flags.toArray(new String[flags.size()]);
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index a11c960..5576058 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -6,12 +6,15 @@
import static com.android.tools.r8.R8CommandTest.getOutputPath;
import static com.android.tools.r8.ToolHelper.EXAMPLES_BUILD_DIR;
import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.android.sdklib.AndroidVersion;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
@@ -20,6 +23,7 @@
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
@@ -87,6 +91,26 @@
}
@Test
+ public void flagsFile() throws Throwable {
+ Path working = temp.getRoot().toPath();
+ Path flagsFile = working.resolve("flags.txt");
+ Path input = Paths.get(EXAMPLES_BUILD_DIR + "/arithmetic.jar").toAbsolutePath();
+ Path output = working.resolve("output.zip");
+ FileUtils.writeTextFile(
+ flagsFile,
+ "--output",
+ output.toString(),
+ "--min-api",
+ "24",
+ input.toString());
+ assertEquals(0, ToolHelper.forkD8(working, "@flags.txt").exitCode);
+ assertTrue(Files.exists(output));
+ Marker marker = ExtractMarker.extractMarkerFromDexFile(output);
+ assertEquals(24, marker.getMinApi().intValue());
+ assertEquals(Tool.D8, marker.getTool());
+ }
+
+ @Test
public void printsHelpOnNoInput() throws Throwable {
ProcessResult result = ToolHelper.forkD8(temp.getRoot().toPath());
assertFalse(result.exitCode == 0);
diff --git a/src/test/java/com/android/tools/r8/R8CommandTest.java b/src/test/java/com/android/tools/r8/R8CommandTest.java
index a7c7e02..c1072bd 100644
--- a/src/test/java/com/android/tools/r8/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/R8CommandTest.java
@@ -11,6 +11,8 @@
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.utils.FileUtils;
import com.google.common.collect.ImmutableList;
@@ -90,6 +92,29 @@
}
@Test
+ public void flagsFile() throws Throwable {
+ Path working = temp.getRoot().toPath();
+ Path library = ToolHelper.getDefaultAndroidJar();
+ Path input = Paths.get(EXAMPLES_BUILD_DIR + "/arithmetic.jar").toAbsolutePath();
+ Path output = working.resolve("output.zip");
+ Path flagsFile = working.resolve("flags.txt");
+ FileUtils.writeTextFile(
+ flagsFile,
+ "--output",
+ output.toString(),
+ "--min-api",
+ "24",
+ "--lib",
+ library.toAbsolutePath().toString(),
+ input.toString());
+ assertEquals(0, ToolHelper.forkR8(working, "@flags.txt").exitCode);
+ assertTrue(Files.exists(output));
+ Marker marker = ExtractMarker.extractMarkerFromDexFile(output);
+ assertEquals(24, marker.getMinApi().intValue());
+ assertEquals(Tool.R8, marker.getTool());
+ }
+
+ @Test
public void printsHelpOnNoInput() throws Throwable {
ProcessResult result = ToolHelper.forkR8(temp.getRoot().toPath());
assertFalse(result.exitCode == 0);
@@ -260,24 +285,6 @@
}
@Test
- public void argumentsInFile() throws Throwable {
- Path inputFile = temp.newFile("foobar.class").toPath();
- Path pgConfFile = temp.newFile("pgconf.config").toPath();
- Path argsFile = temp.newFile("more-args.txt").toPath();
- FileUtils.writeTextFile(argsFile, ImmutableList.of(
- "--debug --no-minification",
- "--pg-conf " + pgConfFile,
- inputFile.toString()
- ));
- R8Command command = parse("@" + argsFile.toString());
- assertEquals(CompilationMode.DEBUG, command.getMode());
- assertFalse(command.getEnableMinification());
- assertFalse(
- command.getEnableTreeShaking()); // We have no keep rules (proguard config file is empty).
- assertEquals(1, ToolHelper.getApp(command).getClassProgramResourcesForTesting().size());
- }
-
- @Test
public void nonExistingOutputJar() throws Throwable {
Path nonExistingJar = temp.getRoot().toPath().resolve("non-existing-archive.jar");
R8Command.builder().setOutput(nonExistingJar, OutputMode.DexIndexed).build();