summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragrieve <agrieve@chromium.org>2015-11-23 14:07:23 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-23 22:08:11 +0000
commitb37a3d86d55cb781acdaf4aa64c1ea4cadae3271 (patch)
tree910178da539abd68d4cb4b6acc40803364a1f75d
parenta931efd5dc8d8783ce73a64fc641627866b6869d (diff)
downloadchromium_src-b37a3d86d55cb781acdaf4aa64c1ea4cadae3271.zip
chromium_src-b37a3d86d55cb781acdaf4aa64c1ea4cadae3271.tar.gz
chromium_src-b37a3d86d55cb781acdaf4aa64c1ea4cadae3271.tar.bz2
Use hermetic timestamps in apkbuilder.py and refactor helper function
This makes it so that the command will always produce the same output given the same inputs. BUG= Review URL: https://codereview.chromium.org/1452843002 Cr-Commit-Position: refs/heads/master@{#361198}
-rwxr-xr-xbuild/android/gyp/apkbuilder.py51
-rwxr-xr-xbuild/android/gyp/java_cpp_enum.py2
-rwxr-xr-xbuild/android/gyp/java_google_api_keys.py10
-rw-r--r--build/android/gyp/util/build_utils.py47
4 files changed, 67 insertions, 43 deletions
diff --git a/build/android/gyp/apkbuilder.py b/build/android/gyp/apkbuilder.py
index 7e0ce23..1837fd6 100755
--- a/build/android/gyp/apkbuilder.py
+++ b/build/android/gyp/apkbuilder.py
@@ -92,16 +92,13 @@ def _AddAssets(apk, paths, disable_compression=False):
"""
# Group all uncompressed assets together in the hope that it will increase
# locality of mmap'ed files.
- for target_compress_type in (zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED):
+ for target_compress in (False, True):
for path in paths:
src_path, dest_path = _SplitAssetPath(path)
- compress_type = zipfile.ZIP_DEFLATED
- if disable_compression or (
- os.path.splitext(src_path)[1] in _NO_COMPRESS_EXTENSIONS):
- compress_type = zipfile.ZIP_STORED
-
- if target_compress_type == compress_type:
+ compress = not disable_compression and (
+ os.path.splitext(src_path)[1] not in _NO_COMPRESS_EXTENSIONS)
+ if target_compress == compress:
apk_path = 'assets/' + dest_path
try:
apk.getinfo(apk_path)
@@ -109,7 +106,8 @@ def _AddAssets(apk, paths, disable_compression=False):
raise Exception('Multiple targets specified the asset path: %s' %
apk_path)
except KeyError:
- apk.write(src_path, apk_path, compress_type)
+ build_utils.AddToZipHermetic(apk, apk_path, src_path=src_path,
+ compress=compress)
def main(args):
@@ -148,36 +146,39 @@ def main(args):
_AddAssets(apk, options.uncompressed_assets, disable_compression=True)
for path in native_libs:
basename = os.path.basename(path)
- apk.write(path, 'lib/%s/%s' % (options.android_abi, basename))
+ apk_path = 'lib/%s/%s' % (options.android_abi, basename)
+ build_utils.AddToZipHermetic(apk, apk_path, src_path=path)
+
for name in options.native_lib_placeholders:
# Make it non-empty so that its checksum is non-zero and is not
# ignored by md5_check.
- apk.writestr('lib/%s/%s' % (options.android_abi, name), ':)',
- zipfile.ZIP_STORED)
- if options.dex_file:
- if options.dex_file.endswith('.zip'):
- with zipfile.ZipFile(options.dex_file, 'r') as dex_zip:
- for dex in (d for d in dex_zip.namelist() if d.endswith('.dex')):
- apk.writestr(dex, dex_zip.read(dex))
- else:
- apk.write(options.dex_file, 'classes.dex')
+ apk_path = 'lib/%s/%s.so' % (options.android_abi, name)
+ build_utils.AddToZipHermetic(apk, apk_path, data=':)')
+
+ if options.dex_file and options.dex_file.endswith('.zip'):
+ with zipfile.ZipFile(options.dex_file, 'r') as dex_zip:
+ for dex in (d for d in dex_zip.namelist() if d.endswith('.dex')):
+ build_utils.AddToZipHermetic(apk, dex, data=dex_zip.read(dex))
+ elif options.dex_file:
+ build_utils.AddToZipHermetic(apk, 'classes.dex',
+ src_path=options.dex_file)
if options.emma_device_jar:
# Add EMMA Java resources to APK.
with zipfile.ZipFile(options.emma_device_jar, 'r') as emma_device_jar:
- for emma_device_jar_entry in emma_device_jar.namelist():
- entry_name_lower = emma_device_jar_entry.lower()
- if entry_name_lower.startswith('meta-inf/'):
+ for apk_path in emma_device_jar.namelist():
+ apk_path_lower = apk_path.lower()
+ if apk_path_lower.startswith('meta-inf/'):
continue
- if entry_name_lower.endswith('/'):
+ if apk_path_lower.endswith('/'):
continue
- if entry_name_lower.endswith('.class'):
+ if apk_path_lower.endswith('.class'):
continue
- apk.writestr(emma_device_jar_entry,
- emma_device_jar.read(emma_device_jar_entry))
+ build_utils.AddToZipHermetic(apk, apk_path,
+ data=emma_device_jar.read(apk_path))
shutil.move(tmp_apk, options.output_apk)
finally:
diff --git a/build/android/gyp/java_cpp_enum.py b/build/android/gyp/java_cpp_enum.py
index a82ebc2..9299bce 100755
--- a/build/android/gyp/java_cpp_enum.py
+++ b/build/android/gyp/java_cpp_enum.py
@@ -345,7 +345,7 @@ def DoMain(argv):
with zipfile.ZipFile(options.srcjar, 'w', zipfile.ZIP_STORED) as srcjar:
for output_path, data in DoGenerate(input_paths):
- srcjar.writestr(build_utils.CreateHermeticZipInfo(output_path), data)
+ build_utils.AddToZipHermetic(srcjar, output_path, data=data)
else:
# TODO(agrieve): Delete this non-srcjar branch once GYP is gone.
output_paths = []
diff --git a/build/android/gyp/java_google_api_keys.py b/build/android/gyp/java_google_api_keys.py
index 95257d3..62c92cd 100755
--- a/build/android/gyp/java_google_api_keys.py
+++ b/build/android/gyp/java_google_api_keys.py
@@ -12,6 +12,8 @@ import string
import sys
import zipfile
+from util import build_utils
+
sys.path.append(
os.path.abspath(os.path.join(sys.path[0], '../../../google_apis')))
import google_api_keys
@@ -23,8 +25,6 @@ from pylib import constants
PACKAGE = 'org.chromium.chrome'
CLASSNAME = 'GoogleAPIKeys'
-HERMETIC_TIMESTAMP = (2001, 1, 1, 0, 0, 0)
-HERMETIC_FILE_ATTR = (0644 << 16L)
def GetScriptName():
@@ -84,10 +84,8 @@ def _DoWriteJarOutput(output_path, constant_definition):
os.makedirs(folder)
with zipfile.ZipFile(output_path, 'w') as srcjar:
path = '%s/%s' % (PACKAGE.replace('.', '/'), CLASSNAME + '.java')
- zipinfo = zipfile.ZipInfo(filename=path,
- date_time=HERMETIC_TIMESTAMP)
- zipinfo.external_attr = HERMETIC_FILE_ATTR
- srcjar.writestr(zipinfo, GenerateOutput(constant_definition))
+ data = GenerateOutput(constant_definition)
+ build_utils.AddToZipHermetic(srcjar, path, data=data)
def _DoMain(argv):
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py
index 94935d2..a8eb7c4 100644
--- a/build/android/gyp/util/build_utils.py
+++ b/build/android/gyp/util/build_utils.py
@@ -27,8 +27,8 @@ COLORAMA_ROOT = os.path.join(constants.DIR_SOURCE_ROOT,
# aapt should ignore OWNERS files in addition the default ignore pattern.
AAPT_IGNORE_PATTERN = ('!OWNERS:!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:' +
'!CVS:!thumbs.db:!picasa.ini:!*~:!*.d.stamp')
-HERMETIC_TIMESTAMP = (2001, 1, 1, 0, 0, 0)
-HERMETIC_FILE_ATTR = (0644 << 16L)
+_HERMETIC_TIMESTAMP = (2001, 1, 1, 0, 0, 0)
+_HERMETIC_FILE_ATTR = (0644 << 16L)
@contextlib.contextmanager
@@ -224,12 +224,39 @@ def ExtractAll(zip_path, path=None, no_clobber=True, pattern=None,
z.extract(name, path)
-def CreateHermeticZipInfo(zip_path):
- """Creates a ZipInfo with a zero'ed out timestamp."""
+def AddToZipHermetic(zip_file, zip_path, src_path=None, data=None,
+ compress=None):
+ """Adds a file to the given ZipFile with a hard-coded modified time.
+
+ Args:
+ zip_file: ZipFile instance to add the file to.
+ zip_path: Destination path within the zip file.
+ src_path: Path of the source file. Mutually exclusive with |data|.
+ data: File data as a string.
+ compress: Whether to enable compression. Default is take from ZipFile
+ constructor.
+ """
+ assert (src_path is None) != (data is None), (
+ '|src_path| and |data| are mutually exclusive.')
CheckZipPath(zip_path)
- zipinfo = zipfile.ZipInfo(filename=zip_path, date_time=HERMETIC_TIMESTAMP)
- zipinfo.external_attr = HERMETIC_FILE_ATTR
- return zipinfo
+ zipinfo = zipfile.ZipInfo(filename=zip_path, date_time=_HERMETIC_TIMESTAMP)
+ zipinfo.external_attr = _HERMETIC_FILE_ATTR
+
+ if src_path:
+ with file(src_path) as f:
+ data = f.read()
+
+ # zipfile will deflate even when it makes the file bigger. To avoid
+ # growing files, disable compression at an arbitrary cut off point.
+ if len(data) < 16:
+ compress = False
+
+ # None converts to ZIP_STORED, when passed explicitly rather than the
+ # default passed to the ZipFile constructor.
+ args = []
+ if compress is not None:
+ args.append(zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED)
+ zip_file.writestr(zipinfo, data, *args)
def DoZip(inputs, output, base_dir=None):
@@ -250,9 +277,7 @@ def DoZip(inputs, output, base_dir=None):
input_tuples.sort(key=lambda tup: tup[0])
with zipfile.ZipFile(output, 'w') as outfile:
for zip_path, fs_path in input_tuples:
- with file(fs_path) as f:
- contents = f.read()
- outfile.writestr(CreateHermeticZipInfo(zip_path), contents)
+ AddToZipHermetic(outfile, zip_path, src_path=fs_path)
def ZipDir(output, base_dir):
@@ -283,7 +308,7 @@ def MergeZips(output, inputs, exclude_patterns=None, path_transform=None):
dst_name = path_transform(name, in_file)
already_added = dst_name in added_names
if not already_added and not MatchesGlob(dst_name, exclude_patterns):
- out_zip.writestr(CreateHermeticZipInfo(dst_name), in_zip.read(name))
+ AddToZipHermetic(out_zip, dst_name, data=in_zip.read(name))
added_names.add(dst_name)