mach: Add support for paths with spaces on Windows (#32936)

The default user name in Windows installations is of the form "FirstName
LastName", so it seems likely that there will be spaces in the user's
path. Based on my testing on Windows 11, the only Servo's bootstrap
script has trouble dealing with spaces in paths. This patch fixes that
by quoting such paths correctly. Our direct and indirect dependencies
seem to handle these without issue and Servo does build and run
correctly with this patch.

In this patch, the logic for gstreamer bootstrap now uses powershell
instead of directly invoking msiexec.exe via cmd.exe as I was unable to
get the installer to run correctly, even with quoting. Some extra hacks
were necessary to propagate the exit code correctly to mach.

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Mukilan Thiyagarajan 2024-08-05 20:12:21 +05:30 committed by GitHub
parent f1602005a0
commit 0ce9ce8dc0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 14 deletions

View file

@ -215,8 +215,8 @@ def bootstrap(topdir):
topdir = os.path.abspath(topdir)
# We don't support paths with spaces for now
# https://github.com/servo/servo/issues/9442
if ' ' in topdir:
# https://github.com/servo/servo/issues/9616
if ' ' in topdir and (not _is_windows()):
print('Cannot run mach in a path with spaces.')
print('Current path:', topdir)
sys.exit(1)

View file

@ -17,14 +17,13 @@ import zipfile
from .. import util
from .base import Base
DEPS_URL = "https://github.com/servo/servo-build-deps/releases/download/msvc-deps/"
DEPS_URL = "https://github.com/servo/servo-build-deps/releases/download/msvc-deps"
DEPENDENCIES = {
"moztools": "4.0",
}
URL_BASE = "https://github.com/servo/servo-build-deps/releases/download/msvc-deps/"
GSTREAMER_URL = f"{URL_BASE}/gstreamer-1.0-msvc-x86_64-1.22.8.msi"
GSTREAMER_DEVEL_URL = f"{URL_BASE}/gstreamer-1.0-devel-msvc-x86_64-1.22.8.msi"
GSTREAMER_URL = f"{DEPS_URL}/gstreamer-1.0-msvc-x86_64-1.22.8.msi"
GSTREAMER_DEVEL_URL = f"{DEPS_URL}/gstreamer-1.0-devel-msvc-x86_64-1.22.8.msi"
DEPENDENCIES_DIR = os.path.join(util.get_target_dir(), "dependencies")
@ -44,7 +43,7 @@ class Windows(Base):
@classmethod
def download_and_extract_dependency(cls, zip_path: str, full_spec: str):
if not os.path.isfile(zip_path):
zip_url = f"{DEPS_URL}{urllib.parse.quote(full_spec)}.zip"
zip_url = f"{DEPS_URL}/{urllib.parse.quote(full_spec)}.zip"
util.download_file(full_spec, zip_url, zip_path)
zip_dir = os.path.dirname(zip_path)
@ -65,7 +64,7 @@ class Windows(Base):
choco_config = os.path.join(util.SERVO_ROOT, "support", "windows", "chocolatey.config")
# This is the format that PowerShell wants arguments passed to it.
cmd_exe_args = f"'/K','choco','install','-y','{choco_config}'"
cmd_exe_args = f"'/K','choco','install','-y', '\"{choco_config}\"'"
if force:
cmd_exe_args += ",'-f'"
@ -158,12 +157,19 @@ class Windows(Base):
print(f"Installing GStreamer packages to {DEPENDENCIES_DIR}...")
os.makedirs(DEPENDENCIES_DIR, exist_ok=True)
common_args = [
f"TARGETDIR={DEPENDENCIES_DIR}", # Install destination
"/qn", # Quiet mode
]
subprocess.check_call(["msiexec", "/a", libs_msi] + common_args)
subprocess.check_call(["msiexec", "/a", devel_msi] + common_args)
for installer in [libs_msi, devel_msi]:
arguments = [
"/a",
f'"{installer}"'
f'TARGETDIR="{DEPENDENCIES_DIR}"', # Install destination
"/qn", # Quiet mode
]
quoted_arguments = ",".join((f"'{arg}'" for arg in arguments))
subprocess.check_call([
"powershell", "exit (Start-Process", "-PassThru", "-Wait", "-verb", "runAs",
"msiexec.exe", "-ArgumentList", f"@({quoted_arguments})", ").ExitCode"
])
assert self.is_gstreamer_installed(cross_compilation_target=None)
return True