mirror of
https://gitlab.com/qemu-project/meson.git
synced 2025-07-02 23:50:40 +08:00

Currently it tries to run "cmd" by default in a MSYS2 bash. Passing "bash" doesn't work since that defaults to WSL and one has to pass an absolute path to bash instead, and even then one misses out on the PS1 override. In case $SHELL is set and the contained path exists prefer it even if we are on Windows. To make the PS1 override work we can't use Unix paths in Python since we might be on Windows, so move the .bashrc check into the temporary bash script itself. This makes "meson devenv" work the same under MSYS2 as on Linux.
82 lines
3.1 KiB
Python
82 lines
3.1 KiB
Python
import os, subprocess
|
|
import argparse
|
|
import tempfile
|
|
|
|
from pathlib import Path
|
|
from . import build
|
|
from .mesonlib import MesonException, RealPathAction, is_windows, setup_vsenv
|
|
|
|
import typing as T
|
|
|
|
def add_arguments(parser: argparse.ArgumentParser) -> None:
|
|
parser.add_argument('-C', dest='wd', action=RealPathAction,
|
|
help='directory to cd into before running')
|
|
parser.add_argument('command', nargs=argparse.REMAINDER,
|
|
help='Command to run in developer environment (default: interactive shell)')
|
|
|
|
def get_windows_shell() -> str:
|
|
mesonbuild = Path(__file__).parent
|
|
script = mesonbuild / 'scripts' / 'cmd_or_ps.ps1'
|
|
command = ['powershell.exe', '-noprofile', '-executionpolicy', 'bypass', '-file', str(script)]
|
|
result = subprocess.check_output(command)
|
|
return result.decode().strip()
|
|
|
|
def get_env(b: build.Build, build_dir: str) -> T.Dict[str, str]:
|
|
env = os.environ.copy()
|
|
for i in b.devenv:
|
|
env = i.get_env(env)
|
|
|
|
extra_env = build.EnvironmentVariables()
|
|
extra_env.set('MESON_DEVENV', ['1'])
|
|
extra_env.set('MESON_PROJECT_NAME', [b.project_name])
|
|
|
|
meson_uninstalled = Path(build_dir) / 'meson-uninstalled'
|
|
if meson_uninstalled.is_dir():
|
|
extra_env.prepend('PKG_CONFIG_PATH', [str(meson_uninstalled)])
|
|
|
|
return extra_env.get_env(env)
|
|
|
|
def run(options: argparse.Namespace) -> int:
|
|
buildfile = Path(options.wd) / 'meson-private' / 'build.dat'
|
|
if not buildfile.is_file():
|
|
raise MesonException(f'Directory {options.wd!r} does not seem to be a Meson build directory.')
|
|
b = build.load(options.wd)
|
|
setup_vsenv(b.need_vsenv)
|
|
|
|
devenv = get_env(b, options.wd)
|
|
|
|
args = options.command
|
|
if not args:
|
|
prompt_prefix = f'[{b.project_name}]'
|
|
shell_env = os.environ.get("SHELL")
|
|
# Prefer $SHELL in a MSYS2 bash despite it being Windows
|
|
if shell_env and os.path.exists(shell_env):
|
|
args = [shell_env]
|
|
elif is_windows():
|
|
shell = get_windows_shell()
|
|
if shell == 'powershell.exe':
|
|
args = ['powershell.exe']
|
|
args += ['-NoLogo', '-NoExit']
|
|
prompt = f'function global:prompt {{ "{prompt_prefix} PS " + $PWD + "> "}}'
|
|
args += ['-Command', prompt]
|
|
else:
|
|
args = [os.environ.get("COMSPEC", r"C:\WINDOWS\system32\cmd.exe")]
|
|
args += ['/k', f'prompt {prompt_prefix} $P$G']
|
|
else:
|
|
args = [os.environ.get("SHELL", os.path.realpath("/bin/sh"))]
|
|
if "bash" in args[0] and not os.environ.get("MESON_DISABLE_PS1_OVERRIDE"):
|
|
tmprc = tempfile.NamedTemporaryFile(mode='w')
|
|
tmprc.write('[ -e ~/.bashrc ] && . ~/.bashrc\n')
|
|
tmprc.write(f'export PS1="{prompt_prefix} $PS1"')
|
|
tmprc.flush()
|
|
# Let the GC remove the tmp file
|
|
args.append("--rcfile")
|
|
args.append(tmprc.name)
|
|
|
|
try:
|
|
return subprocess.call(args, close_fds=False,
|
|
env=devenv,
|
|
cwd=options.wd)
|
|
except subprocess.CalledProcessError as e:
|
|
return e.returncode
|