OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Tool to roll Chromium into Mojo. See: | 6 """Tool to roll Chromium into Mojo. See: |
7 https://github.com/domokit/mojo/wiki/Rolling-code-between-chromium-and-mojo#chro
mium---mojo-updates | 7 https://github.com/domokit/mojo/wiki/Rolling-code-between-chromium-and-mojo#chro
mium---mojo-updates |
8 """ | 8 """ |
9 | 9 |
10 import argparse | 10 import argparse |
11 import glob | 11 import glob |
| 12 import itertools |
12 import os | 13 import os |
13 import subprocess | 14 import subprocess |
14 import sys | 15 import sys |
15 import tempfile | 16 import tempfile |
16 import time | 17 import time |
17 import zipfile | 18 import zipfile |
18 | 19 |
19 import mopy.gn as gn | 20 import mopy.gn as gn |
20 from mopy.config import Config | 21 from mopy.config import Config |
21 from mopy.paths import Paths | 22 from mopy.paths import Paths |
22 from mopy.version import Version | 23 from mopy.version import Version |
23 | 24 |
| 25 sys.path.append(os.path.join(os.path.dirname(__file__), |
| 26 os.pardir, os.pardir, "third_party", "pyelftools")) |
| 27 import elftools |
| 28 import elftools.elf.elffile as elffile |
| 29 |
24 BLACKLISTED_APPS = [ | 30 BLACKLISTED_APPS = [ |
25 # The network service apps are not produced out of the Mojo repo, but may | 31 # The network service apps are not produced out of the Mojo repo, but may |
26 # be present in the build dir. | 32 # be present in the build dir. |
27 "network_service.mojo", | 33 "network_service.mojo", |
28 "network_service_apptests.mojo", | 34 "network_service_apptests.mojo", |
29 ] | 35 ] |
30 | 36 |
31 ARCHITECTURE_INDEPENDENT_FILES = [ | 37 ARCHITECTURE_INDEPENDENT_FILES = [ |
32 # These are files other than *.mojo files which are part of our binary | 38 # These are files other than *.mojo files which are part of our binary |
33 # artifact scheme. These files must be architecture independent. | 39 # artifact scheme. These files must be architecture independent. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 | 78 |
73 depot_tools_path = find_depot_tools.add_depot_tools_to_path() | 79 depot_tools_path = find_depot_tools.add_depot_tools_to_path() |
74 gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil") | 80 gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil") |
75 | 81 |
76 if dry_run: | 82 if dry_run: |
77 print str([gsutil_exe, "cp", source, dest]) | 83 print str([gsutil_exe, "cp", source, dest]) |
78 else: | 84 else: |
79 subprocess.check_call([gsutil_exe, "cp", source, dest]) | 85 subprocess.check_call([gsutil_exe, "cp", source, dest]) |
80 | 86 |
81 | 87 |
| 88 def _get_signature(file_object): |
| 89 """Compute a unique signature of a library file. |
| 90 |
| 91 TODO(qsr): Move this function to devtools and import it from there to ensure |
| 92 signature computation is always coherent. |
| 93 """ |
| 94 try: |
| 95 elf = elffile.ELFFile(file_object) |
| 96 text_section = elf.get_section_by_name(".text") |
| 97 file_object.seek(text_section["sh_offset"]) |
| 98 data = file_object.read(min(4096, text_section["sh_size"])) |
| 99 def combine((i, c)): |
| 100 return i ^ ord(c) |
| 101 result = 16 * [0] |
| 102 for i in xrange(0, len(data), len(result)): |
| 103 result = map(combine, |
| 104 itertools.izip_longest(result, |
| 105 data[i:i + len(result)], |
| 106 fillvalue="\0")) |
| 107 return "".join(["%02x" % x for x in result]) |
| 108 except elftools.common.exceptions.ELFError: |
| 109 return None |
| 110 |
| 111 |
| 112 def upload_symbols(config, build_dir, dry_run): |
| 113 dest_dir = "gs://mojo/symbols/" |
| 114 symbols_dir = os.path.join(build_dir, "symbols") |
| 115 for name in os.listdir(symbols_dir): |
| 116 path = os.path.join(symbols_dir, name) |
| 117 with open(path) as f: |
| 118 signature = _get_signature(f) |
| 119 if signature is not None: |
| 120 dest = dest_dir + _get_signature(f) |
| 121 upload(config, path, dest, dry_run) |
| 122 |
| 123 |
82 def upload_shell(config, dry_run, verbose): | 124 def upload_shell(config, dry_run, verbose): |
83 paths = Paths(config) | 125 paths = Paths(config) |
84 zipfile_name = target(config) | 126 zipfile_name = target(config) |
85 version = Version().version | 127 version = Version().version |
86 | 128 |
87 # Upload the binary. | 129 # Upload the binary. |
88 # TODO(blundell): Change this to be in the same structure as the LATEST files, | 130 # TODO(blundell): Change this to be in the same structure as the LATEST files, |
89 # e.g., gs://mojo/shell/linux-x64/<version>/shell.zip. | 131 # e.g., gs://mojo/shell/linux-x64/<version>/shell.zip. |
90 dest = "gs://mojo/shell/" + version + "/" + zipfile_name + ".zip" | 132 dest = "gs://mojo/shell/" + version + "/" + zipfile_name + ".zip" |
91 with tempfile.NamedTemporaryFile() as zip_file: | 133 with tempfile.NamedTemporaryFile() as zip_file: |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 259 |
218 build_directory = gn.BuildDirectoryForConfig(config, Paths(config).src_root) | 260 build_directory = gn.BuildDirectoryForConfig(config, Paths(config).src_root) |
219 apps_to_upload = find_apps_to_upload(build_directory) | 261 apps_to_upload = find_apps_to_upload(build_directory) |
220 for app in apps_to_upload: | 262 for app in apps_to_upload: |
221 upload_app(app, config, args.dry_run) | 263 upload_app(app, config, args.dry_run) |
222 | 264 |
223 files_to_upload = find_architecture_independent_files(build_directory) | 265 files_to_upload = find_architecture_independent_files(build_directory) |
224 for file_to_upload in files_to_upload: | 266 for file_to_upload in files_to_upload: |
225 upload_file(file_to_upload, config, args.dry_run) | 267 upload_file(file_to_upload, config, args.dry_run) |
226 | 268 |
| 269 upload_symbols(config, build_directory, args.dry_run) |
| 270 |
227 return 0 | 271 return 0 |
228 | 272 |
229 if __name__ == "__main__": | 273 if __name__ == "__main__": |
230 sys.exit(main()) | 274 sys.exit(main()) |
OLD | NEW |