]> git.saurik.com Git - android/aapt.git/blame_incremental - Main.cpp
Initial Contribution
[android/aapt.git] / Main.cpp
... / ...
CommitLineData
1//
2// Copyright 2006 The Android Open Source Project
3//
4// Android Asset Packaging Tool main entry point.
5//
6#include "Main.h"
7#include "Bundle.h"
8
9#include <utils.h>
10#include <utils/ZipFile.h>
11
12#include <stdlib.h>
13#include <getopt.h>
14#include <assert.h>
15
16using namespace android;
17
18static const char* gProgName = "aapt";
19
20/*
21 * When running under Cygwin on Windows, this will convert slash-based
22 * paths into back-slash-based ones. Otherwise the ApptAssets file comparisons
23 * fail later as they use back-slash separators under Windows.
24 *
25 * This operates in-place on the path string.
26 */
27void convertPath(char *path) {
28 if (path != NULL && OS_PATH_SEPARATOR != '/') {
29 for (; *path; path++) {
30 if (*path == '/') {
31 *path = OS_PATH_SEPARATOR;
32 }
33 }
34 }
35}
36
37/*
38 * Print usage info.
39 */
40void usage(void)
41{
42 fprintf(stderr, "Android Asset Packaging Tool\n\n");
43 fprintf(stderr, "Usage:\n");
44 fprintf(stderr,
45 " %s l[ist] [-v] [-a] file.{zip,jar,apk}\n"
46 " List contents of Zip-compatible archive.\n\n", gProgName);
47 fprintf(stderr,
48 " %s d[ump] WHAT file.{apk} [asset [asset ...]]\n"
49 " permissions Print the permissions from the APK.\n"
50 " resources Print the resource table from the APK.\n"
51 " configurations Print the configurations in the APK.\n"
52 " xmltree Print the compiled xmls in the given assets.\n"
53 " xmlstrings Print the strings of the given compiled xml assets.\n\n", gProgName);
54 fprintf(stderr,
55 " %s p[ackage] [-f][-u][-m][-v][-x][-M AndroidManifest.xml] \\\n"
56 " [-I base-package [-I base-package ...]] \\\n"
57 " [-A asset-source-dir] [-P public-definitions-file] \\\n"
58 " [-S resource-sources] [-F apk-file] [-J R-file-dir] \\\n"
59 " [raw-files-dir [raw-files-dir] ...]\n"
60 "\n"
61 " Package the android resources. It will read assets and resources that are\n"
62 " supplied with the -M -A -S or raw-files-dir arguments. The -J -P -F and -R\n"
63 " options control which files are output.\n\n"
64 , gProgName);
65 fprintf(stderr,
66 " %s r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]\n"
67 " Delete specified files from Zip-compatible archive.\n\n",
68 gProgName);
69 fprintf(stderr,
70 " %s a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]\n"
71 " Add specified files to Zip-compatible archive.\n\n", gProgName);
72 fprintf(stderr,
73 " %s v[ersion]\n"
74 " Print program version.\n\n", gProgName);
75 fprintf(stderr,
76 " Modifiers:\n"
77 " -a print Android-specific data (resources, manifest) when listing\n"
78 " -c specify which configurations to include. The default is all\n"
79 " configurations. The value of the parameter should be a comma\n"
80 " separated list of configuration values. Locales should be specified\n"
81 " as either a language or language-region pair. Some examples:\n"
82 " en\n"
83 " port,en\n"
84 " port,land,en_US\n"
85 " If you put the special locale, zz_ZZ on the list, it will perform\n"
86 " pseudolocalization on the default locale, modifying all of the\n"
87 " strings so you can look for strings that missed the\n"
88 " internationalization process. For example:\n"
89 " port,land,zz_ZZ\n"
90 " -d one or more device assets to include, separated by commas\n"
91 " -f force overwrite of existing files\n"
92 " -j specify a jar or zip file containing classes to include\n"
93 " -m make package directories under location specified by -J\n"
94#if 0
95 " -p pseudolocalize the default configuration\n"
96#endif
97 " -u update existing packages (add new, replace older, remove deleted files)\n"
98 " -v verbose output\n"
99 " -x create extending (non-application) resource IDs\n"
100 " -z require localization of resource attributes marked with\n"
101 " localization=\"suggested\"\n"
102 " -A additional directory in which to find raw asset files\n"
103 " -F specify the apk file to output\n"
104 " -I add an existing package to base include set\n"
105 " -J specify where to output R.java resource constant definitions\n"
106 " -M specify full path to AndroidManifest.xml to include in zip\n"
107 " -P specify where to output public resource definitions\n"
108 " -S directory in which to find resources\n"
109 " -0 don't compress files we're adding\n");
110}
111
112/*
113 * Dispatch the command.
114 */
115int handleCommand(Bundle* bundle)
116{
117 //printf("--- command %d (verbose=%d force=%d):\n",
118 // bundle->getCommand(), bundle->getVerbose(), bundle->getForce());
119 //for (int i = 0; i < bundle->getFileSpecCount(); i++)
120 // printf(" %d: '%s'\n", i, bundle->getFileSpecEntry(i));
121
122 switch (bundle->getCommand()) {
123 case kCommandVersion: return doVersion(bundle);
124 case kCommandList: return doList(bundle);
125 case kCommandDump: return doDump(bundle);
126 case kCommandAdd: return doAdd(bundle);
127 case kCommandRemove: return doRemove(bundle);
128 case kCommandPackage: return doPackage(bundle);
129 default:
130 fprintf(stderr, "%s: requested command not yet supported\n", gProgName);
131 return 1;
132 }
133}
134
135/*
136 * Parse args.
137 */
138int main(int argc, char* const argv[])
139{
140 Bundle bundle;
141 bool wantUsage = false;
142 int result = 1; // pessimistically assume an error.
143
144 /* default to compression */
145 bundle.setCompressionMethod(ZipEntry::kCompressDeflated);
146
147 if (argc < 2) {
148 wantUsage = true;
149 goto bail;
150 }
151
152 if (argv[1][0] == 'v')
153 bundle.setCommand(kCommandVersion);
154 else if (argv[1][0] == 'd')
155 bundle.setCommand(kCommandDump);
156 else if (argv[1][0] == 'l')
157 bundle.setCommand(kCommandList);
158 else if (argv[1][0] == 'a')
159 bundle.setCommand(kCommandAdd);
160 else if (argv[1][0] == 'r')
161 bundle.setCommand(kCommandRemove);
162 else if (argv[1][0] == 'p')
163 bundle.setCommand(kCommandPackage);
164 else {
165 fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]);
166 wantUsage = true;
167 goto bail;
168 }
169 argc -= 2;
170 argv += 2;
171
172 /*
173 * Pull out flags. We support "-fv" and "-f -v".
174 */
175 while (argc && argv[0][0] == '-') {
176 /* flag(s) found */
177 const char* cp = argv[0] +1;
178
179 while (*cp != '\0') {
180 switch (*cp) {
181 case 'v':
182 bundle.setVerbose(true);
183 break;
184 case 'a':
185 bundle.setAndroidList(true);
186 break;
187 case 'c':
188 argc--;
189 argv++;
190 if (!argc) {
191 fprintf(stderr, "ERROR: No argument supplied for '-c' option\n");
192 wantUsage = true;
193 goto bail;
194 }
195 bundle.addConfigurations(argv[0]);
196 break;
197 case 'f':
198 bundle.setForce(true);
199 break;
200 case 'm':
201 bundle.setMakePackageDirs(true);
202 break;
203#if 0
204 case 'p':
205 bundle.setPseudolocalize(true);
206 break;
207#endif
208 case 'u':
209 bundle.setUpdate(true);
210 break;
211 case 'x':
212 bundle.setExtending(true);
213 break;
214 case 'z':
215 bundle.setRequireLocalization(true);
216 break;
217 case 'j':
218 argc--;
219 argv++;
220 if (!argc) {
221 fprintf(stderr, "ERROR: No argument supplied for '-j' option\n");
222 wantUsage = true;
223 goto bail;
224 }
225 convertPath(argv[0]);
226 bundle.addJarFile(argv[0]);
227 break;
228 case 'A':
229 argc--;
230 argv++;
231 if (!argc) {
232 fprintf(stderr, "ERROR: No argument supplied for '-A' option\n");
233 wantUsage = true;
234 goto bail;
235 }
236 convertPath(argv[0]);
237 bundle.setAssetSourceDir(argv[0]);
238 break;
239 case 'I':
240 argc--;
241 argv++;
242 if (!argc) {
243 fprintf(stderr, "ERROR: No argument supplied for '-I' option\n");
244 wantUsage = true;
245 goto bail;
246 }
247 convertPath(argv[0]);
248 bundle.addPackageInclude(argv[0]);
249 break;
250 case 'F':
251 argc--;
252 argv++;
253 if (!argc) {
254 fprintf(stderr, "ERROR: No argument supplied for '-F' option\n");
255 wantUsage = true;
256 goto bail;
257 }
258 convertPath(argv[0]);
259 bundle.setOutputAPKFile(argv[0]);
260 break;
261 case 'J':
262 argc--;
263 argv++;
264 if (!argc) {
265 fprintf(stderr, "ERROR: No argument supplied for '-J' option\n");
266 wantUsage = true;
267 goto bail;
268 }
269 convertPath(argv[0]);
270 bundle.setRClassDir(argv[0]);
271 break;
272 case 'M':
273 argc--;
274 argv++;
275 if (!argc) {
276 fprintf(stderr, "ERROR: No argument supplied for '-M' option\n");
277 wantUsage = true;
278 goto bail;
279 }
280 convertPath(argv[0]);
281 bundle.setAndroidManifestFile(argv[0]);
282 break;
283 case 'P':
284 argc--;
285 argv++;
286 if (!argc) {
287 fprintf(stderr, "ERROR: No argument supplied for '-P' option\n");
288 wantUsage = true;
289 goto bail;
290 }
291 convertPath(argv[0]);
292 bundle.setPublicOutputFile(argv[0]);
293 break;
294 case 'S':
295 argc--;
296 argv++;
297 if (!argc) {
298 fprintf(stderr, "ERROR: No argument supplied for '-S' option\n");
299 wantUsage = true;
300 goto bail;
301 }
302 convertPath(argv[0]);
303 bundle.setResourceSourceDir(argv[0]);
304 break;
305 case '0':
306 bundle.setCompressionMethod(ZipEntry::kCompressStored);
307 break;
308 default:
309 fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);
310 wantUsage = true;
311 goto bail;
312 }
313
314 cp++;
315 }
316 argc--;
317 argv++;
318 }
319
320 /*
321 * We're past the flags. The rest all goes straight in.
322 */
323 bundle.setFileSpec(argv, argc);
324
325 result = handleCommand(&bundle);
326
327bail:
328 if (wantUsage) {
329 usage();
330 result = 2;
331 }
332
333 //printf("--> returning %d\n", result);
334 return result;
335}