summaryrefslogtreecommitdiffstats
path: root/external_libs/python/pyzmq-14.7.0/buildutils/patch.py
blob: 925b67b754052b3aa57a0f015ab8fb0f4e3f2f50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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']