diff options
author | Martin Robinson <mrobinson@igalia.com> | 2023-05-18 15:09:30 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2023-05-19 13:08:43 +0200 |
commit | 5be14ecc3cc92309637604b48bdcf249b110ac16 (patch) | |
tree | ef5f13d8e79866eda1a84c847837938c884ebb2c /python/servo/platform/linux.py | |
parent | e09f85e17bd504a4c1c218ad14fa1a0ecbcaa839 (diff) | |
download | servo-5be14ecc3cc92309637604b48bdcf249b110ac16.tar.gz servo-5be14ecc3cc92309637604b48bdcf249b110ac16.zip |
Start organizing platform-specific Python code
This starts to split platform-specific Python code into its own module,
which should help to tidy up our mach commands and make things more
reusable.
Diffstat (limited to 'python/servo/platform/linux.py')
-rw-r--r-- | python/servo/platform/linux.py | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/python/servo/platform/linux.py b/python/servo/platform/linux.py new file mode 100644 index 00000000000..da1a83a3b27 --- /dev/null +++ b/python/servo/platform/linux.py @@ -0,0 +1,171 @@ +# Copyright 2023 The Servo Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution. +# +# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +import os +import subprocess + +from typing import Tuple + +import distro +import six + +from .base import Base + +# Please keep these in sync with the packages in README.md +APT_PKGS = ['git', 'curl', 'autoconf', 'libx11-dev', 'libfreetype6-dev', + 'libgl1-mesa-dri', 'libglib2.0-dev', 'xorg-dev', 'gperf', 'g++', + 'build-essential', 'cmake', 'libssl-dev', + 'liblzma-dev', 'libxmu6', 'libxmu-dev', + "libxcb-render0-dev", "libxcb-shape0-dev", "libxcb-xfixes0-dev", + 'libgles2-mesa-dev', 'libegl1-mesa-dev', 'libdbus-1-dev', + 'libharfbuzz-dev', 'ccache', 'clang', 'libunwind-dev', + 'libgstreamer1.0-dev', 'libgstreamer-plugins-base1.0-dev', + 'libgstreamer-plugins-bad1.0-dev', 'autoconf2.13', + 'libunwind-dev', 'llvm-dev'] +DNF_PKGS = ['libtool', 'gcc-c++', 'libXi-devel', 'freetype-devel', + 'libunwind-devel', 'mesa-libGL-devel', 'mesa-libEGL-devel', + 'glib2-devel', 'libX11-devel', 'libXrandr-devel', 'gperf', + 'fontconfig-devel', 'cabextract', 'ttmkfdir', 'expat-devel', + 'rpm-build', 'openssl-devel', 'cmake', + 'libXcursor-devel', 'libXmu-devel', + 'dbus-devel', 'ncurses-devel', 'harfbuzz-devel', 'ccache', + 'clang', 'clang-libs', 'llvm', 'autoconf213', 'python3-devel', + 'gstreamer1-devel', 'gstreamer1-plugins-base-devel', + 'gstreamer1-plugins-bad-free-devel', 'libjpeg-turbo-devel', + 'zlib', 'libjpeg'] +XBPS_PKGS = ['libtool', 'gcc', 'libXi-devel', 'freetype-devel', + 'libunwind-devel', 'MesaLib-devel', 'glib-devel', 'pkg-config', + 'libX11-devel', 'libXrandr-devel', 'gperf', 'bzip2-devel', + 'fontconfig-devel', 'cabextract', 'expat-devel', 'cmake', + 'cmake', 'libXcursor-devel', 'libXmu-devel', 'dbus-devel', + 'ncurses-devel', 'harfbuzz-devel', 'ccache', 'glu-devel', + 'clang', 'gstreamer1-devel', 'autoconf213', + 'gst-plugins-base1-devel', 'gst-plugins-bad1-devel'] + + +class Linux(Base): + def __init__(self): + (self.distro, self.version) = Linux.get_distro_and_version() + + @staticmethod + def get_distro_and_version() -> Tuple[str, str]: + distrib = six.ensure_str(distro.name()) + version = six.ensure_str(distro.version()) + + if distrib in ['LinuxMint', 'Linux Mint', 'KDE neon', 'Pop!_OS']: + if '.' in version: + major, _ = version.split('.', 1) + else: + major = version + + distrib = 'Ubuntu' + if major == '22': + version = '22.04' + elif major == '21': + version = '21.04' + elif major == '20': + version = '20.04' + elif major == '19': + version = '18.04' + elif major == '18': + version = '16.04' + + if distrib.lower() == 'elementary': + distrib = 'Ubuntu' + if version == '5.0': + version = '18.04' + elif version[0:3] == '0.4': + version = '16.04' + + return (distrib, version) + + def _platform_bootstrap(self, _cache_dir: str, 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') + print('') + print('You will need to run a nix-shell if you are trying ' + 'to run any of the built binaries') + print('To enter the nix-shell manually use:') + print(' $ nix-shell etc/shell.nix') + return False + + if self.distro.lower() == 'ubuntu' and self.version > '22.04': + print(f"WARNING: unsupported version of {self.distro}: {self.version}") + + # FIXME: Better version checking for these distributions. + if self.distro.lower() not in [ + 'arch linux', + 'arch', + 'centos linux', + 'centos', + 'debian gnu/linux', + 'fedora linux', + 'fedora', + 'nixos', + 'ubuntu', + 'void', + ]: + raise NotImplementedError("mach bootstrap does not support " + f"{self.distro}, please file a bug") + + installed_something = self.install_non_gstreamer_dependencies(force) + installed_something |= self._platform_bootstrap_gstreamer(_cache_dir, force) + return installed_something + + def install_non_gstreamer_dependencies(self, force: bool) -> bool: + install = False + pkgs = [] + if self.distro in ['Ubuntu', 'Debian GNU/Linux']: + command = ['apt-get', 'install'] + pkgs = APT_PKGS + if subprocess.call(['dpkg', '-s'] + pkgs, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) != 0: + install = True + elif self.distro in ['CentOS', 'CentOS Linux', 'Fedora', 'Fedora Linux']: + installed_pkgs = str(subprocess.check_output(['rpm', '-qa'])).replace('\n', '|') + pkgs = DNF_PKGS + for pkg in pkgs: + command = ['dnf', 'install'] + if "|{}".format(pkg) not in installed_pkgs: + install = True + break + elif self.distro == 'void': + installed_pkgs = str(subprocess.check_output(['xbps-query', '-l'])) + pkgs = XBPS_PKGS + for pkg in pkgs: + command = ['xbps-install', '-A'] + if "ii {}-".format(pkg) not in installed_pkgs: + install = force = True + break + + if not install: + return False + + def run_as_root(command, force=False): + if os.geteuid() != 0: + command.insert(0, 'sudo') + if force: + command.append('-y') + return subprocess.call(command) + + print("Installing missing dependencies...") + if run_as_root(command + pkgs, force) != 0: + raise Exception("Installation of dependencies failed.") + return True + + def _platform_bootstrap_gstreamer(self, _cache_dir: str, _force: bool) -> bool: + if self.is_gstreamer_installed(): + return False + + gstdir = os.path.join(os.curdir, "support", "linux", "gstreamer") + if not os.path.isdir(os.path.join(gstdir, "gst", "lib")): + subprocess.check_call(["bash", "gstreamer.sh"], cwd=gstdir) + return True + return False |