Index: scripts/slave/recipe_modules/isolate/resources/remove_build_metadata.py |
diff --git a/scripts/slave/recipe_modules/isolate/resources/remove_build_metadata.py b/scripts/slave/recipe_modules/isolate/resources/remove_build_metadata.py |
deleted file mode 100755 |
index 287ee9b96adf768a0ab66fbb39d9368ac8fbcd78..0000000000000000000000000000000000000000 |
--- a/scripts/slave/recipe_modules/isolate/resources/remove_build_metadata.py |
+++ /dev/null |
@@ -1,159 +0,0 @@ |
-#!/usr/bin/env python |
-# Copyright 2014 The Chromium Authors. All rights reserved. |
-# Use of this source code is governed by a BSD-style license that can be |
-# found in the LICENSE file. |
-"""Remove the build metadata embedded in the artifacts of a build.""" |
- |
-import json |
-import multiprocessing |
-import optparse |
-import os |
-import Queue |
-import shutil |
-import subprocess |
-import sys |
-import tempfile |
-import threading |
-import zipfile |
- |
- |
-BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
- |
- |
-def get_files_to_clean(build_dir, recursive=False): |
- """Get the list of files to clean.""" |
- allowed = frozenset( |
- ('', '.apk', '.app', '.dll', '.dylib', '.exe', '.nexe', '.so')) |
- non_x_ok_exts = frozenset(('.apk', '.isolated')) |
- min_timestamp = 0 |
- if os.path.exists(os.path.join(build_dir, 'build.ninja')): |
- min_timestamp = os.path.getmtime(os.path.join(build_dir, 'build.ninja')) |
- |
- def check(f): |
- if not os.path.isfile(f) or os.path.basename(f).startswith('.'): |
- return False |
- if os.path.getmtime(os.path.join(build_dir, f)) < min_timestamp: |
- return False |
- ext = os.path.splitext(f)[1] |
- return (ext in non_x_ok_exts) or (ext in allowed and os.access(f, os.X_OK)) |
- |
- ret_files = set() |
- for root, dirs, files in os.walk(build_dir): |
- if not recursive: |
- dirs[:] = [d for d in dirs if d.endswith('_apk')] |
- for f in (f for f in files if check(os.path.join(root, f))): |
- ret_files.add(os.path.relpath(os.path.join(root, f), build_dir)) |
- return ret_files |
- |
- |
-def run_zap_timestamp(src_dir, filepath): |
- """Run zap_timestamp.exe on a PE binary.""" |
- assert sys.platform == 'win32' |
- syzygy_dir = os.path.join( |
- src_dir, 'third_party', 'syzygy', 'binaries', 'exe') |
- zap_timestamp_exe = os.path.join(syzygy_dir, 'zap_timestamp.exe') |
- sys.stdout.write('Processing: %s\n' % os.path.basename(filepath)) |
- proc = subprocess.Popen( |
- [zap_timestamp_exe, '--input-image=%s' % filepath, '--overwrite'], |
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
- log, _ = proc.communicate() |
- if proc.returncode != 0: |
- sys.stderr.write('%s failed:\n%s\n' % (os.path.basename(filepath), log)) |
- return proc.returncode |
- |
- |
-def remove_pe_metadata(filename, src_dir): |
- """Remove the build metadata from a PE file.""" |
- # Only run zap_timestamp on the PE files for which we have a PDB. |
- ret = 0 |
- if os.path.exists(filename + '.pdb'): |
- ret = run_zap_timestamp(src_dir, filename) |
- return ret |
- |
- |
-def remove_apk_timestamps(filename): |
- """Remove the timestamps embedded in an apk archive.""" |
- sys.stdout.write('Processing: %s\n' % os.path.basename(filename)) |
- with zipfile.ZipFile(filename, 'r') as zf: |
- # Creates a temporary file. |
- out_file, out_filename = tempfile.mkstemp(prefix='remote_apk_timestamp') |
- os.close(out_file) |
- try: |
- with zipfile.ZipFile(out_filename, 'w') as zf_o: |
- # Copy the data from the original file to the new one. |
- for info in zf.infolist(): |
- # Overwrite the timestamp with a constant value. |
- info.date_time = (1980, 1, 1, 0, 0, 0) |
- zf_o.writestr(info, zf.read(info.filename)) |
- # Remove the original file and replace it by the modified one. |
- os.remove(filename) |
- shutil.move(out_filename, filename) |
- finally: |
- if os.path.isfile(out_filename): |
- os.remove(out_filename) |
- |
- |
-def remove_metadata_worker(file_queue, failed_queue, build_dir, src_dir): |
- """Worker thread for the remove_metadata function.""" |
- while True: |
- f = file_queue.get() |
- if f.endswith(('.dll', '.exe')): |
- if remove_pe_metadata(os.path.join(build_dir, f), src_dir): |
- ret = 1 |
- failed_queue.put(f) |
- elif f.endswith('.apk'): |
- remove_apk_timestamps(os.path.join(build_dir, f)) |
- file_queue.task_done() |
- |
- |
-def remove_metadata(build_dir, src_dir, recursive): |
- """Remove the build metadata from the artifacts of a build.""" |
- with open(os.path.join(BASE_DIR, 'deterministic_build_blacklist.json')) as f: |
- blacklist = frozenset(json.load(f)) |
- files = Queue.Queue() |
- for f in get_files_to_clean(build_dir, recursive) - blacklist: |
- files.put(f) |
- failed_files = Queue.Queue() |
- |
- for _ in xrange(multiprocessing.cpu_count()): |
- worker = threading.Thread(target=remove_metadata_worker, |
- args=(files, |
- failed_files, |
- build_dir, |
- src_dir)) |
- worker.daemon = True |
- worker.start() |
- |
- files.join() |
- if not failed_files.empty(): |
- print >> sys.stderr, 'Failed for the following files:' |
- failed_files_list = [] |
- while not failed_files.empty(): |
- failed_files_list.append(failed_files.get()) |
- print >> sys.stderr, '\n'.join(' ' + i for i in sorted(failed_files_list)) |
- return 1 |
- |
- return 0 |
- |
- |
-def main(): |
- parser = optparse.OptionParser(usage='%prog [options]') |
- # TODO(sebmarchand): Add support for reading the list of artifact from a |
- # .isolated file. |
- parser.add_option('--build-dir', help='The build directory.') |
- parser.add_option('--src-dir', help='The source directory.') |
- parser.add_option('-r', '--recursive', action='store_true', default=False, |
- help='Indicates if the script should be recursive.') |
- options, _ = parser.parse_args() |
- |
- if not options.build_dir: |
- parser.error('--build-dir is required') |
- |
- if sys.platform == 'win32' and not options.src_dir: |
- parser.error('--src-dir is required') |
- |
- return remove_metadata(options.build_dir, options.src_dir, options.recursive) |
- |
- |
-if __name__ == '__main__': |
- sys.exit(main()) |