aboutsummaryrefslogtreecommitdiffstats
path: root/python/servo/platform/linux.py
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2023-05-18 15:09:30 +0200
committerMartin Robinson <mrobinson@igalia.com>2023-05-19 13:08:43 +0200
commit5be14ecc3cc92309637604b48bdcf249b110ac16 (patch)
treeef5f13d8e79866eda1a84c847837938c884ebb2c /python/servo/platform/linux.py
parente09f85e17bd504a4c1c218ad14fa1a0ecbcaa839 (diff)
downloadservo-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.py171
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