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
Create `mach bootstrap` based on Mozilla's mozboot bootstrapper #12916
Merged
+343
−32
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.
Create `mach bootstrap` based on Mozilla's mozboot bootstrapper
- Loading branch information
commit fc3555556cfe5ee775281eb05cfeea232efa68c7
| @@ -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/. |
| @@ -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. | ||
| """ | ||
| @@ -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() |
| @@ -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", | ||
| ] |
| @@ -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) |
| @@ -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!') |
Oops, something went wrong.
ProTip!
Use n and p to navigate between commits in a pull request.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Can't we just use
distutils.spawn.find_executable? (like we do inmach_bootstrap.py)