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 12 import argparse 13 import common 14 import json 15 import os 16 import shlex 17 import shutil 18 import subprocess 19 import sys 20 import utils 21 22 import 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. 27 IGNORE_LIST = [ 28 'WindowsMobile', 29 'App Certification Kit', 30 'Debuggers', 31 'Extension SDKs', 32 'DesignTime', 33 'AccChecker', 34 ] 35 36 REPO_CHROME = 'https://chromium.googlesource.com/chromium/src.git' 37 38 39 def 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 49 def 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 59 def 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 97 def 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 112 def 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 126 if __name__ == '__main__': 127 main() 128