aboutsummaryrefslogtreecommitdiffstats
path: root/python/servo/bootstrapper
diff options
context:
space:
mode:
Diffstat (limited to 'python/servo/bootstrapper')
-rw-r--r--python/servo/bootstrapper/__init__.py3
-rw-r--r--python/servo/bootstrapper/base.py62
-rw-r--r--python/servo/bootstrapper/bootstrap.py41
-rw-r--r--python/servo/bootstrapper/packages.py28
-rw-r--r--python/servo/bootstrapper/windows_gnu.py75
-rw-r--r--python/servo/bootstrapper/windows_msvc.py86
6 files changed, 295 insertions, 0 deletions
diff --git a/python/servo/bootstrapper/__init__.py b/python/servo/bootstrapper/__init__.py
new file mode 100644
index 00000000000..6fbe8159b2d
--- /dev/null
+++ b/python/servo/bootstrapper/__init__.py
@@ -0,0 +1,3 @@
+# 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/.
diff --git a/python/servo/bootstrapper/base.py b/python/servo/bootstrapper/base.py
new file mode 100644
index 00000000000..40f3d1f5ebc
--- /dev/null
+++ b/python/servo/bootstrapper/base.py
@@ -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/.
+
+from __future__ import print_function, unicode_literals
+
+import distutils
+import subprocess
+
+
+class BaseBootstrapper(object):
+ """Base class for system bootstrappers."""
+
+ def __init__(self, interactive=False):
+ self.package_manager_updated = False
+ self.interactive = interactive
+
+ def ensure_system_packages(self):
+ '''
+ Check for missing packages.
+ '''
+ raise NotImplementedError('%s must implement ensure_system_packages()' %
+ __name__)
+
+ def install_system_packages(self):
+ '''
+ Install packages required to build Servo.
+ '''
+ raise NotImplementedError('%s must implement install_system_packages()' %
+ __name__)
+
+ def install_mobile_android_packages(self):
+ '''
+ Install packages required to build Servo for Android.
+ '''
+ raise NotImplementedError('Cannot bootstrap Servo for Android: '
+ '%s does not yet implement install_mobile_android_packages()'
+ % __name__)
+
+ def which(self, name):
+ """Python implementation of which.
+
+ It returns the path of an executable or None if it couldn't be found.
+ """
+ return distutils.spawn.find_executable(name)
+
+ def check_output(self, *args, **kwargs):
+ """Run subprocess.check_output."""
+ return subprocess.check_output(*args, **kwargs)
+
+ def _ensure_package_manager_updated(self):
+ if self.package_manager_updated:
+ return
+
+ self._update_package_manager()
+ self.package_manager_updated = True
+
+ def _update_package_manager(self):
+ """Updates the package manager's manifests/package list.
+
+ This should be defined in child classes.
+ """
diff --git a/python/servo/bootstrapper/bootstrap.py b/python/servo/bootstrapper/bootstrap.py
new file mode 100644
index 00000000000..c6ac9d196eb
--- /dev/null
+++ b/python/servo/bootstrapper/bootstrap.py
@@ -0,0 +1,41 @@
+# 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 __future__ import print_function
+
+import sys
+
+from windows_gnu import WindowsGnuBootstrapper
+from windows_msvc import WindowsMsvcBootstrapper
+
+
+class Bootstrapper(object):
+ """Main class that performs system bootstrap."""
+
+ def __init__(self):
+ self.instance = None
+ cls = None
+ args = {}
+
+ if sys.platform.startswith('msys'):
+ cls = WindowsGnuBootstrapper
+
+ elif sys.platform.startswith('win32'):
+ cls = WindowsMsvcBootstrapper
+
+ if cls is None:
+ sys.exit('Bootstrap support is not yet available for your OS.')
+
+ self.instance = cls(**args)
+
+ 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:
+ self.instance.install_system_packages()
+ else:
+ self.instance.ensure_system_packages()
diff --git a/python/servo/bootstrapper/packages.py b/python/servo/bootstrapper/packages.py
new file mode 100644
index 00000000000..7e9a7cd9c0e
--- /dev/null
+++ b/python/servo/bootstrapper/packages.py
@@ -0,0 +1,28 @@
+# 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/.
+
+# Listed all packages for different platforms in one file
+
+WINDOWS_GNU = [
+ "mingw-w64-x86_64-toolchain",
+ "mingw-w64-x86_64-freetype",
+ "mingw-w64-x86_64-icu",
+ "mingw-w64-x86_64-nspr",
+ "mingw-w64-x86_64-ca-certificates",
+ "mingw-w64-x86_64-expat",
+ "mingw-w64-x86_64-cmake",
+ "tar",
+ "diffutils",
+ "patch",
+ "patchutils",
+ "make",
+ "python2-setuptools",
+]
+
+WINDOWS_MSVC = [
+ "cmake-3.6.1",
+ "ninja-1.7.1",
+ "openssl-1.0.1t-vs2015",
+ "moztools-0.0.1-5",
+]
diff --git a/python/servo/bootstrapper/windows_gnu.py b/python/servo/bootstrapper/windows_gnu.py
new file mode 100644
index 00000000000..794f1790cd1
--- /dev/null
+++ b/python/servo/bootstrapper/windows_gnu.py
@@ -0,0 +1,75 @@
+# 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 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.'''
+
+ def __init__(self, **kwargs):
+ BaseBootstrapper.__init__(self, **kwargs)
+
+ if not self.which('pacman'):
+ raise NotImplementedError('The Windows bootstrapper only works with msys2 with pacman. Get msys2 at '
+ 'http://msys2.github.io/')
+
+ def ensure_system_packages(self):
+ install_packages = []
+ for p in deps:
+ command = ['pacman', '-Qs', p]
+ if self.run_check(command):
+ install_packages += [p]
+ if install_packages:
+ install_packages(install_packages)
+
+ def install_system_packages(self, packages=deps):
+ self._ensure_package_manager_updated()
+ self.pacman_install(*packages)
+
+ def install_mobile_android_packages(self):
+ sys.exit('We do not support building Android on Windows. Sorry!')
+
+ 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)
+
+ def pacman_upgrade(self):
+ command = ['pacman', '--sync', '--refresh', '--sysupgrade']
+ self.run(command)
+
+ def pacman_install(self, *packages):
+ command = ['pacman', '--sync']
+ if not self.force:
+ command.append('--needed')
+ if not self.interactive:
+ command.append('--noconfirm')
+ command.extend(packages)
+ self.run(command)
+
+ # downgrade GCC to 5.4.0-1
+ gcc_type = ["gcc", "gcc-ada", "gcc-fortran", "gcc-libgfortran", "gcc-libs", "gcc-objc"]
+ gcc_version = "5.4.0-1"
+ mingw_url = "http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-{}-{}-any.pkg.tar.xz"
+ gcc_list = []
+ for gcc in gcc_type:
+ gcc_list += [mingw_url.format(gcc, gcc_version)]
+ downgrade_command = ['pacman', '-U']
+ if not self.interactive:
+ downgrade_command.append('--noconfirm')
+ downgrade_command.extend(gcc_list)
+ self.run(downgrade_command)
diff --git a/python/servo/bootstrapper/windows_msvc.py b/python/servo/bootstrapper/windows_msvc.py
new file mode 100644
index 00000000000..f4926276549
--- /dev/null
+++ b/python/servo/bootstrapper/windows_msvc.py
@@ -0,0 +1,86 @@
+# 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 os
+import sys
+import shutil
+from distutils import spawn
+
+from base import BaseBootstrapper
+from packages import WINDOWS_MSVC as deps
+
+
+class WindowsMsvcBootstrapper(BaseBootstrapper):
+ '''Bootstrapper for MSVC building on Windows.'''
+
+ def __init__(self, **kwargs):
+ BaseBootstrapper.__init__(self, **kwargs)
+
+ def ensure_system_packages(self):
+ self.install_system_packages()
+
+ def install_system_packages(self, packages=deps):
+ from servo.bootstrap_commands import extract, download_file
+
+ deps_dir = os.path.join(".servo", "msvc-dependencies")
+ deps_url = "https://servo-rust.s3.amazonaws.com/msvc-deps/"
+ first_run = True
+
+ if self.force:
+ if os.path.isdir(deps_dir):
+ shutil.rmtree(deps_dir)
+
+ if not os.path.isdir(deps_dir):
+ os.makedirs(deps_dir)
+
+ # Read file with installed dependencies, if exist
+ installed_deps_file = os.path.join(deps_dir, "installed-dependencies.txt")
+ if os.path.exists(installed_deps_file):
+ installed_deps = [l.strip() for l in open(installed_deps_file)]
+ else:
+ installed_deps = []
+
+ # list of dependencies that need to be updated
+ update_deps = list(set(packages) - set(installed_deps))
+
+ for dep in packages:
+ dep_name = dep.split("-")[0]
+
+ # Don't download CMake if already exists in PATH
+ if dep_name == "cmake":
+ if spawn.find_executable(dep_name):
+ continue
+
+ dep_dir = os.path.join(deps_dir, dep_name)
+ # if not installed or need to be updated
+ if not os.path.exists(dep_dir) or dep in update_deps:
+ if first_run:
+ print "Installing missing MSVC dependencies..."
+ first_run = False
+
+ dep_version_dir = os.path.join(deps_dir, dep)
+
+ if os.path.exists(dep_version_dir):
+ shutil.rmtree(dep_version_dir)
+
+ dep_zip = dep_version_dir + ".zip"
+ if not os.path.isfile(dep_zip):
+ download_file(dep, "%s%s.zip" % (deps_url, dep), dep_zip)
+
+ print "Extracting %s..." % dep,
+ extract(dep_zip, deps_dir)
+ print "done"
+
+ # Delete directory if exist
+ if os.path.exists(dep_dir):
+ shutil.rmtree(dep_dir)
+ os.rename(dep_version_dir, dep_dir)
+
+ # Write in installed-dependencies.txt file
+ with open(installed_deps_file, 'w') as installed_file:
+ for line in packages:
+ installed_file.write(line + "\n")
+
+ def install_mobile_android_packages(self):
+ sys.exit('We do not support building Android on Windows. Sorry!')