|
1 |
| -# Copyright 2012-2016 The Meson development team |
| 1 | +# Copyright 2012-2021 The Meson development team |
2 | 2 |
|
3 | 3 | # Licensed under the Apache License, Version 2.0 (the "License");
|
4 | 4 | # you may not use this file except in compliance with the License.
|
|
27 | 27 | from .environment import detect_msys2_arch
|
28 | 28 | from .wrap import wraptool
|
29 | 29 |
|
| 30 | +bat_template = '''@ECHO OFF |
| 31 | +
|
| 32 | +call "{}" |
| 33 | +
|
| 34 | +ECHO {} |
| 35 | +SET |
| 36 | +''' |
| 37 | + |
| 38 | +# If on Windows and VS is installed but not set up in the environment, |
| 39 | +# set it to be runnable. In this way Meson can be directly invoked |
| 40 | +# from any shell, VS Code etc. |
| 41 | +def setup_vsenv(): |
| 42 | + import subprocess, json, pathlib |
| 43 | + if not mesonlib.is_windows(): |
| 44 | + return |
| 45 | + bat_placeholder = 'nananananananananananananananana' |
| 46 | + # If an existing build tool chain exists in PATH -> do nothing. |
| 47 | + if shutil.which('cc'): |
| 48 | + return |
| 49 | + if shutil.which('clang'): |
| 50 | + return |
| 51 | + if shutil.which('clang-cl'): |
| 52 | + return |
| 53 | + if os.environ.get('OSTYPE', bat_placeholder) == 'cygwin': |
| 54 | + return |
| 55 | + if 'Visual Studio' in os.environ['PATH']: |
| 56 | + return |
| 57 | + bat_locator_bin = r'c:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' |
| 58 | + if not os.path.exists(bat_locator_bin): |
| 59 | + return |
| 60 | + bat_json = subprocess.check_output([bat_locator_bin, '-latest', '-format', 'json']) |
| 61 | + bat_info = json.loads(bat_json) |
| 62 | + if not bat_info: |
| 63 | + bat_json = subprocess.check_output([bat_locator_bin, '-prerelease', '-format', 'json']) |
| 64 | + bat_info = json.loads(bat_json) |
| 65 | + if not bat_info: |
| 66 | + # VS installer instelled but not VS itself maybe? |
| 67 | + return |
| 68 | + print('Activating VS', bat_info[0]['catalog']['productDisplayVersion']) |
| 69 | + bat_root = bat_info[0]['installationPath'] |
| 70 | + bat_path = bat_root + r'\VC\Auxiliary\Build\vcvars64.bat' |
| 71 | + if not os.path.exists(bat_path): |
| 72 | + return |
| 73 | + |
| 74 | + bat_file = pathlib.Path.home() / 'vsdetect.bat' |
| 75 | + |
| 76 | + bat_separator = '---SPLIT---' |
| 77 | + bat_contents = bat_template.format(bat_path, bat_separator) |
| 78 | + bat_file.write_text(bat_contents) |
| 79 | + try: |
| 80 | + bat_output = subprocess.check_output(str(bat_file), universal_newlines=True) |
| 81 | + finally: |
| 82 | + bat_file.unlink() |
| 83 | + bat_lines = bat_output.split('\n') |
| 84 | + bat_separator_seen = False |
| 85 | + for bat_line in bat_lines: |
| 86 | + if bat_line == bat_separator: |
| 87 | + bat_separator_seen = True |
| 88 | + continue |
| 89 | + if not bat_separator_seen: |
| 90 | + continue |
| 91 | + if not bat_line: |
| 92 | + continue |
| 93 | + k, v = bat_line.split('=', 1) |
| 94 | + os.environ[k] = v |
| 95 | + |
| 96 | + |
30 | 97 |
|
31 | 98 | # Note: when adding arguments, please also add them to the completion
|
32 | 99 | # scripts in $MESONSRC/data/shell-completions/
|
@@ -222,6 +289,7 @@ def run(original_args, mainfile):
|
222 | 289 | return CommandLineParser().run(args)
|
223 | 290 |
|
224 | 291 | def main():
|
| 292 | + setup_vsenv() |
225 | 293 | # Always resolve the command path so Ninja can find it for regen, tests, etc.
|
226 | 294 | if 'meson.exe' in sys.executable:
|
227 | 295 | assert(os.path.isabs(sys.executable))
|
|
0 commit comments