blob: d714687ee914ff9416660b7ca0da038d1b4c8c0e [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001//
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
Elliott Hughes9ec96f92015-07-29 14:35:18 -07009#include <utils/Compat.h>
Adam Lesinski282e1812014-01-23 18:17:42 -080010#include <utils/Log.h>
11#include <utils/threads.h>
12#include <utils/List.h>
13#include <utils/Errors.h>
14
Adam Lesinski4bf58102014-11-03 11:21:19 -080015#include <cstdlib>
Adam Lesinski282e1812014-01-23 18:17:42 -080016#include <getopt.h>
Adam Lesinski4bf58102014-11-03 11:21:19 -080017#include <cassert>
Adam Lesinski282e1812014-01-23 18:17:42 -080018
19using namespace android;
20
21static const char* gProgName = "aapt";
22
Dan Willemsen896f0182017-09-08 22:02:41 -070023#ifndef AAPT_VERSION
24 #define AAPT_VERSION ""
25#endif
26
27/*
28 * Show version info. All the cool kids do it.
29 */
30int doVersion(Bundle* bundle)
31{
32 if (bundle->getFileSpecCount() != 0) {
33 printf("(ignoring extra arguments)\n");
34 }
35 printf("Android Asset Packaging Tool, v0.2-" AAPT_VERSION "\n");
36
37 return 0;
38}
39
Adam Lesinski282e1812014-01-23 18:17:42 -080040/*
41 * When running under Cygwin on Windows, this will convert slash-based
42 * paths into back-slash-based ones. Otherwise the ApptAssets file comparisons
43 * fail later as they use back-slash separators under Windows.
44 *
45 * This operates in-place on the path string.
46 */
47void convertPath(char *path) {
48 if (path != NULL && OS_PATH_SEPARATOR != '/') {
49 for (; *path; path++) {
50 if (*path == '/') {
51 *path = OS_PATH_SEPARATOR;
52 }
53 }
54 }
55}
56
57/*
58 * Print usage info.
59 */
60void usage(void)
61{
62 fprintf(stderr, "Android Asset Packaging Tool\n\n");
63 fprintf(stderr, "Usage:\n");
64 fprintf(stderr,
65 " %s l[ist] [-v] [-a] file.{zip,jar,apk}\n"
66 " List contents of Zip-compatible archive.\n\n", gProgName);
67 fprintf(stderr,
68 " %s d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]\n"
69 " strings Print the contents of the resource table string pool in the APK.\n"
70 " badging Print the label and icon for the app declared in APK.\n"
71 " permissions Print the permissions from the APK.\n"
72 " resources Print the resource table from the APK.\n"
73 " configurations Print the configurations in the APK.\n"
74 " xmltree Print the compiled xmls in the given assets.\n"
75 " xmlstrings Print the strings of the given compiled xml assets.\n\n", gProgName);
76 fprintf(stderr,
77 " %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n"
78 " [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n"
79 " [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
80 " [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\n"
81 " [--rename-manifest-package PACKAGE] \\\n"
82 " [--rename-instrumentation-target-package PACKAGE] \\\n"
83 " [--utf16] [--auto-add-overlay] \\\n"
84 " [--max-res-version VAL] \\\n"
85 " [-I base-package [-I base-package ...]] \\\n"
86 " [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n"
Rohit Agrawal86229cb2016-04-21 16:29:58 -070087 " [-D main-dex-class-list-file] \\\n"
Adam Lesinski282e1812014-01-23 18:17:42 -080088 " [-S resource-sources [-S resource-sources ...]] \\\n"
89 " [-F apk-file] [-J R-file-dir] \\\n"
90 " [--product product1,product2,...] \\\n"
Johan Redestig6ab7a782015-01-07 09:24:39 +010091 " [-c CONFIGS] [--preferred-density DENSITY] \\\n"
Adam Lesinskifab50872014-04-16 14:40:42 -070092 " [--split CONFIGS [--split CONFIGS]] \\\n"
Adam Lesinski833f3cc2014-06-18 15:06:01 -070093 " [--feature-of package [--feature-after package]] \\\n"
Adam Lesinski282e1812014-01-23 18:17:42 -080094 " [raw-files-dir [raw-files-dir] ...] \\\n"
95 " [--output-text-symbols DIR]\n"
96 "\n"
97 " Package the android resources. It will read assets and resources that are\n"
98 " supplied with the -M -A -S or raw-files-dir arguments. The -J -P -F and -R\n"
99 " options control which files are output.\n\n"
100 , gProgName);
101 fprintf(stderr,
102 " %s r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]\n"
103 " Delete specified files from Zip-compatible archive.\n\n",
104 gProgName);
105 fprintf(stderr,
106 " %s a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]\n"
107 " Add specified files to Zip-compatible archive.\n\n", gProgName);
108 fprintf(stderr,
109 " %s c[runch] [-v] -S resource-sources ... -C output-folder ...\n"
110 " Do PNG preprocessing on one or several resource folders\n"
111 " and store the results in the output folder.\n\n", gProgName);
112 fprintf(stderr,
113 " %s s[ingleCrunch] [-v] -i input-file -o outputfile\n"
114 " Do PNG preprocessing on a single file.\n\n", gProgName);
115 fprintf(stderr,
116 " %s v[ersion]\n"
117 " Print program version.\n\n", gProgName);
118 fprintf(stderr,
119 " Modifiers:\n"
120 " -a print Android-specific data (resources, manifest) when listing\n"
121 " -c specify which configurations to include. The default is all\n"
122 " configurations. The value of the parameter should be a comma\n"
123 " separated list of configuration values. Locales should be specified\n"
124 " as either a language or language-region pair. Some examples:\n"
125 " en\n"
126 " port,en\n"
127 " port,land,en_US\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800128 " -d one or more device assets to include, separated by commas\n"
129 " -f force overwrite of existing files\n"
130 " -g specify a pixel tolerance to force images to grayscale, default 0\n"
131 " -j specify a jar or zip file containing classes to include\n"
132 " -k junk path of file(s) added\n"
133 " -m make package directories under location specified by -J\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800134 " -u update existing packages (add new, replace older, remove deleted files)\n"
135 " -v verbose output\n"
136 " -x create extending (non-application) resource IDs\n"
137 " -z require localization of resource attributes marked with\n"
138 " localization=\"suggested\"\n"
139 " -A additional directory in which to find raw asset files\n"
140 " -G A file to output proguard options into.\n"
Rohit Agrawal86229cb2016-04-21 16:29:58 -0700141 " -D A file to output proguard options for the main dex into.\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800142 " -F specify the apk file to output\n"
143 " -I add an existing package to base include set\n"
144 " -J specify where to output R.java resource constant definitions\n"
145 " -M specify full path to AndroidManifest.xml to include in zip\n"
146 " -P specify where to output public resource definitions\n"
147 " -S directory in which to find resources. Multiple directories will be scanned\n"
148 " and the first match found (left to right) will take precedence.\n"
149 " -0 specifies an additional extension for which such files will not\n"
150 " be stored compressed in the .apk. An empty string means to not\n"
151 " compress any files at all.\n"
152 " --debug-mode\n"
153 " inserts android:debuggable=\"true\" in to the application node of the\n"
154 " manifest, making the application debuggable even on production devices.\n"
155 " --include-meta-data\n"
156 " when used with \"dump badging\" also includes meta-data tags.\n"
Igor Viarheichyka191d042014-06-02 17:16:24 -0700157 " --pseudo-localize\n"
158 " generate resources for pseudo-locales (en-XA and ar-XB).\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800159 " --min-sdk-version\n"
160 " inserts android:minSdkVersion in to manifest. If the version is 7 or\n"
161 " higher, the default encoding for resources will be in UTF-8.\n"
162 " --target-sdk-version\n"
163 " inserts android:targetSdkVersion in to manifest.\n"
164 " --max-res-version\n"
165 " ignores versioned resource directories above the given value.\n"
166 " --values\n"
167 " when used with \"dump resources\" also includes resource values.\n"
168 " --version-code\n"
169 " inserts android:versionCode in to manifest.\n"
170 " --version-name\n"
171 " inserts android:versionName in to manifest.\n"
Jeff Davidsondf08d1c2014-02-25 12:28:08 -0800172 " --replace-version\n"
173 " If --version-code and/or --version-name are specified, these\n"
174 " values will replace any value already in the manifest. By\n"
175 " default, nothing is changed if the manifest already defines\n"
176 " these attributes.\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800177 " --custom-package\n"
178 " generates R.java into a different package.\n"
179 " --extra-packages\n"
180 " generate R.java for libraries. Separate libraries with ':'.\n"
181 " --generate-dependencies\n"
182 " generate dependency files in the same directories for R.java and resource package\n"
183 " --auto-add-overlay\n"
184 " Automatically add resources that are only in overlays.\n"
Adam Lesinskifab50872014-04-16 14:40:42 -0700185 " --preferred-density\n"
186 " Specifies a preference for a particular density. Resources that do not\n"
187 " match this density and have variants that are a closer match are removed.\n"
188 " --split\n"
189 " Builds a separate split APK for the configurations listed. This can\n"
190 " be loaded alongside the base APK at runtime.\n"
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700191 " --feature-of\n"
192 " Builds a split APK that is a feature of the apk specified here. Resources\n"
193 " in the base APK can be referenced from the the feature APK.\n"
194 " --feature-after\n"
195 " An app can have multiple Feature Split APKs which must be totally ordered.\n"
196 " If --feature-of is specified, this flag specifies which Feature Split APK\n"
197 " comes before this one. The first Feature Split APK should not define\n"
198 " anything here.\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800199 " --rename-manifest-package\n"
200 " Rewrite the manifest so that its package name is the package name\n"
201 " given here. Relative class names (for example .Foo) will be\n"
202 " changed to absolute names with the old package so that the code\n"
203 " does not need to change.\n"
204 " --rename-instrumentation-target-package\n"
205 " Rewrite the manifest so that all of its instrumentation\n"
206 " components target the given package. Useful when used in\n"
207 " conjunction with --rename-manifest-package to fix tests against\n"
208 " a package that has been renamed.\n"
209 " --product\n"
210 " Specifies which variant to choose for strings that have\n"
211 " product variants\n"
212 " --utf16\n"
213 " changes default encoding for resources to UTF-16. Only useful when API\n"
214 " level is set to 7 or higher where the default encoding is UTF-8.\n"
215 " --non-constant-id\n"
216 " Make the resources ID non constant. This is required to make an R java class\n"
217 " that does not contain the final value but is used to make reusable compiled\n"
218 " libraries that need to access resources.\n"
Adam Lesinskide898ff2014-01-29 18:20:45 -0800219 " --shared-lib\n"
220 " Make a shared library resource package that can be loaded by an application\n"
221 " at runtime to access the libraries resources. Implies --non-constant-id.\n"
Tao Baia6d7e3f2015-09-01 18:49:54 -0700222 " --app-as-shared-lib\n"
223 " Make an app resource package that also can be loaded as shared library at runtime.\n"
224 " Implies --non-constant-id.\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800225 " --error-on-failed-insert\n"
226 " Forces aapt to return an error if it fails to insert values into the manifest\n"
227 " with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\n"
228 " and --version-name.\n"
229 " Insertion typically fails if the manifest already defines the attribute.\n"
Ying Wangcd28bd32013-11-14 17:12:10 -0800230 " --error-on-missing-config-entry\n"
231 " Forces aapt to return an error if it fails to find an entry for a configuration.\n"
Adam Lesinski282e1812014-01-23 18:17:42 -0800232 " --output-text-symbols\n"
233 " Generates a text file containing the resource symbols of the R class in the\n"
234 " specified folder.\n"
235 " --ignore-assets\n"
236 " Assets to be ignored. Default pattern is:\n"
Adam Lesinski6e460562015-04-21 14:20:15 -0700237 " %s\n"
Adrian Roos58922482015-06-01 17:59:41 -0700238 " --skip-symbols-without-default-localization\n"
239 " Prevents symbols from being generated for strings that do not have a default\n"
240 " localization\n"
Adam Lesinski6e460562015-04-21 14:20:15 -0700241 " --no-version-vectors\n"
Adam Lesinski78713992015-12-07 14:02:15 -0800242 " Do not automatically generate versioned copies of vector XML resources.\n"
Yuichi Araki4d35cca2017-01-18 20:42:17 +0900243 " --no-version-transitions\n"
244 " Do not automatically generate versioned copies of transition XML resources.\n"
Adam Lesinski78713992015-12-07 14:02:15 -0800245 " --private-symbols\n"
246 " Java package name to use when generating R.java for private resources.\n",
Adam Lesinski282e1812014-01-23 18:17:42 -0800247 gDefaultIgnoreAssets);
248}
249
250/*
251 * Dispatch the command.
252 */
253int handleCommand(Bundle* bundle)
254{
255 //printf("--- command %d (verbose=%d force=%d):\n",
256 // bundle->getCommand(), bundle->getVerbose(), bundle->getForce());
257 //for (int i = 0; i < bundle->getFileSpecCount(); i++)
258 // printf(" %d: '%s'\n", i, bundle->getFileSpecEntry(i));
259
260 switch (bundle->getCommand()) {
261 case kCommandVersion: return doVersion(bundle);
262 case kCommandList: return doList(bundle);
263 case kCommandDump: return doDump(bundle);
264 case kCommandAdd: return doAdd(bundle);
265 case kCommandRemove: return doRemove(bundle);
266 case kCommandPackage: return doPackage(bundle);
267 case kCommandCrunch: return doCrunch(bundle);
268 case kCommandSingleCrunch: return doSingleCrunch(bundle);
Jerome Dochez6f1280c2014-09-26 10:21:21 -0700269 case kCommandDaemon: return runInDaemonMode(bundle);
Adam Lesinski282e1812014-01-23 18:17:42 -0800270 default:
271 fprintf(stderr, "%s: requested command not yet supported\n", gProgName);
272 return 1;
273 }
274}
275
276/*
277 * Parse args.
278 */
279int main(int argc, char* const argv[])
280{
281 char *prog = argv[0];
282 Bundle bundle;
283 bool wantUsage = false;
284 int result = 1; // pessimistically assume an error.
285 int tolerance = 0;
286
287 /* default to compression */
288 bundle.setCompressionMethod(ZipEntry::kCompressDeflated);
289
290 if (argc < 2) {
291 wantUsage = true;
292 goto bail;
293 }
294
295 if (argv[1][0] == 'v')
296 bundle.setCommand(kCommandVersion);
297 else if (argv[1][0] == 'd')
298 bundle.setCommand(kCommandDump);
299 else if (argv[1][0] == 'l')
300 bundle.setCommand(kCommandList);
301 else if (argv[1][0] == 'a')
302 bundle.setCommand(kCommandAdd);
303 else if (argv[1][0] == 'r')
304 bundle.setCommand(kCommandRemove);
305 else if (argv[1][0] == 'p')
306 bundle.setCommand(kCommandPackage);
307 else if (argv[1][0] == 'c')
308 bundle.setCommand(kCommandCrunch);
309 else if (argv[1][0] == 's')
310 bundle.setCommand(kCommandSingleCrunch);
Jerome Dochez6f1280c2014-09-26 10:21:21 -0700311 else if (argv[1][0] == 'm')
312 bundle.setCommand(kCommandDaemon);
Adam Lesinski282e1812014-01-23 18:17:42 -0800313 else {
314 fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]);
315 wantUsage = true;
316 goto bail;
317 }
318 argc -= 2;
319 argv += 2;
320
321 /*
322 * Pull out flags. We support "-fv" and "-f -v".
323 */
324 while (argc && argv[0][0] == '-') {
325 /* flag(s) found */
326 const char* cp = argv[0] +1;
327
328 while (*cp != '\0') {
329 switch (*cp) {
330 case 'v':
331 bundle.setVerbose(true);
332 break;
333 case 'a':
334 bundle.setAndroidList(true);
335 break;
336 case 'c':
337 argc--;
338 argv++;
339 if (!argc) {
340 fprintf(stderr, "ERROR: No argument supplied for '-c' option\n");
341 wantUsage = true;
342 goto bail;
343 }
344 bundle.addConfigurations(argv[0]);
345 break;
346 case 'f':
347 bundle.setForce(true);
348 break;
349 case 'g':
350 argc--;
351 argv++;
352 if (!argc) {
353 fprintf(stderr, "ERROR: No argument supplied for '-g' option\n");
354 wantUsage = true;
355 goto bail;
356 }
357 tolerance = atoi(argv[0]);
358 bundle.setGrayscaleTolerance(tolerance);
359 printf("%s: Images with deviation <= %d will be forced to grayscale.\n", prog, tolerance);
360 break;
361 case 'k':
362 bundle.setJunkPath(true);
363 break;
364 case 'm':
365 bundle.setMakePackageDirs(true);
366 break;
367#if 0
368 case 'p':
369 bundle.setPseudolocalize(true);
370 break;
371#endif
372 case 'u':
373 bundle.setUpdate(true);
374 break;
375 case 'x':
376 bundle.setExtending(true);
377 break;
378 case 'z':
379 bundle.setRequireLocalization(true);
380 break;
381 case 'j':
382 argc--;
383 argv++;
384 if (!argc) {
385 fprintf(stderr, "ERROR: No argument supplied for '-j' option\n");
386 wantUsage = true;
387 goto bail;
388 }
389 convertPath(argv[0]);
390 bundle.addJarFile(argv[0]);
391 break;
392 case 'A':
393 argc--;
394 argv++;
395 if (!argc) {
396 fprintf(stderr, "ERROR: No argument supplied for '-A' option\n");
397 wantUsage = true;
398 goto bail;
399 }
400 convertPath(argv[0]);
Adam Lesinski09384302014-01-22 16:07:42 -0800401 bundle.addAssetSourceDir(argv[0]);
Adam Lesinski282e1812014-01-23 18:17:42 -0800402 break;
403 case 'G':
404 argc--;
405 argv++;
406 if (!argc) {
407 fprintf(stderr, "ERROR: No argument supplied for '-G' option\n");
408 wantUsage = true;
409 goto bail;
410 }
411 convertPath(argv[0]);
412 bundle.setProguardFile(argv[0]);
413 break;
Rohit Agrawal86229cb2016-04-21 16:29:58 -0700414 case 'D':
415 argc--;
416 argv++;
417 if (!argc) {
418 fprintf(stderr, "ERROR: No argument supplied for '-D' option\n");
419 wantUsage = true;
420 goto bail;
421 }
422 convertPath(argv[0]);
423 bundle.setMainDexProguardFile(argv[0]);
424 break;
Adam Lesinski282e1812014-01-23 18:17:42 -0800425 case 'I':
426 argc--;
427 argv++;
428 if (!argc) {
429 fprintf(stderr, "ERROR: No argument supplied for '-I' option\n");
430 wantUsage = true;
431 goto bail;
432 }
433 convertPath(argv[0]);
434 bundle.addPackageInclude(argv[0]);
435 break;
436 case 'F':
437 argc--;
438 argv++;
439 if (!argc) {
440 fprintf(stderr, "ERROR: No argument supplied for '-F' option\n");
441 wantUsage = true;
442 goto bail;
443 }
444 convertPath(argv[0]);
445 bundle.setOutputAPKFile(argv[0]);
446 break;
447 case 'J':
448 argc--;
449 argv++;
450 if (!argc) {
451 fprintf(stderr, "ERROR: No argument supplied for '-J' option\n");
452 wantUsage = true;
453 goto bail;
454 }
455 convertPath(argv[0]);
456 bundle.setRClassDir(argv[0]);
457 break;
458 case 'M':
459 argc--;
460 argv++;
461 if (!argc) {
462 fprintf(stderr, "ERROR: No argument supplied for '-M' option\n");
463 wantUsage = true;
464 goto bail;
465 }
466 convertPath(argv[0]);
467 bundle.setAndroidManifestFile(argv[0]);
468 break;
469 case 'P':
470 argc--;
471 argv++;
472 if (!argc) {
473 fprintf(stderr, "ERROR: No argument supplied for '-P' option\n");
474 wantUsage = true;
475 goto bail;
476 }
477 convertPath(argv[0]);
478 bundle.setPublicOutputFile(argv[0]);
479 break;
480 case 'S':
481 argc--;
482 argv++;
483 if (!argc) {
484 fprintf(stderr, "ERROR: No argument supplied for '-S' option\n");
485 wantUsage = true;
486 goto bail;
487 }
488 convertPath(argv[0]);
489 bundle.addResourceSourceDir(argv[0]);
490 break;
491 case 'C':
492 argc--;
493 argv++;
494 if (!argc) {
495 fprintf(stderr, "ERROR: No argument supplied for '-C' option\n");
496 wantUsage = true;
497 goto bail;
498 }
499 convertPath(argv[0]);
500 bundle.setCrunchedOutputDir(argv[0]);
501 break;
502 case 'i':
503 argc--;
504 argv++;
505 if (!argc) {
506 fprintf(stderr, "ERROR: No argument supplied for '-i' option\n");
507 wantUsage = true;
508 goto bail;
509 }
510 convertPath(argv[0]);
511 bundle.setSingleCrunchInputFile(argv[0]);
512 break;
513 case 'o':
514 argc--;
515 argv++;
516 if (!argc) {
517 fprintf(stderr, "ERROR: No argument supplied for '-o' option\n");
518 wantUsage = true;
519 goto bail;
520 }
521 convertPath(argv[0]);
522 bundle.setSingleCrunchOutputFile(argv[0]);
523 break;
524 case '0':
525 argc--;
526 argv++;
527 if (!argc) {
528 fprintf(stderr, "ERROR: No argument supplied for '-e' option\n");
529 wantUsage = true;
530 goto bail;
531 }
532 if (argv[0][0] != 0) {
533 bundle.addNoCompressExtension(argv[0]);
534 } else {
535 bundle.setCompressionMethod(ZipEntry::kCompressStored);
536 }
537 break;
538 case '-':
539 if (strcmp(cp, "-debug-mode") == 0) {
540 bundle.setDebugMode(true);
541 } else if (strcmp(cp, "-min-sdk-version") == 0) {
542 argc--;
543 argv++;
544 if (!argc) {
545 fprintf(stderr, "ERROR: No argument supplied for '--min-sdk-version' option\n");
546 wantUsage = true;
547 goto bail;
548 }
549 bundle.setMinSdkVersion(argv[0]);
550 } else if (strcmp(cp, "-target-sdk-version") == 0) {
551 argc--;
552 argv++;
553 if (!argc) {
554 fprintf(stderr, "ERROR: No argument supplied for '--target-sdk-version' option\n");
555 wantUsage = true;
556 goto bail;
557 }
558 bundle.setTargetSdkVersion(argv[0]);
559 } else if (strcmp(cp, "-max-sdk-version") == 0) {
560 argc--;
561 argv++;
562 if (!argc) {
563 fprintf(stderr, "ERROR: No argument supplied for '--max-sdk-version' option\n");
564 wantUsage = true;
565 goto bail;
566 }
567 bundle.setMaxSdkVersion(argv[0]);
568 } else if (strcmp(cp, "-max-res-version") == 0) {
569 argc--;
570 argv++;
571 if (!argc) {
572 fprintf(stderr, "ERROR: No argument supplied for '--max-res-version' option\n");
573 wantUsage = true;
574 goto bail;
575 }
576 bundle.setMaxResVersion(argv[0]);
577 } else if (strcmp(cp, "-version-code") == 0) {
578 argc--;
579 argv++;
580 if (!argc) {
581 fprintf(stderr, "ERROR: No argument supplied for '--version-code' option\n");
582 wantUsage = true;
583 goto bail;
584 }
585 bundle.setVersionCode(argv[0]);
586 } else if (strcmp(cp, "-version-name") == 0) {
587 argc--;
588 argv++;
589 if (!argc) {
590 fprintf(stderr, "ERROR: No argument supplied for '--version-name' option\n");
591 wantUsage = true;
592 goto bail;
593 }
594 bundle.setVersionName(argv[0]);
Jeff Davidsondf08d1c2014-02-25 12:28:08 -0800595 } else if (strcmp(cp, "-replace-version") == 0) {
596 bundle.setReplaceVersion(true);
Adam Lesinski282e1812014-01-23 18:17:42 -0800597 } else if (strcmp(cp, "-values") == 0) {
598 bundle.setValues(true);
599 } else if (strcmp(cp, "-include-meta-data") == 0) {
600 bundle.setIncludeMetaData(true);
601 } else if (strcmp(cp, "-custom-package") == 0) {
602 argc--;
603 argv++;
604 if (!argc) {
605 fprintf(stderr, "ERROR: No argument supplied for '--custom-package' option\n");
606 wantUsage = true;
607 goto bail;
608 }
609 bundle.setCustomPackage(argv[0]);
610 } else if (strcmp(cp, "-extra-packages") == 0) {
611 argc--;
612 argv++;
613 if (!argc) {
614 fprintf(stderr, "ERROR: No argument supplied for '--extra-packages' option\n");
615 wantUsage = true;
616 goto bail;
617 }
618 bundle.setExtraPackages(argv[0]);
619 } else if (strcmp(cp, "-generate-dependencies") == 0) {
620 bundle.setGenDependencies(true);
621 } else if (strcmp(cp, "-utf16") == 0) {
622 bundle.setWantUTF16(true);
Adam Lesinskifab50872014-04-16 14:40:42 -0700623 } else if (strcmp(cp, "-preferred-density") == 0) {
Adam Lesinski282e1812014-01-23 18:17:42 -0800624 argc--;
625 argv++;
626 if (!argc) {
Adam Lesinskifab50872014-04-16 14:40:42 -0700627 fprintf(stderr, "ERROR: No argument supplied for '--preferred-density' option\n");
Adam Lesinski282e1812014-01-23 18:17:42 -0800628 wantUsage = true;
629 goto bail;
630 }
Adam Lesinskifab50872014-04-16 14:40:42 -0700631 bundle.setPreferredDensity(argv[0]);
632 } else if (strcmp(cp, "-split") == 0) {
633 argc--;
634 argv++;
635 if (!argc) {
636 fprintf(stderr, "ERROR: No argument supplied for '--split' option\n");
637 wantUsage = true;
638 goto bail;
639 }
640 bundle.addSplitConfigurations(argv[0]);
Adam Lesinski833f3cc2014-06-18 15:06:01 -0700641 } else if (strcmp(cp, "-feature-of") == 0) {
642 argc--;
643 argv++;
644 if (!argc) {
645 fprintf(stderr, "ERROR: No argument supplied for '--feature-of' option\n");
646 wantUsage = true;
647 goto bail;
648 }
649 bundle.setFeatureOfPackage(argv[0]);
650 } else if (strcmp(cp, "-feature-after") == 0) {
651 argc--;
652 argv++;
653 if (!argc) {
654 fprintf(stderr, "ERROR: No argument supplied for '--feature-after' option\n");
655 wantUsage = true;
656 goto bail;
657 }
658 bundle.setFeatureAfterPackage(argv[0]);
Adam Lesinski282e1812014-01-23 18:17:42 -0800659 } else if (strcmp(cp, "-rename-manifest-package") == 0) {
660 argc--;
661 argv++;
662 if (!argc) {
663 fprintf(stderr, "ERROR: No argument supplied for '--rename-manifest-package' option\n");
664 wantUsage = true;
665 goto bail;
666 }
667 bundle.setManifestPackageNameOverride(argv[0]);
668 } else if (strcmp(cp, "-rename-instrumentation-target-package") == 0) {
669 argc--;
670 argv++;
671 if (!argc) {
672 fprintf(stderr, "ERROR: No argument supplied for '--rename-instrumentation-target-package' option\n");
673 wantUsage = true;
674 goto bail;
675 }
676 bundle.setInstrumentationPackageNameOverride(argv[0]);
677 } else if (strcmp(cp, "-auto-add-overlay") == 0) {
678 bundle.setAutoAddOverlay(true);
679 } else if (strcmp(cp, "-error-on-failed-insert") == 0) {
680 bundle.setErrorOnFailedInsert(true);
Ying Wangcd28bd32013-11-14 17:12:10 -0800681 } else if (strcmp(cp, "-error-on-missing-config-entry") == 0) {
682 bundle.setErrorOnMissingConfigEntry(true);
Adam Lesinski282e1812014-01-23 18:17:42 -0800683 } else if (strcmp(cp, "-output-text-symbols") == 0) {
684 argc--;
685 argv++;
686 if (!argc) {
687 fprintf(stderr, "ERROR: No argument supplied for '-output-text-symbols' option\n");
688 wantUsage = true;
689 goto bail;
690 }
691 bundle.setOutputTextSymbols(argv[0]);
692 } else if (strcmp(cp, "-product") == 0) {
693 argc--;
694 argv++;
695 if (!argc) {
696 fprintf(stderr, "ERROR: No argument supplied for '--product' option\n");
697 wantUsage = true;
698 goto bail;
699 }
700 bundle.setProduct(argv[0]);
701 } else if (strcmp(cp, "-non-constant-id") == 0) {
702 bundle.setNonConstantId(true);
Adrian Roos58922482015-06-01 17:59:41 -0700703 } else if (strcmp(cp, "-skip-symbols-without-default-localization") == 0) {
704 bundle.setSkipSymbolsWithoutDefaultLocalization(true);
Adam Lesinskide898ff2014-01-29 18:20:45 -0800705 } else if (strcmp(cp, "-shared-lib") == 0) {
706 bundle.setNonConstantId(true);
707 bundle.setBuildSharedLibrary(true);
Tao Baia6d7e3f2015-09-01 18:49:54 -0700708 } else if (strcmp(cp, "-app-as-shared-lib") == 0) {
709 bundle.setNonConstantId(true);
710 bundle.setBuildAppAsSharedLibrary(true);
Adam Lesinski282e1812014-01-23 18:17:42 -0800711 } else if (strcmp(cp, "-no-crunch") == 0) {
712 bundle.setUseCrunchCache(true);
713 } else if (strcmp(cp, "-ignore-assets") == 0) {
714 argc--;
715 argv++;
716 if (!argc) {
717 fprintf(stderr, "ERROR: No argument supplied for '--ignore-assets' option\n");
718 wantUsage = true;
719 goto bail;
720 }
721 gUserIgnoreAssets = argv[0];
Igor Viarheichyka191d042014-06-02 17:16:24 -0700722 } else if (strcmp(cp, "-pseudo-localize") == 0) {
723 bundle.setPseudolocalize(PSEUDO_ACCENTED | PSEUDO_BIDI);
Adam Lesinski6e460562015-04-21 14:20:15 -0700724 } else if (strcmp(cp, "-no-version-vectors") == 0) {
725 bundle.setNoVersionVectors(true);
Yuichi Araki4d35cca2017-01-18 20:42:17 +0900726 } else if (strcmp(cp, "-no-version-transitions") == 0) {
727 bundle.setNoVersionTransitions(true);
Adam Lesinski78713992015-12-07 14:02:15 -0800728 } else if (strcmp(cp, "-private-symbols") == 0) {
729 argc--;
730 argv++;
731 if (!argc) {
732 fprintf(stderr, "ERROR: No argument supplied for "
733 "'--private-symbols' option\n");
734 wantUsage = true;
735 goto bail;
736 }
737 bundle.setPrivateSymbolsPackage(String8(argv[0]));
Adam Lesinski282e1812014-01-23 18:17:42 -0800738 } else {
739 fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
740 wantUsage = true;
741 goto bail;
742 }
743 cp += strlen(cp) - 1;
744 break;
745 default:
746 fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);
747 wantUsage = true;
748 goto bail;
749 }
750
751 cp++;
752 }
753 argc--;
754 argv++;
755 }
756
757 /*
758 * We're past the flags. The rest all goes straight in.
759 */
760 bundle.setFileSpec(argv, argc);
761
762 result = handleCommand(&bundle);
763
764bail:
765 if (wantUsage) {
766 usage();
767 result = 2;
768 }
769
770 //printf("--> returning %d\n", result);
771 return result;
772}