Fix the build on Ubuntu 20.04 (#31019)

Ubuntu 20.04 doesn't have a new enough version of GStreamer, so
automatically disable media when running on that platform.

This also cleans up the media detection a bit, putting the result in a
`enable-media` variable and moving some of the logic into the build
scripts themselves rather than the platform module.
This commit is contained in:
Martin Robinson 2024-01-07 22:25:22 +01:00 committed by GitHub
parent d0ce48db06
commit 79a0f76d26
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 45 deletions

View file

@ -58,7 +58,6 @@ class MachCommands(CommandBase):
def build(self, build_type: BuildType, jobs=None, params=None, no_package=False,
verbose=False, very_verbose=False, libsimpleservo=False, **kwargs):
opts = params or []
has_media_stack = "media-gstreamer" in self.features
if build_type.is_release():
opts += ["--release"]
@ -74,7 +73,7 @@ class MachCommands(CommandBase):
if very_verbose:
opts += ["-vv"]
env = self.build_env(is_build=True)
env = self.build_env()
self.ensure_bootstrapped()
self.ensure_clobbered()
@ -173,7 +172,7 @@ class MachCommands(CommandBase):
status = 1
# copy needed gstreamer DLLs in to servo.exe dir
if has_media_stack:
if self.enable_media:
print("Packaging gstreamer DLLs")
if not package_gstreamer_dlls(env, servo_exe_dir, target_triple):
status = 1
@ -189,7 +188,7 @@ class MachCommands(CommandBase):
servo_bin_dir = os.path.dirname(servo_path)
assert os.path.exists(servo_bin_dir)
if has_media_stack:
if self.enable_media:
print("Packaging gstreamer dylibs")
if not package_gstreamer_dylibs(self.cross_compile_target, servo_path):
return 1

View file

@ -250,6 +250,7 @@ class CommandBase(object):
def __init__(self, context):
self.context = context
self.enable_media = False
self.features = []
self.cross_compile_target = None
self.is_android_build = False
@ -493,13 +494,13 @@ class CommandBase(object):
'vcdir': vcinstalldir,
}
def build_env(self, is_build=False):
def build_env(self):
"""Return an extended environment dictionary."""
env = os.environ.copy()
servo.platform.get().set_gstreamer_environment_variables_if_necessary(
env, cross_compilation_target=self.cross_compile_target,
check_installation=is_build)
if self.enable_media and not self.is_android_build:
servo.platform.get().set_gstreamer_environment_variables_if_necessary(
env, cross_compilation_target=self.cross_compile_target)
effective_target = self.cross_compile_target or servo.platform.host_triple()
if "msvc" in effective_target:
@ -806,7 +807,7 @@ class CommandBase(object):
if build_configuration:
self.configure_cross_compilation(kwargs['target'], kwargs['android'], kwargs['win_arm64'])
self.features = kwargs.get("features", None) or []
self.configure_media_stack(kwargs['media_stack'])
self.enable_media = self.is_media_enabled(kwargs['media_stack'])
return original_function(self, *args, **kwargs)
@ -874,10 +875,10 @@ class CommandBase(object):
if self.cross_compile_target:
print(f"Targeting '{self.cross_compile_target}' for cross-compilation")
def configure_media_stack(self, media_stack: Optional[str]):
"""Determine what media stack to use based on the value of the build target
def is_media_enabled(self, media_stack: Optional[str]):
"""Determine whether media is enabled based on the value of the build target
platform and the value of the '--media-stack' command-line argument.
The chosen media stack is written into the `features` instance variable."""
Returns true if media is enabled."""
if not media_stack:
if self.config["build"]["media-stack"] != "auto":
media_stack = self.config["build"]["media-stack"]
@ -890,8 +891,16 @@ class CommandBase(object):
media_stack = "gstreamer"
else:
media_stack = "dummy"
if media_stack != "dummy":
self.features += ["media-" + media_stack]
# This is a workaround for Ubuntu 20.04, which doesn't support a new enough GStreamer.
# Once we drop support for this platform (it's currently needed for wpt.fyi runners),
# we can remove this workaround and officially only support Ubuntu 22.04 and up.
platform = servo.platform.get()
if not self.cross_compile_target and platform.is_linux and \
not platform.is_gstreamer_installed(self.cross_compile_target):
return False
return media_stack != "dummy"
def run_cargo_build_like_command(
self, command: str, cargo_args: List[str],
@ -903,6 +912,17 @@ class CommandBase(object):
):
env = env or self.build_env()
# Android GStreamer integration is handled elsewhere.
# NB: On non-Linux platforms we cannot check whether GStreamer is installed until
# environment variables are set via `self.build_env()`.
platform = servo.platform.get()
if self.enable_media and not self.is_android_build and \
not platform.is_gstreamer_installed(self.cross_compile_target):
raise FileNotFoundError(
"GStreamer libraries not found (>= version 1.18)."
"Please see installation instructions in README.md"
)
args = []
if "--manifest-path" not in cargo_args:
if libsimpleservo or self.is_android_build:
@ -922,6 +942,8 @@ class CommandBase(object):
if "-p" not in cargo_args: # We're building specific package, that may not have features
features = list(self.features)
if self.enable_media:
features.append("media-gstreamer")
if self.config["build"]["debug-mozjs"] or debug_mozjs:
features.append("debugmozjs")

