| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 """Bootstraps gn. | 6 """Bootstraps gn. |
| 7 | 7 |
| 8 It is done by first building it manually in a temporary directory, then building | 8 It is done by first building it manually in a temporary directory, then building |
| 9 it with its own BUILD.gn to the final destination. | 9 it with its own BUILD.gn to the final destination. |
| 10 """ | 10 """ |
| 11 | 11 |
| 12 import contextlib | 12 import contextlib |
| 13 import errno | 13 import errno |
| 14 import json |
| 14 import logging | 15 import logging |
| 15 import optparse | 16 import optparse |
| 16 import os | 17 import os |
| 17 import shutil | 18 import shutil |
| 18 import subprocess | 19 import subprocess |
| 19 import sys | 20 import sys |
| 20 import tempfile | 21 import tempfile |
| 21 | 22 |
| 22 BOOTSTRAP_DIR = os.path.dirname(os.path.abspath(__file__)) | 23 BOOTSTRAP_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 23 GN_ROOT = os.path.dirname(BOOTSTRAP_DIR) | 24 GN_ROOT = os.path.dirname(BOOTSTRAP_DIR) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 49 | 50 |
| 50 | 51 |
| 51 def main(argv): | 52 def main(argv): |
| 52 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) | 53 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) |
| 53 parser.add_option('-d', '--debug', action='store_true', | 54 parser.add_option('-d', '--debug', action='store_true', |
| 54 help='Do a debug build. Defaults to release build.') | 55 help='Do a debug build. Defaults to release build.') |
| 55 parser.add_option('-o', '--output', | 56 parser.add_option('-o', '--output', |
| 56 help='place output in PATH', metavar='PATH') | 57 help='place output in PATH', metavar='PATH') |
| 57 parser.add_option('-s', '--no-rebuild', action='store_true', | 58 parser.add_option('-s', '--no-rebuild', action='store_true', |
| 58 help='Do not rebuild GN with GN.') | 59 help='Do not rebuild GN with GN.') |
| 60 parser.add_option('--temp-build-dir', action='store_true', |
| 61 help='Build GN in temporary directory') |
| 62 parser.add_option('--use-bundled-clang', action='store_true', |
| 63 help='Use bundled clang compiler (e.g. when host toolchain ' |
| 64 'is too old to support C++11)') |
| 59 parser.add_option('-v', '--verbose', action='store_true', | 65 parser.add_option('-v', '--verbose', action='store_true', |
| 60 help='Log more details') | 66 help='Log more details') |
| 67 parser.add_option('--json') |
| 61 options, args = parser.parse_args(argv) | 68 options, args = parser.parse_args(argv) |
| 62 | 69 |
| 63 if args: | 70 if args: |
| 64 parser.error('Unrecognized command line arguments: %s.' % ', '.join(args)) | 71 parser.error('Unrecognized command line arguments: %s.' % ', '.join(args)) |
| 65 | 72 |
| 66 logging.basicConfig(level=logging.DEBUG if options.verbose else logging.ERROR) | 73 logging.basicConfig(level=logging.DEBUG if options.verbose else logging.ERROR) |
| 67 | 74 |
| 68 if options.debug: | 75 if options.debug: |
| 69 build_rel = os.path.join('out', 'Debug') | 76 build_rel = os.path.join('out', 'Debug') |
| 70 else: | 77 else: |
| 71 build_rel = os.path.join('out', 'Release') | 78 build_rel = os.path.join('out', 'Release') |
| 72 build_root = os.path.join(SRC_ROOT, build_rel) | 79 |
| 80 failures = [] |
| 73 | 81 |
| 74 try: | 82 try: |
| 75 with scoped_tempdir() as tempdir: | 83 with scoped_tempdir() as tempdir: |
| 76 print 'Building gn manually in a temporary directory for bootstrapping...' | 84 print 'Building gn manually in a temporary directory for bootstrapping...' |
| 77 build_gn_with_ninja_manually(tempdir, options) | 85 build_gn_with_ninja_manually(tempdir, options) |
| 78 temp_gn = os.path.join(tempdir, 'gn') | 86 temp_gn = os.path.join(tempdir, 'gn') |
| 87 if options.temp_build_dir: |
| 88 build_root = os.path.join(tempdir, 'build_root') |
| 89 else: |
| 90 build_root = os.path.join(SRC_ROOT, build_rel) |
| 79 out_gn = os.path.join(build_root, 'gn') | 91 out_gn = os.path.join(build_root, 'gn') |
| 80 | 92 |
| 81 if options.no_rebuild: | 93 if options.no_rebuild: |
| 82 mkdir_p(build_root) | 94 mkdir_p(build_root) |
| 83 shutil.copy2(temp_gn, out_gn) | 95 shutil.copy2(temp_gn, out_gn) |
| 84 else: | 96 else: |
| 85 print 'Building gn using itself to %s...' % build_rel | 97 print 'Building gn using itself to %s...' % build_root |
| 86 build_gn_with_gn(temp_gn, build_rel, options) | 98 build_gn_with_gn(temp_gn, build_root, options) |
| 87 | 99 |
| 88 if options.output: | 100 if options.output: |
| 89 # Preserve the executable permission bit. | 101 # Preserve the executable permission bit. |
| 90 shutil.copy2(out_gn, options.output) | 102 shutil.copy2(out_gn, options.output) |
| 91 except subprocess.CalledProcessError as e: | 103 except subprocess.CalledProcessError as e: |
| 92 print >> sys.stderr, str(e) | 104 print >> sys.stderr, str(e) |
| 93 return 1 | 105 failures.append(str(e)) |
| 94 return 0 | 106 |
| 107 if options.json: |
| 108 with open(options.json, 'w') as f: |
| 109 json.dump(failures, f) |
| 110 return 1 if failures else 0 |
| 95 | 111 |
| 96 | 112 |
| 97 def build_gn_with_ninja_manually(tempdir, options): | 113 def build_gn_with_ninja_manually(tempdir, options): |
| 98 write_ninja(os.path.join(tempdir, 'build.ninja'), options) | 114 write_ninja(os.path.join(tempdir, 'build.ninja'), options) |
| 99 cmd = ['ninja', '-C', tempdir] | 115 cmd = ['ninja', '-C', tempdir] |
| 100 if options.verbose: | 116 if options.verbose: |
| 101 cmd.append('-v') | 117 cmd.append('-v') |
| 102 cmd.append('gn') | 118 cmd.append('gn') |
| 103 check_call(cmd) | 119 check_call(cmd) |
| 104 | 120 |
| 105 def write_ninja(path, options): | 121 def write_ninja(path, options): |
| 106 cc = os.environ.get('CC', '') | 122 default_cc = '' |
| 107 cxx = os.environ.get('CXX', '') | 123 default_cxx = '' |
| 124 if options.use_bundled_clang: |
| 125 clang_dir = os.path.join( |
| 126 SRC_ROOT, 'third_party', 'llvm-build', 'Release+Asserts', 'bin') |
| 127 default_cc = os.path.join(clang_dir, 'clang') |
| 128 default_cxx = os.path.join(clang_dir, 'clang++') |
| 129 cc = os.environ.get('CC', default_cc) |
| 130 cxx = os.environ.get('CXX', default_cxx) |
| 108 cflags = os.environ.get('CFLAGS', '').split() | 131 cflags = os.environ.get('CFLAGS', '').split() |
| 109 cflags_cc = os.environ.get('CXXFLAGS', '').split() | 132 cflags_cc = os.environ.get('CXXFLAGS', '').split() |
| 110 ld = os.environ.get('LD', cxx) | 133 ld = os.environ.get('LD', cxx) |
| 111 ldflags = os.environ.get('LDFLAGS', '').split() | 134 ldflags = os.environ.get('LDFLAGS', '').split() |
| 112 include_dirs = [SRC_ROOT] | 135 include_dirs = [SRC_ROOT] |
| 113 libs = [] | 136 libs = [] |
| 114 | 137 |
| 115 if is_posix: | 138 if is_posix: |
| 116 if options.debug: | 139 if options.debug: |
| 117 cflags.extend(['-O0', '-g']) | 140 cflags.extend(['-O0', '-g']) |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 'base/threading/simple_thread.cc', | 243 'base/threading/simple_thread.cc', |
| 221 'base/threading/thread_checker_impl.cc', | 244 'base/threading/thread_checker_impl.cc', |
| 222 'base/threading/thread_collision_warner.cc', | 245 'base/threading/thread_collision_warner.cc', |
| 223 'base/threading/thread_id_name_manager.cc', | 246 'base/threading/thread_id_name_manager.cc', |
| 224 'base/threading/thread_local_storage.cc', | 247 'base/threading/thread_local_storage.cc', |
| 225 'base/threading/thread_restrictions.cc', | 248 'base/threading/thread_restrictions.cc', |
| 226 'base/threading/worker_pool.cc', | 249 'base/threading/worker_pool.cc', |
| 227 'base/time/time.cc', | 250 'base/time/time.cc', |
| 228 'base/timer/elapsed_timer.cc', | 251 'base/timer/elapsed_timer.cc', |
| 229 'base/timer/timer.cc', | 252 'base/timer/timer.cc', |
| 253 'base/trace_event/category_filter.cc', |
| 254 'base/trace_event/trace_config.cc', |
| 230 'base/trace_event/trace_event_impl.cc', | 255 'base/trace_event/trace_event_impl.cc', |
| 231 'base/trace_event/trace_event_impl_constants.cc', | 256 'base/trace_event/trace_event_impl_constants.cc', |
| 232 'base/trace_event/trace_event_memory.cc', | 257 'base/trace_event/trace_event_memory.cc', |
| 233 'base/trace_event/trace_event_synthetic_delay.cc', | 258 'base/trace_event/trace_event_synthetic_delay.cc', |
| 259 'base/trace_event/trace_options.cc', |
| 234 'base/tracked_objects.cc', | 260 'base/tracked_objects.cc', |
| 235 'base/tracking_info.cc', | 261 'base/tracking_info.cc', |
| 236 'base/values.cc', | 262 'base/values.cc', |
| 237 'base/vlog.cc', | 263 'base/vlog.cc', |
| 238 ]) | 264 ]) |
| 239 | 265 |
| 240 if is_posix: | 266 if is_posix: |
| 241 static_libraries['base']['sources'].extend([ | 267 static_libraries['base']['sources'].extend([ |
| 242 'base/base_paths_posix.cc', | 268 'base/base_paths_posix.cc', |
| 243 'base/debug/debugger_posix.cc', | 269 'base/debug/debugger_posix.cc', |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 cmd.append('-v') | 434 cmd.append('-v') |
| 409 cmd.append('gn') | 435 cmd.append('gn') |
| 410 check_call(cmd) | 436 check_call(cmd) |
| 411 | 437 |
| 412 if not options.debug: | 438 if not options.debug: |
| 413 check_call(['strip', os.path.join(build_dir, 'gn')]) | 439 check_call(['strip', os.path.join(build_dir, 'gn')]) |
| 414 | 440 |
| 415 | 441 |
| 416 if __name__ == '__main__': | 442 if __name__ == '__main__': |
| 417 sys.exit(main(sys.argv[1:])) | 443 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |