Merge "Refactor zipalign to allow unit tests"
This commit is contained in:
commit
6be3371c23
8 changed files with 254 additions and 129 deletions
|
@ -4,20 +4,31 @@
|
||||||
// Zip alignment tool
|
// Zip alignment tool
|
||||||
//
|
//
|
||||||
|
|
||||||
cc_binary_host {
|
cc_defaults {
|
||||||
name: "zipalign",
|
name: "zipalign_defaults",
|
||||||
|
target: {
|
||||||
|
windows: {
|
||||||
|
host_ldlibs: ["-lpthread"],
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_host_static {
|
||||||
|
name: "libzipalign",
|
||||||
srcs: [
|
srcs: [
|
||||||
"ZipAlign.cpp",
|
"ZipAlign.cpp",
|
||||||
"ZipEntry.cpp",
|
"ZipEntry.cpp",
|
||||||
"ZipFile.cpp",
|
"ZipFile.cpp",
|
||||||
],
|
],
|
||||||
|
export_include_dirs: [
|
||||||
|
"include",
|
||||||
|
],
|
||||||
cflags: ["-Wall", "-Werror"],
|
cflags: ["-Wall", "-Werror"],
|
||||||
|
|
||||||
// NOTE: Do not add any shared_libs dependencies because they will break the
|
// NOTE: Do not add any shared_libs dependencies because they will break the
|
||||||
// static_sdk_tools target.
|
// static_sdk_tools target.
|
||||||
static_libs: [
|
whole_static_libs: [
|
||||||
"libutils",
|
"libutils",
|
||||||
"libcutils",
|
"libcutils",
|
||||||
"liblog",
|
"liblog",
|
||||||
|
@ -26,11 +37,32 @@ cc_binary_host {
|
||||||
"libbase",
|
"libbase",
|
||||||
"libzopfli",
|
"libzopfli",
|
||||||
],
|
],
|
||||||
|
defaults: ["zipalign_defaults"],
|
||||||
target: {
|
}
|
||||||
windows: {
|
|
||||||
host_ldlibs: ["-lpthread"],
|
cc_binary_host {
|
||||||
enabled: true,
|
name: "zipalign",
|
||||||
},
|
srcs: [
|
||||||
},
|
"ZipAlignMain.cpp",
|
||||||
|
],
|
||||||
|
cflags: ["-Wall", "-Werror"],
|
||||||
|
static_libs: [
|
||||||
|
"libzipalign",
|
||||||
|
],
|
||||||
|
defaults: ["zipalign_defaults"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_test_host {
|
||||||
|
name: "zipalign_tests",
|
||||||
|
srcs: [
|
||||||
|
"tests/src/*_test.cpp",
|
||||||
|
],
|
||||||
|
static_libs: [
|
||||||
|
"libzipalign",
|
||||||
|
"libgmock",
|
||||||
|
],
|
||||||
|
data: [
|
||||||
|
"tests/data/unaligned.zip",
|
||||||
|
],
|
||||||
|
defaults: ["zipalign_defaults"],
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,35 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Zip alignment tool
|
|
||||||
*/
|
|
||||||
#include "ZipFile.h"
|
#include "ZipFile.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
using namespace android;
|
namespace android {
|
||||||
|
|
||||||
/*
|
|
||||||
* Show program usage.
|
|
||||||
*/
|
|
||||||
void usage(void)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Zip alignment utility\n");
|
|
||||||
fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
|
|
||||||
fprintf(stderr,
|
|
||||||
"Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
|
|
||||||
" zipalign -c [-p] [-v] <align> infile.zip\n\n" );
|
|
||||||
fprintf(stderr,
|
|
||||||
" <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
|
|
||||||
fprintf(stderr, " -c: check alignment only (does not modify file)\n");
|
|
||||||
fprintf(stderr, " -f: overwrite existing outfile.zip\n");
|
|
||||||
fprintf(stderr, " -p: memory page alignment for stored shared object files\n");
|
|
||||||
fprintf(stderr, " -v: verbose output\n");
|
|
||||||
fprintf(stderr, " -z: recompress using Zopfli\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getAlignment(bool pageAlignSharedLibs, int defaultAlignment,
|
static int getAlignment(bool pageAlignSharedLibs, int defaultAlignment,
|
||||||
ZipEntry* pEntry) {
|
ZipEntry* pEntry) {
|
||||||
|
@ -126,7 +104,7 @@ static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfl
|
||||||
* Process a file. We open the input and output files, failing if the
|
* Process a file. We open the input and output files, failing if the
|
||||||
* output file exists and "force" wasn't specified.
|
* output file exists and "force" wasn't specified.
|
||||||
*/
|
*/
|
||||||
static int process(const char* inFileName, const char* outFileName,
|
int process(const char* inFileName, const char* outFileName,
|
||||||
int alignment, bool force, bool zopfli, bool pageAlignSharedLibs)
|
int alignment, bool force, bool zopfli, bool pageAlignSharedLibs)
|
||||||
{
|
{
|
||||||
ZipFile zin, zout;
|
ZipFile zin, zout;
|
||||||
|
@ -169,7 +147,7 @@ static int process(const char* inFileName, const char* outFileName,
|
||||||
/*
|
/*
|
||||||
* Verify the alignment of a zip archive.
|
* Verify the alignment of a zip archive.
|
||||||
*/
|
*/
|
||||||
static int verify(const char* fileName, int alignment, bool verbose,
|
int verify(const char* fileName, int alignment, bool verbose,
|
||||||
bool pageAlignSharedLibs)
|
bool pageAlignSharedLibs)
|
||||||
{
|
{
|
||||||
ZipFile zipFile;
|
ZipFile zipFile;
|
||||||
|
@ -218,92 +196,4 @@ static int verify(const char* fileName, int alignment, bool verbose,
|
||||||
return foundBad ? 1 : 0;
|
return foundBad ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
} // namespace android
|
||||||
* Parse args.
|
|
||||||
*/
|
|
||||||
int main(int argc, char* const argv[])
|
|
||||||
{
|
|
||||||
bool wantUsage = false;
|
|
||||||
bool check = false;
|
|
||||||
bool force = false;
|
|
||||||
bool verbose = false;
|
|
||||||
bool zopfli = false;
|
|
||||||
bool pageAlignSharedLibs = false;
|
|
||||||
int result = 1;
|
|
||||||
int alignment;
|
|
||||||
char* endp;
|
|
||||||
|
|
||||||
if (argc < 4) {
|
|
||||||
wantUsage = true;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
|
|
||||||
while (argc && argv[0][0] == '-') {
|
|
||||||
const char* cp = argv[0] +1;
|
|
||||||
|
|
||||||
while (*cp != '\0') {
|
|
||||||
switch (*cp) {
|
|
||||||
case 'c':
|
|
||||||
check = true;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
force = true;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
verbose = true;
|
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
zopfli = true;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
pageAlignSharedLibs = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
|
|
||||||
wantUsage = true;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
cp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!((check && argc == 2) || (!check && argc == 3))) {
|
|
||||||
wantUsage = true;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
alignment = strtol(argv[0], &endp, 10);
|
|
||||||
if (*endp != '\0' || alignment <= 0) {
|
|
||||||
fprintf(stderr, "Invalid value for alignment: %s\n", argv[0]);
|
|
||||||
wantUsage = true;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check) {
|
|
||||||
/* check existing archive for correct alignment */
|
|
||||||
result = verify(argv[1], alignment, verbose, pageAlignSharedLibs);
|
|
||||||
} else {
|
|
||||||
/* create the new archive */
|
|
||||||
result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs);
|
|
||||||
|
|
||||||
/* trust, but verify */
|
|
||||||
if (result == 0) {
|
|
||||||
result = verify(argv[2], alignment, verbose, pageAlignSharedLibs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bail:
|
|
||||||
if (wantUsage) {
|
|
||||||
usage();
|
|
||||||
result = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
136
tools/zipalign/ZipAlignMain.cpp
Normal file
136
tools/zipalign/ZipAlignMain.cpp
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zip alignment tool
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ZipAlign.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
using namespace android;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show program usage.
|
||||||
|
*/
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Zip alignment utility\n");
|
||||||
|
fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
|
||||||
|
" zipalign -c [-p] [-v] <align> infile.zip\n\n" );
|
||||||
|
fprintf(stderr,
|
||||||
|
" <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
|
||||||
|
fprintf(stderr, " -c: check alignment only (does not modify file)\n");
|
||||||
|
fprintf(stderr, " -f: overwrite existing outfile.zip\n");
|
||||||
|
fprintf(stderr, " -p: memory page alignment for stored shared object files\n");
|
||||||
|
fprintf(stderr, " -v: verbose output\n");
|
||||||
|
fprintf(stderr, " -z: recompress using Zopfli\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse args.
|
||||||
|
*/
|
||||||
|
int main(int argc, char* const argv[])
|
||||||
|
{
|
||||||
|
bool wantUsage = false;
|
||||||
|
bool check = false;
|
||||||
|
bool force = false;
|
||||||
|
bool verbose = false;
|
||||||
|
bool zopfli = false;
|
||||||
|
bool pageAlignSharedLibs = false;
|
||||||
|
int result = 1;
|
||||||
|
int alignment;
|
||||||
|
char* endp;
|
||||||
|
|
||||||
|
if (argc < 4) {
|
||||||
|
wantUsage = true;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
|
while (argc && argv[0][0] == '-') {
|
||||||
|
const char* cp = argv[0] +1;
|
||||||
|
|
||||||
|
while (*cp != '\0') {
|
||||||
|
switch (*cp) {
|
||||||
|
case 'c':
|
||||||
|
check = true;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
force = true;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = true;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
zopfli = true;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
pageAlignSharedLibs = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
|
||||||
|
wantUsage = true;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((check && argc == 2) || (!check && argc == 3))) {
|
||||||
|
wantUsage = true;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
alignment = strtol(argv[0], &endp, 10);
|
||||||
|
if (*endp != '\0' || alignment <= 0) {
|
||||||
|
fprintf(stderr, "Invalid value for alignment: %s\n", argv[0]);
|
||||||
|
wantUsage = true;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check) {
|
||||||
|
/* check existing archive for correct alignment */
|
||||||
|
result = verify(argv[1], alignment, verbose, pageAlignSharedLibs);
|
||||||
|
} else {
|
||||||
|
/* create the new archive */
|
||||||
|
result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs);
|
||||||
|
|
||||||
|
/* trust, but verify */
|
||||||
|
if (result == 0) {
|
||||||
|
result = verify(argv[2], alignment, verbose, pageAlignSharedLibs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
if (wantUsage) {
|
||||||
|
usage();
|
||||||
|
result = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -29,7 +29,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
using namespace android;
|
namespace android {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize a new ZipEntry structure from a FILE* positioned at a
|
* Initialize a new ZipEntry structure from a FILE* positioned at a
|
||||||
|
@ -696,3 +696,5 @@ void ZipEntry::CentralDirEntry::dump(void) const
|
||||||
ALOGD(" comment: '%s'\n", mFileComment);
|
ALOGD(" comment: '%s'\n", mFileComment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
using namespace android;
|
namespace android {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some environments require the "b", some choke on it.
|
* Some environments require the "b", some choke on it.
|
||||||
|
@ -134,7 +134,7 @@ status_t ZipFile::open(const char* zipFileName, int flags)
|
||||||
/*
|
/*
|
||||||
* Return the Nth entry in the archive.
|
* Return the Nth entry in the archive.
|
||||||
*/
|
*/
|
||||||
android::ZipEntry* ZipFile::getEntryByIndex(int idx) const
|
ZipEntry* ZipFile::getEntryByIndex(int idx) const
|
||||||
{
|
{
|
||||||
if (idx < 0 || idx >= (int) mEntries.size())
|
if (idx < 0 || idx >= (int) mEntries.size())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -145,7 +145,7 @@ android::ZipEntry* ZipFile::getEntryByIndex(int idx) const
|
||||||
/*
|
/*
|
||||||
* Find an entry by name.
|
* Find an entry by name.
|
||||||
*/
|
*/
|
||||||
android::ZipEntry* ZipFile::getEntryByName(const char* fileName) const
|
ZipEntry* ZipFile::getEntryByName(const char* fileName) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Do a stupid linear string-compare search.
|
* Do a stupid linear string-compare search.
|
||||||
|
@ -1397,3 +1397,4 @@ void ZipFile::EndOfCentralDir::dump(void) const
|
||||||
mCentralDirSize, mCentralDirOffset, mCommentLen);
|
mCentralDirSize, mCentralDirOffset, mCommentLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace android
|
||||||
|
|
49
tools/zipalign/include/ZipAlign.h
Normal file
49
tools/zipalign/include/ZipAlign.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZIPALIGN_H
|
||||||
|
#define ZIPALIGN_H
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate a new, aligned, zip "output" from an "input" zip.
|
||||||
|
* - alignTo: Alignment (in bytes) for uncompressed entries.
|
||||||
|
* - force : Overwrite output if it exists, fail otherwise.
|
||||||
|
* - zopfli : Recompress compressed entries with more efficient algorithm.
|
||||||
|
* Copy compressed entries as-is, and unaligned, otherwise.
|
||||||
|
* - pageAlignSharedLibs: Align .so files to 4096 and other files to
|
||||||
|
* alignTo, or all files to alignTo if false..
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
*/
|
||||||
|
int process(const char* input, const char* output, int alignTo, bool force,
|
||||||
|
bool zopfli, bool pageAlignSharedLibs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify the alignment of a zip archive.
|
||||||
|
* - alignTo: Alignment (in bytes) for uncompressed entries.
|
||||||
|
* - pageAlignSharedLibs: Align .so files to 4096 and other files to
|
||||||
|
* alignTo, or all files to alignTo if false..
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
*/
|
||||||
|
int verify(const char* fileName, int alignTo, bool verbose,
|
||||||
|
bool pageAlignSharedLibs);
|
||||||
|
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ZIPALIGN_H
|
BIN
tools/zipalign/tests/data/unaligned.zip
Normal file
BIN
tools/zipalign/tests/data/unaligned.zip
Normal file
Binary file not shown.
15
tools/zipalign/tests/src/align_test.cpp
Normal file
15
tools/zipalign/tests/src/align_test.cpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "ZipAlign.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
using namespace android;
|
||||||
|
|
||||||
|
TEST(Align, Unaligned) {
|
||||||
|
const char* src = "tests/data/unaligned.zip";
|
||||||
|
const char* dst = "tests/data/unaligned_out.zip";
|
||||||
|
int result = process(src, dst, 4, true, false, 4096);
|
||||||
|
ASSERT_EQ(0, result);
|
||||||
|
}
|
Loading…
Reference in a new issue