blob: 8dbc785866752d504d28deb92139691441c65817 [file] [log] [blame]
// Copyright (c) 2017, the Rex 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;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class ExtractMarker {
private static class Command extends BaseCommand {
public static class Builder
extends BaseCommand.Builder<ExtractMarker.Command, ExtractMarker.Command.Builder> {
private boolean verbose;
@Override
ExtractMarker.Command.Builder self() {
return this;
}
public Builder setVerbose(boolean verbose) {
this.verbose = verbose;
return self();
}
@Override
public ExtractMarker.Command build() throws CompilationException, IOException {
// If printing versions ignore everything else.
if (isPrintHelp()) {
return new ExtractMarker.Command(isPrintHelp());
}
validate();
return new ExtractMarker.Command(getAppBuilder().build(), verbose, programFiles);
}
}
static final String USAGE_MESSAGE = String.join("\n", ImmutableList.of(
"Usage: extractmarker [options] <input-files>",
" where <input-files> are dex or vdex files",
" --version # Print the version of r8.",
" --verbose # More verbose output.",
" --help # Print this message."));
public static ExtractMarker.Command.Builder builder() {
// Allow vdex files for the extract marker tool.
return new ExtractMarker.Command.Builder().setVdexAllowed();
}
public static ExtractMarker.Command.Builder parse(String[] args)
throws CompilationException, IOException {
ExtractMarker.Command.Builder builder = builder();
parse(args, builder);
return builder;
}
private static void parse(String[] args, ExtractMarker.Command.Builder builder)
throws CompilationException, IOException {
for (int i = 0; i < args.length; i++) {
String arg = args[i].trim();
if (arg.length() == 0) {
continue;
} else if (arg.equals("--verbose")) {
builder.setVerbose(true);
} else if (arg.equals("--help")) {
builder.setPrintHelp(true);
} else {
if (arg.startsWith("--")) {
throw new CompilationException("Unknown option: " + arg);
}
builder.addProgramFiles(Paths.get(arg));
}
}
}
private final List<Path> programFiles;
private final boolean verbose;
private Command(AndroidApp inputApp, boolean verbose, List<Path> programFiles) {
super(inputApp);
this.programFiles = programFiles;
this.verbose = verbose;
}
private Command(boolean printHelp) {
super(printHelp, false);
this.verbose = false;
programFiles = ImmutableList.of();
}
public List<Path> getProgramFiles() {
return programFiles;
}
public boolean getVerbose() {
return verbose;
}
@Override
InternalOptions getInternalOptions() {
return new InternalOptions();
}
}
public static void main(String[] args)
throws IOException, CompilationException, ExecutionException {
ExtractMarker.Command.Builder builder = ExtractMarker.Command.parse(args);
ExtractMarker.Command command = builder.build();
if (command.isPrintHelp()) {
System.out.println(ExtractMarker.Command.USAGE_MESSAGE);
return;
}
try {
AndroidApp app = command.getInputApp();
InternalOptions options = new InternalOptions();
// Dex code is not needed for getting the marker. VDex files typically contains quickened byte
// codes which cannot be read, and we want to get the marker from vdex files as well.
options.skipReadingDexCode = true;
DexApplication dexApp = new ApplicationReader(app, options, new Timing("ExtractMarker"))
.read();
Marker readMarker = dexApp.dexItemFactory.extractMarker();
if (command.getVerbose()) {
for (int i = 0; i < command.getProgramFiles().size(); i++) {
if (i != 0) {
System.out.print(", ");
}
System.out.print(command.getProgramFiles().get(i));
}
System.out.print(": ");
}
if (readMarker == null) {
System.out.println("D8/R8 marker not found.");
System.exit(1);
} else {
System.out.println(readMarker.toString());
}
} catch (CompilationError e) {
System.out.println("Failed to read dex file: '" + e.getMessage() + "'");
System.exit(0);
}
}
}