Home | History | Annotate | Download | only in win_toolchain
      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