| 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:]))
|
|
|