Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mach Bootstrap: Support for more platforms #13226

Closed
wants to merge 7 commits into from
Next

Add support for Debian and Fedora distributions

  • Loading branch information
UK992 committed Sep 11, 2016
commit 374083fe9461b6581ab1189fe7f30a18dff30df7
@@ -4,6 +4,8 @@

from __future__ import print_function, unicode_literals

import os
import sys
import distutils
import subprocess

@@ -44,6 +46,23 @@ def which(self, name):
"""
return distutils.spawn.find_executable(name)

def run(self, command):
subprocess.check_call(command, stdin=sys.stdin)

def run_check(self, command):
return subprocess.call(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

def run_as_root(self, command):
if os.geteuid() != 0:
if self.which('sudo'):
command.insert(0, 'sudo')
else:
command = ['su', 'root', '-c', ' '.join(command)]

print('Executing as root:', subprocess.list2cmdline(command))

subprocess.check_call(command, stdin=sys.stdin)

def check_output(self, *args, **kwargs):
"""Run subprocess.check_output."""
return subprocess.check_output(*args, **kwargs)
@@ -4,12 +4,31 @@

from __future__ import print_function

import platform
import sys

from centosfedora import CentOSFedoraBootstrapper
from debian import DebianBootstrapper
from windows_gnu import WindowsGnuBootstrapper
from windows_msvc import WindowsMsvcBootstrapper


DEBIAN_DISTROS = (
'Debian',
'debian',
'Ubuntu',
# Most Linux Mint editions are based on Ubuntu. One is based on Debian.
# The difference is reported in dist_id from platform.linux_distribution.
# But it doesn't matter since we share a bootstrapper between Debian and
# Ubuntu.
'Mint',
'LinuxMint',
'Elementary OS',
'Elementary',
'"elementary OS"',
)


class Bootstrapper(object):
"""Main class that performs system bootstrap."""

@@ -18,7 +37,21 @@ def __init__(self):
cls = None
args = {}

if sys.platform.startswith('msys'):
if sys.platform.startswith('linux'):
distro, version, dist_id = platform.linux_distribution()

if distro in ('CentOS', 'CentOS Linux', 'Fedora'):
cls = CentOSFedoraBootstrapper
args['distro'] = distro
elif distro in DEBIAN_DISTROS:
cls = DebianBootstrapper
else:
sys.exit('Bootstrap support for this Linux distro not yet available.')

args['version'] = version
args['dist_id'] = dist_id

elif sys.platform.startswith('msys'):
cls = WindowsGnuBootstrapper

elif sys.platform.startswith('win32'):
@@ -33,9 +66,12 @@ def bootstrap(self, android=False, interactive=False, force=False):
self.instance.interactive = interactive
self.instance.force = force

if android:
self.instance.install_mobile_android_packages()
elif force:
if force:
self.instance.install_system_packages()
else:
self.instance.ensure_system_packages()

if android:
self.instance.install_mobile_android_packages()

print
@@ -0,0 +1,45 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

from base import BaseBootstrapper


class CentOSFedoraBootstrapper(BaseBootstrapper):
from packages import CENTOSFEDORA as desktop_deps

def __init__(self, distro, version, dist_id, **kwargs):
BaseBootstrapper.__init__(self, **kwargs)

self.distro = distro
self.version = version
self.dist_id = dist_id

def ensure_system_packages(self):
install_packages = []
installed_list = str(self.check_output(['rpm', '-qa'])).replace('\n', '|')
install_packages = []
for p in self.desktop_deps:
if not "|" + p in installed_list:
install_packages += [p]
if install_packages:
print "Installing missing packages..."
self.install_system_packages(install_packages)

def install_system_packages(self, packages=desktop_deps):
self.dnf_install(*packages)

def install_mobile_android_packages(self):
raise NotImplementedError('Bootstrap support for Android not yet available.')

def dnf_install(self, *packages):
if self.which('dnf'):
command = ['dnf', 'reinstall' if self.force else 'install']
else:
command = ['yum', 'install']

if not self.interactive:
command.append('-y')
command.extend(packages)

self.run_as_root(command)
@@ -0,0 +1,62 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import subprocess

from base import BaseBootstrapper


class DebianBootstrapper(BaseBootstrapper):
'''Bootstrapper for Debian-based distributions.'''

from packages import DEBIAN as desktop_deps

def __init__(self, version, dist_id, **kwargs):
BaseBootstrapper.__init__(self, **kwargs)
# Find Python virtualenv package name
venv = subprocess.Popen(['apt-cache', 'policy', 'virtualenv'], stdout=subprocess.PIPE)
self.virtualenv = 'virtualenv' if "virtualenv:" in venv.stdout.read() else 'python-virtualenv'
self.desktop_deps += [self.virtualenv]

self.version = version
self.dist_id = dist_id

def ensure_system_packages(self):
printed = False

for package in self.desktop_deps:
if self.run_check(['dpkg', '-s', package]):
if not printed:
print "Updating package manager..."
self._ensure_package_manager_updated()
print "Installing missing packages..."
printed = True

print "Installing %s..." % package
self.apt_install(package)

def install_system_packages(self, packages=desktop_deps):
self._ensure_package_manager_updated()
self.apt_install(*packages)

def install_mobile_android_packages(self):
raise NotImplementedError('Bootstrap support for Android not yet available.')

def _update_package_manager(self):
self.apt_update()

def apt_install(self, *packages):
command = ['apt-get', 'install']
if not self.interactive:
command.append('-y')
if self.force:
command.append('--reinstall')
command.extend(packages)
self.run_as_root(command)

def apt_update(self):
command = ['apt-get', 'update']
if not self.interactive:
command.append('-y')
self.run_as_root(command)
@@ -4,6 +4,61 @@

# Listed all packages for different platforms in one file

CENTOSFEDORA = [
"curl",
"freeglut-devel",
"libtool",
"gcc-c++",
"libXi-devel",
"freetype-devel",
"mesa-libGL-devel",
"mesa-libEGL-devel",
"glib2-devel",
"libX11-devel",
"libXrandr-devel",
"gperf",
"fontconfig-devel",
"cabextract",
"ttmkfdir",
"python",
"python2-virtualenv",
"python-pip",
"expat-devel",
"rpm-build",
"openssl-devel",
"cmake",
"bzip2-devel",
"libXcursor-devel",
"libXmu-devel",
"mesa-libOSMesa-devel",
"dbus-devel",
]

DEBIAN = [
"git",
"curl",
"freeglut3-dev",
"autoconf",
"libfreetype6-dev",
"libgl1-mesa-dri",
"libglib2.0-dev",
"xorg-dev",
"gperf",
"g++",
"build-essential",
"cmake",
"python-pip",
"libssl-dev",
"libbz2-dev",
"libosmesa6-dev",
"libxmu6",
"libxmu-dev",
"libglu1-mesa-dev",
"libgles2-mesa-dev",
"libegl1-mesa-dev",
"libdbus-1-dev",
]

WINDOWS_GNU = [
"mingw-w64-x86_64-toolchain",
"mingw-w64-x86_64-freetype",
@@ -3,15 +3,15 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import sys
import subprocess

from base import BaseBootstrapper
from packages import WINDOWS_GNU as deps


class WindowsGnuBootstrapper(BaseBootstrapper):
'''Bootstrapper for msys2 based environments for building in Windows.'''

from packages import WINDOWS_GNU as deps

def __init__(self, **kwargs):
BaseBootstrapper.__init__(self, **kwargs)

@@ -21,12 +21,13 @@ def __init__(self, **kwargs):

def ensure_system_packages(self):
install_packages = []
for p in deps:
for p in self.deps:
command = ['pacman', '-Qs', p]
if self.run_check(command):
install_packages += [p]
if install_packages:
install_packages(install_packages)
print "Installing missing packages..."
self.install_system_packages(install_packages)

def install_system_packages(self, packages=deps):
self._ensure_package_manager_updated()
@@ -38,12 +39,6 @@ def install_mobile_android_packages(self):
def _update_package_manager(self):
self.pacman_update()

def run(self, command):
subprocess.check_call(command, stdin=sys.stdin)

def run_check(self, command):
return subprocess.call(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

def pacman_update(self):
command = ['pacman', '--sync', '--refresh']
self.run(command)
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.