Link mudraw binary to bundled libraries on Mac OS X

This commit is contained in:
Jonathan Springer 2014-06-13 23:40:12 -04:00
parent 8b446d6819
commit a4d4d233b0
1 changed files with 57 additions and 0 deletions

View File

@ -93,6 +93,11 @@ MuPDF
Required for PDF support in OpenLP. Install using macports, or use the
'--mudraw-bin' option of this script to point to the mudraw binary.
MachOLib
Python library to analyze and edit Mach-O headers, the executable format
used by Mac OS X. Used to relink the mudraw binary from MuPDF to the bundled
libraries. Install using macports or pip.
config.ini.default
The configuration file contains settings of the version string to include
in the bundle as well as directory and file settings for different
@ -126,6 +131,9 @@ from subprocess import Popen, PIPE
from configparser import ConfigParser
from argparse import ArgumentParser
from macholib.MachO import MachO
from macholib.util import flipwritable, in_system_path
def _which(command):
"""
@ -451,9 +459,58 @@ class MacosxBuilder(object):
self._print_verbose('... mudraw')
if self.mudraw_bin and os.path.isfile(self.mudraw_bin):
copy(os.path.join(self.mudraw_bin), os.path.join(self.dist_path, 'mudraw'))
self.relink_mudraw()
else:
self._print('... WARNING: mudraw not found')
def relink_mudraw(self):
"""
Relink mudraw to bundled libraries
"""
self._print('Linking mudraw with bundled libraries...')
libname = os.path.join(self.dist_path, 'mudraw')
distname = os.path.relpath(self.dist_path, libname)
self._print_verbose('... mudraw path %s', libname)
# Determine how many directories up is the directory with shared
# dynamic libraries. '../'
# E.g. ./qt4_plugins/images/ -> ./../../
parent_dir = ''
# Check if distname is not only base filename.
if os.path.dirname(distname):
parent_level = len(os.path.dirname(distname).split(os.sep))
parent_dir = parent_level * (os.pardir + os.sep)
def match_func(pth):
"""
For system libraries leave path unchanged.
"""
# Match non system dynamic libraries.
if not in_system_path(pth):
# Use relative path to dependend dynamic libraries bases on
# location of the executable.
pth = os.path.join('@loader_path', parent_dir, os.path.basename(pth))
self._print_verbose('... %s', pth)
return pth
# Rewrite mach headers with @loader_path.
dll = MachO(libname)
dll.rewriteLoadCommands(match_func)
# Write changes into file.
# Write code is based on macholib example.
try:
self._print_verbose('... writing new library paths')
f = open(dll.filename, 'rb+')
for header in dll.headers:
f.seek(0)
dll.write(f)
f.seek(0, 2)
f.flush()
f.close()
except Exception:
pass
def update_translations(self):
"""
Update the translations.