Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: build/toolchain/win/setup_toolchain.py

Issue 1183633003: cross gn Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/toolchain/win/BUILD.gn ('k') | build/win/message_compiler.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 # Copies the given "win tool" (which the toolchain uses to wrap compiler 5 # Copies the given "win tool" (which the toolchain uses to wrap compiler
6 # invocations) and the environment blocks for the 32-bit and 64-bit builds on 6 # invocations) and the environment blocks for the 32-bit and 64-bit builds on
7 # Windows to the build directory. 7 # Windows to the build directory.
8 # 8 #
9 # The arguments are the visual studio install location and the location of the 9 # The arguments are the visual studio install location and the location of the
10 # win tool. The script assumes that the root build directory is the current dir 10 # win tool. The script assumes that the root build directory is the current dir
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 if re.match(envvar + '=', line.lower()): 42 if re.match(envvar + '=', line.lower()):
43 var, setting = line.split('=', 1) 43 var, setting = line.split('=', 1)
44 if envvar == 'path': 44 if envvar == 'path':
45 # Our own rules (for running gyp-win-tool) and other actions in 45 # Our own rules (for running gyp-win-tool) and other actions in
46 # Chromium rely on python being in the path. Add the path to this 46 # Chromium rely on python being in the path. Add the path to this
47 # python here so that if it's not in the path when ninja is run 47 # python here so that if it's not in the path when ninja is run
48 # later, python will still be found. 48 # later, python will still be found.
49 setting = os.path.dirname(sys.executable) + os.pathsep + setting 49 setting = os.path.dirname(sys.executable) + os.pathsep + setting
50 env[var.upper()] = setting 50 env[var.upper()] = setting
51 break 51 break
52 for required in ('SYSTEMROOT', 'TEMP', 'TMP'): 52 if sys.platform in ('win32', 'cygwin'):
53 if required not in env: 53 for required in ('SYSTEMROOT', 'TEMP', 'TMP'):
54 raise Exception('Environment variable "%s" ' 54 if required not in env:
55 'required to be set to valid path' % required) 55 raise Exception('Environment variable "%s" '
56 'required to be set to valid path' % required)
56 return env 57 return env
57 58
58 59
59 def _DetectVisualStudioPath(): 60 def _DetectVisualStudioPath():
60 """Return path to the GYP_MSVS_VERSION of Visual Studio. 61 """Return path to the GYP_MSVS_VERSION of Visual Studio.
61 """ 62 """
62 63
63 # Use the code in build/vs_toolchain.py to avoid duplicating code. 64 # Use the code in build/vs_toolchain.py to avoid duplicating code.
64 chromium_dir = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..')) 65 chromium_dir = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..'))
65 sys.path.append(os.path.join(chromium_dir, 'build')) 66 sys.path.append(os.path.join(chromium_dir, 'build'))
66 import vs_toolchain 67 import vs_toolchain
67 return vs_toolchain.DetectVisualStudioPath() 68 return vs_toolchain.DetectVisualStudioPath()
68 69
69 70
70 def _SetupScript(target_cpu, sdk_dir): 71 def _InterpretBatFile(batpath, env):
71 """Returns a command (with arguments) to be used to set up the 72 """Interprets a simple .bat file consisting of set, if, and goto statements,
72 environment.""" 73 reading and writing variables to and from |env|."""
74 var_re = re.compile(r'%'
75 r'(?P<mods>~(?:[fdpnxsatz]|\$[^:]*:)*)?'
76 r'(?P<name>[0-9]|[a-zA-Z][a-zA-Z0-9]*%|%|\*)')
77 def _ExpandVar(m):
78 name = m.group('name')
79 if name == '%': return '%'
80 if name == '*' or ':' in name:
81 raise ValueError("'%s' variable interpolation not implemented" % name);
82 if name[-1] == '%': name = name[:-1]
83 replacement = env.get(name, '')
84 mods = m.group('mods')
85 if mods and len(mods) > 1:
86 assert mods[0] == '~'
87 replacement, mod_index = '', 1
88 while mod_index < len(mods):
89 if mods[mod_index] == 'd':
90 replacement += os.path.splitdrive(env.get(name, ''))[0]
91 elif mods[mod_index] == 'p':
92 replacement += os.path.dirname(env.get(name, '')) + os.path.sep
93 else:
94 raise ValueError("modifier '%s' not implemented" % mods[mod_index])
95 mod_index += 1
96 return replacement
97 with open(batpath) as f:
98 for l in f:
99 l = l.strip()
100 if l.startswith('@echo'): continue
101 if l.startswith('::'): continue
102 l = re.sub(var_re, _ExpandVar, l)
103 if l.startswith('set '):
104 key, val = l[len('set '):].split('=', 1)
105 # clang-cl wants include and lib separated by ';'s,
106 # but PATH is of course separated by :
107 env[key] = val.replace('\\', os.path.sep)
108 if key == 'PATH': env[key] = env[key].replace(';', os.path.pathsep)
109 continue
110 if l.startswith('if '):
111 if 'else' in l: raise ValueError('else not implemented')
112 m = re.match(r'if\s+(?P<lhs>"[^"]*")\s*==\s*(?P<rhs>"[^"]*")\s*'
113 r'(?P<body>[^(]*)$', l)
114 if not m: raise ValueError('only very limited if statement support')
115 if m.group('rhs') != m.group('lhs'): continue # if condition false: skip
116 l = m.group('body')
117 # fall through
118 if l.startswith('goto'):
119 label = re.match(r'goto\s*(?P<label>\S*)', l).group('label')
120 if label.upper() == ':EOF': break
121 l = next(f)
122 while l.strip() != ':' + label:
123 l = next(f)
124 continue
125 raise ValueError('unimplemented bat statement "%s"' % l)
126
127
128 def _LoadToolchainEnv(cpu, sdk_dir):
129 """Returns a dictionary with environment variables that must be set while
130 running binaries from the toolchain (e.g. INCLUDE and PATH for cl.exe)."""
73 # Check if we are running in the SDK command line environment and use 131 # Check if we are running in the SDK command line environment and use
74 # the setup script from the SDK if so. |target_cpu| should be either 132 # the setup script from the SDK if so. |cpu| should be either 'x86' or 'x64'.
75 # 'x86' or 'x64'. 133 assert cpu in ('x86', 'x64')
76 assert target_cpu in ('x86', 'x64')
77 if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir: 134 if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir:
78 return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')), 135 script = os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd'))
79 '/' + target_cpu] 136 # SetEnv.Cmd is fairly simple and controlled by us. Run it through a
137 # manual simple bat parser, which also runs on non-Windows hosts.
138 env = dict(os.environ)
139 env['0'] = script
140 env['1'] = '/' + cpu
141 _InterpretBatFile(script, env)
142 variables = '\n'.join(['%s=%s' % (k, v) for k, v in env.iteritems()])
80 else: 143 else:
81 if 'GYP_MSVS_OVERRIDE_PATH' not in os.environ: 144 if 'GYP_MSVS_OVERRIDE_PATH' not in os.environ:
82 os.environ['GYP_MSVS_OVERRIDE_PATH'] = _DetectVisualStudioPath() 145 os.environ['GYP_MSVS_OVERRIDE_PATH'] = _DetectVisualStudioPath()
83 # We only support x64-hosted tools. 146 # We only support x64-hosted tools.
84 return [os.path.normpath(os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'], 147 args = [os.path.normpath(os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
85 'VC/vcvarsall.bat')), 148 'VC/vcvarsall.bat')),
86 'amd64_x86' if target_cpu == 'x86' else 'amd64'] 149 'amd64_x86' if cpu == 'x86' else 'amd64']
87 150 # Don't try to manually parse vcvarsall.bat; we don't control it and it's
88 151 # likely complicated. Assume a Windows host for this.
89 def _LoadToolchainEnv(cpu, win_sdk_path): 152 args.extend(('&&', 'set'))
90 """Returns a dictionary with environment variables that must be set while 153 popen = subprocess.Popen(
91 running binaries from the toolchain (e.g. INCLUDE and PATH for cl.exe).""" 154 args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
92 args = _SetupScript(cpu, win_sdk_path) 155 variables, _ = popen.communicate()
93 args.extend(('&&', 'set')) 156 if popen.returncode != 0:
94 popen = subprocess.Popen( 157 raise Exception('"%s" failed with error %d' % (args, popen.returncode))
95 args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
96 variables, _ = popen.communicate()
97 if popen.returncode != 0:
98 raise Exception('"%s" failed with error %d' % (args, popen.returncode))
99 return _ExtractImportantEnvironment(variables) 158 return _ExtractImportantEnvironment(variables)
100 159
101 160
102 def _FormatAsEnvironmentBlock(envvar_dict): 161 def _FormatAsEnvironmentBlock(envvar_dict):
103 """Format as an 'environment block' directly suitable for CreateProcess. 162 """Format as an 'environment block' directly suitable for CreateProcess.
104 Briefly this is a list of key=value\0, terminated by an additional \0. See 163 Briefly this is a list of key=value\0, terminated by an additional \0. See
105 CreateProcess documentation for more details.""" 164 CreateProcess documentation for more details."""
106 block = '' 165 block = ''
107 nul = '\0' 166 nul = '\0'
108 for key, value in envvar_dict.iteritems(): 167 for key, value in envvar_dict.iteritems():
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 vc_bin_dir = os.path.realpath(path) 215 vc_bin_dir = os.path.realpath(path)
157 break 216 break
158 217
159 # The Windows SDK include directories must be first. They both have a sal.h, 218 # The Windows SDK include directories must be first. They both have a sal.h,
160 # and the SDK one is newer and the SDK uses some newer features from it not 219 # and the SDK one is newer and the SDK uses some newer features from it not
161 # present in the Visual Studio one. 220 # present in the Visual Studio one.
162 # Having the Windows SDK first is also the only way to control which SDK 221 # Having the Windows SDK first is also the only way to control which SDK
163 # version is used. 222 # version is used.
164 223
165 if win_sdk_path: 224 if win_sdk_path:
225 # INCLUDE always uses ; separators, even on non-Windows.
166 additional_includes = [ 226 additional_includes = [
167 os.path.join(win_sdk_path, 'Include', '10.0.10586.0', p) 227 os.path.join(win_sdk_path, 'Include', '10.0.10586.0', p)
168 for p in ['shared', 'um', 'winrt']] 228 for p in ['shared', 'um', 'winrt']]
169 additional_includes = os.path.pathsep.join(additional_includes) 229 additional_includes = ';'.join(additional_includes)
170 env['INCLUDE'] = additional_includes + os.path.pathsep + env['INCLUDE'] 230 env['INCLUDE'] = additional_includes + ';' + env['INCLUDE']
171 env_block = _FormatAsEnvironmentBlock(env) 231 env_block = _FormatAsEnvironmentBlock(env)
172 with open('environment.' + cpu, 'wb') as f: 232 with open('environment.' + cpu, 'wb') as f:
173 f.write(env_block) 233 f.write(env_block)
174 234
175 # Create a store app version of the environment. 235 # Create a store app version of the environment.
176 if 'LIB' in env: 236 if 'LIB' in env:
177 env['LIB'] = env['LIB'] .replace(r'\VC\LIB', r'\VC\LIB\STORE') 237 env['LIB'] = env['LIB'] .replace(r'\VC\LIB', r'\VC\LIB\STORE')
178 if 'LIBPATH' in env: 238 if 'LIBPATH' in env:
179 env['LIBPATH'] = env['LIBPATH'].replace(r'\VC\LIB', r'\VC\LIB\STORE') 239 env['LIBPATH'] = env['LIBPATH'].replace(r'\VC\LIB', r'\VC\LIB\STORE')
180 env_block = _FormatAsEnvironmentBlock(env) 240 env_block = _FormatAsEnvironmentBlock(env)
181 with open('environment.winrt_' + cpu, 'wb') as f: 241 with open('environment.winrt_' + cpu, 'wb') as f:
182 f.write(env_block) 242 f.write(env_block)
183 243
184 assert vc_bin_dir 244 assert vc_bin_dir
185 print 'vc_bin_dir = "%s"' % vc_bin_dir 245 print 'vc_bin_dir = "%s"' % vc_bin_dir
186 246
187 247
188 if __name__ == '__main__': 248 if __name__ == '__main__':
189 main() 249 main()
OLDNEW
« no previous file with comments | « build/toolchain/win/BUILD.gn ('k') | build/win/message_compiler.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698