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 |