1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Copyright (c) 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import errno 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import os 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import re 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import subprocess 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import sys 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)""" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Copies the given "win tool" (which the toolchain uses to wrap compiler 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)invocations) and the environment blocks for the 32-bit and 64-bit builds on 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Windows to the build directory. 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)The arguments are the visual studio install location and the location of the 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)win tool. The script assumes that the root build directory is the current dir 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)and the files will be written to the current directory. 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)""" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)def ExtractImportantEnvironment(): 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Extracts environment variables required for the toolchain from the 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current environment.""" 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) envvars_to_save = ( 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 'include', # Needed by midl compiler. 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 'path', 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 'pathext', 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 'systemroot', 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 'temp', 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 'tmp', 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ) 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) result = {} 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for envvar in envvars_to_save: 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if envvar in os.environ: 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) envvar = envvar.lower() 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if envvar == 'path': 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Our own rules (for running gyp-win-tool) and other actions in 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Chromium rely on python being in the path. Add the path to this 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # python here so that if it's not in the path when ninja is run 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # later, python will still be found. 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) result[envvar.upper()] = os.path.dirname(sys.executable) + \ 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os.pathsep + os.environ[envvar] 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else: 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) result[envvar.upper()] = os.environ[envvar] 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for required in ('SYSTEMROOT', 'TEMP', 'TMP'): 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if required not in result: 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) raise Exception('Environment variable "%s" ' 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'required to be set to valid path' % required) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return result 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)def FormatAsEnvironmentBlock(envvar_dict): 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Format as an 'environment block' directly suitable for CreateProcess. 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Briefly this is a list of key=value\0, terminated by an additional \0. See 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateProcess documentation for more details.""" 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) block = '' 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) nul = '\0' 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for key, value in envvar_dict.iteritems(): 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) block += key + '=' + value + nul 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) block += nul 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return block 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)def CopyTool(source_path): 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Copies the given tool to the current directory, including a warning not 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) to edit it.""" 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) with open(source_path) as source_file: 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) tool_source = source_file.readlines() 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Add header and write it out to the current directory (which should be the 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # root build dir). 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) with open("gyp-win-tool", 'w') as tool_file: 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) tool_file.write(''.join([tool_source[0], 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '# Generated by setup_toolchain.py do not edit.\n'] 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) + tool_source[1:])) 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)if len(sys.argv) != 4: 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) print('Usage setup_toolchain.py ' 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) '<visual studio path> <win tool path> <win sdk path>') 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sys.exit(2) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)vs_path = sys.argv[1] 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)tool_source = sys.argv[2] 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)win_sdk_path = sys.argv[3] 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CopyTool(tool_source) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)important_env_vars = ExtractImportantEnvironment() 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)path = important_env_vars["PATH"].split(";") 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Add 32-bit compiler path to the beginning and write the block. 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)path32 = [os.path.join(vs_path, "VC\\BIN")] + \ 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) [os.path.join(win_sdk_path, "bin\\x86")] + \ 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)important_env_vars["PATH"] = ";".join(path32) 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)environ = FormatAsEnvironmentBlock(important_env_vars) 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)with open('environment.x86', 'wb') as env_file: 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) env_file.write(environ) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Add 64-bit compiler path to the beginning and write the block. 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)path64 = [os.path.join(vs_path, "VC\\BIN\\amd64")] + \ 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) [os.path.join(win_sdk_path, "bin\\x64")] + \ 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) path 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)important_env_vars["PATH"] = ";".join(path64) 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)environ = FormatAsEnvironmentBlock(important_env_vars) 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)with open('environment.x64', 'wb') as env_file: 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) env_file.write(environ) 109