aboutsummaryrefslogtreecommitdiffstats
path: root/python/servo/build_commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/servo/build_commands.py')
-rw-r--r--python/servo/build_commands.py107
1 files changed, 6 insertions, 101 deletions
diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py
index 93a432041df..61cede7e7b3 100644
--- a/python/servo/build_commands.py
+++ b/python/servo/build_commands.py
@@ -31,11 +31,12 @@ from mach.decorators import (
from mach.registrar import Registrar
import servo.platform
+import servo.platform.macos
import servo.util
import servo.visual_studio
from servo.command_base import BuildType, CommandBase, call, check_call
-from servo.gstreamer import windows_dlls, windows_plugins, macos_plugins
+from servo.gstreamer import windows_dlls, windows_plugins, package_gstreamer_dylibs
SUPPORTED_ASAN_TARGETS = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu",
"x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]
@@ -154,8 +155,10 @@ class MachCommands(CommandBase):
assert os.path.exists(servo_bin_dir)
if self.enable_media:
- print("Packaging gstreamer dylibs")
- if not package_gstreamer_dylibs(self.cross_compile_target, built_binary):
+ library_target_directory = path.join(path.dirname(built_binary), "lib/")
+ if not package_gstreamer_dylibs(built_binary,
+ library_target_directory,
+ self.cross_compile_target):
return 1
# On the Mac, set a lovely icon. This makes it easier to pick out the Servo binary in tools
@@ -293,104 +296,6 @@ class MachCommands(CommandBase):
print(f"[Warning] Could not generate notification: {e}", file=sys.stderr)
-def otool(s):
- o = subprocess.Popen(['/usr/bin/otool', '-L', s], stdout=subprocess.PIPE)
- for line in map(lambda s: s.decode('ascii'), o.stdout):
- if line[0] == '\t':
- yield line.split(' ', 1)[0][1:]
-
-
-def install_name_tool(binary, *args):
- try:
- subprocess.check_call(['install_name_tool', *args, binary])
- except subprocess.CalledProcessError as e:
- print("install_name_tool exited with return value %d" % e.returncode)
-
-
-def change_link_name(binary, old, new):
- install_name_tool(binary, '-change', old, f"@executable_path/{new}")
-
-
-def is_system_library(lib):
- return lib.startswith("/System/Library") or lib.startswith("/usr/lib") or ".asan." in lib
-
-
-def is_relocatable_library(lib):
- return lib.startswith("@rpath/")
-
-
-def change_non_system_libraries_path(libraries, relative_path, binary):
- for lib in libraries:
- if is_system_library(lib) or is_relocatable_library(lib):
- continue
- new_path = path.join(relative_path, path.basename(lib))
- change_link_name(binary, lib, new_path)
-
-
-def resolve_rpath(lib, rpath_root):
- if not is_relocatable_library(lib):
- return lib
-
- rpaths = ['', '../', 'gstreamer-1.0/']
- for rpath in rpaths:
- full_path = rpath_root + lib.replace('@rpath/', rpath)
- if path.exists(full_path):
- return path.normpath(full_path)
-
- raise Exception("Unable to satisfy rpath dependency: " + lib)
-
-
-def copy_dependencies(binary_path, lib_path, gst_lib_dir):
- relative_path = path.relpath(lib_path, path.dirname(binary_path)) + "/"
-
- # Update binary libraries
- binary_dependencies = set(otool(binary_path))
- change_non_system_libraries_path(binary_dependencies, relative_path, binary_path)
-
- plugins = [os.path.join(gst_lib_dir, "gstreamer-1.0", plugin) for plugin in macos_plugins()]
- binary_dependencies = binary_dependencies.union(plugins)
-
- # Update dependencies libraries
- need_checked = binary_dependencies
- checked = set()
- while need_checked:
- checking = set(need_checked)
- need_checked = set()
- for f in checking:
- # No need to check these for their dylibs
- if is_system_library(f):
- continue
- full_path = resolve_rpath(f, gst_lib_dir)
- need_relinked = set(otool(full_path))
- new_path = path.join(lib_path, path.basename(full_path))
- if not path.exists(new_path):
- shutil.copyfile(full_path, new_path)
- change_non_system_libraries_path(need_relinked, relative_path, new_path)
- need_checked.update(need_relinked)
- checked.update(checking)
- need_checked.difference_update(checked)
-
-
-def package_gstreamer_dylibs(cross_compilation_target, servo_bin):
- gst_root = servo.platform.get().gstreamer_root(cross_compilation_target)
-
- # This might be None if we are cross-compiling.
- if not gst_root:
- return True
-
- lib_dir = path.join(path.dirname(servo_bin), "lib")
- if os.path.exists(lib_dir):
- shutil.rmtree(lib_dir)
- os.mkdir(lib_dir)
- try:
- copy_dependencies(servo_bin, lib_dir, path.join(gst_root, 'lib', ''))
- except Exception as e:
- print("ERROR: could not package required dylibs")
- print(e)
- return False
- return True
-
-
def copy_windows_dlls_to_build_directory(servo_binary: str, target_triple: str) -> bool:
servo_exe_dir = os.path.dirname(servo_binary)
assert os.path.exists(servo_exe_dir)