| OLD | NEW |
| 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import errno |
| 5 import os | 6 import os |
| 6 import re | 7 import re |
| 8 import subprocess |
| 7 import sys | 9 import sys |
| 8 | 10 |
| 11 """ |
| 12 Copies the given "win tool" (which the toolchain uses to wrap compiler |
| 13 invocations) and the environment blocks for the 32-bit and 64-bit builds on |
| 14 Windows to the build directory. |
| 15 |
| 16 The arguments are the visual studio install location and the location of the |
| 17 win tool. The script assumes that the root build directory is the current dir |
| 18 and the files will be written to the current directory. |
| 19 """ |
| 20 |
| 21 |
| 9 def ExtractImportantEnvironment(): | 22 def ExtractImportantEnvironment(): |
| 10 """Extracts environment variables required for the toolchain from the | 23 """Extracts environment variables required for the toolchain from the |
| 11 current environment.""" | 24 current environment.""" |
| 12 envvars_to_save = ( | 25 envvars_to_save = ( |
| 13 'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. | 26 'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. |
| 14 'Path', | 27 'Path', |
| 15 'PATHEXT', | 28 'PATHEXT', |
| 16 'SystemRoot', | 29 'SystemRoot', |
| 17 'TEMP', | 30 'TEMP', |
| 18 'TMP', | 31 'TMP', |
| (...skipping 10 matching lines...) Expand all Loading... |
| 29 os.pathsep + os.environ[envvar] | 42 os.pathsep + os.environ[envvar] |
| 30 else: | 43 else: |
| 31 result[envvar.upper()] = os.environ[envvar] | 44 result[envvar.upper()] = os.environ[envvar] |
| 32 for required in ('SYSTEMROOT', 'TEMP', 'TMP'): | 45 for required in ('SYSTEMROOT', 'TEMP', 'TMP'): |
| 33 if required not in result: | 46 if required not in result: |
| 34 raise Exception('Environment variable "%s" ' | 47 raise Exception('Environment variable "%s" ' |
| 35 'required to be set to valid path' % required) | 48 'required to be set to valid path' % required) |
| 36 return result | 49 return result |
| 37 | 50 |
| 38 | 51 |
| 39 # VC setup will add a path like this in 32-bit mode: | |
| 40 # c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN | |
| 41 # And this in 64-bit mode: | |
| 42 # c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\amd64 | |
| 43 # Note that in 64-bit it's duplicated but the 64-bit one comes first. | |
| 44 # | |
| 45 # What we get as the path when running this will depend on which VS setup | |
| 46 # script you've run. The following two functions try to do this. | |
| 47 | |
| 48 # For 32-bit compiles remove anything that ends in "\VC\WIN\amd64". | |
| 49 def FixupPath32(path): | |
| 50 find_64 = re.compile("VC\\\\BIN\\\\amd64\\\\*$", flags=re.IGNORECASE) | |
| 51 | |
| 52 for i in range(len(path)): | |
| 53 if find_64.search(path[i]): | |
| 54 # Found 32-bit path, insert the 64-bit one immediately before it. | |
| 55 dir_64 = path[i].rstrip("\\") | |
| 56 dir_64 = dir_64[:len(dir_64) - 6] # Trim off "\amd64". | |
| 57 path[i] = dir_64 | |
| 58 break | |
| 59 return path | |
| 60 | |
| 61 # For 64-bit compiles, append anything ending in "\VC\BIN" with "\amd64" as | |
| 62 # long as that thing isn't already in the list, and append it immediately | |
| 63 # before the non-amd64-one. | |
| 64 def FixupPath64(path): | |
| 65 find_32 = re.compile("VC\\\\BIN\\\\*$", flags=re.IGNORECASE) | |
| 66 | |
| 67 for i in range(len(path)): | |
| 68 if find_32.search(path[i]): | |
| 69 # Found 32-bit path, insert the 64-bit one immediately before it. | |
| 70 dir_32 = path[i] | |
| 71 if dir_32[len(dir_32) - 1] == '\\': | |
| 72 dir_64 = dir_32 + "amd64" | |
| 73 else: | |
| 74 dir_64 = dir_32 + "\\amd64" | |
| 75 path.insert(i, dir_64) | |
| 76 break | |
| 77 | |
| 78 return path | |
| 79 | |
| 80 | |
| 81 def FormatAsEnvironmentBlock(envvar_dict): | 52 def FormatAsEnvironmentBlock(envvar_dict): |
| 82 """Format as an 'environment block' directly suitable for CreateProcess. | 53 """Format as an 'environment block' directly suitable for CreateProcess. |
| 83 Briefly this is a list of key=value\0, terminated by an additional \0. See | 54 Briefly this is a list of key=value\0, terminated by an additional \0. See |
| 84 CreateProcess documentation for more details.""" | 55 CreateProcess documentation for more details.""" |
| 85 block = '' | 56 block = '' |
| 86 nul = '\0' | 57 nul = '\0' |
| 87 for key, value in envvar_dict.iteritems(): | 58 for key, value in envvar_dict.iteritems(): |
| 88 block += key + '=' + value + nul | 59 block += key + '=' + value + nul |
| 89 block += nul | 60 block += nul |
| 90 return block | 61 return block |
| 91 | 62 |
| 63 |
| 92 def CopyTool(source_path): | 64 def CopyTool(source_path): |
| 93 """Copies the given tool to the current directory, including a warning not | 65 """Copies the given tool to the current directory, including a warning not |
| 94 to edit it.""" | 66 to edit it.""" |
| 95 with open(source_path) as source_file: | 67 with open(source_path) as source_file: |
| 96 tool_source = source_file.readlines() | 68 tool_source = source_file.readlines() |
| 97 | 69 |
| 98 # Add header and write it out to the current directory (which should be the | 70 # Add header and write it out to the current directory (which should be the |
| 99 # root build dir). | 71 # root build dir). |
| 100 with open("gyp-win-tool", 'w') as tool_file: | 72 with open("gyp-win-tool", 'w') as tool_file: |
| 101 tool_file.write(''.join([tool_source[0], | 73 tool_file.write(''.join([tool_source[0], |
| 102 '# Generated by setup_toolchain.py do not edit.\n'] | 74 '# Generated by setup_toolchain.py do not edit.\n'] |
| 103 + tool_source[1:])) | 75 + tool_source[1:])) |
| 104 | 76 |
| 77 if len(sys.argv) != 3: |
| 78 print 'Usage setup_toolchain.py <visual studio path> <win tool path>' |
| 79 sys.exit(2) |
| 80 vs_path = sys.argv[1] |
| 81 tool_source = sys.argv[2] |
| 105 | 82 |
| 106 # Find the tool source, it's the first argument, and copy it. | 83 CopyTool(tool_source) |
| 107 if len(sys.argv) != 2: | |
| 108 print "Need one argument (win_tool source path)." | |
| 109 sys.exit(1) | |
| 110 CopyTool(sys.argv[1]) | |
| 111 | 84 |
| 112 important_env_vars = ExtractImportantEnvironment() | 85 important_env_vars = ExtractImportantEnvironment() |
| 113 path = important_env_vars["PATH"].split(";") | 86 path = important_env_vars["PATH"].split(";") |
| 114 | 87 |
| 115 important_env_vars["PATH"] = ";".join(FixupPath32(path)) | 88 # Add 32-bit compiler path to the beginning and write the block. |
| 89 path32 = [os.path.join(vs_path, "VC\\BIN")] + path |
| 90 important_env_vars["PATH"] = ";".join(path32) |
| 116 environ = FormatAsEnvironmentBlock(important_env_vars) | 91 environ = FormatAsEnvironmentBlock(important_env_vars) |
| 117 with open('environment.x86', 'wb') as env_file: | 92 with open('environment.x86', 'wb') as env_file: |
| 118 env_file.write(environ) | 93 env_file.write(environ) |
| 119 | 94 |
| 120 important_env_vars["PATH"] = ";".join(FixupPath64(path)) | 95 # Add 64-bit compiler path to the beginning and write the block. |
| 96 path64 = [os.path.join(vs_path, "VC\\BIN\\amd64")] + path |
| 97 important_env_vars["PATH"] = ";".join(path64) |
| 121 environ = FormatAsEnvironmentBlock(important_env_vars) | 98 environ = FormatAsEnvironmentBlock(important_env_vars) |
| 122 with open('environment.x64', 'wb') as env_file: | 99 with open('environment.x64', 'wb') as env_file: |
| 123 env_file.write(environ) | 100 env_file.write(environ) |
| OLD | NEW |