• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dx.command;
18 
19 import com.android.dx.Version;
20 
21 /**
22  * Main class for dx. It recognizes enough options to be able to dispatch
23  * to the right "actual" main.
24  */
25 public class Main {
26     private static final String USAGE_MESSAGE =
27         "usage:\n" +
28         "  dx --dex [--debug] [--verbose] [--positions=<style>] [--no-locals]\n" +
29         "  [--no-optimize] [--statistics] [--[no-]optimize-list=<file>] [--no-strict]\n" +
30         "  [--keep-classes] [--output=<file>] [--dump-to=<file>] [--dump-width=<n>]\n" +
31         "  [--dump-method=<name>[*]] [--verbose-dump] [--no-files] [--core-library]\n" +
32         "  [--num-threads=<n>] [--incremental] [--force-jumbo] [--no-warning]\n" +
33         "  [--multi-dex [--main-dex-list=<file> [--minimal-main-dex]]\n" +
34         "  [--input-list=<file>] [--min-sdk-version=<n>]\n" +
35         "  [--allow-all-interface-method-invokes]\n" +
36         "  [<file>.class | <file>.{zip,jar,apk} | <directory>] ...\n" +
37         "    Convert a set of classfiles into a dex file, optionally embedded in a\n" +
38         "    jar/zip. Output name must end with one of: .dex .jar .zip .apk or be a\n" +
39         "    directory.\n" +
40         "    Positions options: none, important, lines.\n" +
41         "    --multi-dex: allows to generate several dex files if needed. This option is\n" +
42         "    exclusive with --incremental, causes --num-threads to be ignored and only\n" +
43         "    supports folder or archive output.\n" +
44         "    --main-dex-list=<file>: <file> is a list of class file names, classes\n" +
45         "    defined by those class files are put in classes.dex.\n" +
46         "    --minimal-main-dex: only classes selected by --main-dex-list are to be put\n" +
47         "    in the main dex.\n" +
48         "    --input-list: <file> is a list of inputs.\n" +
49         "    Each line in <file> must end with one of: .class .jar .zip .apk or be a\n" +
50         "    directory.\n" +
51         "    --min-sdk-version=<n>: Enable dex file features that require at least sdk\n" +
52         "    version <n>.\n" +
53         "  dx --annotool --annotation=<class> [--element=<element types>]\n" +
54         "  [--print=<print types>]\n" +
55         "  dx --dump [--debug] [--strict] [--bytes] [--optimize]\n" +
56         "  [--basic-blocks | --rop-blocks | --ssa-blocks | --dot] [--ssa-step=<step>]\n" +
57         "  [--width=<n>] [<file>.class | <file>.txt] ...\n" +
58         "    Dump classfiles, or transformations thereof, in a human-oriented format.\n" +
59         "  dx --find-usages <file.dex> <declaring type> <member>\n" +
60         "    Find references and declarations to a field or method.\n" +
61         "    <declaring type> is a class name in internal form, like Ljava/lang/Object;\n" +
62         "    <member> is a field or method name, like hashCode.\n" +
63         "  dx -J<option> ... <arguments, in one of the above forms>\n" +
64         "    Pass VM-specific options to the virtual machine that runs dx.\n" +
65         "  dx --version\n" +
66         "    Print the version of this tool (" + Version.VERSION + ").\n" +
67         "  dx --help\n" +
68         "    Print this message.";
69 
70     /**
71      * This class is uninstantiable.
72      */
Main()73     private Main() {
74         // This space intentionally left blank.
75     }
76 
77     /**
78      * Run!
79      */
main(String[] args)80     public static void main(String[] args) {
81         boolean gotCmd = false;
82         boolean showUsage = false;
83 
84         try {
85             for (int i = 0; i < args.length; i++) {
86                 String arg = args[i];
87                 if (arg.equals("--") || !arg.startsWith("--")) {
88                     gotCmd = false;
89                     showUsage = true;
90                     break;
91                 }
92 
93                 gotCmd = true;
94                 if (arg.equals("--dex")) {
95                     com.android.dx.command.dexer.Main.main(without(args, i));
96                     break;
97                 } else if (arg.equals("--dump")) {
98                     com.android.dx.command.dump.Main.main(without(args, i));
99                     break;
100                 } else if (arg.equals("--annotool")) {
101                     com.android.dx.command.annotool.Main.main(
102                             without(args, i));
103                     break;
104                 } else if (arg.equals("--find-usages")) {
105                     com.android.dx.command.findusages.Main.main(without(args, i));
106                     break;
107                 } else if (arg.equals("--version")) {
108                     version();
109                     break;
110                 } else if (arg.equals("--help")) {
111                     showUsage = true;
112                     break;
113                 } else {
114                     gotCmd = false;
115                 }
116             }
117         } catch (UsageException ex) {
118             showUsage = true;
119         } catch (RuntimeException ex) {
120             System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
121             ex.printStackTrace();
122             System.exit(2);
123         } catch (Throwable ex) {
124             System.err.println("\nUNEXPECTED TOP-LEVEL ERROR:");
125             ex.printStackTrace();
126             if ((ex instanceof NoClassDefFoundError)
127                     || (ex instanceof NoSuchMethodError)) {
128                 System.err.println(
129                         "Note: You may be using an incompatible " +
130                         "virtual machine or class library.\n" +
131                         "(This program is known to be incompatible " +
132                         "with recent releases of GCJ.)");
133             }
134             System.exit(3);
135         }
136 
137         if (!gotCmd) {
138             System.err.println("error: no command specified");
139             showUsage = true;
140         }
141 
142         if (showUsage) {
143             usage();
144             System.exit(1);
145         }
146     }
147 
148     /**
149      * Prints the version message.
150      */
version()151     private static void version() {
152         System.err.println("dx version " + Version.VERSION);
153         System.exit(0);
154     }
155 
156     /**
157      * Prints the usage message.
158      */
usage()159     private static void usage() {
160         System.err.println(USAGE_MESSAGE);
161     }
162 
163     /**
164      * Returns a copy of the given args array, but without the indicated
165      * element.
166      *
167      * @param orig {@code non-null;} original array
168      * @param n which element to omit
169      * @return {@code non-null;} new array
170      */
without(String[] orig, int n)171     private static String[] without(String[] orig, int n) {
172         int len = orig.length - 1;
173         String[] newa = new String[len];
174         System.arraycopy(orig, 0, newa, 0, n);
175         System.arraycopy(orig, n + 1, newa, n, len - n);
176         return newa;
177     }
178 }
179