1*9e94795aSAndroid Build Coastguard Worker /*
2*9e94795aSAndroid Build Coastguard Worker * Copyright (C) 2008 The Android Open Source Project
3*9e94795aSAndroid Build Coastguard Worker *
4*9e94795aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*9e94795aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*9e94795aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*9e94795aSAndroid Build Coastguard Worker *
8*9e94795aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*9e94795aSAndroid Build Coastguard Worker *
10*9e94795aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*9e94795aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*9e94795aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9e94795aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*9e94795aSAndroid Build Coastguard Worker * limitations under the License.
15*9e94795aSAndroid Build Coastguard Worker */
16*9e94795aSAndroid Build Coastguard Worker
17*9e94795aSAndroid Build Coastguard Worker /*
18*9e94795aSAndroid Build Coastguard Worker * Zip alignment tool
19*9e94795aSAndroid Build Coastguard Worker */
20*9e94795aSAndroid Build Coastguard Worker
21*9e94795aSAndroid Build Coastguard Worker #include "ZipAlign.h"
22*9e94795aSAndroid Build Coastguard Worker
23*9e94795aSAndroid Build Coastguard Worker #include <getopt.h>
24*9e94795aSAndroid Build Coastguard Worker #include <stdio.h>
25*9e94795aSAndroid Build Coastguard Worker #include <stdlib.h>
26*9e94795aSAndroid Build Coastguard Worker
27*9e94795aSAndroid Build Coastguard Worker using namespace android;
28*9e94795aSAndroid Build Coastguard Worker
29*9e94795aSAndroid Build Coastguard Worker /*
30*9e94795aSAndroid Build Coastguard Worker * Show program usage.
31*9e94795aSAndroid Build Coastguard Worker */
usage(void)32*9e94795aSAndroid Build Coastguard Worker void usage(void)
33*9e94795aSAndroid Build Coastguard Worker {
34*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, "Zip alignment utility\n");
35*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
36*9e94795aSAndroid Build Coastguard Worker fprintf(stderr,
37*9e94795aSAndroid Build Coastguard Worker "Usage: zipalign [-f] [-p] [-P <pagesize_kb>] [-v] [-z] <align> infile.zip outfile.zip\n"
38*9e94795aSAndroid Build Coastguard Worker " zipalign -c [-p] [-P <pagesize_kb>] [-v] <align> infile.zip\n\n" );
39*9e94795aSAndroid Build Coastguard Worker fprintf(stderr,
40*9e94795aSAndroid Build Coastguard Worker " <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
41*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " -c: check alignment only (does not modify file)\n");
42*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " -f: overwrite existing outfile.zip\n");
43*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " -p: 4kb page-align uncompressed .so files\n");
44*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " -v: verbose output\n");
45*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " -z: recompress using Zopfli\n");
46*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " -P <pagesize_kb>: Align uncompressed .so files to the specified\n");
47*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " page size. Valid values for <pagesize_kb> are 4, 16\n");
48*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, " and 64. '-P' cannot be used in combination with '-p'.\n");
49*9e94795aSAndroid Build Coastguard Worker }
50*9e94795aSAndroid Build Coastguard Worker
51*9e94795aSAndroid Build Coastguard Worker
52*9e94795aSAndroid Build Coastguard Worker /*
53*9e94795aSAndroid Build Coastguard Worker * Parse args.
54*9e94795aSAndroid Build Coastguard Worker */
main(int argc,char * const argv[])55*9e94795aSAndroid Build Coastguard Worker int main(int argc, char* const argv[])
56*9e94795aSAndroid Build Coastguard Worker {
57*9e94795aSAndroid Build Coastguard Worker bool wantUsage = false;
58*9e94795aSAndroid Build Coastguard Worker bool check = false;
59*9e94795aSAndroid Build Coastguard Worker bool force = false;
60*9e94795aSAndroid Build Coastguard Worker bool verbose = false;
61*9e94795aSAndroid Build Coastguard Worker bool zopfli = false;
62*9e94795aSAndroid Build Coastguard Worker bool pageAlignSharedLibs = false;
63*9e94795aSAndroid Build Coastguard Worker int pageSize = 4096;
64*9e94795aSAndroid Build Coastguard Worker bool legacyPageAlignmentFlag = false; // -p
65*9e94795aSAndroid Build Coastguard Worker bool pageAlignmentFlag = false; // -P <pagesize_kb>
66*9e94795aSAndroid Build Coastguard Worker int result = 1;
67*9e94795aSAndroid Build Coastguard Worker int alignment;
68*9e94795aSAndroid Build Coastguard Worker char* endp;
69*9e94795aSAndroid Build Coastguard Worker
70*9e94795aSAndroid Build Coastguard Worker int opt;
71*9e94795aSAndroid Build Coastguard Worker
72*9e94795aSAndroid Build Coastguard Worker while ((opt = getopt(argc, argv, "fcpvzP:")) != -1) {
73*9e94795aSAndroid Build Coastguard Worker switch (opt) {
74*9e94795aSAndroid Build Coastguard Worker case 'c':
75*9e94795aSAndroid Build Coastguard Worker check = true;
76*9e94795aSAndroid Build Coastguard Worker break;
77*9e94795aSAndroid Build Coastguard Worker case 'f':
78*9e94795aSAndroid Build Coastguard Worker force = true;
79*9e94795aSAndroid Build Coastguard Worker break;
80*9e94795aSAndroid Build Coastguard Worker case 'v':
81*9e94795aSAndroid Build Coastguard Worker verbose = true;
82*9e94795aSAndroid Build Coastguard Worker break;
83*9e94795aSAndroid Build Coastguard Worker case 'z':
84*9e94795aSAndroid Build Coastguard Worker zopfli = true;
85*9e94795aSAndroid Build Coastguard Worker break;
86*9e94795aSAndroid Build Coastguard Worker case 'p':
87*9e94795aSAndroid Build Coastguard Worker legacyPageAlignmentFlag = true;
88*9e94795aSAndroid Build Coastguard Worker pageAlignSharedLibs = true;
89*9e94795aSAndroid Build Coastguard Worker pageSize = 4096;
90*9e94795aSAndroid Build Coastguard Worker break;
91*9e94795aSAndroid Build Coastguard Worker case 'P':
92*9e94795aSAndroid Build Coastguard Worker pageAlignmentFlag = true;
93*9e94795aSAndroid Build Coastguard Worker pageAlignSharedLibs = true;
94*9e94795aSAndroid Build Coastguard Worker
95*9e94795aSAndroid Build Coastguard Worker if (!optarg) {
96*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, "ERROR: -P requires an argument\n");
97*9e94795aSAndroid Build Coastguard Worker wantUsage = true;
98*9e94795aSAndroid Build Coastguard Worker goto bail;
99*9e94795aSAndroid Build Coastguard Worker }
100*9e94795aSAndroid Build Coastguard Worker
101*9e94795aSAndroid Build Coastguard Worker pageSize = atoi(optarg);
102*9e94795aSAndroid Build Coastguard Worker if (pageSize != 4 && pageSize != 16 && pageSize != 64) {
103*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Invalid argument for -P: %s\n", optarg);
104*9e94795aSAndroid Build Coastguard Worker wantUsage = true;
105*9e94795aSAndroid Build Coastguard Worker goto bail;
106*9e94795aSAndroid Build Coastguard Worker }
107*9e94795aSAndroid Build Coastguard Worker
108*9e94795aSAndroid Build Coastguard Worker pageSize *= 1024; // Convert from kB to bytes.
109*9e94795aSAndroid Build Coastguard Worker
110*9e94795aSAndroid Build Coastguard Worker break;
111*9e94795aSAndroid Build Coastguard Worker default:
112*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, "ERROR: unknown flag -%c\n", opt);
113*9e94795aSAndroid Build Coastguard Worker wantUsage = true;
114*9e94795aSAndroid Build Coastguard Worker goto bail;
115*9e94795aSAndroid Build Coastguard Worker }
116*9e94795aSAndroid Build Coastguard Worker }
117*9e94795aSAndroid Build Coastguard Worker
118*9e94795aSAndroid Build Coastguard Worker if (legacyPageAlignmentFlag && pageAlignmentFlag) {
119*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Invalid options: '-P <pagesize_kb>' and '-p'"
120*9e94795aSAndroid Build Coastguard Worker "cannot be used in combination.\n");
121*9e94795aSAndroid Build Coastguard Worker wantUsage = true;
122*9e94795aSAndroid Build Coastguard Worker goto bail;
123*9e94795aSAndroid Build Coastguard Worker }
124*9e94795aSAndroid Build Coastguard Worker
125*9e94795aSAndroid Build Coastguard Worker if (!((check && (argc - optind) == 2) || (!check && (argc - optind) == 3))) {
126*9e94795aSAndroid Build Coastguard Worker wantUsage = true;
127*9e94795aSAndroid Build Coastguard Worker goto bail;
128*9e94795aSAndroid Build Coastguard Worker }
129*9e94795aSAndroid Build Coastguard Worker
130*9e94795aSAndroid Build Coastguard Worker alignment = strtol(argv[optind], &endp, 10);
131*9e94795aSAndroid Build Coastguard Worker if (*endp != '\0' || alignment <= 0) {
132*9e94795aSAndroid Build Coastguard Worker fprintf(stderr, "Invalid value for alignment: %s\n", argv[optind]);
133*9e94795aSAndroid Build Coastguard Worker wantUsage = true;
134*9e94795aSAndroid Build Coastguard Worker goto bail;
135*9e94795aSAndroid Build Coastguard Worker }
136*9e94795aSAndroid Build Coastguard Worker
137*9e94795aSAndroid Build Coastguard Worker if (check) {
138*9e94795aSAndroid Build Coastguard Worker /* check existing archive for correct alignment */
139*9e94795aSAndroid Build Coastguard Worker result = verify(argv[optind + 1], alignment, verbose, pageAlignSharedLibs, pageSize);
140*9e94795aSAndroid Build Coastguard Worker } else {
141*9e94795aSAndroid Build Coastguard Worker /* create the new archive */
142*9e94795aSAndroid Build Coastguard Worker result = process(argv[optind + 1], argv[optind + 2], alignment, force, zopfli,
143*9e94795aSAndroid Build Coastguard Worker pageAlignSharedLibs, pageSize);
144*9e94795aSAndroid Build Coastguard Worker
145*9e94795aSAndroid Build Coastguard Worker /* trust, but verify */
146*9e94795aSAndroid Build Coastguard Worker if (result == 0) {
147*9e94795aSAndroid Build Coastguard Worker result = verify(argv[optind + 2], alignment, verbose, pageAlignSharedLibs, pageSize);
148*9e94795aSAndroid Build Coastguard Worker }
149*9e94795aSAndroid Build Coastguard Worker }
150*9e94795aSAndroid Build Coastguard Worker
151*9e94795aSAndroid Build Coastguard Worker bail:
152*9e94795aSAndroid Build Coastguard Worker if (wantUsage) {
153*9e94795aSAndroid Build Coastguard Worker usage();
154*9e94795aSAndroid Build Coastguard Worker result = 2;
155*9e94795aSAndroid Build Coastguard Worker }
156*9e94795aSAndroid Build Coastguard Worker
157*9e94795aSAndroid Build Coastguard Worker return result;
158*9e94795aSAndroid Build Coastguard Worker }
159