| 
									
										
										
										
											2006-06-12 20:56:48 +00:00
										 |  |  | ###################################################################### | 
					
						
							|  |  |  | #  This file should be kept compatible with Python 2.3, see PEP 291. # | 
					
						
							|  |  |  | ###################################################################### | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  | import sys, os | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # find_library(name) returns the pathname of a library, or None. | 
					
						
							|  |  |  | if os.name == "nt": | 
					
						
							|  |  |  |     def find_library(name): | 
					
						
							|  |  |  |         # See MSDN for the REAL search order. | 
					
						
							|  |  |  |         for directory in os.environ['PATH'].split(os.pathsep): | 
					
						
							|  |  |  |             fname = os.path.join(directory, name) | 
					
						
							|  |  |  |             if os.path.exists(fname): | 
					
						
							|  |  |  |                 return fname | 
					
						
							|  |  |  |             if fname.lower().endswith(".dll"): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             fname = fname + ".dll" | 
					
						
							|  |  |  |             if os.path.exists(fname): | 
					
						
							|  |  |  |                 return fname | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if os.name == "ce": | 
					
						
							|  |  |  |     # search path according to MSDN: | 
					
						
							|  |  |  |     # - absolute path specified by filename | 
					
						
							|  |  |  |     # - The .exe launch directory | 
					
						
							|  |  |  |     # - the Windows directory | 
					
						
							|  |  |  |     # - ROM dll files (where are they?) | 
					
						
							|  |  |  |     # - OEM specified search path: HKLM\Loader\SystemPath | 
					
						
							|  |  |  |     def find_library(name): | 
					
						
							|  |  |  |         return name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if os.name == "posix" and sys.platform == "darwin": | 
					
						
							|  |  |  |     from ctypes.macholib.dyld import dyld_find as _dyld_find | 
					
						
							|  |  |  |     def find_library(name): | 
					
						
							|  |  |  |         possible = ['lib%s.dylib' % name, | 
					
						
							|  |  |  |                     '%s.dylib' % name, | 
					
						
							|  |  |  |                     '%s.framework/%s' % (name, name)] | 
					
						
							|  |  |  |         for name in possible: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 return _dyld_find(name) | 
					
						
							|  |  |  |             except ValueError: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | elif os.name == "posix": | 
					
						
							|  |  |  |     # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump | 
					
						
							| 
									
										
										
										
											2006-06-11 08:35:14 +00:00
										 |  |  |     import re, tempfile, errno | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _findLib_gcc(name): | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |         expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) | 
					
						
							| 
									
										
										
										
											2006-07-13 17:01:14 +00:00
										 |  |  |         fdout, ccout = tempfile.mkstemp() | 
					
						
							|  |  |  |         os.close(fdout) | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |         cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi;' \ | 
					
						
							| 
									
										
										
										
											2006-07-13 17:01:14 +00:00
										 |  |  |               '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |             f = os.popen(cmd) | 
					
						
							|  |  |  |             trace = f.read() | 
					
						
							|  |  |  |             f.close() | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |         finally: | 
					
						
							| 
									
										
										
										
											2006-07-13 17:01:14 +00:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 os.unlink(ccout) | 
					
						
							|  |  |  |             except OSError, e: | 
					
						
							|  |  |  |                 if e.errno != errno.ENOENT: | 
					
						
							|  |  |  |                     raise | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |         res = re.search(expr, trace) | 
					
						
							|  |  |  |         if not res: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         return res.group(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _get_soname(f): | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |         # assuming GNU binutils / ELF | 
					
						
							|  |  |  |         if not f: | 
					
						
							|  |  |  |             return None | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |         cmd = "objdump -p -j .dynamic 2>/dev/null " + f | 
					
						
							|  |  |  |         res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read()) | 
					
						
							|  |  |  |         if not res: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         return res.group(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |     if (sys.platform.startswith("freebsd") | 
					
						
							|  |  |  |         or sys.platform.startswith("openbsd") | 
					
						
							|  |  |  |         or sys.platform.startswith("dragonfly")): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def _num_version(libname): | 
					
						
							|  |  |  |             # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ] | 
					
						
							|  |  |  |             parts = libname.split(".") | 
					
						
							|  |  |  |             nums = [] | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 while parts: | 
					
						
							|  |  |  |                     nums.insert(0, int(parts.pop())) | 
					
						
							|  |  |  |             except ValueError: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             return nums or [ sys.maxint ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def find_library(name): | 
					
						
							|  |  |  |             ename = re.escape(name) | 
					
						
							|  |  |  |             expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename) | 
					
						
							|  |  |  |             res = re.findall(expr, | 
					
						
							|  |  |  |                              os.popen('/sbin/ldconfig -r 2>/dev/null').read()) | 
					
						
							|  |  |  |             if not res: | 
					
						
							|  |  |  |                 return _get_soname(_findLib_gcc(name)) | 
					
						
							|  |  |  |             res.sort(cmp= lambda x,y: cmp(_num_version(x), _num_version(y))) | 
					
						
							|  |  |  |             return res[-1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def _findLib_ldconfig(name): | 
					
						
							|  |  |  |             # XXX assuming GLIBC's ldconfig (with option -p) | 
					
						
							|  |  |  |             expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) | 
					
						
							|  |  |  |             res = re.search(expr, | 
					
						
							|  |  |  |                             os.popen('/sbin/ldconfig -p 2>/dev/null').read()) | 
					
						
							|  |  |  |             if not res: | 
					
						
							|  |  |  |                 # Hm, this works only for libs needed by the python executable. | 
					
						
							|  |  |  |                 cmd = 'ldd %s 2>/dev/null' % sys.executable | 
					
						
							|  |  |  |                 res = re.search(expr, os.popen(cmd).read()) | 
					
						
							|  |  |  |                 if not res: | 
					
						
							|  |  |  |                     return None | 
					
						
							|  |  |  |             return res.group(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def find_library(name): | 
					
						
							|  |  |  |             return _get_soname(_findLib_ldconfig(name) or _findLib_gcc(name)) | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ################################################################ | 
					
						
							|  |  |  | # test code | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test(): | 
					
						
							|  |  |  |     from ctypes import cdll | 
					
						
							|  |  |  |     if os.name == "nt": | 
					
						
							|  |  |  |         print cdll.msvcrt | 
					
						
							|  |  |  |         print cdll.load("msvcrt") | 
					
						
							|  |  |  |         print find_library("msvcrt") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if os.name == "posix": | 
					
						
							|  |  |  |         # find and load_version | 
					
						
							|  |  |  |         print find_library("m") | 
					
						
							|  |  |  |         print find_library("c") | 
					
						
							|  |  |  |         print find_library("bz2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # getattr | 
					
						
							|  |  |  | ##        print cdll.m | 
					
						
							|  |  |  | ##        print cdll.bz2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # load | 
					
						
							|  |  |  |         if sys.platform == "darwin": | 
					
						
							|  |  |  |             print cdll.LoadLibrary("libm.dylib") | 
					
						
							|  |  |  |             print cdll.LoadLibrary("libcrypto.dylib") | 
					
						
							|  |  |  |             print cdll.LoadLibrary("libSystem.dylib") | 
					
						
							|  |  |  |             print cdll.LoadLibrary("System.framework/System") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print cdll.LoadLibrary("libm.so") | 
					
						
							|  |  |  |             print cdll.LoadLibrary("libcrypt.so") | 
					
						
							|  |  |  |             print find_library("crypt") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     test() |