aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
authorJonathan Schwender <55576758+jschwe@users.noreply.github.com>2025-05-27 17:51:46 +0800
committerGitHub <noreply@github.com>2025-05-27 09:51:46 +0000
commit270dcf879d6fb974a4bf012dfc1c7a952494655d (patch)
tree5861ff9e997d94b3cf36da8b9d597b3c63a765d1 /python
parent86b3b16b4c2ebeba8e807c16c6b798d6bb82fefe (diff)
downloadservo-270dcf879d6fb974a4bf012dfc1c7a952494655d.tar.gz
servo-270dcf879d6fb974a4bf012dfc1c7a952494655d.zip
bootstrap: Add `winget` fallback (#32836)
When `choco` is not available, we can install the same packages from winget. winget is an official package manager from Microsoft, which is available by default on Windows 11. Note: `winget` also has non-interactive installation options, but accepting license agreements should still be the responsibility of the user, so we don't add any such option for now. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix: Bootstrap on windows without `choco` available. Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
Diffstat (limited to 'python')
-rw-r--r--python/servo/platform/windows.py70
1 files changed, 45 insertions, 25 deletions
diff --git a/python/servo/platform/windows.py b/python/servo/platform/windows.py
index 772d115587a..d1c35871d26 100644
--- a/python/servo/platform/windows.py
+++ b/python/servo/platform/windows.py
@@ -13,6 +13,7 @@ import tempfile
from typing import Optional
import urllib
import zipfile
+import shutil
from servo import util
@@ -28,12 +29,51 @@ 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")
+WINGET_DEPENDENCIES = ["Kitware.CMake", "LLVM.LLVM", "Ninja-build.Ninja", "WiXToolset.WiXToolset"]
+
def get_dependency_dir(package):
"""Get the directory that a given Windows dependency should extract to."""
return os.path.join(DEPENDENCIES_DIR, package, DEPENDENCIES[package])
+def _winget_import(force: bool = False):
+ try:
+ # We install tools like LLVM / CMake, so we probably don't want to force-upgrade
+ # a user installed version without good reason.
+ cmd = ["winget", "install", "--interactive"]
+ if force:
+ cmd.append("--force")
+ else:
+ cmd.append("--no-upgrade")
+
+ cmd.extend(WINGET_DEPENDENCIES)
+
+ # The output will be printed to the terminal that `./mach bootstrap` is running in.
+ subprocess.run(cmd, encoding="utf-8")
+ except subprocess.CalledProcessError as e:
+ print("Could not run winget. Follow manual build setup instructions.")
+ raise e
+
+
+def _choco_install(force: bool = False):
+ try:
+ 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}\"'"
+ if force:
+ cmd_exe_args += ",'-f'"
+
+ print(cmd_exe_args)
+ subprocess.check_output(
+ ["powershell", "Start-Process", "-Wait", "-verb", "runAs", "cmd.exe", "-ArgumentList", f"@({cmd_exe_args})"]
+ ).decode("utf-8")
+ except subprocess.CalledProcessError as e:
+ print("Could not run chocolatey. Follow manual build setup instructions.")
+ raise e
+
+
class Windows(Base):
def __init__(self, triple: str):
super().__init__(triple)
@@ -61,31 +101,11 @@ class Windows(Base):
def _platform_bootstrap(self, force: bool) -> bool:
installed_something = self.passive_bootstrap()
-
- try:
- 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}\"'"
- if force:
- cmd_exe_args += ",'-f'"
-
- print(cmd_exe_args)
- subprocess.check_output(
- [
- "powershell",
- "Start-Process",
- "-Wait",
- "-verb",
- "runAs",
- "cmd.exe",
- "-ArgumentList",
- f"@({cmd_exe_args})",
- ]
- ).decode("utf-8")
- except subprocess.CalledProcessError as e:
- print("Could not run chocolatey. Follow manual build setup instructions.")
- raise e
+ # If `winget` works well in practice, we could switch the default in the future.
+ if shutil.which("choco") is not None:
+ _choco_install(force)
+ else:
+ _winget_import()
target = BuildTarget.from_triple(None)
installed_something |= self._platform_bootstrap_gstreamer(target, force)