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 String USAGE_MESSAGE =
     27         "usage:\n" +
     28         "  dx --dex [--debug] [--verbose] [--positions=<style>] " +
     29         "[--no-locals]\n" +
     30         "  [--no-optimize] [--statistics] [--[no-]optimize-list=<file>] " +
     31         "[--no-strict]\n" +
     32         "  [--keep-classes] [--output=<file>] [--dump-to=<file>] " +
     33         "[--dump-width=<n>]\n" +
     34         "  [--dump-method=<name>[*]] [--verbose-dump] [--no-files] " +
     35         "[--core-library]\n" +
     36         "  [--num-threads=<n>] [--incremental] [--force-jumbo]\n" +
     37         "  [--multi-dex [--main-dex-list=<file> [--minimal-main-dex]]\n" +
     38         "  [--input-list=<file>]\n" +
     39         "  [<file>.class | <file>.{zip,jar,apk} | <directory>] ...\n" +
     40         "    Convert a set of classfiles into a dex file, optionally " +
     41         "embedded in a\n" +
     42         "    jar/zip. Output name must end with one of: .dex .jar " +
     43         ".zip .apk or be a directory.\n" +
     44         "    Positions options: none, important, lines.\n" +
     45         "    --multi-dex: allows to generate several dex files if needed. " +
     46         "This option is \n" +
     47         "    exclusive with --incremental, causes --num-threads to be ignored " +
     48         "and only\n" +
     49         "    supports folder or archive output.\n" +
     50         "    --main-dex-list=<file>: <file> is a list of class file names, " +
     51         "classes defined by\n" +
     52         "    those class files are put in classes.dex.\n" +
     53         "    --minimal-main-dex: only classes selected by --main-dex-list are " +
     54         "to be put in\n" +
     55         "    the main dex.\n" +
     56         "    --input-list: <file> is a list of inputs.\n" +
     57         "    Each line in <file> must end with one of: .class .jar .zip .apk or be a directory.\n" +
     58         "  dx --annotool --annotation=<class> [--element=<element types>]\n" +
     59         "  [--print=<print types>]\n" +
     60         "  dx --dump [--debug] [--strict] [--bytes] [--optimize]\n" +
     61         "  [--basic-blocks | --rop-blocks | --ssa-blocks | --dot] " +
     62         "[--ssa-step=<step>]\n" +
     63         "  [--width=<n>] [<file>.class | <file>.txt] ...\n" +
     64         "    Dump classfiles, or transformations thereof, in a " +
     65         "human-oriented format.\n" +
     66         "  dx --find-usages <file.dex> <declaring type> <member>\n" +
     67         "    Find references and declarations to a field or method.\n" +
     68         "    declaring type: a class name in internal form, like " +
     69         "Ljava/lang/Object;\n" +
     70         "    member: a field or method name, like hashCode\n" +
     71         "  dx -J<option> ... <arguments, in one of the above " +
     72         "forms>\n" +
     73         "    Pass VM-specific options to the virtual machine that " +
     74         "runs dx.\n" +
     75         "  dx --version\n" +
     76         "    Print the version of this tool (" + Version.VERSION +
     77         ").\n" +
     78         "  dx --help\n" +
     79         "    Print this message.";
     80 
     81     /**
     82      * This class is uninstantiable.
     83      */
     84     private Main() {
     85         // This space intentionally left blank.
     86     }
     87 
     88     /**
     89      * Run!
     90      */
     91     public static void main(String[] args) {
     92         boolean gotCmd = false;
     93         boolean showUsage = false;
     94 
     95         try {
     96             for (int i = 0; i < args.length; i++) {
     97                 String arg = args[i];
     98                 if (arg.equals("--") || !arg.startsWith("--")) {
     99                     gotCmd = false;
    100                     showUsage = true;
    101                     break;
    102                 }
    103 
    104                 gotCmd = true;
    105                 if (arg.equals("--dex")) {
    106                     com.android.dx.command.dexer.Main.main(without(args, i));
    107                     break;
    108                 } else if (arg.equals("--dump")) {
    109                     com.android.dx.command.dump.Main.main(without(args, i));
    110                     break;
    111                 } else if (arg.equals("--annotool")) {
    112                     com.android.dx.command.annotool.Main.main(
    113                             without(args, i));
    114                     break;
    115                 } else if (arg.equals("--find-usages")) {
    116                     com.android.dx.command.findusages.Main.main(without(args, i));
    117                     break;
    118                 } else if (arg.equals("--version")) {
    119                     version();
    120                     break;
    121                 } else if (arg.equals("--help")) {
    122                     showUsage = true;
    123                     break;
    124                 } else {
    125                     gotCmd = false;
    126                 }
    127             }
    128         } catch (UsageException ex) {
    129             showUsage = true;
    130         } catch (RuntimeException ex) {
    131             System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
    132             ex.printStackTrace();
    133             System.exit(2);
    134         } catch (Throwable ex) {
    135             System.err.println("\nUNEXPECTED TOP-LEVEL ERROR:");
    136             ex.printStackTrace();
    137             if ((ex instanceof NoClassDefFoundError)
    138                     || (ex instanceof NoSuchMethodError)) {
    139                 System.err.println(
    140                         "Note: You may be using an incompatible " +
    141                         "virtual machine or class library.\n" +
    142                         "(This program is known to be incompatible " +
    143                         "with recent releases of GCJ.)");
    144             }
    145             System.exit(3);
    146         }
    147 
    148         if (!gotCmd) {
    149             System.err.println("error: no command specified");
    150             showUsage = true;
    151         }
    152 
    153         if (showUsage) {
    154             usage();
    155             System.exit(1);
    156         }
    157     }
    158 
    159     /**
    160      * Prints the version message.
    161      */
    162     private static void version() {
    163         System.err.println("dx version " + Version.VERSION);
    164         System.exit(0);
    165     }
    166 
    167     /**
    168      * Prints the usage message.
    169      */
    170     private static void usage() {
    171         System.err.println(USAGE_MESSAGE);
    172     }
    173 
    174     /**
    175      * Returns a copy of the given args array, but without the indicated
    176      * element.
    177      *
    178      * @param orig {@code non-null;} original array
    179      * @param n which element to omit
    180      * @return {@code non-null;} new array
    181      */
    182     private static String[] without(String[] orig, int n) {
    183         int len = orig.length - 1;
    184         String[] newa = new String[len];
    185         System.arraycopy(orig, 0, newa, 0, n);
    186         System.arraycopy(orig, n + 1, newa, n, len - n);
    187         return newa;
    188     }
    189 }
    190