Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: tools/gn/bootstrap/bootstrap.py

Issue 403463005: gn: bootstrap: fixes, added mac support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « AUTHORS ('k') | tools/gn/bootstrap/build_mac.ninja.template » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 logging 14 import logging
14 import optparse 15 import optparse
15 import os 16 import os
16 import shutil 17 import shutil
17 import subprocess 18 import subprocess
18 import sys 19 import sys
19 import tempfile 20 import tempfile
20 21
21 BOOTSTRAP_DIR = os.path.dirname(os.path.abspath(__file__)) 22 BOOTSTRAP_DIR = os.path.dirname(os.path.abspath(__file__))
22 GN_ROOT = os.path.dirname(BOOTSTRAP_DIR) 23 GN_ROOT = os.path.dirname(BOOTSTRAP_DIR)
23 SRC_ROOT = os.path.dirname(os.path.dirname(GN_ROOT)) 24 SRC_ROOT = os.path.dirname(os.path.dirname(GN_ROOT))
24 25
25 26 is_linux = sys.platform.startswith('linux')
26 def is_linux(): 27 is_mac = sys.platform.startswith('darwin')
27 return sys.platform.startswith('linux') 28 is_posix = is_linux or is_mac
28
29 29
30 def check_call(cmd, **kwargs): 30 def check_call(cmd, **kwargs):
31 logging.debug('Running: %s', ' '.join(cmd)) 31 logging.debug('Running: %s', ' '.join(cmd))
32 subprocess.check_call(cmd, cwd=GN_ROOT, **kwargs) 32 subprocess.check_call(cmd, cwd=GN_ROOT, **kwargs)
33 33
34 def mkdir_p(path):
35 try:
36 os.makedirs(path)
37 except OSError as e:
38 if e.errno == errno.EEXIST and os.path.isdir(path):
39 pass
40 else: raise
34 41
35 @contextlib.contextmanager 42 @contextlib.contextmanager
36 def scoped_tempdir(): 43 def scoped_tempdir():
37 path = tempfile.mkdtemp() 44 path = tempfile.mkdtemp()
38 try: 45 try:
39 yield path 46 yield path
40 finally: 47 finally:
41 shutil.rmtree(path) 48 shutil.rmtree(path)
42 49
43 50
44 def main(argv): 51 def main(argv):
45 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) 52 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
46 parser.add_option('-d', '--debug', action='store_true', 53 parser.add_option('-d', '--debug', action='store_true',
47 help='Do a debug build. Defaults to release build.') 54 help='Do a debug build. Defaults to release build.')
48 parser.add_option('-o', '--output', 55 parser.add_option('-o', '--output',
49 help='place output in PATH', metavar='PATH') 56 help='place output in PATH', metavar='PATH')
57 parser.add_option('-s', '--no-bootstrap', action='store_true',
brettw 2014/07/17 22:14:49 Typing "bootstrap.py --no-bootstrap" seems weird t
58 help='Do not rebuild GN with GN.')
50 parser.add_option('-v', '--verbose', action='store_true', 59 parser.add_option('-v', '--verbose', action='store_true',
51 help='Log more details') 60 help='Log more details')
52 options, args = parser.parse_args(argv) 61 options, args = parser.parse_args(argv)
53 62
54 if args: 63 if args:
55 parser.error('Unrecognized command line arguments: %s.' % ', '.join(args)) 64 parser.error('Unrecognized command line arguments: %s.' % ', '.join(args))
56 65
57 logging.basicConfig(level=logging.DEBUG if options.verbose else logging.ERROR) 66 logging.basicConfig(level=logging.DEBUG if options.verbose else logging.ERROR)
58 67
59 if options.debug: 68 if options.debug:
60 build_rel = os.path.join('out', 'Debug') 69 build_rel = os.path.join('out', 'Debug')
61 else: 70 else:
62 build_rel = os.path.join('out', 'Release') 71 build_rel = os.path.join('out', 'Release')
63 build_root = os.path.join(SRC_ROOT, build_rel) 72 build_root = os.path.join(SRC_ROOT, build_rel)
64 73
65 try: 74 try:
66 with scoped_tempdir() as tempdir: 75 with scoped_tempdir() as tempdir:
67 print 'Building gn manually in a temporary directory for bootstrapping...' 76 print 'Building gn manually in a temporary directory for bootstrapping...'
68 build_gn_with_ninja_manually(tempdir) 77 build_gn_with_ninja_manually(tempdir, options)
78 temp_gn = os.path.join(tempdir, 'gn')
79 out_gn = os.path.join(build_root, 'gn')
69 80
70 print 'Building gn using itself to %s...' % build_rel 81 if options.no_bootstrap:
71 build_gn_with_gn(os.path.join(tempdir, 'gn'), build_rel, options.debug) 82 mkdir_p(build_root)
83 shutil.copy2(temp_gn, out_gn)
84 else:
85 print 'Building gn using itself to %s...' % build_rel
86 build_gn_with_gn(temp_gn, build_rel, options)
72 87
73 if options.output: 88 if options.output:
74 # Preserve the executable permission bit. 89 # Preserve the executable permission bit.
75 shutil.copy2(os.path.join(build_root, 'gn'), options.output) 90 shutil.copy2(out_gn, options.output)
76 except subprocess.CalledProcessError as e: 91 except subprocess.CalledProcessError as e:
77 print >> sys.stderr, str(e) 92 print >> sys.stderr, str(e)
78 return 1 93 return 1
79 return 0 94 return 0
80 95
81 96
82 def build_gn_with_ninja_manually(tempdir): 97 def build_gn_with_ninja_manually(tempdir, options):
83 write_ninja(os.path.join(tempdir, 'build.ninja')) 98 write_ninja(os.path.join(tempdir, 'build.ninja'), options)
84 check_call(['ninja', '-C', tempdir, 'gn']) 99 cmd = ['ninja', '-C', tempdir]
100 if options.verbose:
101 cmd.append('-v')
102 cmd.append('gn')
103 check_call(cmd)
85 104
86 105 def write_ninja(path, options):
87 def write_ninja(path): 106 cc = os.environ.get('CC', '')
107 cxx = os.environ.get('CXX', '')
88 cflags = os.environ.get('CFLAGS', '').split() 108 cflags = os.environ.get('CFLAGS', '').split()
109 cflags_cc = os.environ.get('CXXFLAGS', '').split()
89 ldflags = os.environ.get('LDFLAGS', '').split() 110 ldflags = os.environ.get('LDFLAGS', '').split()
90 include_dirs = [SRC_ROOT] 111 include_dirs = [SRC_ROOT]
91 libs = [] 112 libs = []
92 113
114 if is_posix:
115 if options.debug:
116 cflags.extend(['-O0', '-g'])
117 else:
118 cflags.extend(['-O2', '-g0'])
119
120 cflags.extend(['-D_FILE_OFFSET_BITS=64 -pthread', '-pipe'])
121 cflags_cc.extend(['-std=gnu++11', '-Wno-c++11-narrowing'])
122
93 static_libraries = { 123 static_libraries = {
94 'base': {'sources': [], 'tool': 'cxx'}, 124 'base': {'sources': [], 'tool': 'cxx'},
95 'dynamic_annotations': {'sources': [], 'tool': 'cc'}, 125 'dynamic_annotations': {'sources': [], 'tool': 'cc'},
96 'gn': {'sources': [], 'tool': 'cxx'}, 126 'gn': {'sources': [], 'tool': 'cxx'},
97 } 127 }
98 128
99 for name in os.listdir(GN_ROOT): 129 for name in os.listdir(GN_ROOT):
100 if not name.endswith('.cc'): 130 if not name.endswith('.cc'):
101 continue 131 continue
102 if name.endswith('_unittest.cc'): 132 if name.endswith('_unittest.cc'):
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 'base/threading/thread_restrictions.cc', 226 'base/threading/thread_restrictions.cc',
197 'base/time/time.cc', 227 'base/time/time.cc',
198 'base/timer/elapsed_timer.cc', 228 'base/timer/elapsed_timer.cc',
199 'base/timer/timer.cc', 229 'base/timer/timer.cc',
200 'base/tracked_objects.cc', 230 'base/tracked_objects.cc',
201 'base/tracking_info.cc', 231 'base/tracking_info.cc',
202 'base/values.cc', 232 'base/values.cc',
203 'base/vlog.cc', 233 'base/vlog.cc',
204 ]) 234 ])
205 235
206 if is_linux(): 236 if is_posix:
237 static_libraries['base']['sources'].extend([
238 'base/base_paths_posix.cc',
239 'base/debug/debugger_posix.cc',
240 'base/debug/stack_trace_posix.cc',
241 'base/file_util_posix.cc',
242 'base/files/file_enumerator_posix.cc',
243 'base/files/file_posix.cc',
244 'base/message_loop/message_pump_libevent.cc',
245 'base/posix/file_descriptor_shuffle.cc',
246 'base/process/kill_posix.cc',
247 'base/process/process_handle_posix.cc',
248 'base/process/process_metrics_posix.cc',
249 'base/process/process_posix.cc',
250 'base/safe_strerror_posix.cc',
251 'base/synchronization/condition_variable_posix.cc',
252 'base/synchronization/lock_impl_posix.cc',
253 'base/synchronization/waitable_event_posix.cc',
254 'base/sys_info_posix.cc',
255 'base/threading/platform_thread_posix.cc',
256 'base/threading/thread_local_posix.cc',
257 'base/threading/thread_local_storage_posix.cc',
258 'base/time/time_posix.cc',
259 ])
207 static_libraries['libevent'] = { 260 static_libraries['libevent'] = {
208 'sources': [ 261 'sources': [
209 'third_party/libevent/buffer.c', 262 'third_party/libevent/buffer.c',
210 'third_party/libevent/epoll.c',
211 'third_party/libevent/evbuffer.c', 263 'third_party/libevent/evbuffer.c',
212 'third_party/libevent/evdns.c', 264 'third_party/libevent/evdns.c',
213 'third_party/libevent/event.c', 265 'third_party/libevent/event.c',
214 'third_party/libevent/event_tagging.c', 266 'third_party/libevent/event_tagging.c',
215 'third_party/libevent/evrpc.c', 267 'third_party/libevent/evrpc.c',
216 'third_party/libevent/evutil.c', 268 'third_party/libevent/evutil.c',
217 'third_party/libevent/http.c', 269 'third_party/libevent/http.c',
218 'third_party/libevent/log.c', 270 'third_party/libevent/log.c',
219 'third_party/libevent/poll.c', 271 'third_party/libevent/poll.c',
220 'third_party/libevent/select.c', 272 'third_party/libevent/select.c',
221 'third_party/libevent/signal.c', 273 'third_party/libevent/signal.c',
222 'third_party/libevent/strlcpy.c', 274 'third_party/libevent/strlcpy.c',
223 ], 275 ],
224 'tool': 'cc', 276 'tool': 'cc',
225 'include_dirs': [ 277 'include_dirs': [],
226 os.path.join(SRC_ROOT, 'third_party', 'libevent', 'linux')
227 ],
228 'cflags': cflags + ['-DHAVE_CONFIG_H'], 278 'cflags': cflags + ['-DHAVE_CONFIG_H'],
229 } 279 }
280
281
282 if is_linux:
283 libs.extend(['-lrt'])
284 ldflags.extend(['-pthread'])
285
230 static_libraries['xdg_user_dirs'] = { 286 static_libraries['xdg_user_dirs'] = {
231 'sources': [ 287 'sources': [
232 'base/third_party/xdg_user_dirs/xdg_user_dir_lookup.cc', 288 'base/third_party/xdg_user_dirs/xdg_user_dir_lookup.cc',
233 ], 289 ],
234 'tool': 'cxx', 290 'tool': 'cxx',
235 } 291 }
236 static_libraries['base']['sources'].extend([ 292 static_libraries['base']['sources'].extend([
237 'base/base_paths_posix.cc',
238 'base/debug/debugger_posix.cc',
239 'base/debug/stack_trace_posix.cc',
240 'base/file_util_posix.cc',
241 'base/files/file_enumerator_posix.cc',
242 'base/files/file_posix.cc',
243 'base/message_loop/message_pump_glib.cc',
244 'base/message_loop/message_pump_libevent.cc',
245 'base/nix/xdg_util.cc', 293 'base/nix/xdg_util.cc',
246 'base/posix/file_descriptor_shuffle.cc',
247 'base/process/internal_linux.cc', 294 'base/process/internal_linux.cc',
248 'base/process/kill_posix.cc',
249 'base/process/process_handle_linux.cc', 295 'base/process/process_handle_linux.cc',
250 'base/process/process_handle_posix.cc',
251 'base/process/process_iterator_linux.cc', 296 'base/process/process_iterator_linux.cc',
252 'base/process/process_linux.cc', 297 'base/process/process_linux.cc',
253 'base/process/process_metrics_linux.cc', 298 'base/process/process_metrics_linux.cc',
254 'base/process/process_metrics_posix.cc',
255 'base/process/process_posix.cc',
256 'base/safe_strerror_posix.cc',
257 'base/strings/sys_string_conversions_posix.cc', 299 'base/strings/sys_string_conversions_posix.cc',
258 'base/synchronization/condition_variable_posix.cc',
259 'base/synchronization/lock_impl_posix.cc',
260 'base/synchronization/waitable_event_posix.cc',
261 'base/sys_info_linux.cc', 300 'base/sys_info_linux.cc',
262 'base/sys_info_posix.cc',
263 'base/threading/platform_thread_linux.cc', 301 'base/threading/platform_thread_linux.cc',
264 'base/threading/platform_thread_posix.cc', 302 ])
265 'base/threading/thread_local_posix.cc', 303 static_libraries['libevent']['include_dirs'].extend([
266 'base/threading/thread_local_storage_posix.cc', 304 os.path.join(SRC_ROOT, 'third_party', 'libevent', 'linux')
267 'base/time/time_posix.cc', 305 ])
306 static_libraries['libevent']['sources'].extend([
307 'third_party/libevent/epoll.c',
268 ]) 308 ])
269 309
270 cflags.extend(['-O2', '-pthread', '-pipe'])
271 310
272 static_libraries['base'].setdefault('cflags', []).extend( 311 if is_mac:
273 subprocess.check_output( 312 static_libraries['base']['sources'].extend([
274 ['pkg-config', 'gtk+-2.0', 'x11', '--cflags']).split()) 313 'base/base_paths_mac.mm',
275 ldflags.extend(['-pthread']) 314 'base/file_util_mac.mm',
276 ldflags.extend(subprocess.check_output( 315 'base/mac/bundle_locations.mm',
277 ['pkg-config', 'gtk+-2.0', 'x11', 316 'base/mac/foundation_util.mm',
278 '--libs-only-L', '--libs-only-other']).split()) 317 'base/mac/mach_logging.cc',
279 libs.extend(subprocess.check_output( 318 'base/mac/scoped_mach_port.cc',
280 ['pkg-config', 'gtk+-2.0', 'x11', '--libs-only-l']).split()) 319 'base/mac/scoped_nsautorelease_pool.mm',
320 'base/message_loop/message_pump_mac.mm',
321 'base/process/process_handle_mac.cc',
322 'base/process/process_iterator_mac.cc',
323 'base/strings/sys_string_conversions_mac.mm',
324 'base/time/time_mac.cc',
325 'base/threading/platform_thread_mac.mm',
326 ])
327 static_libraries['libevent']['include_dirs'].extend([
328 os.path.join(SRC_ROOT, 'third_party', 'libevent', 'mac')
329 ])
330 static_libraries['libevent']['sources'].extend([
331 'third_party/libevent/kqueue.c',
332 ])
281 333
282 with open(os.path.join(GN_ROOT, 'bootstrap', 'build.ninja.template')) as f: 334
335 if is_mac:
336 template_filename = 'build_mac.ninja.template'
337 else:
338 template_filename = 'build.ninja.template'
339
340 with open(os.path.join(GN_ROOT, 'bootstrap', template_filename)) as f:
283 ninja_template = f.read() 341 ninja_template = f.read()
284 342
285 def src_to_obj(path): 343 def src_to_obj(path):
286 return '%s' % os.path.splitext(path)[0] + '.o' 344 return '%s' % os.path.splitext(path)[0] + '.o'
287 345
288 ninja_lines = [] 346 ninja_lines = []
289 for library, settings in static_libraries.iteritems(): 347 for library, settings in static_libraries.iteritems():
290 for src_file in settings['sources']: 348 for src_file in settings['sources']:
291 ninja_lines.extend([ 349 ninja_lines.extend([
292 'build %s: %s %s' % (src_to_obj(src_file), 350 'build %s: %s %s' % (src_to_obj(src_file),
293 settings['tool'], 351 settings['tool'],
294 os.path.join(SRC_ROOT, src_file)), 352 os.path.join(SRC_ROOT, src_file)),
295 ' includes = %s' % ' '.join( 353 ' includes = %s' % ' '.join(
296 ['-I' + dirname for dirname in 354 ['-I' + dirname for dirname in
297 include_dirs + settings.get('include_dirs', [])]), 355 include_dirs + settings.get('include_dirs', [])]),
298 ' cflags = %s' % ' '.join(cflags + settings.get('cflags', [])), 356 ' cflags = %s' % ' '.join(cflags + settings.get('cflags', [])),
357 ' cflags_cc = %s' %
358 ' '.join(cflags_cc + settings.get('cflags_cc', [])),
299 ]) 359 ])
360 if cc:
361 ninja_lines.append(' cc = %s' % cc)
362 if cxx:
363 ninja_lines.append(' cxx = %s' % cxx)
300 364
301 ninja_lines.append('build %s.a: alink_thin %s' % ( 365 ninja_lines.append('build %s.a: alink_thin %s' % (
302 library, 366 library,
303 ' '.join([src_to_obj(src_file) for src_file in settings['sources']]))) 367 ' '.join([src_to_obj(src_file) for src_file in settings['sources']])))
304 368
369 if is_mac:
370 libs.extend([
371 '-framework', 'AppKit',
372 '-framework', 'CoreFoundation',
373 '-framework', 'Foundation',
374 '-framework', 'Security',
375 ]);
376
305 ninja_lines.extend([ 377 ninja_lines.extend([
306 'build gn: link %s' % ( 378 'build gn: link %s' % (
307 ' '.join(['%s.a' % library for library in static_libraries])), 379 ' '.join(['%s.a' % library for library in static_libraries])),
308 ' ld = $ldxx', 380 ' ld = $ldxx',
309 ' ldflags = %s' % ' '.join(ldflags), 381 ' ldflags = %s' % ' '.join(ldflags),
310 ' libs = %s' % ' '.join(libs), 382 ' libs = %s' % ' '.join(libs),
311 '', # Make sure the file ends with a newline. 383 '', # Make sure the file ends with a newline.
312 ]) 384 ])
313 385
314 with open(path, 'w') as f: 386 with open(path, 'w') as f:
315 f.write(ninja_template + '\n'.join(ninja_lines)) 387 f.write(ninja_template + '\n'.join(ninja_lines))
316 388
317 389
318 def build_gn_with_gn(temp_gn, build_dir, debug): 390 def build_gn_with_gn(temp_gn, build_dir, options):
319 cmd = [temp_gn, 'gen', build_dir] 391 cmd = [temp_gn, 'gen', build_dir]
320 if not debug: 392 if not options.debug:
321 cmd.append('--args=is_debug=false') 393 cmd.append('--args=is_debug=false')
322 check_call(cmd) 394 check_call(cmd)
323 check_call(['ninja', '-C', build_dir, 'gn']) 395
396 cmd = ['ninja', '-C', build_dir]
397 if options.verbose:
398 cmd.append('-v')
399 cmd.append('gn')
400 check_call(cmd)
401
324 if not debug: 402 if not debug:
325 check_call(['strip', os.path.join(build_dir, 'gn')]) 403 check_call(['strip', os.path.join(build_dir, 'gn')])
326 404
327 405
328 if __name__ == '__main__': 406 if __name__ == '__main__':
329 sys.exit(main(sys.argv[1:])) 407 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « AUTHORS ('k') | tools/gn/bootstrap/build_mac.ninja.template » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698