GN: Improve bootstrap for Windows Improve bootstrap for Windows and allow bootstrap to work in specified target directory. Additionally, some fixes made to project generation, and for Linux. R=dpranke@chromium.org Change-Id: Ied7f99d3cb83559fbde597cb707b46fcb3e98dc4 Reviewed-on: https://chromium-review.googlesource.com/941214 Commit-Queue: Yngve Pettersen <yngve@vivaldi.com> Reviewed-by: Dirk Pranke <dpranke@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#547867} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 73b7854e6d4c7a186047809aacb9ce1478277c7a
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py index 83f5838..8f32161 100755 --- a/tools/gn/bootstrap/bootstrap.py +++ b/tools/gn/bootstrap/bootstrap.py
@@ -39,12 +39,13 @@ def check_call(cmd, **kwargs): logging.debug('Running: %s', ' '.join(cmd)) - # With shell=False, subprocess expects an executable on Windows - if is_win and cmd and cmd[0].endswith('.py'): - cmd.insert(0, sys.executable) - subprocess.check_call(cmd, cwd=GN_ROOT, **kwargs) +def check_output(cmd, cwd=GN_ROOT, **kwargs): + logging.debug('Running: %s', ' '.join(cmd)) + + return subprocess.check_output(cmd, cwd=cwd, **kwargs) + def mkdir_p(path): try: os.makedirs(path) @@ -71,8 +72,13 @@ build_rel = os.path.join('out', 'Release') build_root = os.path.join(SRC_ROOT, build_rel) + windows_x64_toolchain = None + if is_win: + windows_x64_toolchain = windows_prepare_toolchain(tempdir) + os.environ["PATH"] = windows_x64_toolchain["paths"] + print 'Building gn manually in a temporary directory for bootstrapping...' - build_gn_with_ninja_manually(tempdir, options) + build_gn_with_ninja_manually(tempdir, options, windows_x64_toolchain) temp_gn = os.path.join(tempdir, 'gn') out_gn = os.path.join(build_root, 'gn') @@ -99,6 +105,37 @@ if platform.machine().lower() in ['x86_64', 'amd64']: return 'x64' return 'x86' +def windows_prepare_toolchain(tempdir): + + def CallPythonScopeScript(command, **kwargs): + response = check_output(command, **kwargs) + + _globals = {"__builtins__":None} + _locals = {} + exec(response, _globals, _locals) + + return _locals + + toolchain_paths = CallPythonScopeScript( + [sys.executable, + os.path.join(SRC_ROOT, "build", "vs_toolchain.py"), + "get_toolchain_dir"], + cwd=tempdir) + + windows_x64_toolchain = CallPythonScopeScript( + [sys.executable, + os.path.join(SRC_ROOT, "build", "toolchain", + "win", "setup_toolchain.py"), + toolchain_paths["vs_path"], + toolchain_paths["sdk_path"], + toolchain_paths["runtime_dirs"], + "x64", + "true" + ], + cwd=tempdir) + + return windows_x64_toolchain + def main(argv): parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) parser.add_option('-d', '--debug', action='store_true', @@ -112,7 +149,9 @@ 'temporary location each time') parser.add_option('--gn-gen-args', help='Args to pass to gn gen --args') parser.add_option('--build-path', help='The directory in which to build gn, ' - 'relative to the src directory. (eg. out/Release)') + 'relative to the src directory. (eg. out/Release)' + 'In the no-clean mode an absolute path will also force ' + 'the out_bootstrap to be located in the parent directory') parser.add_option('-v', '--verbose', action='store_true', help='Log more details') options, args = parser.parse_args(argv) @@ -124,7 +163,10 @@ try: if options.no_clean: - build_dir = os.path.join(SRC_ROOT, 'out_bootstrap') + out_bootstrap_dir = SRC_ROOT + if options.build_path and os.path.isabs(options.build_path): + out_bootstrap_dir = os.path.dirname(options.build_path) + build_dir = os.path.join(out_bootstrap_dir, 'out_bootstrap') if not os.path.exists(build_dir): os.makedirs(build_dir) return run_build(build_dir, options) @@ -159,6 +201,7 @@ f.write(' ' + name + '=' + value) check_call([ + sys.executable, os.path.join(SRC_ROOT, 'build', 'write_buildflag_header.py'), '--output', header, '--gen-dir', root_gen_dir, @@ -169,12 +212,13 @@ def write_build_date_header(root_gen_dir): check_call([ + sys.executable, os.path.join(SRC_ROOT, 'build', 'write_build_date_header.py'), os.path.join(root_gen_dir, 'base/generated_build_date.h'), 'default', ]) -def build_gn_with_ninja_manually(tempdir, options): +def build_gn_with_ninja_manually(tempdir, options, windows_x64_toolchain): root_gen_dir = os.path.join(tempdir, 'gen') mkdir_p(root_gen_dir) @@ -215,6 +259,7 @@ # and this file is only included for Mac builds. mkdir_p(os.path.join(root_gen_dir, 'base')) check_call([ + sys.executable, os.path.join(SRC_ROOT, 'build', 'write_build_date_header.py'), os.path.join(root_gen_dir, 'base', 'generated_build_date.h'), 'default' @@ -233,7 +278,7 @@ {'USE_LLD': 'false', 'SUPPORTS_CODE_ORDERING': 'false'}) write_gn_ninja(os.path.join(tempdir, 'build.ninja'), - root_gen_dir, options) + root_gen_dir, options, windows_x64_toolchain) cmd = ['ninja', '-C', tempdir, '-w', 'dupbuild=err'] if options.verbose: cmd.append('-v') @@ -332,12 +377,14 @@ f.write(ninja_template) f.write('\n'.join(ninja_lines)) -def write_gn_ninja(path, root_gen_dir, options): +def write_gn_ninja(path, root_gen_dir, options, windows_x64_toolchain): if is_win: - cc = os.environ.get('CC', 'cl.exe') - cxx = os.environ.get('CXX', 'cl.exe') - ld = os.environ.get('LD', 'link.exe') - ar = os.environ.get('AR', 'lib.exe') + CCPATH = windows_x64_toolchain["vc_bin_dir"] + + cc = os.environ.get('CC', os.path.join(CCPATH, 'cl.exe')) + cxx = os.environ.get('CXX', os.path.join(CCPATH, 'cl.exe')) + ld = os.environ.get('LD', os.path.join(CCPATH, 'link.exe')) + ar = os.environ.get('AR', os.path.join(CCPATH, 'lib.exe')) elif is_aix: cc = os.environ.get('CC', 'gcc') cxx = os.environ.get('CXX', 'c++') @@ -835,6 +882,9 @@ if is_win: static_libraries['base']['sources'].extend([ + "base/allocator/partition_allocator/address_space_randomization.cc", + 'base/allocator/partition_allocator/page_allocator.cc', + "base/allocator/partition_allocator/spin_lock.cc", 'base/base_paths_win.cc', 'base/cpu.cc', 'base/debug/close_handle_hook_win.cc', @@ -871,17 +921,16 @@ 'base/sync_socket_win.cc', 'base/synchronization/condition_variable_win.cc', 'base/synchronization/lock_impl_win.cc', - 'base/synchronization/read_write_lock_win.cc', 'base/synchronization/waitable_event_watcher_win.cc', 'base/synchronization/waitable_event_win.cc', 'base/sys_info_win.cc', 'base/threading/platform_thread_win.cc', 'base/threading/thread_local_storage_win.cc', - 'base/threading/worker_pool_win.cc', 'base/time/time_win.cc', 'base/timer/hi_res_timer_manager_win.cc', 'base/trace_event/heap_profiler_allocation_register_win.cc', 'base/trace_event/trace_event_etw_export_win.cc', + 'base/win/core_winrt_util.cc', 'base/win/enum_variant.cc', 'base/win/event_trace_controller.cc', 'base/win/event_trace_provider.cc', @@ -895,9 +944,12 @@ 'base/win/registry.cc', 'base/win/resource_util.cc', 'base/win/scoped_bstr.cc', + 'base/win/scoped_com_initializer.cc', 'base/win/scoped_handle.cc', + 'base/win/scoped_handle_verifier.cc', 'base/win/scoped_process_information.cc', 'base/win/scoped_variant.cc', + 'base/win/scoped_winrt_initializer.cc', 'base/win/shortcut.cc', 'base/win/startup_information.cc', 'base/win/wait_chain.cc', @@ -930,7 +982,9 @@ gn_gen_args = options.gn_gen_args or '' if not options.debug: gn_gen_args += ' is_debug=false' - cmd = [temp_gn, 'gen', build_dir, '--args=%s' % gn_gen_args] + cmd = [temp_gn, 'gen', build_dir, '--args=%s' % gn_gen_args, + "--root="+SRC_ROOT + ] check_call(cmd) cmd = ['ninja', '-C', build_dir, '-w', 'dupbuild=err']
diff --git a/tools/gn/bootstrap/build_vs.ninja.template b/tools/gn/bootstrap/build_vs.ninja.template index 6e98575..88bba37 100644 --- a/tools/gn/bootstrap/build_vs.ninja.template +++ b/tools/gn/bootstrap/build_vs.ninja.template
@@ -1,25 +1,28 @@ + +arch = environment.x64 + rule cc - command = $cc /nologo /showIncludes /FC @${out}.rsp /c ${in} /Fo${out} + command = ninja -t msvc -e $arch -- $cc /nologo /showIncludes /FC @${out}.rsp /c ${in} /Fo${out} description = CC ${out} rspfile = ${out}.rsp rspfile_content = ${defines} ${includes} ${cflags} ${cflags_c} deps = msvc rule cxx - command = $cxx /nologo /showIncludes /FC @${out}.rsp /c ${in} /Fo${out} + command = ninja -t msvc -e $arch -- $cxx /nologo /showIncludes /FC @${out}.rsp /c ${in} /Fo${out} description = CXX ${out} rspfile = ${out}.rsp rspfile_content = ${defines} ${includes} ${cflags} ${cflags_cc} deps = msvc rule alink_thin - command = $ar /nologo /ignore:4221 /OUT:${out} @${out}.rsp + command = ninja -t msvc -e $arch -- $ar /nologo /ignore:4221 /OUT:${out} @${out}.rsp description = LIB ${out} rspfile = ${out}.rsp rspfile_content = ${in_newline} rule link - command = $ld /nologo /OUT:${out} /PDB:${out}.pdb @${out}.rsp + command = ninja -t msvc -e $arch -- $ld /nologo /OUT:${out} /PDB:${out}.pdb @${out}.rsp description = LINK ${out} rspfile = ${out}.rsp rspfile_content = ${in_newline} ${libs} ${solibs} ${ldflags}