diff options
author | Martin Robinson <mrobinson@webkit.org> | 2023-06-23 11:07:18 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2023-07-03 21:40:24 +0200 |
commit | 633d9b0eb964b09bf4dbb46d81a965a4be2fe8f5 (patch) | |
tree | 9b1eed6c332aaff352d9e6c52a9fe2c081129b69 /python/servo/platform | |
parent | 35ab3116358a50a0ffa549bbe90ce8d2cc755ddb (diff) | |
download | servo-633d9b0eb964b09bf4dbb46d81a965a4be2fe8f5.tar.gz servo-633d9b0eb964b09bf4dbb46d81a965a4be2fe8f5.zip |
Windows bootstrap support
Diffstat (limited to 'python/servo/platform')
-rw-r--r-- | python/servo/platform/base.py | 14 | ||||
-rw-r--r-- | python/servo/platform/linux.py | 2 | ||||
-rw-r--r-- | python/servo/platform/macos.py | 2 | ||||
-rw-r--r-- | python/servo/platform/windows.py | 88 |
4 files changed, 56 insertions, 50 deletions
diff --git a/python/servo/platform/base.py b/python/servo/platform/base.py index b0ac64386bd..65731ba0364 100644 --- a/python/servo/platform/base.py +++ b/python/servo/platform/base.py @@ -75,7 +75,7 @@ class Base: def executable_suffix(self): return "" - def _platform_bootstrap(self, _cache_dir: str, _force: bool) -> bool: + def _platform_bootstrap(self, _force: bool) -> bool: raise NotImplementedError("Bootstrap installation detection not yet available.") def _platform_bootstrap_gstreamer(self, _force: bool) -> bool: @@ -97,11 +97,17 @@ class Base: == 0 ) - def bootstrap(self, cache_dir: str, force: bool): - if not self._platform_bootstrap(cache_dir, force): + def bootstrap(self, force: bool): + if not self._platform_bootstrap(force): print("Dependencies were already installed!") - def bootstrap_gstreamer(self, _cache_dir: str, force: bool): + def passive_bootstrap(self) -> bool: + """A bootstrap method that is called without explicitly invoking `./mach bootstrap` + but that is executed in the process of other `./mach` commands. This should be + as fast as possible.""" + return False + + def bootstrap_gstreamer(self, force: bool): if not self._platform_bootstrap_gstreamer(force): root = self.gstreamer_root(None) if root: diff --git a/python/servo/platform/linux.py b/python/servo/platform/linux.py index 2e3a7d2a5c7..516b7448686 100644 --- a/python/servo/platform/linux.py +++ b/python/servo/platform/linux.py @@ -94,7 +94,7 @@ class Linux(Base): return (distrib, version) - def _platform_bootstrap(self, _cache_dir: str, force: bool) -> bool: + def _platform_bootstrap(self, force: bool) -> bool: if self.distro.lower() == 'nixos': print('NixOS does not need bootstrap, it will automatically enter a nix-shell') print('Just run ./mach build') diff --git a/python/servo/platform/macos.py b/python/servo/platform/macos.py index 38169e9a75a..00f9ad185ed 100644 --- a/python/servo/platform/macos.py +++ b/python/servo/platform/macos.py @@ -54,7 +54,7 @@ class MacOS(Base): return False return True - def _platform_bootstrap(self, _cache_dir: str, force: bool) -> bool: + def _platform_bootstrap(self, _force: bool) -> bool: installed_something = False try: brewfile = os.path.join(util.SERVO_ROOT, "etc", "homebrew", "Brewfile") diff --git a/python/servo/platform/windows.py b/python/servo/platform/windows.py index 8ea2a0a5650..c687d0abf4e 100644 --- a/python/servo/platform/windows.py +++ b/python/servo/platform/windows.py @@ -8,25 +8,19 @@ # except according to those terms. import os -import shutil import subprocess import tempfile from typing import Optional import urllib import zipfile -from distutils.version import LooseVersion -import six from .. import util from .base import Base DEPS_URL = "https://github.com/servo/servo-build-deps/releases/download/msvc-deps/" DEPENDENCIES = { - "cmake": "3.14.3", "llvm": "15.0.5", "moztools": "3.2", - "ninja": "1.7.1", - "nuget": "08-08-2019", "openssl": "111.3.0+1.1.1c-vs2017-2019-09-18", "gstreamer-uwp": "1.16.0.5", "openxr-loader-uwp": "1.0", @@ -38,6 +32,11 @@ GSTREAMER_DEVEL_URL = f"{URL_BASE}/gstreamer-1.0-devel-msvc-x86_64-1.16.0.msi" DEPENDENCIES_DIR = os.path.join(util.get_target_dir(), "dependencies") +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]) + + class Windows(Base): def __init__(self, triple: str): super().__init__(triple) @@ -49,64 +48,65 @@ class Windows(Base): def library_path_variable_name(self): return "LIB" - @staticmethod - def cmake_already_installed(required_version: str) -> bool: - cmake_path = shutil.which("cmake") - if not cmake_path: - return False - - output = subprocess.check_output([cmake_path, "--version"]) - cmake_version_output = six.ensure_str(output).splitlines()[0] - installed_version = cmake_version_output.replace("cmake version ", "") - return LooseVersion(installed_version) >= LooseVersion(required_version) - @classmethod - def prepare_file(cls, deps_dir: str, zip_path: str, full_spec: str): + def download_and_extract_dependency(cls, zip_path: str, full_spec: str): if not os.path.isfile(zip_path): - zip_url = "{}{}.zip".format(DEPS_URL, urllib.parse.quote(full_spec)) + zip_url = f"{DEPS_URL}{urllib.parse.quote(full_spec)}.zip" util.download_file(full_spec, zip_url, zip_path) - print("Extracting {}...".format(full_spec), end="") + zip_dir = os.path.dirname(zip_path) + print(f"Extracting {full_spec} to {zip_dir}...", end="") try: - util.extract(zip_path, deps_dir) + util.extract(zip_path, zip_dir) except zipfile.BadZipfile: - print("\nError: %s.zip is not a valid zip file, redownload..." % full_spec) + print(f"\nError: {full_spec}.zip is not a valid zip file, redownload...") os.remove(zip_path) - cls.prepare_file(deps_dir, zip_path, full_spec) + cls.download_and_extract_dependency(zip_path, full_spec) else: print("done") - def _platform_bootstrap(self, cache_dir: str, _force: bool = False) -> bool: - deps_dir = os.path.join(cache_dir, "msvc-dependencies") - - def get_package_dir(package, version) -> str: - return os.path.join(deps_dir, package, version) - - to_install = {} - for package, version in DEPENDENCIES.items(): - # Don't install CMake if it already exists in PATH - if package == "cmake" and self.cmake_already_installed(version): - continue - - if not os.path.isdir(get_package_dir(package, version)): - to_install[package] = version + def _platform_bootstrap(self, force: bool = False) -> 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 + + return installed_something + + def passive_bootstrap(self) -> bool: + """A bootstrap method that is called without explicitly invoking `./mach bootstrap` + but that is executed in the process of other `./mach` commands. This should be + as fast as possible.""" + to_install = [package for package in DEPENDENCIES if + not os.path.isdir(get_dependency_dir(package))] if not to_install: return False print("Installing missing MSVC dependencies...") - for package, version in to_install.items(): - full_spec = "{}-{}".format(package, version) + for package in to_install: + full_spec = "{}-{}".format(package, DEPENDENCIES[package]) - package_dir = get_package_dir(package, version) + package_dir = get_dependency_dir(package) parent_dir = os.path.dirname(package_dir) if not os.path.isdir(parent_dir): os.makedirs(parent_dir) - self.prepare_file(deps_dir, package_dir + ".zip", full_spec) - - extracted_path = os.path.join(deps_dir, full_spec) - os.rename(extracted_path, package_dir) + self.download_and_extract_dependency(package_dir + ".zip", full_spec) + os.rename(os.path.join(parent_dir, full_spec), package_dir) return True |