1#!/usr/bin/env python 2# 3# Copyright 2016 Google Inc. 4# 5# Use of this source code is governed by a BSD-style license that can be 6# found in the LICENSE file. 7 8 9"""Download an updated VS toolchain""" 10 11 12import argparse 13import common 14import json 15import os 16import shlex 17import shutil 18import subprocess 19import sys 20import utils 21 22import win_toolchain_utils 23 24 25# By default the toolchain includes a bunch of unnecessary stuff with long path 26# names. Trim out directories with these names. 27IGNORE_LIST = [ 28 'WindowsMobile', 29 'App Certification Kit', 30 'Debuggers', 31 'Extension SDKs', 32 'DesignTime', 33 'AccChecker', 34] 35 36REPO_CHROME = 'https://chromium.googlesource.com/chromium/src.git' 37 38 39def filter_toolchain_files(dirname, files): 40 """Callback for shutil.copytree. Return lists of files to skip.""" 41 split = dirname.split(os.path.sep) 42 for ign in IGNORE_LIST: 43 if ign in split: 44 print 'Ignoring dir %s' % dirname 45 return files 46 return [] 47 48 49def get_toolchain_dir(toolchain_dir_output): 50 """Find the toolchain directory.""" 51 prefix = 'vs_path = ' 52 for line in toolchain_dir_output.splitlines(): 53 if line.startswith(prefix): 54 return line[len(prefix):].strip('"') 55 raise Exception('Unable to find toolchain dir in output:\n%s' % ( 56 toolchain_dir_output)) 57 58 59def gen_toolchain(chrome_path, msvs_version, target_dir): 60 """Update the VS toolchain and copy it to the target_dir.""" 61 with utils.chdir(os.path.join(chrome_path, 'src')): 62 subprocess.check_call([utils.GCLIENT, 'sync']) 63 depot_tools = subprocess.check_output([ 64 'python', os.path.join('build', 'find_depot_tools.py')]).rstrip() 65 with utils.git_branch(): 66 vs_toolchain_py = os.path.join('build', 'vs_toolchain.py') 67 env = os.environ.copy() 68 env['GYP_MSVS_VERSION'] = msvs_version 69 subprocess.check_call(['python', vs_toolchain_py, 'update'], env=env) 70 output = subprocess.check_output(['python', vs_toolchain_py, 71 'get_toolchain_dir'], env=env).rstrip() 72 src_dir = get_toolchain_dir(output) 73 # Mock out absolute paths in win_toolchain.json. 74 win_toolchain_utils.abstract(os.path.join('build', 'win_toolchain.json'), 75 os.path.dirname(depot_tools)) 76 77 # Copy the toolchain files to the target_dir. 78 build = os.path.join(os.getcwd(), 'build') 79 dst_build = os.path.join(target_dir, 'src', 'build') 80 os.makedirs(dst_build) 81 for f in ('find_depot_tools.py', 'vs_toolchain.py', 'win_toolchain.json'): 82 shutil.copyfile(os.path.join(build, f), os.path.join(dst_build, f)) 83 84 shutil.copytree(os.path.join(os.getcwd(), 'tools', 'gyp', 'pylib'), 85 os.path.join(target_dir, 'src', 'tools', 'gyp', 'pylib')) 86 87 dst_depot_tools = os.path.join(target_dir, 'depot_tools') 88 os.makedirs(dst_depot_tools) 89 for f in ('gclient.py', 'breakpad.py'): 90 shutil.copyfile(os.path.join(depot_tools, f), 91 os.path.join(dst_depot_tools, f)) 92 toolchain_dst = os.path.join( 93 target_dir, 'depot_tools', os.path.relpath(src_dir, depot_tools)) 94 shutil.copytree(src_dir, toolchain_dst, ignore=filter_toolchain_files) 95 96 97def create_asset(target_dir, msvs_version, chrome_path=None): 98 """Create the asset.""" 99 if not os.path.isdir(target_dir): 100 os.makedirs(target_dir) 101 with utils.tmp_dir() as tmp_dir: 102 if not chrome_path: 103 print ('Syncing Chrome from scratch. If you already have a checkout, ' 104 'specify --chrome_path to save time.') 105 chrome_path = os.path.join(tmp_dir.name, 'src') 106 if not os.path.isdir(chrome_path): 107 subprocess.check_call([utils.GCLIENT, 'config', REPO_CHROME, '--managed']) 108 subprocess.check_call([utils.GCLIENT, 'sync']) 109 110 gen_toolchain(chrome_path, msvs_version, target_dir) 111 112def main(): 113 if sys.platform != 'win32': 114 print >> sys.stderr, 'This script only runs on Windows.' 115 sys.exit(1) 116 117 parser = argparse.ArgumentParser() 118 parser.add_argument('--msvs_version', required=True) 119 parser.add_argument('--chrome_path') 120 parser.add_argument('--target_dir', '-t', required=True) 121 args = parser.parse_args() 122 target_dir = os.path.abspath(args.target_dir) 123 create_asset(target_dir, args.msvs_version, args.chrome_path) 124 125 126if __name__ == '__main__': 127 main() 128