@@ -106,7 +106,7 @@ def _get_platform_dir() -> str:
106106
107107
108108def _load_single_library (lib_name : str ,
109- search_paths : list [Path ]) -> Optional [ctypes .CDLL ]:
109+ search_paths : list [Path ]) -> tuple [ Optional [ctypes .CDLL ], list [ tuple [ Path , Exception ]] ]:
110110 """
111111 Load a single library from the given search paths.
112112
@@ -115,14 +115,16 @@ def _load_single_library(lib_name: str,
115115 search_paths: List of paths to search for the library
116116
117117 Returns:
118- The loaded library or None if loading failed
118+ A tuple of ( loaded library or None, list of (path, error) for files that were found but failed to load)
119119 """
120120 if DEBUG_LIBRARY_LOADING : # pragma: no cover
121121 logger .info (f"Searching for library '{ lib_name } ' in paths: { [str (p ) for p in search_paths ]} " )
122122 current_arch = _get_architecture ()
123123 if DEBUG_LIBRARY_LOADING : # pragma: no cover
124124 logger .info (f"Current architecture: { current_arch } " )
125125
126+ load_errors = []
127+
126128 for path in search_paths :
127129 lib_path = path / lib_name
128130 if DEBUG_LIBRARY_LOADING : # pragma: no cover
@@ -131,17 +133,20 @@ def _load_single_library(lib_name: str,
131133 if DEBUG_LIBRARY_LOADING : # pragma: no cover
132134 logger .info (f"Found library at: { lib_path } " )
133135 try :
134- return ctypes .CDLL (str (lib_path ))
136+ return ctypes .CDLL (str (lib_path )), []
135137 except Exception as e :
136138 error_msg = str (e )
139+ load_errors .append ((lib_path , e ))
137140 if "incompatible architecture" in error_msg :
138141 logger .error (f"Architecture mismatch: Library at { lib_path } is not compatible with current architecture { current_arch } " )
139142 logger .error (f"Error details: { error_msg } " )
143+ elif "GLIBC" in error_msg or "version" in error_msg .lower ():
144+ logger .error (f"Library dependency error at { lib_path } : { error_msg } " )
140145 else :
141146 logger .error (f"Failed to load library from { lib_path } : { e } " )
142147 else :
143148 logger .debug (f"Library not found at: { lib_path } " )
144- return None
149+ return None , load_errors
145150
146151
147152def _get_possible_search_paths () -> list [Path ]:
@@ -250,19 +255,44 @@ def dynamically_load_library(
250255
251256 if lib_name :
252257 # If specific library name is provided, only load that one
253- lib = _load_single_library (lib_name , possible_paths )
258+ lib , load_errors = _load_single_library (lib_name , possible_paths )
254259 if not lib :
255260 platform_id = get_platform_identifier ()
256261 current_arch = _get_architecture ()
257- logger .error (f"Could not find { lib_name } in any of the search paths: { [str (p ) for p in possible_paths ]} " )
258- logger .error (f"Platform: { platform_id } , Architecture: { current_arch } " )
259- raise RuntimeError (f"Could not find { lib_name } in any of the search paths (Platform: { platform_id } , Architecture: { current_arch } )" )
262+
263+ if load_errors :
264+ # Library files were found but failed to load
265+ error_details = "\n " .join ([f" - { path } : { error } " for path , error in load_errors ])
266+ logger .error (f"Found { lib_name } but failed to load it. Errors encountered:" )
267+ logger .error (error_details )
268+ logger .error (f"Platform: { platform_id } , Architecture: { current_arch } " )
269+ raise RuntimeError (
270+ f"Found { lib_name } at { len (load_errors )} location(s) but failed to load:\n { error_details } \n "
271+ f"Platform: { platform_id } , Architecture: { current_arch } "
272+ )
273+ else :
274+ # Library file was not found in any search path
275+ logger .error (f"Could not find { lib_name } in any of the search paths: { [str (p ) for p in possible_paths ]} " )
276+ logger .error (f"Platform: { platform_id } , Architecture: { current_arch } " )
277+ raise RuntimeError (
278+ f"Could not find { lib_name } in any of the search paths (Platform: { platform_id } , Architecture: { current_arch } )"
279+ )
260280 return lib
261281
262282 # Default path (no library name provided in the environment)
263- c2pa_lib = _load_single_library (c2pa_lib_name , possible_paths )
283+ c2pa_lib , load_errors = _load_single_library (c2pa_lib_name , possible_paths )
264284 if not c2pa_lib :
265- logger .error (f"Could not find { c2pa_lib_name } in any of the search paths: { [str (p ) for p in possible_paths ]} " )
266- raise RuntimeError (f"Could not find { c2pa_lib_name } in any of the search paths" )
285+ if load_errors :
286+ # Library files were found but failed to load
287+ error_details = "\n " .join ([f" - { path } : { error } " for path , error in load_errors ])
288+ logger .error (f"Found { c2pa_lib_name } but failed to load it. Errors encountered:" )
289+ logger .error (error_details )
290+ raise RuntimeError (
291+ f"Found { c2pa_lib_name } at { len (load_errors )} location(s) but failed to load:\n { error_details } "
292+ )
293+ else :
294+ # Library file was not found in any search path
295+ logger .error (f"Could not find { c2pa_lib_name } in any of the search paths: { [str (p ) for p in possible_paths ]} " )
296+ raise RuntimeError (f"Could not find { c2pa_lib_name } in any of the search paths" )
267297
268298 return c2pa_lib
0 commit comments