diff options
Diffstat (limited to 'buildutils/patch.py')
-rw-r--r-- | buildutils/patch.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/buildutils/patch.py b/buildutils/patch.py new file mode 100644 index 0000000..925b67b --- /dev/null +++ b/buildutils/patch.py @@ -0,0 +1,61 @@ +"""utils for patching libraries""" + +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + + +import re +import sys +import os +import logging + +from .misc import get_output_error + +pjoin = os.path.join + +# LIB_PAT from delocate +LIB_PAT = re.compile(r"\s*(.*) \(compatibility version (\d+\.\d+\.\d+), " + r"current version (\d+\.\d+\.\d+)\)") + +def _get_libs(fname): + rc, so, se = get_output_error(['otool', '-L', fname]) + if rc: + logging.error("otool -L %s failed: %r" % (fname, se)) + return + for line in so.splitlines()[1:]: + m = LIB_PAT.match(line) + if m: + yield m.group(1) + +def _find_library(lib, path): + """Find a library""" + for d in path[::-1]: + real_lib = os.path.join(d, lib) + if os.path.exists(real_lib): + return real_lib + +def _install_name_change(fname, lib, real_lib): + rc, so, se = get_output_error(['install_name_tool', '-change', lib, real_lib, fname]) + if rc: + logging.error("Couldn't update load path: %s", se) + +def patch_lib_paths(fname, library_dirs): + """Load any weakly-defined libraries from their real location + + (only on OS X) + + - Find libraries with `otool -L` + - Update with `install_name_tool -change` + """ + if sys.platform != 'darwin': + return + + libs = _get_libs(fname) + for lib in libs: + if not lib.startswith(('@', '/')): + real_lib = _find_library(lib, library_dirs) + if real_lib: + _install_name_change(fname, lib, real_lib) + + +__all__ = ['patch_lib_paths']
\ No newline at end of file |