xref: /aosp_15_r20/build/make/tools/zipalign/ZipAlignMain.cpp (revision 9e94795a3d4ef5c1d47486f9a02bb378756cea8a)
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