Index: build/toolchain/win/setup_toolchain.py |
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py |
index 5e292ab07840c546504194411343f73223390208..42c3af1b6cd7e65d3e0641d680ecc9162952cbe1 100644 |
--- a/build/toolchain/win/setup_toolchain.py |
+++ b/build/toolchain/win/setup_toolchain.py |
@@ -19,39 +19,59 @@ and the files will be written to the current directory. |
""" |
-def ExtractImportantEnvironment(): |
- """Extracts environment variables required for the toolchain from the |
- current environment.""" |
+def _ExtractImportantEnvironment(output_of_set): |
+ """Extracts environment variables required for the toolchain to run from |
+ a textual dump output by the cmd.exe 'set' command.""" |
envvars_to_save = ( |
- 'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. |
- 'include', # Needed by midl compiler. |
+ 'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. |
+ 'include', |
+ 'lib', |
+ 'libpath', |
'path', |
'pathext', |
'systemroot', |
'temp', |
'tmp', |
) |
- result = {} |
- for envvar in envvars_to_save: |
- if envvar in os.environ: |
- envvar = envvar.lower() |
- if envvar == 'path': |
- # Our own rules (for running gyp-win-tool) and other actions in |
- # Chromium rely on python being in the path. Add the path to this |
- # python here so that if it's not in the path when ninja is run |
- # later, python will still be found. |
- result[envvar.upper()] = os.path.dirname(sys.executable) + \ |
- os.pathsep + os.environ[envvar] |
- else: |
- result[envvar.upper()] = os.environ[envvar] |
+ env = {} |
+ for line in output_of_set.splitlines(): |
+ for envvar in envvars_to_save: |
+ if re.match(envvar + '=', line.lower()): |
+ var, setting = line.split('=', 1) |
+ if envvar == 'path': |
+ # Our own rules (for running gyp-win-tool) and other actions in |
+ # Chromium rely on python being in the path. Add the path to this |
+ # python here so that if it's not in the path when ninja is run |
+ # later, python will still be found. |
+ setting = os.path.dirname(sys.executable) + os.pathsep + setting |
+ env[var.upper()] = setting |
+ break |
for required in ('SYSTEMROOT', 'TEMP', 'TMP'): |
- if required not in result: |
+ if required not in env: |
raise Exception('Environment variable "%s" ' |
'required to be set to valid path' % required) |
- return result |
+ return env |
-def FormatAsEnvironmentBlock(envvar_dict): |
+def _SetupScript(target_arch, sdk_dir): |
+ """Returns a command (with arguments) to be used to set up the |
+ environment.""" |
+ # Check if we are running in the SDK command line environment and use |
+ # the setup script from the SDK if so. |target_arch| should be either |
+ # 'x86' or 'x64'. |
+ assert target_arch 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_arch] |
+ else: |
+ # We only support x64-hosted tools. |
+ # TODO(scottmg|dpranke): Non-depot_tools toolchain: need to get Visual |
+ # Studio install location from registry. |
+ return [os.path.normpath(os.path.join(FIND_VS_IN_REG, 'VC/vcvarsall.bat')), |
+ 'amd64_x86' if target_arch == 'x86' else 'amd64'] |
+ |
+ |
+def _FormatAsEnvironmentBlock(envvar_dict): |
"""Format as an 'environment block' directly suitable for CreateProcess. |
Briefly this is a list of key=value\0, terminated by an additional \0. See |
CreateProcess documentation for more details.""" |
@@ -63,7 +83,7 @@ def FormatAsEnvironmentBlock(envvar_dict): |
return block |
-def CopyTool(source_path): |
+def _CopyTool(source_path): |
"""Copies the given tool to the current directory, including a warning not |
to edit it.""" |
with open(source_path) as source_file: |
@@ -76,33 +96,39 @@ def CopyTool(source_path): |
'# Generated by setup_toolchain.py do not edit.\n'] |
+ tool_source[1:])) |
-if len(sys.argv) != 4: |
- print('Usage setup_toolchain.py ' |
- '<visual studio path> <win tool path> <win sdk path>') |
- sys.exit(2) |
-vs_path = sys.argv[1] |
-tool_source = sys.argv[2] |
-win_sdk_path = sys.argv[3] |
- |
-CopyTool(tool_source) |
- |
-important_env_vars = ExtractImportantEnvironment() |
-path = important_env_vars["PATH"].split(";") |
- |
-# Add 32-bit compiler path to the beginning and write the block. |
-path32 = [os.path.join(vs_path, "VC\\BIN")] + \ |
- [os.path.join(win_sdk_path, "bin\\x86")] + \ |
- path |
-important_env_vars["PATH"] = ";".join(path32) |
-environ = FormatAsEnvironmentBlock(important_env_vars) |
-with open('environment.x86', 'wb') as env_file: |
- env_file.write(environ) |
- |
-# Add 64-bit compiler path to the beginning and write the block. |
-path64 = [os.path.join(vs_path, "VC\\BIN\\amd64")] + \ |
- [os.path.join(win_sdk_path, "bin\\x64")] + \ |
- path |
-important_env_vars["PATH"] = ";".join(path64) |
-environ = FormatAsEnvironmentBlock(important_env_vars) |
-with open('environment.x64', 'wb') as env_file: |
- env_file.write(environ) |
+ |
+def main(): |
+ if len(sys.argv) != 5: |
+ print('Usage setup_toolchain.py ' |
+ '<visual studio path> <win tool path> <win sdk path> <runtime dirs>') |
+ sys.exit(2) |
+ vs_path = sys.argv[1] |
+ tool_source = sys.argv[2] |
+ win_sdk_path = sys.argv[3] |
+ runtime_dirs = sys.argv[4] |
+ |
+ _CopyTool(tool_source) |
+ |
+ archs = ('x86', 'x64') |
+ # TODO(scottmg|goma): Do we need an equivalent of |
+ # ninja_use_custom_environment_files? |
+ for arch in archs: |
+ # Extract environment variables for subprocesses. |
+ args = _SetupScript(arch, win_sdk_path) |
+ args.extend(('&&', 'set')) |
+ popen = subprocess.Popen( |
+ args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
+ variables, _ = popen.communicate() |
+ env = _ExtractImportantEnvironment(variables) |
+ env['PATH'] = runtime_dirs + ';' + env['PATH'] |
+ |
+ # TODO(scottmg|thakis|dpranke): Is there an equivalent to |
+ # msvs_system_include_dirs that we need to inject into INCLUDE here? |
+ |
+ env_block = _FormatAsEnvironmentBlock(env) |
+ with open('environment.' + arch, 'wb') as f: |
+ f.write(env_block) |
+ |
+ |
+if __name__ == '__main__': |
+ main() |