|
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