Home | History | Annotate | Download | only in command
      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      */
     73     private Main() {
     74         // This space intentionally left blank.
     75     }
     76 
     77     /**
     78      * Run!
     79      */
     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      */
    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      */
    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      */
    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