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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/toolchain/win/BUILD.gn ('k') | build/win/message_compiler.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/toolchain/win/setup_toolchain.py
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py
index 1e20387b0b240e987b22e85898c9368d8b0b0b9a..3fd21ea832f386083a748fc389f4beb407fe6eb9 100644
--- a/build/toolchain/win/setup_toolchain.py
+++ b/build/toolchain/win/setup_toolchain.py
@@ -49,10 +49,11 @@ def _ExtractImportantEnvironment(output_of_set):
setting = os.path.dirname(sys.executable) + os.pathsep + setting
env[var.upper()] = setting
break
- for required in ('SYSTEMROOT', 'TEMP', 'TMP'):
- if required not in env:
- raise Exception('Environment variable "%s" '
- 'required to be set to valid path' % required)
+ if sys.platform in ('win32', 'cygwin'):
+ for required in ('SYSTEMROOT', 'TEMP', 'TMP'):
+ if required not in env:
+ raise Exception('Environment variable "%s" '
+ 'required to be set to valid path' % required)
return env
@@ -67,35 +68,93 @@ def _DetectVisualStudioPath():
return vs_toolchain.DetectVisualStudioPath()
-def _SetupScript(target_cpu, sdk_dir):
- """Returns a command (with arguments) to be used to set up the
- environment."""
+def _InterpretBatFile(batpath, env):
+ """Interprets a simple .bat file consisting of set, if, and goto statements,
+ reading and writing variables to and from |env|."""
+ var_re = re.compile(r'%'
+ r'(?P<mods>~(?:[fdpnxsatz]|\$[^:]*:)*)?'
+ r'(?P<name>[0-9]|[a-zA-Z][a-zA-Z0-9]*%|%|\*)')
+ def _ExpandVar(m):
+ name = m.group('name')
+ if name == '%': return '%'
+ if name == '*' or ':' in name:
+ raise ValueError("'%s' variable interpolation not implemented" % name);
+ if name[-1] == '%': name = name[:-1]
+ replacement = env.get(name, '')
+ mods = m.group('mods')
+ if mods and len(mods) > 1:
+ assert mods[0] == '~'
+ replacement, mod_index = '', 1
+ while mod_index < len(mods):
+ if mods[mod_index] == 'd':
+ replacement += os.path.splitdrive(env.get(name, ''))[0]
+ elif mods[mod_index] == 'p':
+ replacement += os.path.dirname(env.get(name, '')) + os.path.sep
+ else:
+ raise ValueError("modifier '%s' not implemented" % mods[mod_index])
+ mod_index += 1
+ return replacement
+ with open(batpath) as f:
+ for l in f:
+ l = l.strip()
+ if l.startswith('@echo'): continue
+ if l.startswith('::'): continue
+ l = re.sub(var_re, _ExpandVar, l)
+ if l.startswith('set '):
+ key, val = l[len('set '):].split('=', 1)
+ # clang-cl wants include and lib separated by ';'s,
+ # but PATH is of course separated by :
+ env[key] = val.replace('\\', os.path.sep)
+ if key == 'PATH': env[key] = env[key].replace(';', os.path.pathsep)
+ continue
+ if l.startswith('if '):
+ if 'else' in l: raise ValueError('else not implemented')
+ m = re.match(r'if\s+(?P<lhs>"[^"]*")\s*==\s*(?P<rhs>"[^"]*")\s*'
+ r'(?P<body>[^(]*)$', l)
+ if not m: raise ValueError('only very limited if statement support')
+ if m.group('rhs') != m.group('lhs'): continue # if condition false: skip
+ l = m.group('body')
+ # fall through
+ if l.startswith('goto'):
+ label = re.match(r'goto\s*(?P<label>\S*)', l).group('label')
+ if label.upper() == ':EOF': break
+ l = next(f)
+ while l.strip() != ':' + label:
+ l = next(f)
+ continue
+ raise ValueError('unimplemented bat statement "%s"' % l)
+
+
+def _LoadToolchainEnv(cpu, sdk_dir):
+ """Returns a dictionary with environment variables that must be set while
+ running binaries from the toolchain (e.g. INCLUDE and PATH for cl.exe)."""
# Check if we are running in the SDK command line environment and use
- # the setup script from the SDK if so. |target_cpu| should be either
- # 'x86' or 'x64'.
- assert target_cpu in ('x86', 'x64')
+ # the setup script from the SDK if so. |cpu| should be either 'x86' or 'x64'.
+ assert cpu in ('x86', 'x64')
if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir:
- return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')),
- '/' + target_cpu]
+ script = os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd'))
+ # SetEnv.Cmd is fairly simple and controlled by us. Run it through a
+ # manual simple bat parser, which also runs on non-Windows hosts.
+ env = dict(os.environ)
+ env['0'] = script
+ env['1'] = '/' + cpu
+ _InterpretBatFile(script, env)
+ variables = '\n'.join(['%s=%s' % (k, v) for k, v in env.iteritems()])
else:
if 'GYP_MSVS_OVERRIDE_PATH' not in os.environ:
os.environ['GYP_MSVS_OVERRIDE_PATH'] = _DetectVisualStudioPath()
# We only support x64-hosted tools.
- return [os.path.normpath(os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
+ args = [os.path.normpath(os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
'VC/vcvarsall.bat')),
- 'amd64_x86' if target_cpu == 'x86' else 'amd64']
-
-
-def _LoadToolchainEnv(cpu, win_sdk_path):
- """Returns a dictionary with environment variables that must be set while
- running binaries from the toolchain (e.g. INCLUDE and PATH for cl.exe)."""
- args = _SetupScript(cpu, win_sdk_path)
- args.extend(('&&', 'set'))
- popen = subprocess.Popen(
- args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- variables, _ = popen.communicate()
- if popen.returncode != 0:
- raise Exception('"%s" failed with error %d' % (args, popen.returncode))
+ 'amd64_x86' if cpu == 'x86' else 'amd64']
+ # Don't try to manually parse vcvarsall.bat; we don't control it and it's
+ # likely complicated. Assume a Windows host for this.
+ args.extend(('&&', 'set'))
+ popen = subprocess.Popen(
+ args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ variables, _ = popen.communicate()
+ if popen.returncode != 0:
+ raise Exception('"%s" failed with error %d' % (args, popen.returncode))
return _ExtractImportantEnvironment(variables)
@@ -163,11 +222,12 @@ def main():
# version is used.
if win_sdk_path:
+ # INCLUDE always uses ; separators, even on non-Windows.
additional_includes = [
os.path.join(win_sdk_path, 'Include', '10.0.10586.0', p)
for p in ['shared', 'um', 'winrt']]
- additional_includes = os.path.pathsep.join(additional_includes)
- env['INCLUDE'] = additional_includes + os.path.pathsep + env['INCLUDE']
+ additional_includes = ';'.join(additional_includes)
+ env['INCLUDE'] = additional_includes + ';' + env['INCLUDE']
env_block = _FormatAsEnvironmentBlock(env)
with open('environment.' + cpu, 'wb') as f:
f.write(env_block)
« 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