|
1 | 1 | import os |
2 | 2 | import ctypes |
3 | 3 |
|
4 | | -def load_shared_library(lib_path): |
| 4 | +####################################################################################################################### |
| 5 | +# Version #1 |
| 6 | +####################################################################################################################### |
| 7 | +# def load_shared_library(lib_path): |
5 | 8 |
|
6 | | - # Load a shared library ensuring its symbols are globally available. This is necessary as |
7 | | - # the library provides symbols that your extension module (e.g., openfhe.so) depends on. |
8 | | - return ctypes.CDLL(lib_path, mode=ctypes.RTLD_GLOBAL) |
| 9 | +# # Load a shared library ensuring its symbols are globally available. This is necessary as |
| 10 | +# # the library provides symbols that your extension module (e.g., openfhe.so) depends on. |
| 11 | +# return ctypes.CDLL(lib_path, mode=ctypes.RTLD_GLOBAL) |
9 | 12 |
|
10 | | -# The absolute path of the current package directory |
11 | | -package_dir = os.path.abspath(os.path.dirname(__file__)) |
| 13 | +# # The absolute path of the current package directory |
| 14 | +# package_dir = os.path.abspath(os.path.dirname(__file__)) |
| 15 | + |
| 16 | +# # The directory where the shared libraries are located |
| 17 | +# libs_dir = os.path.join(package_dir, 'lib') |
| 18 | + |
| 19 | +# # List of all shared libraries to be loaded |
| 20 | +# shared_libs = ['libOPENFHEcore.so.1', |
| 21 | +# 'libOPENFHEbinfhe.so.1', |
| 22 | +# 'libOPENFHEpke.so.1', |
| 23 | +# 'libgomp.so'] |
| 24 | + |
| 25 | +# # Load each shared library |
| 26 | +# for lib in shared_libs: |
| 27 | +# lib_path = os.path.join(libs_dir, lib) |
| 28 | +# if not os.path.exists(lib_path): |
| 29 | +# raise FileNotFoundError(f"Required shared library not found: {lib_path}") |
| 30 | +# load_shared_library(lib_path) |
| 31 | + |
| 32 | +# # Import the Python wrapper module (openfhe.so) from this package |
| 33 | +# from .openfhe import * |
12 | 34 |
|
13 | | -# The directory where the shared libraries are located |
14 | | -libs_dir = os.path.join(package_dir, 'lib') |
| 35 | +####################################################################################################################### |
| 36 | +# Version #2 |
| 37 | +####################################################################################################################### |
| 38 | +# Description: |
| 39 | +# 1. check all directories in LD_LIBRARY_PATH for each .so.1. |
| 40 | +# 2. fall back cleanly to the bundled wheel contents if the external .so is missing. |
| 41 | +# 3. ensure RTLD_GLOBAL is used so Pybind11 bindings don’t hit undefined symbol errors. |
| 42 | +def load_shared_library(libname, fallback_dir): |
| 43 | + # Search LD_LIBRARY_PATH |
| 44 | + ld_paths = os.environ.get("LD_LIBRARY_PATH", "").split(":") |
| 45 | + for path in ld_paths: |
| 46 | + # skip 'libgomp.so' if LD_LIBRARY_PATH is set as we should get it from the libgomp.so location |
| 47 | + if libname == 'libgomp.so': |
| 48 | + return |
| 49 | + lib_path = os.path.join(path, libname) |
| 50 | + if os.path.exists(lib_path): |
| 51 | + return ctypes.CDLL(lib_path, mode=ctypes.RTLD_GLOBAL) |
| 52 | + |
| 53 | + # Fallback to bundled wheel/lib directory |
| 54 | + fallback_path = os.path.join(fallback_dir, libname) |
| 55 | + if os.path.exists(fallback_path): |
| 56 | + return ctypes.CDLL(fallback_path, mode=ctypes.RTLD_GLOBAL) |
| 57 | + |
| 58 | + raise FileNotFoundError( |
| 59 | + f"Shared library {libname} not found in LD_LIBRARY_PATH or fallback path:\n" |
| 60 | + f" - LD_LIBRARY_PATH: {ld_paths}\n" |
| 61 | + f" - Fallback path: {fallback_path}" |
| 62 | + ) |
| 63 | + |
| 64 | +# Path to the bundled `lib/` directory inside site-packages |
| 65 | +package_dir = os.path.abspath(os.path.dirname(__file__)) |
| 66 | +internal_lib_dir = os.path.join(package_dir, 'lib') |
15 | 67 |
|
16 | | -# List of all shared libraries to be loaded |
17 | | -shared_libs = ['libOPENFHEcore.so.1', |
18 | | - 'libOPENFHEbinfhe.so.1', |
19 | | - 'libOPENFHEpke.so.1', |
20 | | - 'libgomp.so'] |
| 68 | +# Shared libraries required |
| 69 | +shared_libs = [ |
| 70 | + 'libOPENFHEcore.so.1', |
| 71 | + 'libOPENFHEpke.so.1', |
| 72 | + 'libOPENFHEbinfhe.so.1', |
| 73 | + 'libgomp.so', # should be excluded if LD_LIBRARY_PATH is set |
| 74 | +] |
21 | 75 |
|
22 | | -# Load each shared library |
| 76 | +# Load them from LD_LIBRARY_PATH or internal fallback |
23 | 77 | for lib in shared_libs: |
24 | | - lib_path = os.path.join(libs_dir, lib) |
25 | | - if not os.path.exists(lib_path): |
26 | | - raise FileNotFoundError(f"Required shared library not found: {lib_path}") |
27 | | - load_shared_library(lib_path) |
| 78 | + load_shared_library(lib, fallback_dir=internal_lib_dir) |
28 | 79 |
|
29 | | -# Import the Python wrapper module (openfhe.so) from this package |
| 80 | +# Import the Pybind11 extension after shared libraries are loaded |
30 | 81 | from .openfhe import * |
0 commit comments