aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md46
-rwxr-xr-xmach7
-rw-r--r--python/mach_bootstrap.py18
-rw-r--r--python/servo/bootstrap.py125
-rw-r--r--python/servo/bootstrap_commands.py21
-rw-r--r--python/servo/command_base.py51
-rw-r--r--python/servo/package_commands.py4
-rw-r--r--python/servo/testing_commands.py5
-rw-r--r--python/servo/util.py2
-rw-r--r--servo-tidy.toml1
-rw-r--r--support/linux/gstreamer/.gitignore2
-rw-r--r--support/linux/gstreamer/gstreamer.sh12
12 files changed, 278 insertions, 16 deletions
diff --git a/README.md b/README.md
index db98506d280..9211b7703a1 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,10 @@ If you've already partially compiled servo but forgot to do this step, run `./ma
#### On Debian-based Linuxes
+Please run `./mach bootstrap`.
+
+If this doesn't work, file a bug, and, run the commands below:
+
``` sh
sudo apt install git curl autoconf libx11-dev \
libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \
@@ -89,15 +93,50 @@ sudo apt install git curl autoconf libx11-dev \
```
If you using a version prior to **Ubuntu 17.04** or **Debian Sid**, replace `libssl1.0-dev` with `libssl-dev`.
+Additionally, you'll need a local copy of GStreamer with a version later than 12.0. You can place it in `support/linux/gstreamer/gstreamer`, or run `./mach bootstrap-gstreamer` to set it up.
If you are using **Ubuntu 16.04** run `export HARFBUZZ_SYS_NO_PKG_CONFIG=1` before building to avoid an error with harfbuzz.
-If you are on **Ubuntu 14.04** and encountered errors on installing these dependencies involving `libcheese`, see [#6158](https://github.com/servo/servo/issues/6158) for a workaround.
+If you are on **Ubuntu 14.04** and encountered errors on installing these dependencies involving `libcheese`, see [#6158](https://github.com/servo/servo/issues/6158) for a workaround. You may also need to install gcc 4.9, clang 4.0, and cmake 3.2:
+
+<details>
+gcc 4.9:
+
+```sh
+sudo add-apt-repository ppa:ubuntu-toolchain-r/test
+sudo apt-get update
+sudo apt-get install gcc-4.9 g++-4.9
+sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9
+```
+
+clang 4.0:
+
+```sh
+wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
+sudo apt-add-repository "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main"
+sudo apt-get update
+sudo apt-get install -y clang-4.0
+```
+
+cmake 3.2:
+
+```sh
+sudo apt-get install software-properties-common
+sudo add-apt-repository ppa:george-edison55/cmake-3.x
+sudo apt-get update
+sudo apt-get install cmake
+```
+
+</details>
If `virtualenv` does not exist, try `python-virtualenv`.
#### On Fedora
+Please run `./mach bootstrap`.
+
+If this doesn't work, file a bug, and, run the commands below:
+
``` sh
sudo dnf install curl libtool gcc-c++ libXi-devel \
freetype-devel mesa-libGL-devel mesa-libEGL-devel glib2-devel libX11-devel libXrandr-devel gperf \
@@ -108,6 +147,11 @@ sudo dnf install curl libtool gcc-c++ libXi-devel \
```
#### On CentOS
+
+Please run `./mach bootstrap`.
+
+If this doesn't work, file a bug, and, run the commands below:
+
``` sh
sudo yum install curl libtool gcc-c++ libXi-devel \
freetype-devel mesa-libGL-devel mesa-libEGL-devel glib2-devel libX11-devel libXrandr-devel gperf \
diff --git a/mach b/mach
index c328f6b08fa..c9ae9fc2b40 100755
--- a/mach
+++ b/mach
@@ -20,8 +20,11 @@ def main(args):
topdir = os.path.abspath(os.path.dirname(sys.argv[0]))
sys.path.insert(0, os.path.join(topdir, "python"))
import mach_bootstrap
- mach = mach_bootstrap.bootstrap(topdir)
- sys.exit(mach.run(sys.argv[1:]))
+ if len(sys.argv) > 1 and sys.argv[1] == "bootstrap":
+ sys.exit(mach_bootstrap.bootstrap_command_only(topdir))
+ else:
+ mach = mach_bootstrap.bootstrap(topdir)
+ sys.exit(mach.run(sys.argv[1:]))
if __name__ == '__main__':
diff --git a/python/mach_bootstrap.py b/python/mach_bootstrap.py
index 2db4bf01c30..3435b39f06a 100644
--- a/python/mach_bootstrap.py
+++ b/python/mach_bootstrap.py
@@ -224,11 +224,29 @@ def _is_windows():
return sys.platform == 'win32'
+class DummyContext(object):
+ pass
+
+
+def bootstrap_command_only(topdir):
+ from servo.bootstrap import bootstrap
+
+ context = DummyContext()
+ context.topdir = topdir
+ force = False
+ if len(sys.argv) == 3 and sys.argv[2] == "-f":
+ force = True
+ bootstrap(context, force)
+ return 0
+
+
def bootstrap(topdir):
_ensure_case_insensitive_if_windows()
topdir = os.path.abspath(topdir)
+ len(sys.argv) > 1 and sys.argv[1] == "bootstrap"
+
# We don't support paths with Unicode characters for now
# https://github.com/servo/servo/issues/10002
try:
diff --git a/python/servo/bootstrap.py b/python/servo/bootstrap.py
index e20fda210a6..0e128d2826e 100644
--- a/python/servo/bootstrap.py
+++ b/python/servo/bootstrap.py
@@ -17,22 +17,57 @@ import servo.packages as packages
from servo.util import extract, download_file, host_triple
-def run_as_root(command):
+def install_trusty_deps(force):
+ version = str(subprocess.check_output(['gcc', '-dumpversion'])).split('.')
+ gcc = True
+ if int(version[0]) > 4:
+ gcc = False
+ elif int(version[0]) == 4 and int(version[1]) >= 9:
+ gcc = False
+
+ version = str(subprocess.check_output(['clang', '-dumpversion'])).split('.')
+ clang = int(version[0]) < 4
+
+ if gcc:
+ run_as_root(["add-apt-repository", "ppa:ubuntu-toolchain-r/test"], force)
+ run_as_root(["apt-get", "update"])
+ run_as_root(["apt-get", "install", "gcc-4.9", "g++-4.9"], force)
+ run_as_root(['update-alternatives', '--install', '/usr/bin/gcc', 'gcc',
+ '/usr/bin/gcc-4.9', '60', '--slave', '/usr/bin/g++', 'g++',
+ '/usr/bin/g++-4.9'])
+ if clang:
+ run_as_root(["bash", "-c", 'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -'])
+ run_as_root(["apt-add-repository", "deb http://apt.llvm.org/trusty/ llvm-toolchain-xenial-4.0 main"], force)
+ run_as_root(["apt-get", "update"])
+ run_as_root(["apt-get", "install", "clang-4.0"], force)
+
+ return gcc or clang
+
+
+def check_gstreamer_lib():
+ return subprocess.call(["pkg-config", "gstreamer-1.0 >= 1.12"],
+ stdout=PIPE, stderr=PIPE) == 0
+
+
+def run_as_root(command, force=False):
if os.geteuid() != 0:
command.insert(0, 'sudo')
+ if force:
+ command += "-y"
return subprocess.call(command)
-def install_salt_dependencies(context, force):
+def install_linux_deps(context, pkgs_ubuntu, pkgs_fedora, force):
install = False
+ pkgs = []
if context.distro == 'Ubuntu':
- pkgs = ['build-essential', 'libssl-dev', 'libffi-dev', 'python-dev']
command = ['apt-get', 'install']
+ pkgs = pkgs_ubuntu
if subprocess.call(['dpkg', '-s'] + pkgs, stdout=PIPE, stderr=PIPE) != 0:
install = True
elif context.distro in ['CentOS', 'CentOS Linux', 'Fedora']:
installed_pkgs = str(subprocess.check_output(['rpm', '-qa'])).replace('\n', '|')
- pkgs = ['gcc', 'libffi-devel', 'python-devel', 'openssl-devel']
+ pkgs = pkgs_fedora
for p in pkgs:
command = ['dnf', 'install']
if "|{}".format(p) not in installed_pkgs:
@@ -42,8 +77,74 @@ def install_salt_dependencies(context, force):
if install:
if force:
command.append('-y')
- print("Installing missing Salt dependencies...")
+ print("Installing missing dependencies...")
run_as_root(command + pkgs)
+ return True
+ return False
+
+
+def install_salt_dependencies(context, force):
+ pkgs_apt = ['build-essential', 'libssl-dev', 'libffi-dev', 'python-dev']
+ pkgs_dnf = ['gcc', 'libffi-devel', 'python-devel', 'openssl-devel']
+ if not install_linux_deps(context, pkgs_apt, pkgs_dnf, force):
+ print("Dependencies are already installed")
+
+
+def gstreamer(context, force=False):
+ cur = os.curdir
+ gstdir = os.path.join(cur, "support", "linux", "gstreamer")
+ if not os.path.isdir(os.path.join(gstdir, "gstreamer", "lib")):
+ subprocess.check_call(["bash", "gstreamer.sh"], cwd=gstdir)
+ return True
+ return False
+
+
+def linux(context, force=False):
+ # Please keep these in sync with the packages in README.md
+ pkgs_apt = ['git', 'curl', 'autoconf', 'libx11-dev', 'libfreetype6-dev',
+ 'libgl1-mesa-dri', 'libglib2.0-dev', 'xorg-dev', 'gperf', 'g++',
+ 'build-essential', 'cmake', 'python-pip',
+ 'libbz2-dev', 'libosmesa6-dev', 'libxmu6', 'libxmu-dev', 'libglu1-mesa-dev',
+ 'libgles2-mesa-dev', 'libegl1-mesa-dev', 'libdbus-1-dev', 'libharfbuzz-dev',
+ 'ccache', 'clang', 'autoconf2.13']
+ pkgs_dnf = ['libtool', 'gcc-c++', 'libXi-devel', 'freetype-devel',
+ 'mesa-libGL-devel', 'mesa-libEGL-devel', 'glib2-devel', 'libX11-devel',
+ 'libXrandr-devel', 'gperf', 'fontconfig-devel', 'cabextract', 'ttmkfdir',
+ 'python2', 'python2-virtualenv', 'python2-pip', 'expat-devel', 'rpm-build',
+ 'openssl-devel', 'cmake', 'bzip2-devel', 'libXcursor-devel', 'libXmu-devel',
+ 'mesa-libOSMesa-devel', 'dbus-devel', 'ncurses-devel', 'harfbuzz-devel',
+ 'ccache', 'mesa-libGLU-devel', 'clang', 'clang-libs', 'gstreamer1-devel',
+ 'gstreamer1-plugins-base-devel', 'gstreamer1-plugins-bad-free-devel', 'autoconf213']
+ if context.distro == "Ubuntu":
+ if context.distro_version == "17.04":
+ pkgs_apt += ["libssl-dev"]
+ elif int(context.distro_version.split(".")[0]) < 17:
+ pkgs_apt += ["libssl-dev"]
+ else:
+ pkgs_apt += ["libssl1.0-dev"]
+
+ if context.distro_version == "14.04":
+ pkgs_apt += ["python-virtualenv"]
+ else:
+ pkgs_apt += ["virtualenv"]
+ pkgs_apt += ['libgstreamer1.0-dev', 'libgstreamer-plugins-base1.0-dev',
+ 'libgstreamer-plugins-bad1.0-dev']
+
+ elif context.distro == "Debian" and context.distro_version == "Sid":
+ pkgs_apt += ["libssl-dev"]
+ else:
+ pkgs_apt += ["libssl1.0-dev"]
+
+ installed_something = install_linux_deps(context, pkgs_apt, pkgs_dnf, force)
+
+ if not check_gstreamer_lib():
+ installed_something |= gstreamer(context, force)
+
+ if context.distro == "Ubuntu" and context.distro_version == "14.04":
+ installed_something |= install_trusty_deps(force)
+
+ if not installed_something:
+ print("Dependencies were already installed!")
def salt(context, force=False):
@@ -226,11 +327,16 @@ def windows_msvc(context, force=False):
return 0
-def bootstrap(context, force=False):
+LINUX_SPECIFIC_BOOTSTRAPPERS = {
+ "salt": salt,
+ "gstreamer": gstreamer,
+}
+
+
+def bootstrap(context, force=False, specific=None):
'''Dispatches to the right bootstrapping function for the OS.'''
bootstrapper = None
-
if "windows-msvc" in host_triple():
bootstrapper = windows_msvc
elif "linux-gnu" in host_triple():
@@ -243,7 +349,10 @@ def bootstrap(context, force=False):
'ubuntu',
]:
context.distro = distro
- bootstrapper = salt
+ context.distro_version = version
+ bootstrapper = LINUX_SPECIFIC_BOOTSTRAPPERS.get(specific, linux)
+ else:
+ raise Exception("mach bootstrap does not support %s, please file a bug" % distro)
if bootstrapper is None:
print('Bootstrap support is not yet available for your OS.')
diff --git a/python/servo/bootstrap_commands.py b/python/servo/bootstrap_commands.py
index 28e39916f39..0650f943278 100644
--- a/python/servo/bootstrap_commands.py
+++ b/python/servo/bootstrap_commands.py
@@ -53,8 +53,29 @@ class MachCommands(CommandBase):
action='store_true',
help='Boostrap without confirmation')
def bootstrap(self, force=False):
+ # This entry point isn't actually invoked, ./mach bootstrap is directly
+ # called by mach (see mach_bootstrap.bootstrap_command_only) so that
+ # it can install dependencies without needing mach's dependencies
return bootstrap.bootstrap(self.context, force=force)
+ @Command('bootstrap-salt',
+ description='Install and set up the salt environment.',
+ category='bootstrap')
+ @CommandArgument('--force', '-f',
+ action='store_true',
+ help='Boostrap without confirmation')
+ def bootstrap_salt(self, force=False):
+ return bootstrap.bootstrap(self.context, force=force, specific="salt")
+
+ @Command('bootstrap-gstreamer',
+ description='Set up a local copy of the gstreamer libraries (linux only).',
+ category='bootstrap')
+ @CommandArgument('--force', '-f',
+ action='store_true',
+ help='Boostrap without confirmation')
+ def bootstrap_gstreamer(self, force=False):
+ return bootstrap.bootstrap(self.context, force=force, specific="gstreamer")
+
@Command('bootstrap-android',
description='Install the Android SDK and NDK.',
category='bootstrap')
diff --git a/python/servo/command_base.py b/python/servo/command_base.py
index 7d81b5a29ef..b335dcd69eb 100644
--- a/python/servo/command_base.py
+++ b/python/servo/command_base.py
@@ -24,6 +24,7 @@ import tarfile
from xml.etree.ElementTree import XML
from servo.util import download_file
import urllib2
+from bootstrap import check_gstreamer_lib
from mach.registrar import Registrar
import toml
@@ -347,6 +348,9 @@ class CommandBase(object):
build_type = "release" if release else "debug"
return path.join(base_path, build_type, apk_name)
+ def get_gstreamer_path(self):
+ return path.join(self.context.topdir, "support", "linux", "gstreamer", "gstreamer")
+
def get_binary_path(self, release, dev, android=False):
# TODO(autrilla): this function could still use work - it shouldn't
# handle quitting, or printing. It should return the path, or an error.
@@ -476,6 +480,37 @@ class CommandBase(object):
bin_folder = path.join(destination_folder, "PFiles", "Mozilla research", "Servo Tech Demo")
return path.join(bin_folder, "servo{}".format(BIN_SUFFIX))
+ def needs_gstreamer_env(self, target):
+ try:
+ if check_gstreamer_lib():
+ return False
+ except:
+ # Some systems don't have pkg-config; we can't probe in this case
+ # and must hope for the best
+ return False
+ effective_target = target or host_triple()
+ if "x86_64" not in effective_target or "android" in effective_target:
+ # We don't build gstreamer for non-x86_64 / android yet
+ return False
+ if sys.platform == "linux2":
+ if path.isdir(self.get_gstreamer_path()):
+ return True
+ else:
+ raise Exception("Your system's gstreamer libraries are out of date \
+(we need at least 1.12). Please run ./mach bootstrap-gstreamer")
+ else:
+ raise Exception("Your system's gstreamer libraries are out of date \
+(we need at least 1.12). If you're unable to \
+install them, let us know by filing a bug!")
+ return False
+
+ def set_run_env(self, android=False):
+ """Some commands, like test-wpt, don't use a full build env,
+ but may still need dynamic search paths. This command sets that up"""
+ if not android and self.needs_gstreamer_env(None):
+ gstpath = self.get_gstreamer_path()
+ os.environ["LD_LIBRARY_PATH"] = path.join(gstpath, "lib", "x86_64-linux-gnu")
+
def build_env(self, hosts_file_path=None, target=None, is_build=False, test_unit=False):
"""Return an extended environment dictionary."""
env = os.environ.copy()
@@ -513,12 +548,26 @@ class CommandBase(object):
# Link LLVM
env["LIBCLANG_PATH"] = path.join(package_dir("llvm"), "lib")
- if is_windows():
if not os.environ.get("NATIVE_WIN32_PYTHON"):
env["NATIVE_WIN32_PYTHON"] = sys.executable
# Always build harfbuzz from source
env["HARFBUZZ_SYS_NO_PKG_CONFIG"] = "true"
+ if self.needs_gstreamer_env(target):
+ gstpath = self.get_gstreamer_path()
+ extra_path += [path.join(gstpath, "bin")]
+ libpath = path.join(gstpath, "lib", "x86_64-linux-gnu")
+ # we append in the reverse order so that system gstreamer libraries
+ # do not get precedence
+ extra_path = [libpath] + extra_path
+ extra_lib = [libpath] + extra_path
+ append_to_path_env(path.join(libpath, "pkgconfig"), env, "PKG_CONFIG_PATH")
+
+ if sys.platform == "linux2":
+ distro, version, _ = platform.linux_distribution()
+ if distro == "Ubuntu" and (version == "16.04" or version == "14.04"):
+ env["HARFBUZZ_SYS_NO_PKG_CONFIG"] = "true"
+
if extra_path:
env["PATH"] = "%s%s%s" % (os.pathsep.join(extra_path), os.pathsep, env["PATH"])
diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py
index 9a3c8f62d63..1e91032dea6 100644
--- a/python/servo/package_commands.py
+++ b/python/servo/package_commands.py
@@ -184,7 +184,6 @@ class PackageCommands(CommandBase):
default=None,
help='Package using the given Gradle flavor')
def package(self, release=False, dev=False, android=None, debug=False, debugger=None, target=None, flavor=None):
- env = self.build_env()
if android is None:
android = self.config["build"]["android"]
if target and android:
@@ -192,6 +191,9 @@ class PackageCommands(CommandBase):
sys.exit(1)
if not android:
android = self.handle_android_target(target)
+ else:
+ target = self.config["android"]["target"]
+ env = self.build_env(target=target)
binary_path = self.get_binary_path(release, dev, android=android)
dir_to_root = self.get_top_dir()
target_dir = path.dirname(binary_path)
diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py
index 1cfddcc1ac7..8e18fce5437 100644
--- a/python/servo/testing_commands.py
+++ b/python/servo/testing_commands.py
@@ -380,9 +380,10 @@ class MachCommands(CommandBase):
binary_args=self.in_android_emulator(release, dev) + (binary_args or []),
binary=sys.executable,
)
- return self._test_wpt(**kwargs)
+ return self._test_wpt(android=True, **kwargs)
- def _test_wpt(self, **kwargs):
+ def _test_wpt(self, android=False, **kwargs):
+ self.set_run_env(android)
hosts_file_path = path.join(self.context.topdir, 'tests', 'wpt', 'hosts')
os.environ["hosts_file_path"] = hosts_file_path
run_file = path.abspath(path.join(self.context.topdir, "tests", "wpt", "run.py"))
diff --git a/python/servo/util.py b/python/servo/util.py
index d71cffe27da..c093978e631 100644
--- a/python/servo/util.py
+++ b/python/servo/util.py
@@ -20,7 +20,6 @@ import StringIO
import sys
import zipfile
import urllib2
-import certifi
try:
@@ -30,6 +29,7 @@ except ImportError:
# The cafile parameter was added in 2.7.9
if HAS_SNI and sys.version_info >= (2, 7, 9):
+ import certifi
STATIC_RUST_LANG_ORG_DIST = "https://static.rust-lang.org/dist"
URLOPEN_KWARGS = {"cafile": certifi.where()}
else:
diff --git a/servo-tidy.toml b/servo-tidy.toml
index 46f4fa505c5..f687e5cb692 100644
--- a/servo-tidy.toml
+++ b/servo-tidy.toml
@@ -61,6 +61,7 @@ files = [
"./resources/hsts_preload.json",
"./tests/wpt/metadata/MANIFEST.json",
"./support/android/openssl.sh",
+ "./support/linux/gstreamer/gstreamer.sh",
# Upstream code from Khronos/WebGL uses tabs for indentation
"./tests/wpt/webgl/tests",
# Our import script is not currently respecting the lint.
diff --git a/support/linux/gstreamer/.gitignore b/support/linux/gstreamer/.gitignore
new file mode 100644
index 00000000000..3b805050af7
--- /dev/null
+++ b/support/linux/gstreamer/.gitignore
@@ -0,0 +1,2 @@
+gstreamer/
+
diff --git a/support/linux/gstreamer/gstreamer.sh b/support/linux/gstreamer/gstreamer.sh
new file mode 100644
index 00000000000..1f7e92b4086
--- /dev/null
+++ b/support/linux/gstreamer/gstreamer.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+# 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/.
+
+set -o errexit
+
+wget http://servo-deps.s3.amazonaws.com/gstreamer/gstreamer-x86_64-linux-gnu.tar.gz -O gstreamer.tar.gz
+tar -zxf gstreamer.tar.gz
+rm gstreamer.tar.gz
+sed -i "s;prefix=/root/gstreamer;prefix=${PWD}/gstreamer;g" ${PWD}/gstreamer/lib/x86_64-linux-gnu/pkgconfig/*.pc