• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 vogar.commands;
18 
19 import com.google.common.collect.Lists;
20 
21 import java.io.File;
22 import java.util.Collection;
23 import java.util.List;
24 
25 import vogar.Log;
26 import vogar.util.Strings;
27 
28 /**
29  * Runs the Jack compiler to generate dex files.
30  */
31 public class Jack {
32     private static final File JACK_SCRIPT;
33     private static final File JACK_JAR;
34 
35     // Initialise the files for jack and jill, letting them be null if the files
36     // cannot be found.
37     static {
38         String sdkTop = System.getenv("ANDROID_BUILD_TOP");
39 
40         final File jackScript = new File(sdkTop + "/prebuilts/sdk/tools/jack");
41         final File jackJar = new File(sdkTop + "/prebuilts/sdk/tools/jack.jar");
42 
43         // If the system environment variable JACK_JAR is set then use that,
44         // otherwise find the jar relative to the AOSP source.
45         String jackJarEnv = System.getenv("JACK_JAR");
46 
47         final File jackJarFromEnv = (jackJarEnv != null) ? new File(jackJarEnv) : null;
48 
49         if (!jackScript.exists()) {
50             JACK_SCRIPT = null;
51         } else {
52             JACK_SCRIPT = jackScript;
53         }
54 
55         if (jackJarEnv != null && jackJarFromEnv.exists()) {
56             JACK_JAR = jackJarFromEnv;
57         } else {
58             if (!jackJar.exists()) {
59                 JACK_JAR = null;
60             } else {
61                 JACK_JAR = jackJar;
62             }
63         }
64     }
65 
66     /**
67      * Get an instance of the jack command with appropriate path settings.
68      *
69      * @return an instance of a jack command with appropriate paths to its dependencies if needed.
70      * @throws IllegalStateException when the jack command cannot be found.
71      */
getJackCommand(Log log)72     public static Jack getJackCommand(Log log) throws IllegalStateException {
73         if (JACK_SCRIPT != null) {
74             // Configure jack compiler with right JACK_SCRIPT path.
75             return new Jack(log, Lists.newArrayList(JACK_SCRIPT.getAbsolutePath()));
76         }
77         if (JACK_JAR != null) {
78             // Fallback to jack.jar, for previous releases.
79             return new Jack(log, Lists.newArrayList("java", "-jar", JACK_JAR.getAbsolutePath()));
80         }
81         throw new IllegalStateException("Jack library not found, cannot use jack.");
82     }
83 
84     private final Command.Builder builder;
85 
Jack(Log log, Collection<String> jackArgs)86     private Jack(Log log, Collection<String> jackArgs) {
87         this.builder = new Command.Builder(log);
88         builder.args(jackArgs);
89     }
90 
importFile(String path)91     public Jack importFile(String path) {
92         builder.args("--import", path);
93         return this;
94     }
95 
importMeta(String dir)96     public Jack importMeta(String dir) {
97         builder.args("--import-meta", dir);
98         return this;
99     }
100 
importResource(String dir)101     public Jack importResource(String dir) {
102         builder.args("--import-resource", dir);
103         return this;
104     }
105 
incrementalFolder(String dir)106     public Jack incrementalFolder(String dir) {
107         builder.args("--incremental--folder", dir);
108         return this;
109     }
110 
multiDex(String mode)111     public Jack multiDex(String mode) {
112         builder.args("--multi-dex", mode);
113         return this;
114     }
115 
sourceVersion(String version)116     public Jack sourceVersion(String version) {
117         setProperty("jack.java.source.version=" + version);
118         return this;
119     }
120 
minApiLevel(String minApiLevel)121     public Jack minApiLevel(String minApiLevel) {
122         setProperty("jack.android.min-api-level=" + minApiLevel);
123         return this;
124     }
125 
outputDex(String dir)126     public Jack outputDex(String dir) {
127         builder.args("--output-dex", dir);
128         return this;
129     }
130 
outputDexZip(String zipFile)131     public Jack outputDexZip(String zipFile) {
132         builder.args("--output-dex-zip", zipFile);
133         return this;
134     }
135 
outputJack(String path)136     public Jack outputJack(String path) {
137         builder.args("--output-jack", path);
138         return this;
139     }
140 
processor(String names)141     public Jack processor(String names) {
142         builder.args("--processor", names);
143         return this;
144     }
145 
processorPath(String path)146     public Jack processorPath(String path) {
147         builder.args("--processorpath", path);
148         return this;
149     }
150 
verbose(String mode)151     public Jack verbose(String mode) {
152         builder.args("--verbose", mode);
153         return this;
154     }
155 
addAnnotationProcessor(String processor)156     public Jack addAnnotationProcessor(String processor) {
157         builder.args("-A", processor);
158         return this;
159     }
160 
setProperty(String property)161     public Jack setProperty(String property) {
162         builder.args("-D", property);
163         return this;
164     }
165 
setClassPath(String classPath)166     public Jack setClassPath(String classPath) {
167         builder.args("-cp", classPath);
168         return this;
169     }
170 
setDebug()171     public Jack setDebug() {
172         builder.args("-g");
173         return this;
174     }
175 
setEnvVar(String key, String value)176     public Jack setEnvVar(String key, String value) {
177         builder.env(key, value);
178         return this;
179     }
180 
181     /**
182      * Runs the command with the preconfigured options on Jack, and returns the outcome.
183      *
184      * @return A list of output lines from running the command.
185      */
invoke()186     public List<String> invoke() {
187         return builder.execute();
188     }
189 
190     /**
191      * Runs the command with the preconfigured options on Jack, and returns the outcome.
192      * This method does not dirty the existing Jack instance, and can be safely reused
193      * to compile other files.
194      * @param files The files to compile.
195      * @return A list of output lines from running the command.
196      */
compile(Collection<File> files)197     public List<String> compile(Collection<File> files) {
198         return new Command.Builder(builder)
199                 .args((Object[]) Strings.objectsToStrings(files))
200                 .execute();
201     }
202 }
203