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 |