Index: tools/gn/bootstrap/bootstrap.py |
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..fd6538ea7baa9d2970d777769e1b337a97ea674d |
--- /dev/null |
+++ b/tools/gn/bootstrap/bootstrap.py |
@@ -0,0 +1,301 @@ |
+#!/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. |
+ |
+import contextlib |
+import optparse |
+import os |
+import shutil |
+import subprocess |
+import sys |
+import tempfile |
+ |
+ |
+GN_ROOT = os.path.abspath(os.path.join( |
+ os.path.dirname(os.path.abspath(__file__)), '..')) |
+ |
+SRC_ROOT = os.path.abspath(os.path.join( |
+ GN_ROOT, '..', '..')) |
+ |
+BUILD_ROOT = os.path.abspath(os.path.join( |
+ SRC_ROOT, 'out', 'Release')) |
+ |
+ |
+def is_linux(): |
+ return sys.platform.startswith('linux') |
+ |
+ |
+@contextlib.contextmanager |
+def scoped_tempdir(): |
+ path = tempfile.mkdtemp() |
+ try: |
+ yield path |
+ finally: |
+ shutil.rmtree(path) |
+ |
+ |
+def main(argv): |
+ parser = optparse.OptionParser() |
+ parser.add_option('-o', '--output', |
+ help='place output in PATH', metavar='PATH') |
+ options, args = parser.parse_args(argv) |
+ |
+ if not options.output: |
+ parser.error('Please specify --output.') |
+ |
+ if args: |
+ parser.error('Unrecognized command line arguments: %s.' % ', '.join(args)) |
+ |
+ with scoped_tempdir() as tempdir: |
+ print 'Building gn manually...' |
+ write_ninja(os.path.join(tempdir, 'build.ninja')) |
+ subprocess.check_call(['ninja', '-C', tempdir, 'gn']) |
+ |
+ print 'Building gn using itself...' |
+ subprocess.check_call([ |
+ os.path.join(tempdir, 'gn'), |
+ '--args=is_debug=false', |
+ '--output=%s' % os.path.relpath(BUILD_ROOT, SRC_ROOT)]) |
+ subprocess.check_call(['ninja', '-C', BUILD_ROOT, 'gn']) |
+ subprocess.check_call(['strip', os.path.join(BUILD_ROOT, 'gn')]) |
+ |
+ # Preserve the executable permission bit. |
+ shutil.copy2(os.path.join(BUILD_ROOT, 'gn'), options.output) |
+ |
+ return 0 |
+ |
+ |
+def write_ninja(path): |
+ cflags = os.environ.get('CFLAGS', '').split() |
+ ldflags = os.environ.get('LDFLAGS', '').split() |
+ include_dirs = [SRC_ROOT] |
+ libs = [] |
+ |
+ static_libraries = { |
+ 'base': {'sources': [], 'tool': 'cxx'}, |
+ 'dynamic_annotations': {'sources': [], 'tool': 'cc'}, |
+ 'gn': {'sources': [], 'tool': 'cxx'}, |
+ } |
+ |
+ for name in os.listdir(GN_ROOT): |
+ if not name.endswith('.cc'): |
+ continue |
+ if name.endswith('_unittest.cc'): |
+ continue |
+ if name in ['generate_test_gn_data.cc']: |
+ continue |
+ full_path = os.path.join(GN_ROOT, name) |
+ static_libraries['gn']['sources'].append( |
+ os.path.relpath(full_path, SRC_ROOT)) |
+ |
+ static_libraries['dynamic_annotations']['sources'].extend([ |
+ 'base/third_party/dynamic_annotations/dynamic_annotations.c', |
+ ]) |
+ static_libraries['base']['sources'].extend([ |
+ 'base/at_exit.cc', |
+ 'base/atomicops_internals_x86_gcc.cc', |
+ 'base/base_paths.cc', |
+ 'base/base_switches.cc', |
+ 'base/callback_internal.cc', |
+ 'base/command_line.cc', |
+ 'base/debug/alias.cc', |
+ 'base/debug/stack_trace.cc', |
+ 'base/debug/trace_event_impl.cc', |
+ 'base/debug/trace_event_impl_constants.cc', |
+ 'base/debug/trace_event_memory.cc', |
+ 'base/debug/trace_event_synthetic_delay.cc', |
+ 'base/environment.cc', |
+ 'base/file_util.cc', |
+ 'base/files/file.cc', |
+ 'base/files/file_enumerator.cc', |
+ 'base/files/file_path.cc', |
+ 'base/files/file_path_constants.cc', |
+ 'base/json/json_parser.cc', |
+ 'base/json/json_reader.cc', |
+ 'base/json/json_string_value_serializer.cc', |
+ 'base/json/json_writer.cc', |
+ 'base/json/string_escape.cc', |
+ 'base/lazy_instance.cc', |
+ 'base/location.cc', |
+ 'base/logging.cc', |
+ 'base/memory/ref_counted.cc', |
+ 'base/memory/ref_counted_memory.cc', |
+ 'base/memory/singleton.cc', |
+ 'base/memory/weak_ptr.cc', |
+ 'base/message_loop/incoming_task_queue.cc', |
+ 'base/message_loop/message_loop.cc', |
+ 'base/message_loop/message_loop_proxy.cc', |
+ 'base/message_loop/message_loop_proxy_impl.cc', |
+ 'base/message_loop/message_pump.cc', |
+ 'base/message_loop/message_pump_default.cc', |
+ 'base/metrics/bucket_ranges.cc', |
+ 'base/metrics/histogram.cc', |
+ 'base/metrics/histogram_base.cc', |
+ 'base/metrics/histogram_samples.cc', |
+ 'base/metrics/sample_map.cc', |
+ 'base/metrics/sample_vector.cc', |
+ 'base/metrics/sparse_histogram.cc', |
+ 'base/metrics/statistics_recorder.cc', |
+ 'base/path_service.cc', |
+ 'base/pending_task.cc', |
+ 'base/pickle.cc', |
+ 'base/process/kill.cc', |
+ 'base/process/process_iterator.cc', |
+ 'base/process/process_metrics.cc', |
+ 'base/profiler/alternate_timer.cc', |
+ 'base/profiler/tracked_time.cc', |
+ 'base/run_loop.cc', |
+ 'base/sequence_checker_impl.cc', |
+ 'base/sequenced_task_runner.cc', |
+ 'base/strings/string16.cc', |
+ 'base/strings/string_number_conversions.cc', |
+ 'base/strings/string_piece.cc', |
+ 'base/strings/string_split.cc', |
+ 'base/strings/string_util.cc', |
+ 'base/strings/string_util_constants.cc', |
+ 'base/strings/stringprintf.cc', |
+ 'base/strings/utf_string_conversion_utils.cc', |
+ 'base/strings/utf_string_conversions.cc', |
+ 'base/synchronization/cancellation_flag.cc', |
+ 'base/synchronization/lock.cc', |
+ 'base/sys_info.cc', |
+ 'base/task_runner.cc', |
+ 'base/third_party/dmg_fp/dtoa_wrapper.cc', |
+ 'base/third_party/dmg_fp/g_fmt.cc', |
+ 'base/third_party/icu/icu_utf.cc', |
+ 'base/third_party/nspr/prtime.cc', |
+ 'base/thread_task_runner_handle.cc', |
+ 'base/threading/non_thread_safe_impl.cc', |
+ 'base/threading/post_task_and_reply_impl.cc', |
+ 'base/threading/sequenced_worker_pool.cc', |
+ 'base/threading/simple_thread.cc', |
+ 'base/threading/thread_checker_impl.cc', |
+ 'base/threading/thread_collision_warner.cc', |
+ 'base/threading/thread_id_name_manager.cc', |
+ 'base/threading/thread_local_storage.cc', |
+ 'base/threading/thread_restrictions.cc', |
+ 'base/time/time.cc', |
+ 'base/timer/elapsed_timer.cc', |
+ 'base/timer/timer.cc', |
+ 'base/tracked_objects.cc', |
+ 'base/tracking_info.cc', |
+ 'base/values.cc', |
+ 'base/vlog.cc', |
+ ]) |
+ |
+ if is_linux(): |
+ static_libraries['libevent'] = { |
+ 'sources': [ |
+ 'third_party/libevent/buffer.c', |
+ 'third_party/libevent/epoll.c', |
+ 'third_party/libevent/evbuffer.c', |
+ 'third_party/libevent/evdns.c', |
+ 'third_party/libevent/event.c', |
+ 'third_party/libevent/event_tagging.c', |
+ 'third_party/libevent/evrpc.c', |
+ 'third_party/libevent/evutil.c', |
+ 'third_party/libevent/http.c', |
+ 'third_party/libevent/log.c', |
+ 'third_party/libevent/poll.c', |
+ 'third_party/libevent/select.c', |
+ 'third_party/libevent/signal.c', |
+ 'third_party/libevent/strlcpy.c', |
+ ], |
+ 'tool': 'cc', |
+ 'include_dirs': [ |
+ os.path.join(SRC_ROOT, 'third_party', 'libevent', 'linux') |
+ ], |
+ 'cflags': cflags + ['-DHAVE_CONFIG_H'], |
+ } |
+ static_libraries['xdg_user_dirs'] = { |
+ 'sources': [ |
+ 'base/third_party/xdg_user_dirs/xdg_user_dir_lookup.cc', |
+ ], |
+ 'tool': 'cxx', |
+ } |
+ static_libraries['base']['sources'].extend([ |
+ 'base/base_paths_posix.cc', |
+ 'base/debug/debugger_posix.cc', |
+ 'base/debug/stack_trace_posix.cc', |
+ 'base/file_util_posix.cc', |
+ 'base/files/file_enumerator_posix.cc', |
+ 'base/files/file_posix.cc', |
+ 'base/message_loop/message_pump_glib.cc', |
+ 'base/message_loop/message_pump_gtk.cc', |
+ 'base/message_loop/message_pump_libevent.cc', |
+ 'base/nix/xdg_util.cc', |
+ 'base/posix/file_descriptor_shuffle.cc', |
+ 'base/process/internal_linux.cc', |
+ 'base/process/kill_posix.cc', |
+ 'base/process/process_handle_linux.cc', |
+ 'base/process/process_handle_posix.cc', |
+ 'base/process/process_iterator_linux.cc', |
+ 'base/process/process_linux.cc', |
+ 'base/process/process_metrics_linux.cc', |
+ 'base/process/process_metrics_posix.cc', |
+ 'base/process/process_posix.cc', |
+ 'base/safe_strerror_posix.cc', |
+ 'base/strings/sys_string_conversions_posix.cc', |
+ 'base/synchronization/condition_variable_posix.cc', |
+ 'base/synchronization/lock_impl_posix.cc', |
+ 'base/synchronization/waitable_event_posix.cc', |
+ 'base/sys_info_linux.cc', |
+ 'base/sys_info_posix.cc', |
+ 'base/threading/platform_thread_linux.cc', |
+ 'base/threading/platform_thread_posix.cc', |
+ 'base/threading/thread_local_posix.cc', |
+ 'base/threading/thread_local_storage_posix.cc', |
+ 'base/time/time_posix.cc', |
+ ]) |
+ |
+ cflags.extend(['-O2', '-pthread', '-pipe']) |
+ |
+ static_libraries['base'].setdefault('cflags', []).extend( |
+ subprocess.check_output( |
+ ['pkg-config', 'gtk+-2.0', 'x11', '--cflags']).split()) |
+ ldflags.extend(['-pthread']) |
+ ldflags.extend(subprocess.check_output( |
+ ['pkg-config', 'gtk+-2.0', 'x11', |
+ '--libs-only-L', '--libs-only-other']).split()) |
+ libs.extend(subprocess.check_output( |
+ ['pkg-config', 'gtk+-2.0', 'x11', '--libs-only-l']).split()) |
+ |
+ with open(os.path.join(GN_ROOT, 'bootstrap', 'build.ninja.template')) as f: |
+ ninja_template = f.read() |
+ |
+ def src_to_obj(path): |
+ return '%s' % os.path.splitext(src_file)[0] + '.o' |
+ |
+ ninja_lines = [] |
+ for library, settings in static_libraries.iteritems(): |
+ for src_file in settings['sources']: |
+ ninja_lines.extend([ |
+ 'build %s: %s %s' % (src_to_obj(src_file), |
+ settings['tool'], |
+ os.path.join(SRC_ROOT, src_file)), |
+ ' includes = %s' % ' '.join( |
+ ['-I' + dirname for dirname in |
+ include_dirs + settings.get('include_dirs', [])]), |
+ ' cflags = %s' % ' '.join(cflags + settings.get('cflags', [])), |
+ ]) |
+ |
+ ninja_lines.append('build %s.a: alink_thin %s' % ( |
+ library, |
+ ' '.join([src_to_obj(src_file) for src_file in settings['sources']]))) |
+ |
+ ninja_lines.extend([ |
+ 'build gn: link %s' % ( |
+ ' '.join(['%s.a' % library for library in static_libraries])), |
+ ' ld = $ldxx', |
+ ' ldflags = %s' % ' '.join(ldflags), |
+ ' libs = %s' % ' '.join(libs), |
+ '', # Make sure the file ends with a newline. |
+ ]) |
+ |
+ with open(path, 'w') as f: |
+ f.write(ninja_template + '\n'.join(ninja_lines)) |
+ |
+ |
+if __name__ == '__main__': |
+ sys.exit(main(sys.argv[1:])) |