View file

@ -26,11 +26,6 @@ class Base:
def set_gstreamer_environment_variables_if_necessary(
self, env: Dict[str, str], cross_compilation_target: Optional[str], check_installation=True
):
# Environment variables are not needed when cross-compiling on any platform other
# than Windows. GStreamer for Android is handled elsewhere.
if cross_compilation_target and (not self.is_windows or "android" in cross_compilation_target):
return
# We may not need to update environment variables if GStreamer is installed
# for the system on Linux.
gstreamer_root = self.gstreamer_root(cross_compilation_target)
@ -52,14 +47,6 @@ class Base:
)
env["GST_PLUGIN_SYSTEM_PATH"] = os.path.join(gstreamer_root, "lib", "gstreamer-1.0")
# If we are not cross-compiling GStreamer must be installed for the system. In
# the cross-compilation case, we might be picking it up from another directory.
if check_installation and not self.is_gstreamer_installed(cross_compilation_target):
raise FileNotFoundError(
"GStreamer libraries not found (>= version 1.18)."
"Please see installation instructions in README.md"
)
def gstreamer_root(self, _cross_compilation_target: Optional[str]) -> Optional[str]:
raise NotImplementedError("Do not know how to get GStreamer path for platform.")

View file

@ -12,7 +12,6 @@ import subprocess
from typing import Optional, Tuple
import distro
from .. import util
from .base import Base
# Please keep these in sync with the packages on the wiki, using the instructions below
@ -75,8 +74,6 @@ XBPS_PKGS = ['libtool', 'gcc', 'libXi-devel', 'freetype-devel',
GSTREAMER_URL = \
"https://github.com/servo/servo-build-deps/releases/download/linux/gstreamer-1.16-x86_64-linux-gnu.20190515.tar.gz"
PREPACKAGED_GSTREAMER_ROOT = \
os.path.join(util.get_target_dir(), "dependencies", "gstreamer")
class Linux(Base):
@ -154,7 +151,6 @@ class Linux(Base):
f"{self.distro}, please file a bug")
installed_something = self.install_non_gstreamer_dependencies(force)
installed_something |= self._platform_bootstrap_gstreamer(force)
return installed_something
def install_non_gstreamer_dependencies(self, force: bool) -> bool:
@ -199,18 +195,9 @@ class Linux(Base):
return True
def gstreamer_root(self, cross_compilation_target: Optional[str]) -> Optional[str]:
if cross_compilation_target:
return None
if os.path.exists(PREPACKAGED_GSTREAMER_ROOT):
return PREPACKAGED_GSTREAMER_ROOT
# GStreamer might be installed system-wide, but we do not return a root in this
# case because we don't have to update environment variables.
return None
def _platform_bootstrap_gstreamer(self, force: bool) -> bool:
if not force and self.is_gstreamer_installed(cross_compilation_target=None):
return False
def _platform_bootstrap_gstreamer(self, _force: bool) -> bool:
raise EnvironmentError(
"Bootstrapping GStreamer on Linux is not supported. "
+ "Please install it using your distribution package manager.")

View file

@ -266,7 +266,7 @@ class PostBuildCommands(CommandBase):
else:
copy2(full_name, destination)
env = self.build_env(is_build=True)
env = self.build_env()
returncode = self.run_cargo_build_like_command("doc", params, env=env, **kwargs)
if returncode:
return returncode

View file

@ -258,9 +258,7 @@ class MachCommands(CommandBase):
if nocapture:
args += ["--", "--nocapture"]
# We are setting is_build here to true, because running `cargo test` can trigger builds.
env = self.build_env(is_build=True)
env = self.build_env()
return self.run_cargo_build_like_command(
"bench" if bench else "test",
args,