|
10 | 10 | # user code can override this null handler
|
11 | 11 | logger.addHandler(logging.NullHandler())
|
12 | 12 |
|
| 13 | +def library_name(name, abi_number): |
| 14 | + is_windows = os.name == 'nt' |
| 15 | + is_mac = sys.platform == 'darwin' |
| 16 | + |
| 17 | + if is_windows: |
| 18 | + return f'lib{name}-{abi_number}.dll' |
| 19 | + elif is_mac: |
| 20 | + return f'lib{name}.{abi_number}.dylib' |
| 21 | + else: |
| 22 | + return f'lib{name}.so.{abi_number}' |
| 23 | + |
13 | 24 | # pull in our module version number
|
14 | 25 | from .version import __version__
|
15 | 26 |
|
|
48 | 59 |
|
49 | 60 | ffi = FFI()
|
50 | 61 |
|
51 |
| - _is_windows = os.name == 'nt' |
52 |
| - _is_mac = sys.platform == 'darwin' |
53 |
| - |
54 |
| - # yuk |
55 |
| - if _is_windows: |
56 |
| - vips_lib = ffi.dlopen('libvips-42.dll') |
57 |
| - elif _is_mac: |
58 |
| - vips_lib = ffi.dlopen('libvips.42.dylib') |
59 |
| - else: |
60 |
| - vips_lib = ffi.dlopen('libvips.so.42') |
| 62 | + vips_lib = ffi.dlopen(library_name('vips', 42)) |
| 63 | + glib_lib = vips_lib |
| 64 | + gobject_lib = vips_lib |
61 | 65 |
|
62 | 66 | logger.debug('Loaded lib %s', vips_lib)
|
63 | 67 |
|
64 |
| - if _is_windows: |
65 |
| - # On Windows, `GetProcAddress()` can only search in a specified DLL and |
66 |
| - # doesn't look into its dependent libraries for symbols. Therefore, we |
67 |
| - # check if the GLib DLLs are available. If these can not be found, we |
68 |
| - # assume that GLib is statically linked into libvips. |
69 |
| - try: |
70 |
| - glib_lib = ffi.dlopen('libglib-2.0-0.dll') |
71 |
| - gobject_lib = ffi.dlopen('libgobject-2.0-0.dll') |
72 |
| - |
73 |
| - logger.debug('Loaded lib %s', glib_lib) |
74 |
| - logger.debug('Loaded lib %s', gobject_lib) |
75 |
| - except Exception: |
76 |
| - glib_lib = vips_lib |
77 |
| - gobject_lib = vips_lib |
78 |
| - else: |
79 |
| - # macOS and *nix uses `dlsym()`, which also searches for named symbols |
80 |
| - # in the dependencies of the shared library. Therefore, we can support |
81 |
| - # a single shared libvips library with all dependencies statically |
82 |
| - # linked. |
83 |
| - glib_lib = vips_lib |
84 |
| - gobject_lib = vips_lib |
85 |
| - |
86 | 68 | ffi.cdef('''
|
87 | 69 | int vips_init (const char* argv0);
|
88 | 70 | int vips_version (int flag);
|
|
108 | 90 |
|
109 | 91 | ffi.cdef(cdefs(features))
|
110 | 92 |
|
| 93 | + # We can sometimes get dependent libraries from libvips -- either the platform |
| 94 | + # will open dependencies for us automatically, or the libvips binary has been |
| 95 | + # built to includes all main dependencies (common on windows, can happen |
| 96 | + # elsewhere). |
| 97 | + # |
| 98 | + # We must get glib functions from libvips if we can, since it will be the |
| 99 | + # one that libvips itself is using, and they will share runtime types. |
| 100 | + try: |
| 101 | + is_unified = gobject_lib.g_type_from_name(b'VipsImage') != 0 |
| 102 | + except Exception: |
| 103 | + is_unified = False |
| 104 | + |
| 105 | + if not is_unified: |
| 106 | + glib_lib = ffi.dlopen(library_name('glib-2.0', 0)) |
| 107 | + gobject_lib = ffi.dlopen(library_name('gobject-2.0', 0)) |
| 108 | + |
| 109 | + logger.debug('Loaded lib %s', glib_lib) |
| 110 | + logger.debug('Loaded lib %s', gobject_lib) |
| 111 | + |
111 | 112 |
|
112 | 113 | from .error import *
|
113 | 114 |
|
|
0 commit comments